mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
chore: move controllers and middleware (#8119)
This commit is contained in:
parent
81f0265095
commit
40e079a247
28 changed files with 55 additions and 60 deletions
50
server/src/controllers/activity.controller.ts
Normal file
50
server/src/controllers/activity.controller.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Query, Res } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { Response } from 'express';
|
||||
import {
|
||||
ActivityCreateDto,
|
||||
ActivityDto,
|
||||
ActivityResponseDto,
|
||||
ActivitySearchDto,
|
||||
ActivityStatisticsResponseDto,
|
||||
} from 'src/domain/activity/activity.dto';
|
||||
import { ActivityService } from 'src/domain/activity/activity.service';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Activity')
|
||||
@Controller('activity')
|
||||
@Authenticated()
|
||||
export class ActivityController {
|
||||
constructor(private service: ActivityService) {}
|
||||
|
||||
@Get()
|
||||
getActivities(@Auth() auth: AuthDto, @Query() dto: ActivitySearchDto): Promise<ActivityResponseDto[]> {
|
||||
return this.service.getAll(auth, dto);
|
||||
}
|
||||
|
||||
@Get('statistics')
|
||||
getActivityStatistics(@Auth() auth: AuthDto, @Query() dto: ActivityDto): Promise<ActivityStatisticsResponseDto> {
|
||||
return this.service.getStatistics(auth, dto);
|
||||
}
|
||||
|
||||
@Post()
|
||||
async createActivity(
|
||||
@Auth() auth: AuthDto,
|
||||
@Body() dto: ActivityCreateDto,
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
): Promise<ActivityResponseDto> {
|
||||
const { duplicate, value } = await this.service.create(auth, dto);
|
||||
if (duplicate) {
|
||||
res.status(HttpStatus.OK);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
deleteActivity(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.delete(auth, id);
|
||||
}
|
||||
}
|
||||
96
server/src/controllers/album.controller.ts
Normal file
96
server/src/controllers/album.controller.ts
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AlbumCountResponseDto, AlbumResponseDto } from 'src/domain/album/album-response.dto';
|
||||
import { AlbumService } from 'src/domain/album/album.service';
|
||||
import { AddUsersDto } from 'src/domain/album/dto/album-add-users.dto';
|
||||
import { CreateAlbumDto } from 'src/domain/album/dto/album-create.dto';
|
||||
import { UpdateAlbumDto } from 'src/domain/album/dto/album-update.dto';
|
||||
import { AlbumInfoDto } from 'src/domain/album/dto/album.dto';
|
||||
import { GetAlbumsDto } from 'src/domain/album/dto/get-albums.dto';
|
||||
import { BulkIdResponseDto, BulkIdsDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { Auth, Authenticated, SharedLinkRoute } from 'src/middleware/auth.guard';
|
||||
import { ParseMeUUIDPipe, UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Album')
|
||||
@Controller('album')
|
||||
@Authenticated()
|
||||
export class AlbumController {
|
||||
constructor(private service: AlbumService) {}
|
||||
|
||||
@Get('count')
|
||||
getAlbumCount(@Auth() auth: AuthDto): Promise<AlbumCountResponseDto> {
|
||||
return this.service.getCount(auth);
|
||||
}
|
||||
|
||||
@Get()
|
||||
getAllAlbums(@Auth() auth: AuthDto, @Query() query: GetAlbumsDto): Promise<AlbumResponseDto[]> {
|
||||
return this.service.getAll(auth, query);
|
||||
}
|
||||
|
||||
@Post()
|
||||
createAlbum(@Auth() auth: AuthDto, @Body() dto: CreateAlbumDto): Promise<AlbumResponseDto> {
|
||||
return this.service.create(auth, dto);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Get(':id')
|
||||
getAlbumInfo(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Query() dto: AlbumInfoDto,
|
||||
): Promise<AlbumResponseDto> {
|
||||
return this.service.get(auth, id, dto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
updateAlbumInfo(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: UpdateAlbumDto,
|
||||
): Promise<AlbumResponseDto> {
|
||||
return this.service.update(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
deleteAlbum(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto) {
|
||||
return this.service.delete(auth, id);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Put(':id/assets')
|
||||
addAssetsToAlbum(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: BulkIdsDto,
|
||||
): Promise<BulkIdResponseDto[]> {
|
||||
return this.service.addAssets(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id/assets')
|
||||
removeAssetFromAlbum(
|
||||
@Auth() auth: AuthDto,
|
||||
@Body() dto: BulkIdsDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
): Promise<BulkIdResponseDto[]> {
|
||||
return this.service.removeAssets(auth, id, dto);
|
||||
}
|
||||
|
||||
@Put(':id/users')
|
||||
addUsersToAlbum(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: AddUsersDto,
|
||||
): Promise<AlbumResponseDto> {
|
||||
return this.service.addUsers(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id/user/:userId')
|
||||
removeUserFromAlbum(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Param('userId', new ParseMeUUIDPipe({ version: '4' })) userId: string,
|
||||
) {
|
||||
return this.service.removeUser(auth, id, userId);
|
||||
}
|
||||
}
|
||||
48
server/src/controllers/api-key.controller.ts
Normal file
48
server/src/controllers/api-key.controller.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import {
|
||||
APIKeyCreateDto,
|
||||
APIKeyCreateResponseDto,
|
||||
APIKeyResponseDto,
|
||||
APIKeyUpdateDto,
|
||||
} from 'src/domain/api-key/api-key.dto';
|
||||
import { APIKeyService } from 'src/domain/api-key/api-key.service';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('API Key')
|
||||
@Controller('api-key')
|
||||
@Authenticated()
|
||||
export class APIKeyController {
|
||||
constructor(private service: APIKeyService) {}
|
||||
|
||||
@Post()
|
||||
createApiKey(@Auth() auth: AuthDto, @Body() dto: APIKeyCreateDto): Promise<APIKeyCreateResponseDto> {
|
||||
return this.service.create(auth, dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
getApiKeys(@Auth() auth: AuthDto): Promise<APIKeyResponseDto[]> {
|
||||
return this.service.getAll(auth);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
getApiKey(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<APIKeyResponseDto> {
|
||||
return this.service.getById(auth, id);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
updateApiKey(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: APIKeyUpdateDto,
|
||||
): Promise<APIKeyResponseDto> {
|
||||
return this.service.update(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
deleteApiKey(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.delete(auth, id);
|
||||
}
|
||||
}
|
||||
27
server/src/controllers/app.controller.ts
Normal file
27
server/src/controllers/app.controller.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { Controller, Get, Header } from '@nestjs/common';
|
||||
import { ApiExcludeEndpoint } from '@nestjs/swagger';
|
||||
import { SystemConfigService } from 'src/domain/system-config/system-config.service';
|
||||
import { PublicRoute } from 'src/middleware/auth.guard';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private service: SystemConfigService) {}
|
||||
|
||||
@ApiExcludeEndpoint()
|
||||
@Get('.well-known/immich')
|
||||
getImmichWellKnown() {
|
||||
return {
|
||||
api: {
|
||||
endpoint: '/api',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ApiExcludeEndpoint()
|
||||
@PublicRoute()
|
||||
@Get('custom.css')
|
||||
@Header('Content-Type', 'text/css')
|
||||
getCustomCss() {
|
||||
return this.service.getCustomCss();
|
||||
}
|
||||
}
|
||||
127
server/src/controllers/asset.controller.ts
Normal file
127
server/src/controllers/asset.controller.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { AssetService } from 'src/domain/asset/asset.service';
|
||||
import { AssetJobsDto } from 'src/domain/asset/dto/asset-ids.dto';
|
||||
import { UpdateStackParentDto } from 'src/domain/asset/dto/asset-stack.dto';
|
||||
import { AssetStatsDto, AssetStatsResponseDto } from 'src/domain/asset/dto/asset-statistics.dto';
|
||||
import {
|
||||
AssetBulkDeleteDto,
|
||||
AssetBulkUpdateDto,
|
||||
DeviceIdDto,
|
||||
RandomAssetsDto,
|
||||
UpdateAssetDto,
|
||||
} from 'src/domain/asset/dto/asset.dto';
|
||||
import { MapMarkerDto } from 'src/domain/asset/dto/map-marker.dto';
|
||||
import { MemoryLaneDto } from 'src/domain/asset/dto/memory-lane.dto';
|
||||
import { TimeBucketAssetDto, TimeBucketDto } from 'src/domain/asset/dto/time-bucket.dto';
|
||||
import { AssetResponseDto, MemoryLaneResponseDto } from 'src/domain/asset/response-dto/asset-response.dto';
|
||||
import { MapMarkerResponseDto } from 'src/domain/asset/response-dto/map-marker-response.dto';
|
||||
import { TimeBucketResponseDto } from 'src/domain/asset/response-dto/time-bucket-response.dto';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { MetadataSearchDto } from 'src/domain/search/dto/search.dto';
|
||||
import { SearchService } from 'src/domain/search/search.service';
|
||||
import { Auth, Authenticated, SharedLinkRoute } from 'src/middleware/auth.guard';
|
||||
import { Route } from 'src/middleware/file-upload.interceptor';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Asset')
|
||||
@Controller('assets')
|
||||
@Authenticated()
|
||||
export class AssetsController {
|
||||
constructor(private searchService: SearchService) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ deprecated: true })
|
||||
async searchAssets(@Auth() auth: AuthDto, @Query() dto: MetadataSearchDto): Promise<AssetResponseDto[]> {
|
||||
const {
|
||||
assets: { items },
|
||||
} = await this.searchService.searchMetadata(auth, dto);
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
@ApiTags('Asset')
|
||||
@Controller(Route.ASSET)
|
||||
@Authenticated()
|
||||
export class AssetController {
|
||||
constructor(private service: AssetService) {}
|
||||
|
||||
@Get('map-marker')
|
||||
getMapMarkers(@Auth() auth: AuthDto, @Query() options: MapMarkerDto): Promise<MapMarkerResponseDto[]> {
|
||||
return this.service.getMapMarkers(auth, options);
|
||||
}
|
||||
|
||||
@Get('memory-lane')
|
||||
getMemoryLane(@Auth() auth: AuthDto, @Query() dto: MemoryLaneDto): Promise<MemoryLaneResponseDto[]> {
|
||||
return this.service.getMemoryLane(auth, dto);
|
||||
}
|
||||
|
||||
@Get('random')
|
||||
getRandom(@Auth() auth: AuthDto, @Query() dto: RandomAssetsDto): Promise<AssetResponseDto[]> {
|
||||
return this.service.getRandom(auth, dto.count ?? 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all asset of a device that are in the database, ID only.
|
||||
*/
|
||||
@Get('/device/:deviceId')
|
||||
getAllUserAssetsByDeviceId(@Auth() auth: AuthDto, @Param() { deviceId }: DeviceIdDto) {
|
||||
return this.service.getUserAssetsByDeviceId(auth, deviceId);
|
||||
}
|
||||
|
||||
@Get('statistics')
|
||||
getAssetStatistics(@Auth() auth: AuthDto, @Query() dto: AssetStatsDto): Promise<AssetStatsResponseDto> {
|
||||
return this.service.getStatistics(auth, dto);
|
||||
}
|
||||
|
||||
@Authenticated({ isShared: true })
|
||||
@Get('time-buckets')
|
||||
getTimeBuckets(@Auth() auth: AuthDto, @Query() dto: TimeBucketDto): Promise<TimeBucketResponseDto[]> {
|
||||
return this.service.getTimeBuckets(auth, dto);
|
||||
}
|
||||
|
||||
@Authenticated({ isShared: true })
|
||||
@Get('time-bucket')
|
||||
getTimeBucket(@Auth() auth: AuthDto, @Query() dto: TimeBucketAssetDto): Promise<AssetResponseDto[]> {
|
||||
return this.service.getTimeBucket(auth, dto) as Promise<AssetResponseDto[]>;
|
||||
}
|
||||
|
||||
@Post('jobs')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
runAssetJobs(@Auth() auth: AuthDto, @Body() dto: AssetJobsDto): Promise<void> {
|
||||
return this.service.run(auth, dto);
|
||||
}
|
||||
|
||||
@Put()
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
updateAssets(@Auth() auth: AuthDto, @Body() dto: AssetBulkUpdateDto): Promise<void> {
|
||||
return this.service.updateAll(auth, dto);
|
||||
}
|
||||
|
||||
@Delete()
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
deleteAssets(@Auth() auth: AuthDto, @Body() dto: AssetBulkDeleteDto): Promise<void> {
|
||||
return this.service.deleteAll(auth, dto);
|
||||
}
|
||||
|
||||
@Put('stack/parent')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
updateStackParent(@Auth() auth: AuthDto, @Body() dto: UpdateStackParentDto): Promise<void> {
|
||||
return this.service.updateStackParent(auth, dto);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Get(':id')
|
||||
getAssetInfo(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetResponseDto> {
|
||||
return this.service.get(auth, id) as Promise<AssetResponseDto>;
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
updateAsset(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: UpdateAssetDto,
|
||||
): Promise<AssetResponseDto> {
|
||||
return this.service.update(auth, id, dto);
|
||||
}
|
||||
}
|
||||
43
server/src/controllers/audit.controller.ts
Normal file
43
server/src/controllers/audit.controller.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import {
|
||||
AuditDeletesDto,
|
||||
AuditDeletesResponseDto,
|
||||
FileChecksumDto,
|
||||
FileChecksumResponseDto,
|
||||
FileReportDto,
|
||||
FileReportFixDto,
|
||||
} from 'src/domain/audit/audit.dto';
|
||||
import { AuditService } from 'src/domain/audit/audit.service';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { AdminRoute, Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
|
||||
@ApiTags('Audit')
|
||||
@Controller('audit')
|
||||
@Authenticated()
|
||||
export class AuditController {
|
||||
constructor(private service: AuditService) {}
|
||||
|
||||
@Get('deletes')
|
||||
getAuditDeletes(@Auth() auth: AuthDto, @Query() dto: AuditDeletesDto): Promise<AuditDeletesResponseDto> {
|
||||
return this.service.getDeletes(auth, dto);
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Get('file-report')
|
||||
getAuditFiles(): Promise<FileReportDto> {
|
||||
return this.service.getFileReport();
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Post('file-report/checksum')
|
||||
getFileChecksums(@Body() dto: FileChecksumDto): Promise<FileChecksumResponseDto[]> {
|
||||
return this.service.getChecksums(dto);
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Post('file-report/fix')
|
||||
fixAuditFiles(@Body() dto: FileReportFixDto): Promise<void> {
|
||||
return this.service.fixItems(dto.items);
|
||||
}
|
||||
}
|
||||
86
server/src/controllers/auth.controller.ts
Normal file
86
server/src/controllers/auth.controller.ts
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Req, Res } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { Request, Response } from 'express';
|
||||
import { IMMICH_ACCESS_COOKIE, IMMICH_AUTH_TYPE_COOKIE, IMMICH_IS_AUTHENTICATED } from 'src/domain/auth/auth.constant';
|
||||
import {
|
||||
AuthDeviceResponseDto,
|
||||
AuthDto,
|
||||
ChangePasswordDto,
|
||||
LoginCredentialDto,
|
||||
LoginResponseDto,
|
||||
LogoutResponseDto,
|
||||
SignUpDto,
|
||||
ValidateAccessTokenResponseDto,
|
||||
} from 'src/domain/auth/auth.dto';
|
||||
import { AuthService, LoginDetails } from 'src/domain/auth/auth.service';
|
||||
import { UserResponseDto, mapUser } from 'src/domain/user/response-dto/user-response.dto';
|
||||
import { Auth, Authenticated, GetLoginDetails, PublicRoute } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Authentication')
|
||||
@Controller('auth')
|
||||
@Authenticated()
|
||||
export class AuthController {
|
||||
constructor(private service: AuthService) {}
|
||||
|
||||
@PublicRoute()
|
||||
@Post('login')
|
||||
async login(
|
||||
@Body() loginCredential: LoginCredentialDto,
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@GetLoginDetails() loginDetails: LoginDetails,
|
||||
): Promise<LoginResponseDto> {
|
||||
const { response, cookie } = await this.service.login(loginCredential, loginDetails);
|
||||
res.header('Set-Cookie', cookie);
|
||||
return response;
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Post('admin-sign-up')
|
||||
signUpAdmin(@Body() dto: SignUpDto): Promise<UserResponseDto> {
|
||||
return this.service.adminSignUp(dto);
|
||||
}
|
||||
|
||||
@Get('devices')
|
||||
getAuthDevices(@Auth() auth: AuthDto): Promise<AuthDeviceResponseDto[]> {
|
||||
return this.service.getDevices(auth);
|
||||
}
|
||||
|
||||
@Delete('devices')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
logoutAuthDevices(@Auth() auth: AuthDto): Promise<void> {
|
||||
return this.service.logoutDevices(auth);
|
||||
}
|
||||
|
||||
@Delete('devices/:id')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
logoutAuthDevice(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.logoutDevice(auth, id);
|
||||
}
|
||||
|
||||
@Post('validateToken')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
validateAccessToken(): ValidateAccessTokenResponseDto {
|
||||
return { authStatus: true };
|
||||
}
|
||||
|
||||
@Post('change-password')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
changePassword(@Auth() auth: AuthDto, @Body() dto: ChangePasswordDto): Promise<UserResponseDto> {
|
||||
return this.service.changePassword(auth, dto).then(mapUser);
|
||||
}
|
||||
|
||||
@Post('logout')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
logout(
|
||||
@Req() request: Request,
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Auth() auth: AuthDto,
|
||||
): Promise<LogoutResponseDto> {
|
||||
res.clearCookie(IMMICH_ACCESS_COOKIE);
|
||||
res.clearCookie(IMMICH_AUTH_TYPE_COOKIE);
|
||||
res.clearCookie(IMMICH_IS_AUTHENTICATED);
|
||||
|
||||
return this.service.logout(auth, (request.cookies || {})[IMMICH_AUTH_TYPE_COOKIE]);
|
||||
}
|
||||
}
|
||||
44
server/src/controllers/download.controller.ts
Normal file
44
server/src/controllers/download.controller.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { Body, Controller, HttpCode, HttpStatus, Next, Param, Post, Res, StreamableFile } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { NextFunction, Response } from 'express';
|
||||
import { AssetIdsDto } from 'src/domain/asset/dto/asset-ids.dto';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { DownloadInfoDto, DownloadResponseDto } from 'src/domain/download/download.dto';
|
||||
import { DownloadService } from 'src/domain/download/download.service';
|
||||
import { asStreamableFile, sendFile } from 'src/immich/app.utils';
|
||||
import { Auth, Authenticated, FileResponse, SharedLinkRoute } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Download')
|
||||
@Controller('download')
|
||||
@Authenticated()
|
||||
export class DownloadController {
|
||||
constructor(private service: DownloadService) {}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Post('info')
|
||||
getDownloadInfo(@Auth() auth: AuthDto, @Body() dto: DownloadInfoDto): Promise<DownloadResponseDto> {
|
||||
return this.service.getDownloadInfo(auth, dto);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Post('archive')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@FileResponse()
|
||||
downloadArchive(@Auth() auth: AuthDto, @Body() dto: AssetIdsDto): Promise<StreamableFile> {
|
||||
return this.service.downloadArchive(auth, dto).then(asStreamableFile);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Post('asset/:id')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@FileResponse()
|
||||
async downloadFile(
|
||||
@Res() res: Response,
|
||||
@Next() next: NextFunction,
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
) {
|
||||
await sendFile(res, next, () => this.service.downloadFile(auth, id));
|
||||
}
|
||||
}
|
||||
28
server/src/controllers/face.controller.ts
Normal file
28
server/src/controllers/face.controller.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { Body, Controller, Get, Param, Put, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { AssetFaceResponseDto, FaceDto, PersonResponseDto } from 'src/domain/person/person.dto';
|
||||
import { PersonService } from 'src/domain/person/person.service';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Face')
|
||||
@Controller('face')
|
||||
@Authenticated()
|
||||
export class FaceController {
|
||||
constructor(private service: PersonService) {}
|
||||
|
||||
@Get()
|
||||
getFaces(@Auth() auth: AuthDto, @Query() dto: FaceDto): Promise<AssetFaceResponseDto[]> {
|
||||
return this.service.getFacesById(auth, dto);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
reassignFacesById(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: FaceDto,
|
||||
): Promise<PersonResponseDto> {
|
||||
return this.service.reassignFacesById(auth, id, dto);
|
||||
}
|
||||
}
|
||||
22
server/src/controllers/job.controller.ts
Normal file
22
server/src/controllers/job.controller.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { Body, Controller, Get, Param, Put } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AllJobStatusResponseDto, JobCommandDto, JobIdParamDto, JobStatusDto } from 'src/domain/job/job.dto';
|
||||
import { JobService } from 'src/domain/job/job.service';
|
||||
import { Authenticated } from 'src/middleware/auth.guard';
|
||||
|
||||
@ApiTags('Job')
|
||||
@Controller('jobs')
|
||||
@Authenticated({ admin: true })
|
||||
export class JobController {
|
||||
constructor(private service: JobService) {}
|
||||
|
||||
@Get()
|
||||
getAllJobsStatus(): Promise<AllJobStatusResponseDto> {
|
||||
return this.service.getAllJobsStatus();
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
sendJobCommand(@Param() { id }: JobIdParamDto, @Body() dto: JobCommandDto): Promise<JobStatusDto> {
|
||||
return this.service.handleCommand(id, dto);
|
||||
}
|
||||
}
|
||||
73
server/src/controllers/library.controller.ts
Normal file
73
server/src/controllers/library.controller.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import {
|
||||
CreateLibraryDto,
|
||||
LibraryResponseDto,
|
||||
LibraryStatsResponseDto,
|
||||
ScanLibraryDto,
|
||||
SearchLibraryDto,
|
||||
UpdateLibraryDto,
|
||||
ValidateLibraryDto,
|
||||
ValidateLibraryResponseDto,
|
||||
} from 'src/domain/library/library.dto';
|
||||
import { LibraryService } from 'src/domain/library/library.service';
|
||||
import { AdminRoute, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Library')
|
||||
@Controller('library')
|
||||
@Authenticated()
|
||||
@AdminRoute()
|
||||
export class LibraryController {
|
||||
constructor(private service: LibraryService) {}
|
||||
|
||||
@Get()
|
||||
getAllLibraries(@Query() dto: SearchLibraryDto): Promise<LibraryResponseDto[]> {
|
||||
return this.service.getAll(dto);
|
||||
}
|
||||
|
||||
@Post()
|
||||
createLibrary(@Body() dto: CreateLibraryDto): Promise<LibraryResponseDto> {
|
||||
return this.service.create(dto);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
updateLibrary(@Param() { id }: UUIDParamDto, @Body() dto: UpdateLibraryDto): Promise<LibraryResponseDto> {
|
||||
return this.service.update(id, dto);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
getLibrary(@Param() { id }: UUIDParamDto): Promise<LibraryResponseDto> {
|
||||
return this.service.get(id);
|
||||
}
|
||||
|
||||
@Post(':id/validate')
|
||||
@HttpCode(200)
|
||||
// TODO: change endpoint to validate current settings instead
|
||||
validate(@Param() { id }: UUIDParamDto, @Body() dto: ValidateLibraryDto): Promise<ValidateLibraryResponseDto> {
|
||||
return this.service.validate(id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
deleteLibrary(@Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.delete(id);
|
||||
}
|
||||
|
||||
@Get(':id/statistics')
|
||||
getLibraryStatistics(@Param() { id }: UUIDParamDto): Promise<LibraryStatsResponseDto> {
|
||||
return this.service.getStatistics(id);
|
||||
}
|
||||
|
||||
@Post(':id/scan')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
scanLibrary(@Param() { id }: UUIDParamDto, @Body() dto: ScanLibraryDto) {
|
||||
return this.service.queueScan(id, dto);
|
||||
}
|
||||
|
||||
@Post(':id/removeOffline')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
removeOfflineFiles(@Param() { id }: UUIDParamDto) {
|
||||
return this.service.queueRemoveOffline(id);
|
||||
}
|
||||
}
|
||||
58
server/src/controllers/oauth.controller.ts
Normal file
58
server/src/controllers/oauth.controller.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { Request, Response } from 'express';
|
||||
import {
|
||||
AuthDto,
|
||||
LoginResponseDto,
|
||||
OAuthAuthorizeResponseDto,
|
||||
OAuthCallbackDto,
|
||||
OAuthConfigDto,
|
||||
} from 'src/domain/auth/auth.dto';
|
||||
import { AuthService, LoginDetails } from 'src/domain/auth/auth.service';
|
||||
import { UserResponseDto } from 'src/domain/user/response-dto/user-response.dto';
|
||||
import { Auth, Authenticated, GetLoginDetails, PublicRoute } from 'src/middleware/auth.guard';
|
||||
|
||||
@ApiTags('OAuth')
|
||||
@Controller('oauth')
|
||||
@Authenticated()
|
||||
export class OAuthController {
|
||||
constructor(private service: AuthService) {}
|
||||
|
||||
@PublicRoute()
|
||||
@Get('mobile-redirect')
|
||||
@Redirect()
|
||||
redirectOAuthToMobile(@Req() request: Request) {
|
||||
return {
|
||||
url: this.service.getMobileRedirect(request.url),
|
||||
statusCode: HttpStatus.TEMPORARY_REDIRECT,
|
||||
};
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Post('authorize')
|
||||
startOAuth(@Body() dto: OAuthConfigDto): Promise<OAuthAuthorizeResponseDto> {
|
||||
return this.service.authorize(dto);
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Post('callback')
|
||||
async finishOAuth(
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@Body() dto: OAuthCallbackDto,
|
||||
@GetLoginDetails() loginDetails: LoginDetails,
|
||||
): Promise<LoginResponseDto> {
|
||||
const { response, cookie } = await this.service.callback(dto, loginDetails);
|
||||
res.header('Set-Cookie', cookie);
|
||||
return response;
|
||||
}
|
||||
|
||||
@Post('link')
|
||||
linkOAuthAccount(@Auth() auth: AuthDto, @Body() dto: OAuthCallbackDto): Promise<UserResponseDto> {
|
||||
return this.service.link(auth, dto);
|
||||
}
|
||||
|
||||
@Post('unlink')
|
||||
unlinkOAuthAccount(@Auth() auth: AuthDto): Promise<UserResponseDto> {
|
||||
return this.service.unlink(auth);
|
||||
}
|
||||
}
|
||||
41
server/src/controllers/partner.controller.ts
Normal file
41
server/src/controllers/partner.controller.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';
|
||||
import { ApiQuery, ApiTags } from '@nestjs/swagger';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { PartnerResponseDto, UpdatePartnerDto } from 'src/domain/partner/partner.dto';
|
||||
import { PartnerService } from 'src/domain/partner/partner.service';
|
||||
import { PartnerDirection } from 'src/domain/repositories/partner.repository';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Partner')
|
||||
@Controller('partner')
|
||||
@Authenticated()
|
||||
export class PartnerController {
|
||||
constructor(private service: PartnerService) {}
|
||||
|
||||
@Get()
|
||||
@ApiQuery({ name: 'direction', type: 'string', enum: PartnerDirection, required: true })
|
||||
// TODO: remove 'direction' and convert to full query dto
|
||||
getPartners(@Auth() auth: AuthDto, @Query('direction') direction: PartnerDirection): Promise<PartnerResponseDto[]> {
|
||||
return this.service.getAll(auth, direction);
|
||||
}
|
||||
|
||||
@Post(':id')
|
||||
createPartner(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PartnerResponseDto> {
|
||||
return this.service.create(auth, id);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
updatePartner(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: UpdatePartnerDto,
|
||||
): Promise<PartnerResponseDto> {
|
||||
return this.service.update(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
removePartner(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.remove(auth, id);
|
||||
}
|
||||
}
|
||||
96
server/src/controllers/person.controller.ts
Normal file
96
server/src/controllers/person.controller.ts
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import { Body, Controller, Get, Next, Param, Post, Put, Query, Res } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { NextFunction, Response } from 'express';
|
||||
import { BulkIdResponseDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
|
||||
import { AssetResponseDto } from 'src/domain/asset/response-dto/asset-response.dto';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import {
|
||||
AssetFaceUpdateDto,
|
||||
MergePersonDto,
|
||||
PeopleResponseDto,
|
||||
PeopleUpdateDto,
|
||||
PersonCreateDto,
|
||||
PersonResponseDto,
|
||||
PersonSearchDto,
|
||||
PersonStatisticsResponseDto,
|
||||
PersonUpdateDto,
|
||||
} from 'src/domain/person/person.dto';
|
||||
import { PersonService } from 'src/domain/person/person.service';
|
||||
import { sendFile } from 'src/immich/app.utils';
|
||||
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Person')
|
||||
@Controller('person')
|
||||
@Authenticated()
|
||||
export class PersonController {
|
||||
constructor(private service: PersonService) {}
|
||||
|
||||
@Get()
|
||||
getAllPeople(@Auth() auth: AuthDto, @Query() withHidden: PersonSearchDto): Promise<PeopleResponseDto> {
|
||||
return this.service.getAll(auth, withHidden);
|
||||
}
|
||||
|
||||
@Post()
|
||||
createPerson(@Auth() auth: AuthDto, @Body() dto: PersonCreateDto): Promise<PersonResponseDto> {
|
||||
return this.service.create(auth, dto);
|
||||
}
|
||||
|
||||
@Put()
|
||||
updatePeople(@Auth() auth: AuthDto, @Body() dto: PeopleUpdateDto): Promise<BulkIdResponseDto[]> {
|
||||
return this.service.updateAll(auth, dto);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
getPerson(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PersonResponseDto> {
|
||||
return this.service.getById(auth, id);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
updatePerson(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: PersonUpdateDto,
|
||||
): Promise<PersonResponseDto> {
|
||||
return this.service.update(auth, id, dto);
|
||||
}
|
||||
|
||||
@Get(':id/statistics')
|
||||
getPersonStatistics(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PersonStatisticsResponseDto> {
|
||||
return this.service.getStatistics(auth, id);
|
||||
}
|
||||
|
||||
@Get(':id/thumbnail')
|
||||
@FileResponse()
|
||||
async getPersonThumbnail(
|
||||
@Res() res: Response,
|
||||
@Next() next: NextFunction,
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
) {
|
||||
await sendFile(res, next, () => this.service.getThumbnail(auth, id));
|
||||
}
|
||||
|
||||
@Get(':id/assets')
|
||||
getPersonAssets(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetResponseDto[]> {
|
||||
return this.service.getAssets(auth, id);
|
||||
}
|
||||
|
||||
@Put(':id/reassign')
|
||||
reassignFaces(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: AssetFaceUpdateDto,
|
||||
): Promise<PersonResponseDto[]> {
|
||||
return this.service.reassignFaces(auth, id, dto);
|
||||
}
|
||||
|
||||
@Post(':id/merge')
|
||||
mergePerson(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: MergePersonDto,
|
||||
): Promise<BulkIdResponseDto[]> {
|
||||
return this.service.mergePerson(auth, id, dto);
|
||||
}
|
||||
}
|
||||
68
server/src/controllers/search.controller.ts
Normal file
68
server/src/controllers/search.controller.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import { Body, Controller, Get, HttpCode, HttpStatus, Post, Query } from '@nestjs/common';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { AssetResponseDto } from 'src/domain/asset/response-dto/asset-response.dto';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { PersonResponseDto } from 'src/domain/person/person.dto';
|
||||
import { SearchSuggestionRequestDto } from 'src/domain/search/dto/search-suggestion.dto';
|
||||
import {
|
||||
MetadataSearchDto,
|
||||
PlacesResponseDto,
|
||||
SearchDto,
|
||||
SearchPeopleDto,
|
||||
SearchPlacesDto,
|
||||
SmartSearchDto,
|
||||
} from 'src/domain/search/dto/search.dto';
|
||||
import { SearchExploreResponseDto } from 'src/domain/search/response-dto/search-explore.response.dto';
|
||||
import { SearchResponseDto } from 'src/domain/search/response-dto/search-response.dto';
|
||||
import { SearchService } from 'src/domain/search/search.service';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
|
||||
@ApiTags('Search')
|
||||
@Controller('search')
|
||||
@Authenticated()
|
||||
export class SearchController {
|
||||
constructor(private service: SearchService) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ deprecated: true })
|
||||
search(@Auth() auth: AuthDto, @Query() dto: SearchDto): Promise<SearchResponseDto> {
|
||||
return this.service.search(auth, dto);
|
||||
}
|
||||
|
||||
@Post('metadata')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
searchMetadata(@Auth() auth: AuthDto, @Body() dto: MetadataSearchDto): Promise<SearchResponseDto> {
|
||||
return this.service.searchMetadata(auth, dto);
|
||||
}
|
||||
|
||||
@Post('smart')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
searchSmart(@Auth() auth: AuthDto, @Body() dto: SmartSearchDto): Promise<SearchResponseDto> {
|
||||
return this.service.searchSmart(auth, dto);
|
||||
}
|
||||
|
||||
@Get('explore')
|
||||
getExploreData(@Auth() auth: AuthDto): Promise<SearchExploreResponseDto[]> {
|
||||
return this.service.getExploreData(auth) as Promise<SearchExploreResponseDto[]>;
|
||||
}
|
||||
|
||||
@Get('person')
|
||||
searchPerson(@Auth() auth: AuthDto, @Query() dto: SearchPeopleDto): Promise<PersonResponseDto[]> {
|
||||
return this.service.searchPerson(auth, dto);
|
||||
}
|
||||
|
||||
@Get('places')
|
||||
searchPlaces(@Query() dto: SearchPlacesDto): Promise<PlacesResponseDto[]> {
|
||||
return this.service.searchPlaces(dto);
|
||||
}
|
||||
|
||||
@Get('cities')
|
||||
getAssetsByCity(@Auth() auth: AuthDto): Promise<AssetResponseDto[]> {
|
||||
return this.service.getAssetsByCity(auth);
|
||||
}
|
||||
|
||||
@Get('suggestions')
|
||||
getSearchSuggestions(@Auth() auth: AuthDto, @Query() dto: SearchSuggestionRequestDto): Promise<string[]> {
|
||||
return this.service.getSearchSuggestions(auth, dto);
|
||||
}
|
||||
}
|
||||
75
server/src/controllers/server-info.controller.ts
Normal file
75
server/src/controllers/server-info.controller.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import {
|
||||
ServerConfigDto,
|
||||
ServerFeaturesDto,
|
||||
ServerInfoResponseDto,
|
||||
ServerMediaTypesResponseDto,
|
||||
ServerPingResponse,
|
||||
ServerStatsResponseDto,
|
||||
ServerThemeDto,
|
||||
ServerVersionResponseDto,
|
||||
} from 'src/domain/server-info/server-info.dto';
|
||||
import { ServerInfoService } from 'src/domain/server-info/server-info.service';
|
||||
import { AdminRoute, Authenticated, PublicRoute } from 'src/middleware/auth.guard';
|
||||
|
||||
@ApiTags('Server Info')
|
||||
@Controller('server-info')
|
||||
@Authenticated()
|
||||
export class ServerInfoController {
|
||||
constructor(private service: ServerInfoService) {}
|
||||
|
||||
@Get()
|
||||
getServerInfo(): Promise<ServerInfoResponseDto> {
|
||||
return this.service.getInfo();
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Get('ping')
|
||||
pingServer(): ServerPingResponse {
|
||||
return this.service.ping();
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Get('version')
|
||||
getServerVersion(): ServerVersionResponseDto {
|
||||
return this.service.getVersion();
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Get('features')
|
||||
getServerFeatures(): Promise<ServerFeaturesDto> {
|
||||
return this.service.getFeatures();
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Get('theme')
|
||||
getTheme(): Promise<ServerThemeDto> {
|
||||
return this.service.getTheme();
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Get('config')
|
||||
getServerConfig(): Promise<ServerConfigDto> {
|
||||
return this.service.getConfig();
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Get('statistics')
|
||||
getServerStatistics(): Promise<ServerStatsResponseDto> {
|
||||
return this.service.getStatistics();
|
||||
}
|
||||
|
||||
@PublicRoute()
|
||||
@Get('media-types')
|
||||
getSupportedMediaTypes(): ServerMediaTypesResponseDto {
|
||||
return this.service.getSupportedMediaTypes();
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Post('admin-onboarding')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
setAdminOnboarding(): Promise<void> {
|
||||
return this.service.setAdminOnboarding();
|
||||
}
|
||||
}
|
||||
91
server/src/controllers/shared-link.controller.ts
Normal file
91
server/src/controllers/shared-link.controller.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query, Req, Res } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { Request, Response } from 'express';
|
||||
import { AssetIdsDto } from 'src/domain/asset/dto/asset-ids.dto';
|
||||
import { AssetIdsResponseDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
|
||||
import { IMMICH_SHARED_LINK_ACCESS_COOKIE } from 'src/domain/auth/auth.constant';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { SharedLinkResponseDto } from 'src/domain/shared-link/shared-link-response.dto';
|
||||
import { SharedLinkCreateDto, SharedLinkEditDto, SharedLinkPasswordDto } from 'src/domain/shared-link/shared-link.dto';
|
||||
import { SharedLinkService } from 'src/domain/shared-link/shared-link.service';
|
||||
import { Auth, Authenticated, SharedLinkRoute } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Shared Link')
|
||||
@Controller('shared-link')
|
||||
@Authenticated()
|
||||
export class SharedLinkController {
|
||||
constructor(private readonly service: SharedLinkService) {}
|
||||
|
||||
@Get()
|
||||
getAllSharedLinks(@Auth() auth: AuthDto): Promise<SharedLinkResponseDto[]> {
|
||||
return this.service.getAll(auth);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Get('me')
|
||||
async getMySharedLink(
|
||||
@Auth() auth: AuthDto,
|
||||
@Query() dto: SharedLinkPasswordDto,
|
||||
@Req() request: Request,
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
): Promise<SharedLinkResponseDto> {
|
||||
const sharedLinkToken = request.cookies?.[IMMICH_SHARED_LINK_ACCESS_COOKIE];
|
||||
if (sharedLinkToken) {
|
||||
dto.token = sharedLinkToken;
|
||||
}
|
||||
const response = await this.service.getMine(auth, dto);
|
||||
if (response.token) {
|
||||
res.cookie(IMMICH_SHARED_LINK_ACCESS_COOKIE, response.token, {
|
||||
expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
|
||||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
});
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
getSharedLinkById(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<SharedLinkResponseDto> {
|
||||
return this.service.get(auth, id);
|
||||
}
|
||||
|
||||
@Post()
|
||||
createSharedLink(@Auth() auth: AuthDto, @Body() dto: SharedLinkCreateDto) {
|
||||
return this.service.create(auth, dto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
updateSharedLink(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: SharedLinkEditDto,
|
||||
): Promise<SharedLinkResponseDto> {
|
||||
return this.service.update(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
removeSharedLink(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.remove(auth, id);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Put(':id/assets')
|
||||
addSharedLinkAssets(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: AssetIdsDto,
|
||||
): Promise<AssetIdsResponseDto[]> {
|
||||
return this.service.addAssets(auth, id, dto);
|
||||
}
|
||||
|
||||
@SharedLinkRoute()
|
||||
@Delete(':id/assets')
|
||||
removeSharedLinkAssets(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: AssetIdsDto,
|
||||
): Promise<AssetIdsResponseDto[]> {
|
||||
return this.service.removeAssets(auth, id, dto);
|
||||
}
|
||||
}
|
||||
40
server/src/controllers/system-config.controller.ts
Normal file
40
server/src/controllers/system-config.controller.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { Body, Controller, Get, Put, Query } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { SystemConfigDto } from 'src/domain/system-config/dto/system-config.dto';
|
||||
import { SystemConfigTemplateStorageOptionDto } from 'src/domain/system-config/response-dto/system-config-template-storage-option.dto';
|
||||
import { MapThemeDto } from 'src/domain/system-config/system-config-map-theme.dto';
|
||||
import { SystemConfigService } from 'src/domain/system-config/system-config.service';
|
||||
import { AdminRoute, Authenticated } from 'src/middleware/auth.guard';
|
||||
|
||||
@ApiTags('System Config')
|
||||
@Controller('system-config')
|
||||
@Authenticated({ admin: true })
|
||||
export class SystemConfigController {
|
||||
constructor(private readonly service: SystemConfigService) {}
|
||||
|
||||
@Get()
|
||||
getConfig(): Promise<SystemConfigDto> {
|
||||
return this.service.getConfig();
|
||||
}
|
||||
|
||||
@Get('defaults')
|
||||
getConfigDefaults(): SystemConfigDto {
|
||||
return this.service.getDefaults();
|
||||
}
|
||||
|
||||
@Put()
|
||||
updateConfig(@Body() dto: SystemConfigDto): Promise<SystemConfigDto> {
|
||||
return this.service.updateConfig(dto);
|
||||
}
|
||||
|
||||
@Get('storage-template-options')
|
||||
getStorageTemplateOptions(): SystemConfigTemplateStorageOptionDto {
|
||||
return this.service.getStorageTemplateOptions();
|
||||
}
|
||||
|
||||
@AdminRoute(false)
|
||||
@Get('map/style.json')
|
||||
getMapStyle(@Query() dto: MapThemeDto) {
|
||||
return this.service.getMapStyle(dto.theme);
|
||||
}
|
||||
}
|
||||
66
server/src/controllers/tag.controller.ts
Normal file
66
server/src/controllers/tag.controller.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import { Body, Controller, Delete, Get, Param, Patch, Post, Put } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AssetIdsDto } from 'src/domain/asset/dto/asset-ids.dto';
|
||||
import { AssetIdsResponseDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
|
||||
import { AssetResponseDto } from 'src/domain/asset/response-dto/asset-response.dto';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { TagResponseDto } from 'src/domain/tag/tag-response.dto';
|
||||
import { CreateTagDto, UpdateTagDto } from 'src/domain/tag/tag.dto';
|
||||
import { TagService } from 'src/domain/tag/tag.service';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('Tag')
|
||||
@Controller('tag')
|
||||
@Authenticated()
|
||||
export class TagController {
|
||||
constructor(private service: TagService) {}
|
||||
|
||||
@Post()
|
||||
createTag(@Auth() auth: AuthDto, @Body() dto: CreateTagDto): Promise<TagResponseDto> {
|
||||
return this.service.create(auth, dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
getAllTags(@Auth() auth: AuthDto): Promise<TagResponseDto[]> {
|
||||
return this.service.getAll(auth);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
getTagById(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<TagResponseDto> {
|
||||
return this.service.getById(auth, id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
updateTag(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto, @Body() dto: UpdateTagDto): Promise<TagResponseDto> {
|
||||
return this.service.update(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
deleteTag(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.remove(auth, id);
|
||||
}
|
||||
|
||||
@Get(':id/assets')
|
||||
getTagAssets(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetResponseDto[]> {
|
||||
return this.service.getAssets(auth, id);
|
||||
}
|
||||
|
||||
@Put(':id/assets')
|
||||
tagAssets(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: AssetIdsDto,
|
||||
): Promise<AssetIdsResponseDto[]> {
|
||||
return this.service.addAssets(auth, id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id/assets')
|
||||
untagAssets(
|
||||
@Auth() auth: AuthDto,
|
||||
@Body() dto: AssetIdsDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
): Promise<AssetIdsResponseDto[]> {
|
||||
return this.service.removeAssets(auth, id, dto);
|
||||
}
|
||||
}
|
||||
31
server/src/controllers/trash.controller.ts
Normal file
31
server/src/controllers/trash.controller.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { BulkIdsDto } from 'src/domain/asset/response-dto/asset-ids-response.dto';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { TrashService } from 'src/domain/trash/trash.service';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
|
||||
@ApiTags('Trash')
|
||||
@Controller('trash')
|
||||
@Authenticated()
|
||||
export class TrashController {
|
||||
constructor(private service: TrashService) {}
|
||||
|
||||
@Post('empty')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
emptyTrash(@Auth() auth: AuthDto): Promise<void> {
|
||||
return this.service.empty(auth);
|
||||
}
|
||||
|
||||
@Post('restore')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
restoreTrash(@Auth() auth: AuthDto): Promise<void> {
|
||||
return this.service.restore(auth);
|
||||
}
|
||||
|
||||
@Post('restore/assets')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
restoreAssets(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
|
||||
return this.service.restoreAssets(auth, dto);
|
||||
}
|
||||
}
|
||||
103
server/src/controllers/user.controller.ts
Normal file
103
server/src/controllers/user.controller.ts
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
Next,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
Res,
|
||||
UploadedFile,
|
||||
UseInterceptors,
|
||||
} from '@nestjs/common';
|
||||
import { ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger';
|
||||
import { NextFunction, Response } from 'express';
|
||||
import { AuthDto } from 'src/domain/auth/auth.dto';
|
||||
import { CreateProfileImageDto } from 'src/domain/user/dto/create-profile-image.dto';
|
||||
import { CreateUserDto } from 'src/domain/user/dto/create-user.dto';
|
||||
import { DeleteUserDto } from 'src/domain/user/dto/delete-user.dto';
|
||||
import { UpdateUserDto } from 'src/domain/user/dto/update-user.dto';
|
||||
import { CreateProfileImageResponseDto } from 'src/domain/user/response-dto/create-profile-image-response.dto';
|
||||
import { UserResponseDto } from 'src/domain/user/response-dto/user-response.dto';
|
||||
import { UserService } from 'src/domain/user/user.service';
|
||||
import { sendFile } from 'src/immich/app.utils';
|
||||
import { AdminRoute, Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
|
||||
import { FileUploadInterceptor, Route } from 'src/middleware/file-upload.interceptor';
|
||||
import { UUIDParamDto } from 'src/validation';
|
||||
|
||||
@ApiTags('User')
|
||||
@Controller(Route.USER)
|
||||
@Authenticated()
|
||||
export class UserController {
|
||||
constructor(private service: UserService) {}
|
||||
|
||||
@Get()
|
||||
getAllUsers(@Auth() auth: AuthDto, @Query('isAll') isAll: boolean): Promise<UserResponseDto[]> {
|
||||
return this.service.getAll(auth, isAll);
|
||||
}
|
||||
|
||||
@Get('info/:id')
|
||||
getUserById(@Param() { id }: UUIDParamDto): Promise<UserResponseDto> {
|
||||
return this.service.get(id);
|
||||
}
|
||||
|
||||
@Get('me')
|
||||
getMyUserInfo(@Auth() auth: AuthDto): Promise<UserResponseDto> {
|
||||
return this.service.getMe(auth);
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Post()
|
||||
createUser(@Body() createUserDto: CreateUserDto): Promise<UserResponseDto> {
|
||||
return this.service.create(createUserDto);
|
||||
}
|
||||
|
||||
@Delete('profile-image')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
deleteProfileImage(@Auth() auth: AuthDto): Promise<void> {
|
||||
return this.service.deleteProfileImage(auth);
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Delete(':id')
|
||||
deleteUser(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id }: UUIDParamDto,
|
||||
@Body() dto: DeleteUserDto,
|
||||
): Promise<UserResponseDto> {
|
||||
return this.service.delete(auth, id, dto);
|
||||
}
|
||||
|
||||
@AdminRoute()
|
||||
@Post(':id/restore')
|
||||
restoreUser(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserResponseDto> {
|
||||
return this.service.restore(auth, id);
|
||||
}
|
||||
|
||||
// TODO: replace with @Put(':id')
|
||||
@Put()
|
||||
updateUser(@Auth() auth: AuthDto, @Body() updateUserDto: UpdateUserDto): Promise<UserResponseDto> {
|
||||
return this.service.update(auth, updateUserDto);
|
||||
}
|
||||
|
||||
@UseInterceptors(FileUploadInterceptor)
|
||||
@ApiConsumes('multipart/form-data')
|
||||
@ApiBody({ description: 'A new avatar for the user', type: CreateProfileImageDto })
|
||||
@Post('profile-image')
|
||||
createProfileImage(
|
||||
@Auth() auth: AuthDto,
|
||||
@UploadedFile() fileInfo: Express.Multer.File,
|
||||
): Promise<CreateProfileImageResponseDto> {
|
||||
return this.service.createProfileImage(auth, fileInfo);
|
||||
}
|
||||
|
||||
@Get('profile-image/:id')
|
||||
@FileResponse()
|
||||
async getProfileImage(@Res() res: Response, @Next() next: NextFunction, @Param() { id }: UUIDParamDto) {
|
||||
await sendFile(res, next, () => this.service.getProfileImage(id));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue