Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/photos.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Chemineau <louis@chmn.me>2022-09-22 17:35:00 +0300
committerLouis Chemineau <louis@chmn.me>2022-10-20 12:54:09 +0300
commit37e94bcacad19fe4240f48661be84ee649c47735 (patch)
tree8bdbf7f81d6aa882e8e50cf45d53797e7c6f40bb
parente721cd51df526e1f33cd9e5a22969b26d926d229 (diff)
Display album's name instead of token
Signed-off-by: Louis Chemineau <louis@chmn.me>
-rw-r--r--appinfo/routes.php4
-rw-r--r--lib/Album/AlbumMapper.php2
-rw-r--r--lib/Controller/PublicAlbumController.php29
-rw-r--r--lib/Sabre/Album/PropFindPlugin.php16
-rw-r--r--lib/Sabre/Album/PublicAlbumsHome.php12
-rw-r--r--lib/Sabre/PhotosHome.php8
-rw-r--r--lib/Sabre/RootCollection.php8
-rw-r--r--src/components/Albums/CollaboratorsSelectionForm.vue2
-rw-r--r--src/router/index.js5
-rw-r--r--src/services/Albums.js40
-rw-r--r--src/views/PublicAlbumContent.vue29
11 files changed, 81 insertions, 74 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 2389fc2d..3ba966d5 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -46,12 +46,12 @@ return [
'path' => '',
]
],
- [ 'name' => 'publicAlbum#get', 'url' => '/public/{ownerId}/{token}', 'verb' => 'GET',
+ [ 'name' => 'publicAlbum#get', 'url' => '/public/{ownerId}/{path}', 'verb' => 'GET',
'requirements' => [
'ownerId' => '.*',
],
'requirements' => [
- 'token' => '.*',
+ 'path' => '.*',
],
],
['name' => 'page#index', 'url' => '/folders/{path}', 'verb' => 'GET', 'postfix' => 'folders',
diff --git a/lib/Album/AlbumMapper.php b/lib/Album/AlbumMapper.php
index 577e0064..2b92c3b8 100644
--- a/lib/Album/AlbumMapper.php
+++ b/lib/Album/AlbumMapper.php
@@ -309,7 +309,7 @@ class AlbumMapper {
$displayName = $this->groupManager->get($row['collaborator_id'])->getDisplayName();
break;
case self::TYPE_LINK:
- $displayName = $this->l->t('Public link');;
+ $displayName = $this->l->t('Public link');
break;
default:
throw new \Exception('Invalid collaborator type: ' . $row['collaborator_type']);
diff --git a/lib/Controller/PublicAlbumController.php b/lib/Controller/PublicAlbumController.php
index b9a9364e..c7143363 100644
--- a/lib/Controller/PublicAlbumController.php
+++ b/lib/Controller/PublicAlbumController.php
@@ -24,7 +24,7 @@
namespace OCA\Photos\Controller;
-use OCP\AppFramework\PublicShareController;
+use OCP\AppFramework\Controller;
use OCA\Files\Event\LoadSidebar;
use OCA\Photos\AppInfo\Application;
use OCA\Photos\Service\UserConfigService;
@@ -38,8 +38,7 @@ use OCP\IRequest;
use OCP\ISession;
use OCP\Util;
-
-class PublicAlbumController extends PublicShareController {
+class PublicAlbumController extends Controller {
private IAppManager $appManager;
private IEventDispatcher $eventDispatcher;
private UserConfigService $userConfig;
@@ -62,28 +61,6 @@ class PublicAlbumController extends PublicShareController {
}
/**
- * Validate the token of this share. If the token is invalid this controller
- * will return a 404.
- */
- public function isValidToken(): bool {
- // TODO: uncomment
- // $album = $this->albumMapper->getAlbumForToken($this->getToken);
- // return $album !== null;
- return true;
- }
-
- public function getPasswordHash(): string {
- return '';
- }
-
- /**
- * Allows you to specify if this share is password protected
- */
- protected function isPasswordProtected(): bool {
- return false;
- }
-
- /**
* Your normal controller function. The following annotation will allow guests
* to open the page as well
*
@@ -120,4 +97,4 @@ class PublicAlbumController extends PublicShareController {
return $response;
}
-} \ No newline at end of file
+}
diff --git a/lib/Sabre/Album/PropFindPlugin.php b/lib/Sabre/Album/PropFindPlugin.php
index 00fb8017..3311b43e 100644
--- a/lib/Sabre/Album/PropFindPlugin.php
+++ b/lib/Sabre/Album/PropFindPlugin.php
@@ -87,10 +87,10 @@ class PropFindPlugin extends ServerPlugin {
}
$propFind->handle(FilesPlugin::INTERNAL_FILEID_PROPERTYNAME, fn () => $node->getFile()->getFileId());
- $propFind->handle(FilesPlugin::GETETAG_PROPERTYNAME, fn () => $node->getETag());
- $propFind->handle(self::FILE_NAME_PROPERTYNAME, fn () => $node->getFile()->getName());
- $propFind->handle(self::FAVORITE_PROPERTYNAME, fn () => $node->isFavorite() ? 1 : 0);
- $propFind->handle(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, fn () => json_encode($this->previewManager->isAvailable($fileInfo)));
+ $propFind->handle(FilesPlugin::GETETAG_PROPERTYNAME, fn () => $node->getETag());
+ $propFind->handle(self::FILE_NAME_PROPERTYNAME, fn () => $node->getFile()->getName());
+ $propFind->handle(self::FAVORITE_PROPERTYNAME, fn () => $node->isFavorite() ? 1 : 0);
+ $propFind->handle(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, fn () => json_encode($this->previewManager->isAvailable($fileInfo)));
if ($this->metadataEnabled) {
$propFind->handle(FilesPlugin::FILE_METADATA_SIZE, function () use ($node) {
@@ -110,10 +110,10 @@ class PropFindPlugin extends ServerPlugin {
}
if ($node instanceof AlbumRoot) {
- $propFind->handle(self::LAST_PHOTO_PROPERTYNAME, fn () => $node->getAlbum()->getAlbum()->getLastAddedPhoto());
- $propFind->handle(self::NBITEMS_PROPERTYNAME, fn () => count($node->getChildren()));
- $propFind->handle(self::LOCATION_PROPERTYNAME, fn () => $node->getAlbum()->getAlbum()->getLocation());
- $propFind->handle(self::DATE_RANGE_PROPERTYNAME, fn () => json_encode($node->getDateRange()));
+ $propFind->handle(self::LAST_PHOTO_PROPERTYNAME, fn () => $node->getAlbum()->getAlbum()->getLastAddedPhoto());
+ $propFind->handle(self::NBITEMS_PROPERTYNAME, fn () => count($node->getChildren()));
+ $propFind->handle(self::LOCATION_PROPERTYNAME, fn () => $node->getAlbum()->getAlbum()->getLocation());
+ $propFind->handle(self::DATE_RANGE_PROPERTYNAME, fn () => json_encode($node->getDateRange()));
$propFind->handle(self::COLLABORATORS_PROPERTYNAME, fn () => $node->getCollaborators());
// TODO detect dynamically which metadata groups are requested and
diff --git a/lib/Sabre/Album/PublicAlbumsHome.php b/lib/Sabre/Album/PublicAlbumsHome.php
index 9d7d7362..f7d7e033 100644
--- a/lib/Sabre/Album/PublicAlbumsHome.php
+++ b/lib/Sabre/Album/PublicAlbumsHome.php
@@ -25,19 +25,22 @@ namespace OCA\Photos\Sabre\Album;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\Server;
use OCP\Files\IRootFolder;
use OCP\IUser;
-use OCA\Photos\Sabre\Album\PublicAlbumRoot;
use OCA\Photos\Service\UserConfigService;
use OCA\Photos\Album\AlbumMapper;
class PublicAlbumsHome extends AlbumsHome {
+ private Server $server;
+
public function __construct(
array $principalInfo,
AlbumMapper $albumMapper,
IUser $user,
IRootFolder $rootFolder,
UserConfigService $userConfigService,
+ Server $server
) {
parent::__construct(
$principalInfo,
@@ -46,6 +49,8 @@ class PublicAlbumsHome extends AlbumsHome {
$rootFolder,
$userConfigService,
);
+
+ $this->server = $server;
}
public function getName(): string {
@@ -60,7 +65,10 @@ class PublicAlbumsHome extends AlbumsHome {
}
public function getChild($name) {
- $albums = $this->albumMapper->getSharedAlbumsForCollaboratorWithFiles($name, AlbumMapper::TYPE_LINK);
+ $basicAuth = $this->server->httpRequest->getHeader('Authorization');
+ [, $base64Token] = explode('Basic ', $basicAuth);
+ $token = \base64_decode($base64Token);
+ $albums = $this->albumMapper->getSharedAlbumsForCollaboratorWithFiles($token, AlbumMapper::TYPE_LINK);
array_filter($albums, fn ($album) => $album->getAlbum()->getUserId() === $this->user->getUid());
diff --git a/lib/Sabre/PhotosHome.php b/lib/Sabre/PhotosHome.php
index ba4d266e..7e69e991 100644
--- a/lib/Sabre/PhotosHome.php
+++ b/lib/Sabre/PhotosHome.php
@@ -34,6 +34,7 @@ use OCP\IGroupManager;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\ICollection;
+use Sabre\DAV\Server;
class PhotosHome implements ICollection {
private AlbumMapper $albumMapper;
@@ -42,6 +43,7 @@ class PhotosHome implements ICollection {
private IRootFolder $rootFolder;
private IGroupManager $groupManager;
private UserConfigService $userConfigService;
+ private Server $server;
public function __construct(
array $principalInfo,
@@ -49,7 +51,8 @@ class PhotosHome implements ICollection {
IUser $user,
IRootFolder $rootFolder,
IGroupManager $groupManager,
- UserConfigService $userConfigService
+ UserConfigService $userConfigService,
+ Server $server
) {
$this->principalInfo = $principalInfo;
$this->albumMapper = $albumMapper;
@@ -57,6 +60,7 @@ class PhotosHome implements ICollection {
$this->rootFolder = $rootFolder;
$this->groupManager = $groupManager;
$this->userConfigService = $userConfigService;
+ $this->server = $server;
}
/**
@@ -95,7 +99,7 @@ class PhotosHome implements ICollection {
} elseif ($name === 'sharedalbums') {
return new SharedAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->groupManager, $this->userConfigService);
} elseif ($name === 'public') {
- return new PublicAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService);
+ return new PublicAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService, $this->server);
}
throw new NotFound();
diff --git a/lib/Sabre/RootCollection.php b/lib/Sabre/RootCollection.php
index 2e879f9d..96350927 100644
--- a/lib/Sabre/RootCollection.php
+++ b/lib/Sabre/RootCollection.php
@@ -29,6 +29,7 @@ use OCP\Files\IRootFolder;
use OCP\IUserSession;
use Sabre\DAVACL\AbstractPrincipalCollection;
use Sabre\DAVACL\PrincipalBackend;
+use Sabre\DAV\Server;
use OCP\IGroupManager;
class RootCollection extends AbstractPrincipalCollection {
@@ -37,6 +38,7 @@ class RootCollection extends AbstractPrincipalCollection {
private IRootFolder $rootFolder;
private IGroupManager $groupManager;
private UserConfigService $userConfigService;
+ private Server $server;
public function __construct(
AlbumMapper $folderMapper,
@@ -44,7 +46,8 @@ class RootCollection extends AbstractPrincipalCollection {
IRootFolder $rootFolder,
PrincipalBackend\BackendInterface $principalBackend,
IGroupManager $groupManager,
- UserConfigService $userConfigService
+ UserConfigService $userConfigService,
+ Server $server
) {
parent::__construct($principalBackend, 'principals/users');
@@ -53,6 +56,7 @@ class RootCollection extends AbstractPrincipalCollection {
$this->rootFolder = $rootFolder;
$this->groupManager = $groupManager;
$this->userConfigService = $userConfigService;
+ $this->server = $server;
}
/**
@@ -70,7 +74,7 @@ class RootCollection extends AbstractPrincipalCollection {
if (is_null($user) || $name !== $user->getUID()) {
throw new \Sabre\DAV\Exception\Forbidden();
}
- return new PhotosHome($principalInfo, $this->folderMapper, $user, $this->rootFolder, $this->groupManager, $this->userConfigService);
+ return new PhotosHome($principalInfo, $this->folderMapper, $user, $this->rootFolder, $this->groupManager, $this->userConfigService, $this->server);
}
public function getName(): string {
diff --git a/src/components/Albums/CollaboratorsSelectionForm.vue b/src/components/Albums/CollaboratorsSelectionForm.vue
index d55a3a83..04bbc7f4 100644
--- a/src/components/Albums/CollaboratorsSelectionForm.vue
+++ b/src/components/Albums/CollaboratorsSelectionForm.vue
@@ -348,7 +348,7 @@ export default {
},
async copyPublicLink() {
- await navigator.clipboard.writeText(`${window.location.protocol}//${window.location.host}${generateUrl(`apps/photos/public/${getCurrentUser().uid}/${this.publicLink.id}`)}`)
+ await navigator.clipboard.writeText(`${window.location.protocol}//${window.location.host}${generateUrl(`apps/photos/public/${getCurrentUser().uid}/${this.albumName}?token=${this.publicLink.id}`)}`)
this.publicLinkCopied = true
setTimeout(() => {
this.publicLinkCopied = false
diff --git a/src/router/index.js b/src/router/index.js
index b9a96bc9..d22e28ac 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -120,12 +120,13 @@ const router = new Router({
}),
},
{
- path: '/public/:userId/:token',
+ path: '/public/:userId/:path*',
component: PublicAlbumContent,
name: 'publicAlbums',
props: route => ({
userId: route.params.userId,
- token: route.params.token,
+ albumName: route.params.path,
+ token: route.query.token,
}),
},
{
diff --git a/src/services/Albums.js b/src/services/Albums.js
index 3dc33297..5d5c6a87 100644
--- a/src/services/Albums.js
+++ b/src/services/Albums.js
@@ -21,7 +21,6 @@
*/
import moment from '@nextcloud/moment'
-import { showError } from '@nextcloud/dialogs'
import { translate } from '@nextcloud/l10n'
import client from '../services/DavClient.js'
@@ -43,12 +42,13 @@ import { genFileInfo } from '../utils/fileUtils.js'
/**
*
* @param {string} path - Albums' root path.
- * @param {AbortSignal} signal - Abort signal to cancel the request.
+ * @param {import('webdav').StatOptions} options - Options to forward to the webdav client.
+ * @param {import('webdav').WebDAVClient} customClient
* @return {Promise<Album|null>}
*/
-export async function fetchAlbum(path, signal) {
+export async function fetchAlbum(path, options, customClient) {
try {
- const response = await client.stat(path, {
+ const response = await (customClient || client).stat(path, {
data: `<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:"
xmlns:oc="http://owncloud.org/ns"
@@ -62,8 +62,8 @@ export async function fetchAlbum(path, signal) {
<nc:collaborators />
</d:prop>
</d:propfind>`,
- signal,
details: true,
+ ...options,
})
logger.debug('[Albums] Fetched an album: ', response.data)
@@ -81,12 +81,13 @@ export async function fetchAlbum(path, signal) {
/**
*
* @param {string} path - Albums' root path.
- * @param {AbortSignal} signal - Abort signal to cancel the request.
+ * @param {import('webdav').StatOptions} options - Options to forward to the webdav client.
+ * @param {import('webdav').WebDAVClient} customClient
* @return {Promise<Album[]>}
*/
-export async function fetchAlbums(path, signal) {
+export async function fetchAlbums(path, options, customClient) {
try {
- const response = await client.getDirectoryContents(path, {
+ const response = await (customClient || client).getDirectoryContents(path, {
data: `<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:"
xmlns:oc="http://owncloud.org/ns"
@@ -101,7 +102,7 @@ export async function fetchAlbums(path, signal) {
</d:prop>
</d:propfind>`,
details: true,
- signal,
+ ...options,
})
logger.debug(`[Albums] Fetched ${response.data.length} albums: `, response.data)
@@ -144,14 +145,14 @@ function formatAlbum(album) {
dateRange.start = moment().unix()
dateRange.end = moment().unix()
}
- const dateRangeFormated = {
+ const dateRangeFormatted = {
startDate: moment.unix(dateRange.start).format('MMMM YYYY'),
endDate: moment.unix(dateRange.end).format('MMMM YYYY'),
}
- if (dateRangeFormated.startDate === dateRangeFormated.endDate) {
- album.date = dateRangeFormated.startDate
+ if (dateRangeFormatted.startDate === dateRangeFormatted.endDate) {
+ album.date = dateRangeFormatted.startDate
} else {
- album.date = translate('photos', '{startDate} to {endDate}', dateRangeFormated)
+ album.date = translate('photos', '{startDate} to {endDate}', dateRangeFormatted)
}
return album
@@ -160,15 +161,16 @@ function formatAlbum(album) {
/**
*
* @param {string} path - Albums' root path.
- * @param {AbortSignal} signal - Abort signal to cancel the request.
- * @return {Promise<[]>}
+ * @param {import('webdav').StatOptions} options - Options to forward to the webdav client.
+ * @param {import('webdav').WebDAVClient} customClient
+ * @return {Promise<Array>}
*/
-export async function fetchAlbumContent(path, signal) {
+export async function fetchAlbumContent(path, options, customClient) {
try {
- const response = await client.getDirectoryContents(path, {
+ const response = await (customClient || client).getDirectoryContents(path, {
data: DavRequest,
details: true,
- signal,
+ ...options,
})
const fetchedFiles = response.data
@@ -188,4 +190,4 @@ export async function fetchAlbumContent(path, signal) {
throw error
}
-} \ No newline at end of file
+}
diff --git a/src/views/PublicAlbumContent.vue b/src/views/PublicAlbumContent.vue
index 941bcd60..4a8056a9 100644
--- a/src/views/PublicAlbumContent.vue
+++ b/src/views/PublicAlbumContent.vue
@@ -103,6 +103,7 @@
<script>
import { mapActions, mapGetters } from 'vuex'
+
import MapMarker from 'vue-material-design-icons/MapMarker'
import Plus from 'vue-material-design-icons/Plus'
import ImagePlus from 'vue-material-design-icons/ImagePlus'
@@ -154,6 +155,10 @@ export default {
type: String,
required: true,
},
+ albumName: {
+ type: String,
+ required: true,
+ },
token: {
type: String,
required: true,
@@ -167,7 +172,7 @@ export default {
errorFetchingAlbum: null,
loadingCount: 0,
loadingAddFilesToAlbum: false,
- albumName: '',
+ publicClient: null,
}
},
@@ -215,9 +220,13 @@ export default {
this.loadingAlbum = true
this.errorFetchingAlbum = null
- const album = await fetchAlbum(`/photos/${this.userId}/public/${this.token}`, this.abortController.signal)
+ const album = await fetchAlbum(`/photos/${this.userId}/public/${this.albumName}`, {
+ signal: this.abortController.signal,
+ headers: {
+ Authorization: `Basic ${btoa(this.token)}`,
+ },
+ })
this.addPublicAlbums({ collections: [album] })
- this.albumName = album.basename
} catch (error) {
if (error.response?.status === 404) {
this.errorFetchingAlbum = 404
@@ -245,10 +254,12 @@ export default {
this.loadingFiles = true
this.semaphoreSymbol = semaphoreSymbol
- const fetchedFiles = await fetchAlbumContent(
- `/photos/${this.userId}/public/${this.token}`,
- this.abortController.signal,
- )
+ const fetchedFiles = await fetchAlbumContent(`/photos/${this.userId}/public/${this.albumName}`, {
+ signal: this.abortController.signal,
+ headers: {
+ Authorization: `Basic ${btoa(this.token)}`,
+ },
+ })
const fileIds = fetchedFiles
.map(file => file.fileid.toString())
@@ -281,14 +292,14 @@ export default {
async handleFilesPicked(fileIds) {
this.showAddPhotosModal = false
- await this.addFilesToPublicAlbum({ collectionName: this.albumName, fileIdsToAdd: fileIds })
+ await this.addFilesToPublicAlbum({ collectionId: this.albumName, fileIdsToAdd: fileIds })
// Re-fetch album content to have the proper filenames.
await this.fetchAlbumContent()
},
async handleRemoveFilesFromAlbum(fileIds) {
this.$refs.collectionContent.onUncheckFiles(fileIds)
- await this.removeFilesFromPublicAlbum({ collectionName: this.albumName, fileIdsToRemove: fileIds })
+ await this.removeFilesFromPublicAlbum({ collectionId: this.albumName, fileIdsToRemove: fileIds })
},
},
}