mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
test(server): auth e2e (#3492)
* test(server): auth controller e2e test * test(server): user e2e test * refactor(server): album e2e * fix: linting
This commit is contained in:
parent
9e085c1071
commit
e53625b067
19 changed files with 927 additions and 496 deletions
|
|
@ -101,13 +101,13 @@ describe('AuthService', () => {
|
|||
|
||||
it('should check the user exists', async () => {
|
||||
userMock.getByEmail.mockResolvedValue(null);
|
||||
await expect(sut.login(fixtures.login, loginDetails)).rejects.toBeInstanceOf(BadRequestException);
|
||||
await expect(sut.login(fixtures.login, loginDetails)).rejects.toBeInstanceOf(UnauthorizedException);
|
||||
expect(userMock.getByEmail).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should check the user has a password', async () => {
|
||||
userMock.getByEmail.mockResolvedValue({} as UserEntity);
|
||||
await expect(sut.login(fixtures.login, loginDetails)).rejects.toBeInstanceOf(BadRequestException);
|
||||
await expect(sut.login(fixtures.login, loginDetails)).rejects.toBeInstanceOf(UnauthorizedException);
|
||||
expect(userMock.getByEmail).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
import { SystemConfig, UserEntity } from '@app/infra/entities';
|
||||
import {
|
||||
BadRequestException,
|
||||
Inject,
|
||||
Injectable,
|
||||
InternalServerErrorException,
|
||||
Logger,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { BadRequestException, Inject, Injectable, Logger, UnauthorizedException } from '@nestjs/common';
|
||||
import cookieParser from 'cookie';
|
||||
import { IncomingHttpHeaders } from 'http';
|
||||
import { DateTime } from 'luxon';
|
||||
|
|
@ -90,7 +83,7 @@ export class AuthService {
|
|||
|
||||
if (!user) {
|
||||
this.logger.warn(`Failed login attempt for user ${dto.email} from ip address ${details.clientIp}`);
|
||||
throw new BadRequestException('Incorrect email or password');
|
||||
throw new UnauthorizedException('Incorrect email or password');
|
||||
}
|
||||
|
||||
return this.createLoginResponse(user, AuthType.PASSWORD, details);
|
||||
|
|
@ -129,21 +122,16 @@ export class AuthService {
|
|||
throw new BadRequestException('The server already has an admin');
|
||||
}
|
||||
|
||||
try {
|
||||
const admin = await this.userCore.createUser({
|
||||
isAdmin: true,
|
||||
email: dto.email,
|
||||
firstName: dto.firstName,
|
||||
lastName: dto.lastName,
|
||||
password: dto.password,
|
||||
storageLabel: 'admin',
|
||||
});
|
||||
const admin = await this.userCore.createUser({
|
||||
isAdmin: true,
|
||||
email: dto.email,
|
||||
firstName: dto.firstName,
|
||||
lastName: dto.lastName,
|
||||
password: dto.password,
|
||||
storageLabel: 'admin',
|
||||
});
|
||||
|
||||
return mapAdminSignupResponse(admin);
|
||||
} catch (error) {
|
||||
this.logger.error(`Unable to register admin user: ${error}`, (error as Error).stack);
|
||||
throw new InternalServerErrorException('Failed to register new admin user');
|
||||
}
|
||||
return mapAdminSignupResponse(admin);
|
||||
}
|
||||
|
||||
async validate(headers: IncomingHttpHeaders, params: Record<string, string>): Promise<AuthUserDto | null> {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import {
|
|||
AdminSignupResponseDto,
|
||||
AuthDeviceResponseDto,
|
||||
AuthService,
|
||||
AuthType,
|
||||
AuthUserDto,
|
||||
ChangePasswordDto,
|
||||
IMMICH_ACCESS_COOKIE,
|
||||
|
|
@ -15,7 +14,7 @@ import {
|
|||
UserResponseDto,
|
||||
ValidateAccessTokenResponseDto,
|
||||
} from '@app/domain';
|
||||
import { Body, Controller, Delete, Get, Param, Post, Req, Res } from '@nestjs/common';
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Req, Res } from '@nestjs/common';
|
||||
import { ApiBadRequestResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { Request, Response } from 'express';
|
||||
import { Authenticated, AuthUser, GetLoginDetails, PublicRoute } from '../app.guard';
|
||||
|
|
@ -54,36 +53,39 @@ export class AuthController {
|
|||
}
|
||||
|
||||
@Delete('devices')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
logoutAuthDevices(@AuthUser() authUser: AuthUserDto): Promise<void> {
|
||||
return this.service.logoutDevices(authUser);
|
||||
}
|
||||
|
||||
@Delete('devices/:id')
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
logoutAuthDevice(@AuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||
return this.service.logoutDevice(authUser, id);
|
||||
}
|
||||
|
||||
@Post('validateToken')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
validateAccessToken(): ValidateAccessTokenResponseDto {
|
||||
return { authStatus: true };
|
||||
}
|
||||
|
||||
@Post('change-password')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
changePassword(@AuthUser() authUser: AuthUserDto, @Body() dto: ChangePasswordDto): Promise<UserResponseDto> {
|
||||
return this.service.changePassword(authUser, dto);
|
||||
}
|
||||
|
||||
@Post('logout')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
logout(
|
||||
@Req() req: Request,
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@AuthUser() authUser: AuthUserDto,
|
||||
): Promise<LogoutResponseDto> {
|
||||
const authType: AuthType = req.cookies[IMMICH_AUTH_TYPE_COOKIE];
|
||||
|
||||
res.clearCookie(IMMICH_ACCESS_COOKIE);
|
||||
res.clearCookie(IMMICH_AUTH_TYPE_COOKIE);
|
||||
|
||||
return this.service.logout(authUser, authType);
|
||||
return this.service.logout(authUser, (req.cookies || {})[IMMICH_AUTH_TYPE_COOKIE]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ export class UserController {
|
|||
return this.service.restoreUser(authUser, userId);
|
||||
}
|
||||
|
||||
// TODO: replace with @Put(':id')
|
||||
@Put()
|
||||
updateUser(@AuthUser() authUser: AuthUserDto, @Body() updateUserDto: UpdateUserDto): Promise<UserResponseDto> {
|
||||
return this.service.updateUser(authUser, updateUserDto);
|
||||
|
|
|
|||
2
server/src/immich/index.ts
Normal file
2
server/src/immich/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from './app.module';
|
||||
export * from './controllers';
|
||||
Loading…
Add table
Add a link
Reference in a new issue