import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Post, Put, Req, Res } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Request, Response } from 'express'; import { AuthDto, AuthStatusResponseDto, ChangePasswordDto, LoginCredentialDto, LoginResponseDto, LogoutResponseDto, PinCodeChangeDto, PinCodeSetupDto, SignUpDto, ValidateAccessTokenResponseDto, } from 'src/dtos/auth.dto'; import { UserAdminResponseDto } from 'src/dtos/user.dto'; import { AuthType, ImmichCookie } from 'src/enum'; import { Auth, Authenticated, GetLoginDetails } from 'src/middleware/auth.guard'; import { AuthService, LoginDetails } from 'src/services/auth.service'; import { respondWithCookie, respondWithoutCookie } from 'src/utils/response'; @ApiTags('Authentication') @Controller('auth') export class AuthController { constructor(private service: AuthService) {} @Post('login') async login( @Res({ passthrough: true }) res: Response, @Body() loginCredential: LoginCredentialDto, @GetLoginDetails() loginDetails: LoginDetails, ): Promise { const body = await this.service.login(loginCredential, loginDetails); return respondWithCookie(res, body, { isSecure: loginDetails.isSecure, values: [ { key: ImmichCookie.ACCESS_TOKEN, value: body.accessToken }, { key: ImmichCookie.AUTH_TYPE, value: AuthType.PASSWORD }, { key: ImmichCookie.IS_AUTHENTICATED, value: 'true' }, ], }); } @Post('admin-sign-up') signUpAdmin(@Body() dto: SignUpDto): Promise { return this.service.adminSignUp(dto); } @Post('validateToken') @HttpCode(HttpStatus.OK) @Authenticated() validateAccessToken(): ValidateAccessTokenResponseDto { return { authStatus: true }; } @Post('change-password') @HttpCode(HttpStatus.OK) @Authenticated() changePassword(@Auth() auth: AuthDto, @Body() dto: ChangePasswordDto): Promise { return this.service.changePassword(auth, dto); } @Post('logout') @HttpCode(HttpStatus.OK) @Authenticated() async logout( @Req() request: Request, @Res({ passthrough: true }) res: Response, @Auth() auth: AuthDto, ): Promise { const authType = (request.cookies || {})[ImmichCookie.AUTH_TYPE]; const body = await this.service.logout(auth, authType); return respondWithoutCookie(res, body, [ ImmichCookie.ACCESS_TOKEN, ImmichCookie.AUTH_TYPE, ImmichCookie.IS_AUTHENTICATED, ]); } @Get('status') @Authenticated() getAuthStatus(@Auth() auth: AuthDto): Promise { return this.service.getAuthStatus(auth); } @Post('pin-code') @Authenticated() setupPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeSetupDto): Promise { return this.service.setupPinCode(auth, dto); } @Put('pin-code') @Authenticated() async changePinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeChangeDto): Promise { return this.service.changePinCode(auth, dto); } @Delete('pin-code') @Authenticated() async resetPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeChangeDto): Promise { return this.service.resetPinCode(auth, dto); } @Post('pin-code/verify') @HttpCode(HttpStatus.OK) @Authenticated() async verifyPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeSetupDto): Promise { return this.service.verifyPinCode(auth, dto); } }