mirror of
https://github.com/immich-app/immich.git
synced 2026-07-15 21:32:32 +03:00
refactor(server): album user route params (#29503)
This commit is contained in:
8
mobile/openapi/lib/api/albums_api.dart
generated
8
mobile/openapi/lib/api/albums_api.dart
generated
@@ -681,8 +681,10 @@ class AlbumsApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
|
/// Album ID
|
||||||
///
|
///
|
||||||
/// * [String] userId (required):
|
/// * [String] userId (required):
|
||||||
|
/// Album user ID, or \"me\" to reference the current user.
|
||||||
Future<Response> removeUserFromAlbumWithHttpInfo(String id, String userId, { Future<void>? abortTrigger, }) async {
|
Future<Response> removeUserFromAlbumWithHttpInfo(String id, String userId, { Future<void>? abortTrigger, }) async {
|
||||||
// ignore: prefer_const_declarations
|
// ignore: prefer_const_declarations
|
||||||
final apiPath = r'/albums/{id}/user/{userId}'
|
final apiPath = r'/albums/{id}/user/{userId}'
|
||||||
@@ -718,8 +720,10 @@ class AlbumsApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
|
/// Album ID
|
||||||
///
|
///
|
||||||
/// * [String] userId (required):
|
/// * [String] userId (required):
|
||||||
|
/// Album user ID, or \"me\" to reference the current user.
|
||||||
Future<void> removeUserFromAlbum(String id, String userId, { Future<void>? abortTrigger, }) async {
|
Future<void> removeUserFromAlbum(String id, String userId, { Future<void>? abortTrigger, }) async {
|
||||||
final response = await removeUserFromAlbumWithHttpInfo(id, userId, abortTrigger: abortTrigger,);
|
final response = await removeUserFromAlbumWithHttpInfo(id, userId, abortTrigger: abortTrigger,);
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
@@ -798,8 +802,10 @@ class AlbumsApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
|
/// Album ID
|
||||||
///
|
///
|
||||||
/// * [String] userId (required):
|
/// * [String] userId (required):
|
||||||
|
/// Album user ID, or \"me\" to reference the current user.
|
||||||
///
|
///
|
||||||
/// * [UpdateAlbumUserDto] updateAlbumUserDto (required):
|
/// * [UpdateAlbumUserDto] updateAlbumUserDto (required):
|
||||||
Future<Response> updateAlbumUserWithHttpInfo(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto, { Future<void>? abortTrigger, }) async {
|
Future<Response> updateAlbumUserWithHttpInfo(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto, { Future<void>? abortTrigger, }) async {
|
||||||
@@ -837,8 +843,10 @@ class AlbumsApi {
|
|||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
/// * [String] id (required):
|
/// * [String] id (required):
|
||||||
|
/// Album ID
|
||||||
///
|
///
|
||||||
/// * [String] userId (required):
|
/// * [String] userId (required):
|
||||||
|
/// Album user ID, or \"me\" to reference the current user.
|
||||||
///
|
///
|
||||||
/// * [UpdateAlbumUserDto] updateAlbumUserDto (required):
|
/// * [UpdateAlbumUserDto] updateAlbumUserDto (required):
|
||||||
Future<void> updateAlbumUser(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto, { Future<void>? abortTrigger, }) async {
|
Future<void> updateAlbumUser(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto, { Future<void>? abortTrigger, }) async {
|
||||||
|
|||||||
@@ -2702,6 +2702,7 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"required": true,
|
"required": true,
|
||||||
"in": "path",
|
"in": "path",
|
||||||
|
"description": "Album ID",
|
||||||
"schema": {
|
"schema": {
|
||||||
"format": "uuid",
|
"format": "uuid",
|
||||||
"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})$",
|
||||||
@@ -2712,6 +2713,14 @@
|
|||||||
"name": "userId",
|
"name": "userId",
|
||||||
"required": true,
|
"required": true,
|
||||||
"in": "path",
|
"in": "path",
|
||||||
|
"description": "Album user ID, or \"me\" to reference the current user.",
|
||||||
|
"x-immich-history": [
|
||||||
|
{
|
||||||
|
"version": "v3",
|
||||||
|
"state": "Updated",
|
||||||
|
"description": "\"me\" as a value is deprecated"
|
||||||
|
}
|
||||||
|
],
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -2762,6 +2771,7 @@
|
|||||||
"name": "id",
|
"name": "id",
|
||||||
"required": true,
|
"required": true,
|
||||||
"in": "path",
|
"in": "path",
|
||||||
|
"description": "Album ID",
|
||||||
"schema": {
|
"schema": {
|
||||||
"format": "uuid",
|
"format": "uuid",
|
||||||
"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})$",
|
||||||
@@ -2772,6 +2782,14 @@
|
|||||||
"name": "userId",
|
"name": "userId",
|
||||||
"required": true,
|
"required": true,
|
||||||
"in": "path",
|
"in": "path",
|
||||||
|
"description": "Album user ID, or \"me\" to reference the current user.",
|
||||||
|
"x-immich-history": [
|
||||||
|
{
|
||||||
|
"version": "v3",
|
||||||
|
"state": "Updated",
|
||||||
|
"description": "\"me\" as a value is deprecated"
|
||||||
|
}
|
||||||
|
],
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
AlbumsAddAssetsDto,
|
AlbumsAddAssetsDto,
|
||||||
AlbumsAddAssetsResponseDto,
|
AlbumsAddAssetsResponseDto,
|
||||||
AlbumStatisticsResponseDto,
|
AlbumStatisticsResponseDto,
|
||||||
|
AlbumUserParamDto,
|
||||||
CreateAlbumDto,
|
CreateAlbumDto,
|
||||||
GetAlbumsDto,
|
GetAlbumsDto,
|
||||||
UpdateAlbumDto,
|
UpdateAlbumDto,
|
||||||
@@ -18,7 +19,7 @@ import { MapMarkerResponseDto } from 'src/dtos/map.dto';
|
|||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||||
import { AlbumService } from 'src/services/album.service';
|
import { AlbumService } from 'src/services/album.service';
|
||||||
import { ParseMeUUIDPipe, UUIDParamDto } from 'src/validation';
|
import { UUIDParamDto } from 'src/validation';
|
||||||
|
|
||||||
@ApiTags(ApiTag.Albums)
|
@ApiTags(ApiTag.Albums)
|
||||||
@Controller('albums')
|
@Controller('albums')
|
||||||
@@ -175,8 +176,7 @@ export class AlbumController {
|
|||||||
})
|
})
|
||||||
updateAlbumUser(
|
updateAlbumUser(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
@Param() { id }: UUIDParamDto,
|
@Param() { id, userId }: AlbumUserParamDto,
|
||||||
@Param('userId', new ParseMeUUIDPipe({ version: '4' })) userId: string,
|
|
||||||
@Body() dto: UpdateAlbumUserDto,
|
@Body() dto: UpdateAlbumUserDto,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.service.updateUser(auth, id, userId, dto);
|
return this.service.updateUser(auth, id, userId, dto);
|
||||||
@@ -190,11 +190,7 @@ export class AlbumController {
|
|||||||
description: 'Remove a user from an album. Use an ID of "me" to leave a shared album.',
|
description: 'Remove a user from an album. Use an ID of "me" to leave a shared album.',
|
||||||
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removeUserFromAlbum(
|
removeUserFromAlbum(@Auth() auth: AuthDto, @Param() { id, userId }: AlbumUserParamDto): Promise<void> {
|
||||||
@Auth() auth: AuthDto,
|
|
||||||
@Param() { id }: UUIDParamDto,
|
|
||||||
@Param('userId', new ParseMeUUIDPipe({ version: '4' })) userId: string,
|
|
||||||
): Promise<void> {
|
|
||||||
return this.service.removeUser(auth, id, userId);
|
return this.service.removeUser(auth, id, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ShallowDehydrateObject } from 'kysely';
|
import { ShallowDehydrateObject } from 'kysely';
|
||||||
import { createZodDto } from 'nestjs-zod';
|
import { createZodDto } from 'nestjs-zod';
|
||||||
import { AlbumUser, AuthSharedLink } from 'src/database';
|
import { AlbumUser, AuthSharedLink } from 'src/database';
|
||||||
|
import { HistoryBuilder } from 'src/decorators';
|
||||||
import { BulkIdErrorReasonSchema } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdErrorReasonSchema } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { MapAsset } from 'src/dtos/asset-response.dto';
|
import { MapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import { UserResponseSchema, mapUser } from 'src/dtos/user.dto';
|
import { UserResponseSchema, mapUser } from 'src/dtos/user.dto';
|
||||||
@@ -140,6 +141,19 @@ export const AlbumResponseSchema = z
|
|||||||
})
|
})
|
||||||
.meta({ id: 'AlbumResponseDto' });
|
.meta({ id: 'AlbumResponseDto' });
|
||||||
|
|
||||||
|
const AlbumUserParamSchema = z.object({
|
||||||
|
id: z.uuidv4().describe('Album ID'),
|
||||||
|
// TODO: disallow 'me' as a shortcut in v4 and type userId as uuidv4
|
||||||
|
userId: z
|
||||||
|
.string()
|
||||||
|
.refine((value) => value === 'me' || z.uuidv4().safeParse(value).success, {
|
||||||
|
error: 'Must be a UUID v4 or "me"',
|
||||||
|
})
|
||||||
|
.describe('Album user ID, or "me" to reference the current user.')
|
||||||
|
.meta(new HistoryBuilder().updated('v3', '"me" as a value is deprecated').getExtensions()),
|
||||||
|
});
|
||||||
|
|
||||||
|
export class AlbumUserParamDto extends createZodDto(AlbumUserParamSchema) {}
|
||||||
export class AddUsersDto extends createZodDto(AddUsersSchema) {}
|
export class AddUsersDto extends createZodDto(AddUsersSchema) {}
|
||||||
export class AlbumUserCreateDto extends createZodDto(AlbumUserCreateSchema) {}
|
export class AlbumUserCreateDto extends createZodDto(AlbumUserCreateSchema) {}
|
||||||
export class CreateAlbumDto extends createZodDto(CreateAlbumSchema) {}
|
export class CreateAlbumDto extends createZodDto(CreateAlbumSchema) {}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ArgumentMetadata, FileValidator, Injectable, ParseUUIDPipe } from '@nestjs/common';
|
import { FileValidator, Injectable } from '@nestjs/common';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { createZodDto } from 'nestjs-zod';
|
import { createZodDto } from 'nestjs-zod';
|
||||||
import sanitize from 'sanitize-filename';
|
import sanitize from 'sanitize-filename';
|
||||||
@@ -75,16 +75,6 @@ export function IsNotSiblingOf<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ParseMeUUIDPipe extends ParseUUIDPipe {
|
|
||||||
async transform(value: string, metadata: ArgumentMetadata) {
|
|
||||||
if (value == 'me') {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return super.transform(value, metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FileNotEmptyValidator extends FileValidator {
|
export class FileNotEmptyValidator extends FileValidator {
|
||||||
constructor(private requiredFields: string[]) {
|
constructor(private requiredFields: string[]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user