mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
refactor!: remove my shared link dto (#27023)
refactor!: remove deprecated shared link apis
This commit is contained in:
@@ -243,9 +243,21 @@ describe('/shared-links', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should get data for correct password protected link', async () => {
|
it('should get data for correct password protected link', async () => {
|
||||||
|
const response = await request(app)
|
||||||
|
.post('/shared-links/login')
|
||||||
|
.send({ password: 'foo' })
|
||||||
|
.query({ key: linkWithPassword.key });
|
||||||
|
|
||||||
|
expect(response.status).toBe(201);
|
||||||
|
|
||||||
|
const cookies = response.get('Set-Cookie') ?? [];
|
||||||
|
expect(cookies).toHaveLength(1);
|
||||||
|
expect(cookies[0]).toContain('immich_shared_link_token');
|
||||||
|
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/shared-links/me')
|
.get('/shared-links/me')
|
||||||
.query({ key: linkWithPassword.key, password: 'foo' });
|
.query({ key: linkWithPassword.key })
|
||||||
|
.set('Cookie', cookies);
|
||||||
|
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(200);
|
||||||
expect(body).toEqual(
|
expect(body).toEqual(
|
||||||
|
|||||||
Generated
+6
-36
@@ -27,11 +27,7 @@ class AlbumsApi {
|
|||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
///
|
///
|
||||||
/// * [BulkIdsDto] bulkIdsDto (required):
|
/// * [BulkIdsDto] bulkIdsDto (required):
|
||||||
///
|
Future<Response> addAssetsToAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async {
|
||||||
/// * [String] key:
|
|
||||||
///
|
|
||||||
/// * [String] slug:
|
|
||||||
Future<Response> addAssetsToAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { String? key, String? slug, }) async {
|
|
||||||
// ignore: prefer_const_declarations
|
// ignore: prefer_const_declarations
|
||||||
final apiPath = r'/albums/{id}/assets'
|
final apiPath = r'/albums/{id}/assets'
|
||||||
.replaceAll('{id}', id);
|
.replaceAll('{id}', id);
|
||||||
@@ -43,13 +39,6 @@ class AlbumsApi {
|
|||||||
final headerParams = <String, String>{};
|
final headerParams = <String, String>{};
|
||||||
final formParams = <String, String>{};
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
if (key != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'key', key));
|
|
||||||
}
|
|
||||||
if (slug != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'slug', slug));
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentTypes = <String>['application/json'];
|
const contentTypes = <String>['application/json'];
|
||||||
|
|
||||||
|
|
||||||
@@ -73,12 +62,8 @@ class AlbumsApi {
|
|||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
///
|
///
|
||||||
/// * [BulkIdsDto] bulkIdsDto (required):
|
/// * [BulkIdsDto] bulkIdsDto (required):
|
||||||
///
|
Future<List<BulkIdResponseDto>?> addAssetsToAlbum(String id, BulkIdsDto bulkIdsDto,) async {
|
||||||
/// * [String] key:
|
final response = await addAssetsToAlbumWithHttpInfo(id, bulkIdsDto,);
|
||||||
///
|
|
||||||
/// * [String] slug:
|
|
||||||
Future<List<BulkIdResponseDto>?> addAssetsToAlbum(String id, BulkIdsDto bulkIdsDto, { String? key, String? slug, }) async {
|
|
||||||
final response = await addAssetsToAlbumWithHttpInfo(id, bulkIdsDto, key: key, slug: slug, );
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
}
|
}
|
||||||
@@ -104,11 +89,7 @@ class AlbumsApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required):
|
/// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required):
|
||||||
///
|
Future<Response> addAssetsToAlbumsWithHttpInfo(AlbumsAddAssetsDto albumsAddAssetsDto,) async {
|
||||||
/// * [String] key:
|
|
||||||
///
|
|
||||||
/// * [String] slug:
|
|
||||||
Future<Response> addAssetsToAlbumsWithHttpInfo(AlbumsAddAssetsDto albumsAddAssetsDto, { String? key, String? slug, }) async {
|
|
||||||
// ignore: prefer_const_declarations
|
// ignore: prefer_const_declarations
|
||||||
final apiPath = r'/albums/assets';
|
final apiPath = r'/albums/assets';
|
||||||
|
|
||||||
@@ -119,13 +100,6 @@ class AlbumsApi {
|
|||||||
final headerParams = <String, String>{};
|
final headerParams = <String, String>{};
|
||||||
final formParams = <String, String>{};
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
if (key != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'key', key));
|
|
||||||
}
|
|
||||||
if (slug != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'slug', slug));
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentTypes = <String>['application/json'];
|
const contentTypes = <String>['application/json'];
|
||||||
|
|
||||||
|
|
||||||
@@ -147,12 +121,8 @@ class AlbumsApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required):
|
/// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required):
|
||||||
///
|
Future<AlbumsAddAssetsResponseDto?> addAssetsToAlbums(AlbumsAddAssetsDto albumsAddAssetsDto,) async {
|
||||||
/// * [String] key:
|
final response = await addAssetsToAlbumsWithHttpInfo(albumsAddAssetsDto,);
|
||||||
///
|
|
||||||
/// * [String] slug:
|
|
||||||
Future<AlbumsAddAssetsResponseDto?> addAssetsToAlbums(AlbumsAddAssetsDto albumsAddAssetsDto, { String? key, String? slug, }) async {
|
|
||||||
final response = await addAssetsToAlbumsWithHttpInfo(albumsAddAssetsDto, key: key, slug: slug, );
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-39
@@ -27,11 +27,7 @@ class SharedLinksApi {
|
|||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
///
|
///
|
||||||
/// * [AssetIdsDto] assetIdsDto (required):
|
/// * [AssetIdsDto] assetIdsDto (required):
|
||||||
///
|
Future<Response> addSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto,) async {
|
||||||
/// * [String] key:
|
|
||||||
///
|
|
||||||
/// * [String] slug:
|
|
||||||
Future<Response> addSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto, { String? key, String? slug, }) async {
|
|
||||||
// ignore: prefer_const_declarations
|
// ignore: prefer_const_declarations
|
||||||
final apiPath = r'/shared-links/{id}/assets'
|
final apiPath = r'/shared-links/{id}/assets'
|
||||||
.replaceAll('{id}', id);
|
.replaceAll('{id}', id);
|
||||||
@@ -43,13 +39,6 @@ class SharedLinksApi {
|
|||||||
final headerParams = <String, String>{};
|
final headerParams = <String, String>{};
|
||||||
final formParams = <String, String>{};
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
if (key != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'key', key));
|
|
||||||
}
|
|
||||||
if (slug != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'slug', slug));
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentTypes = <String>['application/json'];
|
const contentTypes = <String>['application/json'];
|
||||||
|
|
||||||
|
|
||||||
@@ -73,12 +62,8 @@ class SharedLinksApi {
|
|||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
///
|
///
|
||||||
/// * [AssetIdsDto] assetIdsDto (required):
|
/// * [AssetIdsDto] assetIdsDto (required):
|
||||||
///
|
Future<List<AssetIdsResponseDto>?> addSharedLinkAssets(String id, AssetIdsDto assetIdsDto,) async {
|
||||||
/// * [String] key:
|
final response = await addSharedLinkAssetsWithHttpInfo(id, assetIdsDto,);
|
||||||
///
|
|
||||||
/// * [String] slug:
|
|
||||||
Future<List<AssetIdsResponseDto>?> addSharedLinkAssets(String id, AssetIdsDto assetIdsDto, { String? key, String? slug, }) async {
|
|
||||||
final response = await addSharedLinkAssetsWithHttpInfo(id, assetIdsDto, key: key, slug: slug, );
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
}
|
}
|
||||||
@@ -235,14 +220,8 @@ class SharedLinksApi {
|
|||||||
///
|
///
|
||||||
/// * [String] key:
|
/// * [String] key:
|
||||||
///
|
///
|
||||||
/// * [String] password:
|
|
||||||
/// Link password
|
|
||||||
///
|
|
||||||
/// * [String] slug:
|
/// * [String] slug:
|
||||||
///
|
Future<Response> getMySharedLinkWithHttpInfo({ String? key, String? slug, }) async {
|
||||||
/// * [String] token:
|
|
||||||
/// Access token
|
|
||||||
Future<Response> getMySharedLinkWithHttpInfo({ String? key, String? password, String? slug, String? token, }) async {
|
|
||||||
// ignore: prefer_const_declarations
|
// ignore: prefer_const_declarations
|
||||||
final apiPath = r'/shared-links/me';
|
final apiPath = r'/shared-links/me';
|
||||||
|
|
||||||
@@ -256,15 +235,9 @@ class SharedLinksApi {
|
|||||||
if (key != null) {
|
if (key != null) {
|
||||||
queryParams.addAll(_queryParams('', 'key', key));
|
queryParams.addAll(_queryParams('', 'key', key));
|
||||||
}
|
}
|
||||||
if (password != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'password', password));
|
|
||||||
}
|
|
||||||
if (slug != null) {
|
if (slug != null) {
|
||||||
queryParams.addAll(_queryParams('', 'slug', slug));
|
queryParams.addAll(_queryParams('', 'slug', slug));
|
||||||
}
|
}
|
||||||
if (token != null) {
|
|
||||||
queryParams.addAll(_queryParams('', 'token', token));
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentTypes = <String>[];
|
const contentTypes = <String>[];
|
||||||
|
|
||||||
@@ -288,15 +261,9 @@ class SharedLinksApi {
|
|||||||
///
|
///
|
||||||
/// * [String] key:
|
/// * [String] key:
|
||||||
///
|
///
|
||||||
/// * [String] password:
|
|
||||||
/// Link password
|
|
||||||
///
|
|
||||||
/// * [String] slug:
|
/// * [String] slug:
|
||||||
///
|
Future<SharedLinkResponseDto?> getMySharedLink({ String? key, String? slug, }) async {
|
||||||
/// * [String] token:
|
final response = await getMySharedLinkWithHttpInfo( key: key, slug: slug, );
|
||||||
/// Access token
|
|
||||||
Future<SharedLinkResponseDto?> getMySharedLink({ String? key, String? password, String? slug, String? token, }) async {
|
|
||||||
final response = await getMySharedLinkWithHttpInfo( key: key, password: password, slug: slug, token: token, );
|
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1768,24 +1768,7 @@
|
|||||||
"put": {
|
"put": {
|
||||||
"description": "Send a list of asset IDs and album IDs to add each asset to each album.",
|
"description": "Send a list of asset IDs and album IDs to add each asset to each album.",
|
||||||
"operationId": "addAssetsToAlbums",
|
"operationId": "addAssetsToAlbums",
|
||||||
"parameters": [
|
"parameters": [],
|
||||||
{
|
|
||||||
"name": "key",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "slug",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
@@ -2184,22 +2167,6 @@
|
|||||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "key",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "slug",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
@@ -11427,15 +11394,6 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "password",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"description": "Link password",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "slug",
|
"name": "slug",
|
||||||
"required": false,
|
"required": false,
|
||||||
@@ -11443,15 +11401,6 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "token",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"description": "Access token",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -11766,22 +11715,6 @@
|
|||||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "key",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "slug",
|
|
||||||
"required": false,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
@@ -11838,6 +11771,7 @@
|
|||||||
"state": "Stable"
|
"state": "Stable"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"x-immich-permission": "sharedLink.update",
|
||||||
"x-immich-state": "Stable"
|
"x-immich-state": "Stable"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3684,18 +3684,13 @@ export function createAlbum({ createAlbumDto }: {
|
|||||||
/**
|
/**
|
||||||
* Add assets to albums
|
* Add assets to albums
|
||||||
*/
|
*/
|
||||||
export function addAssetsToAlbums({ key, slug, albumsAddAssetsDto }: {
|
export function addAssetsToAlbums({ albumsAddAssetsDto }: {
|
||||||
key?: string;
|
|
||||||
slug?: string;
|
|
||||||
albumsAddAssetsDto: AlbumsAddAssetsDto;
|
albumsAddAssetsDto: AlbumsAddAssetsDto;
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
data: AlbumsAddAssetsResponseDto;
|
data: AlbumsAddAssetsResponseDto;
|
||||||
}>(`/albums/assets${QS.query(QS.explode({
|
}>("/albums/assets", oazapfts.json({
|
||||||
key,
|
|
||||||
slug
|
|
||||||
}))}`, oazapfts.json({
|
|
||||||
...opts,
|
...opts,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: albumsAddAssetsDto
|
body: albumsAddAssetsDto
|
||||||
@@ -3778,19 +3773,14 @@ export function removeAssetFromAlbum({ id, bulkIdsDto }: {
|
|||||||
/**
|
/**
|
||||||
* Add assets to an album
|
* Add assets to an album
|
||||||
*/
|
*/
|
||||||
export function addAssetsToAlbum({ id, key, slug, bulkIdsDto }: {
|
export function addAssetsToAlbum({ id, bulkIdsDto }: {
|
||||||
id: string;
|
id: string;
|
||||||
key?: string;
|
|
||||||
slug?: string;
|
|
||||||
bulkIdsDto: BulkIdsDto;
|
bulkIdsDto: BulkIdsDto;
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
data: BulkIdResponseDto[];
|
data: BulkIdResponseDto[];
|
||||||
}>(`/albums/${encodeURIComponent(id)}/assets${QS.query(QS.explode({
|
}>(`/albums/${encodeURIComponent(id)}/assets`, oazapfts.json({
|
||||||
key,
|
|
||||||
slug
|
|
||||||
}))}`, oazapfts.json({
|
|
||||||
...opts,
|
...opts,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: bulkIdsDto
|
body: bulkIdsDto
|
||||||
@@ -5906,20 +5896,16 @@ export function sharedLinkLogin({ key, slug, sharedLinkLoginDto }: {
|
|||||||
/**
|
/**
|
||||||
* Retrieve current shared link
|
* Retrieve current shared link
|
||||||
*/
|
*/
|
||||||
export function getMySharedLink({ key, password, slug, token }: {
|
export function getMySharedLink({ key, slug }: {
|
||||||
key?: string;
|
key?: string;
|
||||||
password?: string;
|
|
||||||
slug?: string;
|
slug?: string;
|
||||||
token?: string;
|
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
data: SharedLinkResponseDto;
|
data: SharedLinkResponseDto;
|
||||||
}>(`/shared-links/me${QS.query(QS.explode({
|
}>(`/shared-links/me${QS.query(QS.explode({
|
||||||
key,
|
key,
|
||||||
password,
|
slug
|
||||||
slug,
|
|
||||||
token
|
|
||||||
}))}`, {
|
}))}`, {
|
||||||
...opts
|
...opts
|
||||||
}));
|
}));
|
||||||
@@ -5983,19 +5969,14 @@ export function removeSharedLinkAssets({ id, assetIdsDto }: {
|
|||||||
/**
|
/**
|
||||||
* Add assets to a shared link
|
* Add assets to a shared link
|
||||||
*/
|
*/
|
||||||
export function addSharedLinkAssets({ id, key, slug, assetIdsDto }: {
|
export function addSharedLinkAssets({ id, assetIdsDto }: {
|
||||||
id: string;
|
id: string;
|
||||||
key?: string;
|
|
||||||
slug?: string;
|
|
||||||
assetIdsDto: AssetIdsDto;
|
assetIdsDto: AssetIdsDto;
|
||||||
}, opts?: Oazapfts.RequestOpts) {
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
data: AssetIdsResponseDto[];
|
data: AssetIdsResponseDto[];
|
||||||
}>(`/shared-links/${encodeURIComponent(id)}/assets${QS.query(QS.explode({
|
}>(`/shared-links/${encodeURIComponent(id)}/assets`, oazapfts.json({
|
||||||
key,
|
|
||||||
slug
|
|
||||||
}))}`, oazapfts.json({
|
|
||||||
...opts,
|
...opts,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: assetIdsDto
|
body: assetIdsDto
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export class AlbumController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Put(':id/assets')
|
@Put(':id/assets')
|
||||||
@Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true })
|
@Authenticated({ permission: Permission.AlbumAssetCreate })
|
||||||
@Endpoint({
|
@Endpoint({
|
||||||
summary: 'Add assets to an album',
|
summary: 'Add assets to an album',
|
||||||
description: 'Add multiple assets to a specific album by its ID.',
|
description: 'Add multiple assets to a specific album by its ID.',
|
||||||
@@ -118,7 +118,7 @@ export class AlbumController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Put('assets')
|
@Put('assets')
|
||||||
@Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true })
|
@Authenticated({ permission: Permission.AlbumAssetCreate })
|
||||||
@Endpoint({
|
@Endpoint({
|
||||||
summary: 'Add assets to albums',
|
summary: 'Add assets to albums',
|
||||||
description: 'Send a list of asset IDs and album IDs to add each asset to each album.',
|
description: 'Send a list of asset IDs and album IDs to add each asset to each album.',
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import {
|
|||||||
SharedLinkCreateDto,
|
SharedLinkCreateDto,
|
||||||
SharedLinkEditDto,
|
SharedLinkEditDto,
|
||||||
SharedLinkLoginDto,
|
SharedLinkLoginDto,
|
||||||
SharedLinkPasswordDto,
|
|
||||||
SharedLinkResponseDto,
|
SharedLinkResponseDto,
|
||||||
SharedLinkSearchDto,
|
SharedLinkSearchDto,
|
||||||
} from 'src/dtos/shared-link.dto';
|
} from 'src/dtos/shared-link.dto';
|
||||||
@@ -96,21 +95,7 @@ export class SharedLinkController {
|
|||||||
description: 'Retrieve the current shared link associated with authentication method.',
|
description: 'Retrieve the current shared link associated with authentication method.',
|
||||||
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async getMySharedLink(
|
getMySharedLink(@Auth() auth: AuthDto, @Req() req: Request): Promise<SharedLinkResponseDto> {
|
||||||
@Auth() auth: AuthDto,
|
|
||||||
@Query() dto: SharedLinkPasswordDto,
|
|
||||||
@Req() req: Request,
|
|
||||||
@Res({ passthrough: true }) res: Response,
|
|
||||||
@GetLoginDetails() loginDetails: LoginDetails,
|
|
||||||
): Promise<SharedLinkResponseDto> {
|
|
||||||
if (dto.password) {
|
|
||||||
this.logger.deprecate(
|
|
||||||
'Passing shared link password via query parameters is deprecated and will be removed in the next major release. Please use POST /shared-links/login instead.',
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.sharedLinkLogin(auth, { password: dto.password }, req, res, loginDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.service.getMine(auth, getAuthTokens(req.cookies));
|
return this.service.getMine(auth, getAuthTokens(req.cookies));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +149,7 @@ export class SharedLinkController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Put(':id/assets')
|
@Put(':id/assets')
|
||||||
@Authenticated({ sharedLink: true })
|
@Authenticated({ permission: Permission.SharedLinkUpdate })
|
||||||
@Endpoint({
|
@Endpoint({
|
||||||
summary: 'Add assets to a shared link',
|
summary: 'Add assets to a shared link',
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -57,13 +57,6 @@ const SharedLinkLoginSchema = z
|
|||||||
})
|
})
|
||||||
.meta({ id: 'SharedLinkLoginDto' });
|
.meta({ id: 'SharedLinkLoginDto' });
|
||||||
|
|
||||||
const SharedLinkPasswordSchema = z
|
|
||||||
.object({
|
|
||||||
password: z.string().optional().describe('Link password'),
|
|
||||||
token: z.string().optional().describe('Access token'),
|
|
||||||
})
|
|
||||||
.meta({ id: 'SharedLinkPasswordDto' });
|
|
||||||
|
|
||||||
const SharedLinkResponseSchema = z
|
const SharedLinkResponseSchema = z
|
||||||
.object({
|
.object({
|
||||||
id: z.string().describe('Shared link ID'),
|
id: z.string().describe('Shared link ID'),
|
||||||
@@ -96,7 +89,6 @@ export class SharedLinkSearchDto extends createZodDto(SharedLinkSearchSchema) {}
|
|||||||
export class SharedLinkCreateDto extends createZodDto(SharedLinkCreateSchema) {}
|
export class SharedLinkCreateDto extends createZodDto(SharedLinkCreateSchema) {}
|
||||||
export class SharedLinkEditDto extends createZodDto(SharedLinkEditSchema) {}
|
export class SharedLinkEditDto extends createZodDto(SharedLinkEditSchema) {}
|
||||||
export class SharedLinkLoginDto extends createZodDto(SharedLinkLoginSchema) {}
|
export class SharedLinkLoginDto extends createZodDto(SharedLinkLoginSchema) {}
|
||||||
export class SharedLinkPasswordDto extends createZodDto(SharedLinkPasswordSchema) {}
|
|
||||||
export class SharedLinkResponseDto extends createZodDto(SharedLinkResponseSchema) {}
|
export class SharedLinkResponseDto extends createZodDto(SharedLinkResponseSchema) {}
|
||||||
|
|
||||||
export function mapSharedLink(sharedLink: SharedLink, options: { stripAssetMetadata: boolean }): SharedLinkResponseDto {
|
export function mapSharedLink(sharedLink: SharedLink, options: { stripAssetMetadata: boolean }): SharedLinkResponseDto {
|
||||||
|
|||||||
@@ -717,31 +717,6 @@ describe(AlbumService.name, () => {
|
|||||||
expect(mocks.album.update).not.toHaveBeenCalled();
|
expect(mocks.album.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow a shared link user to add assets', async () => {
|
|
||||||
const album = AlbumFactory.create();
|
|
||||||
const [asset1, asset2, asset3] = [AssetFactory.create(), AssetFactory.create(), AssetFactory.create()];
|
|
||||||
const auth = AuthFactory.from(album.owner).sharedLink({ allowUpload: true, userId: album.ownerId }).build();
|
|
||||||
mocks.access.album.checkSharedLinkAccess.mockResolvedValue(new Set([album.id]));
|
|
||||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset1.id, asset2.id, asset3.id]));
|
|
||||||
mocks.album.getById.mockResolvedValue(getForAlbum(album));
|
|
||||||
mocks.album.getAssetIds.mockResolvedValueOnce(new Set());
|
|
||||||
|
|
||||||
await expect(sut.addAssets(auth, album.id, { ids: [asset1.id, asset2.id, asset3.id] })).resolves.toEqual([
|
|
||||||
{ success: true, id: asset1.id },
|
|
||||||
{ success: true, id: asset2.id },
|
|
||||||
{ success: true, id: asset3.id },
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(mocks.album.update).toHaveBeenCalledWith(album.id, {
|
|
||||||
id: album.id,
|
|
||||||
updatedAt: expect.any(Date),
|
|
||||||
albumThumbnailAssetId: asset1.id,
|
|
||||||
});
|
|
||||||
expect(mocks.album.addAssetIds).toHaveBeenCalledWith(album.id, [asset1.id, asset2.id, asset3.id]);
|
|
||||||
|
|
||||||
expect(mocks.access.album.checkSharedLinkAccess).toHaveBeenCalledWith(auth.sharedLink?.id, new Set([album.id]));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow adding assets shared via partner sharing', async () => {
|
it('should allow adding assets shared via partner sharing', async () => {
|
||||||
const album = AlbumFactory.create();
|
const album = AlbumFactory.create();
|
||||||
const asset = AssetFactory.create();
|
const asset = AssetFactory.create();
|
||||||
@@ -964,40 +939,6 @@ describe(AlbumService.name, () => {
|
|||||||
expect(mocks.album.update).not.toHaveBeenCalled();
|
expect(mocks.album.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow a shared link user to add assets to multiple albums', async () => {
|
|
||||||
const album1 = AlbumFactory.create();
|
|
||||||
const album2 = AlbumFactory.create();
|
|
||||||
const [asset1, asset2, asset3] = [AssetFactory.create(), AssetFactory.create(), AssetFactory.create()];
|
|
||||||
mocks.access.album.checkSharedLinkAccess.mockResolvedValueOnce(new Set([album1.id]));
|
|
||||||
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset1.id, asset2.id, asset3.id]));
|
|
||||||
mocks.album.getById.mockResolvedValueOnce(getForAlbum(album1)).mockResolvedValueOnce(getForAlbum(album2));
|
|
||||||
mocks.album.getAssetIds.mockResolvedValueOnce(new Set()).mockResolvedValueOnce(new Set());
|
|
||||||
|
|
||||||
const auth = AuthFactory.from(album1.owner).sharedLink({ allowUpload: true }).build();
|
|
||||||
await expect(
|
|
||||||
sut.addAssetsToAlbums(auth, {
|
|
||||||
albumIds: [album1.id, album2.id],
|
|
||||||
assetIds: [asset1.id, asset2.id, asset3.id],
|
|
||||||
}),
|
|
||||||
).resolves.toEqual({ success: true, error: undefined });
|
|
||||||
|
|
||||||
expect(mocks.album.update).toHaveBeenCalledTimes(1);
|
|
||||||
expect(mocks.album.update).toHaveBeenNthCalledWith(1, album1.id, {
|
|
||||||
id: album1.id,
|
|
||||||
updatedAt: expect.any(Date),
|
|
||||||
albumThumbnailAssetId: asset1.id,
|
|
||||||
});
|
|
||||||
expect(mocks.album.addAssetIdsToAlbums).toHaveBeenCalledWith([
|
|
||||||
{ albumId: album1.id, assetId: asset1.id },
|
|
||||||
{ albumId: album1.id, assetId: asset2.id },
|
|
||||||
{ albumId: album1.id, assetId: asset3.id },
|
|
||||||
]);
|
|
||||||
expect(mocks.access.album.checkSharedLinkAccess).toHaveBeenCalledWith(
|
|
||||||
auth.sharedLink?.id,
|
|
||||||
new Set([album1.id, album2.id]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow adding assets shared via partner sharing', async () => {
|
it('should allow adding assets shared via partner sharing', async () => {
|
||||||
const user = UserFactory.create();
|
const user = UserFactory.create();
|
||||||
const album1 = AlbumFactory.create();
|
const album1 = AlbumFactory.create();
|
||||||
|
|||||||
@@ -165,12 +165,6 @@ export class AlbumService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addAssets(auth: AuthDto, id: string, dto: BulkIdsDto): Promise<BulkIdResponseDto[]> {
|
async addAssets(auth: AuthDto, id: string, dto: BulkIdsDto): Promise<BulkIdResponseDto[]> {
|
||||||
if (auth.sharedLink) {
|
|
||||||
this.logger.deprecate(
|
|
||||||
'Assets uploaded to a shared link are automatically added and calling this endpoint is no longer necessary. It will be removed in the next major release.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const album = await this.findOrFail(id, { withAssets: false });
|
const album = await this.findOrFail(id, { withAssets: false });
|
||||||
await this.requireAccess({ auth, permission: Permission.AlbumAssetCreate, ids: [id] });
|
await this.requireAccess({ auth, permission: Permission.AlbumAssetCreate, ids: [id] });
|
||||||
|
|
||||||
@@ -201,12 +195,6 @@ export class AlbumService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addAssetsToAlbums(auth: AuthDto, dto: AlbumsAddAssetsDto): Promise<AlbumsAddAssetsResponseDto> {
|
async addAssetsToAlbums(auth: AuthDto, dto: AlbumsAddAssetsDto): Promise<AlbumsAddAssetsResponseDto> {
|
||||||
if (auth.sharedLink) {
|
|
||||||
this.logger.deprecate(
|
|
||||||
'Assets uploaded to a shared link are automatically added and calling this endpoint is no longer necessary. It will be removed in the next major release.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const results: AlbumsAddAssetsResponseDto = {
|
const results: AlbumsAddAssetsResponseDto = {
|
||||||
success: false,
|
success: false,
|
||||||
error: BulkIdErrorReason.DUPLICATE,
|
error: BulkIdErrorReason.DUPLICATE,
|
||||||
|
|||||||
@@ -150,14 +150,7 @@ export class SharedLinkService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addAssets(auth: AuthDto, id: string, dto: AssetIdsDto): Promise<AssetIdsResponseDto[]> {
|
async addAssets(auth: AuthDto, id: string, dto: AssetIdsDto): Promise<AssetIdsResponseDto[]> {
|
||||||
if (auth.sharedLink) {
|
|
||||||
this.logger.deprecate(
|
|
||||||
'Assets uploaded using shared link authentication are now automatically added to the shared link during upload and in the next major release this endpoint will no longer accept shared link authentication',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sharedLink = await this.findOrFail(auth.user.id, id);
|
const sharedLink = await this.findOrFail(auth.user.id, id);
|
||||||
|
|
||||||
if (sharedLink.type !== SharedLinkType.Individual) {
|
if (sharedLink.type !== SharedLinkType.Individual) {
|
||||||
throw new BadRequestException('Invalid shared link type');
|
throw new BadRequestException('Invalid shared link type');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,11 +79,6 @@ const checkSharedLinkAccess = async (
|
|||||||
return sharedLink.allowUpload ? ids : new Set();
|
return sharedLink.allowUpload ? ids : new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Permission.AssetShare: {
|
|
||||||
// TODO: fix this to not use sharedLink.userId for access control
|
|
||||||
return await access.asset.checkOwnerAccess(sharedLink.userId, ids, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Permission.AlbumRead: {
|
case Permission.AlbumRead: {
|
||||||
return await access.album.checkSharedLinkAccess(sharedLinkId, ids);
|
return await access.album.checkSharedLinkAccess(sharedLinkId, ids);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user