1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

test(server): change password (#1177)

This commit is contained in:
Jason Rasmussen 2022-12-26 17:36:06 -05:00 committed by GitHub
parent 4f8bc641bd
commit 0c896d9e59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 34 deletions

View File

@ -1,11 +1,10 @@
import { UserEntity } from '@app/database/entities/user.entity';
import { BadRequestException } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { BadRequestException, UnauthorizedException } from '@nestjs/common';
import * as bcrypt from 'bcrypt';
import { AuthType } from '../../constants/jwt.constant';
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
import { OAuthService } from '../oauth/oauth.service';
import { IUserRepository, USER_REPOSITORY } from '../user/user-repository';
import { IUserRepository } from '../user/user-repository';
import { AuthService } from './auth.service';
import { SignUpDto } from './dto/sign-up.dto';
import { LoginResponseDto } from './response-dto/login-response.dto';
@ -20,6 +19,17 @@ const fixtures = {
const CLIENT_IP = '127.0.0.1';
jest.mock('bcrypt');
jest.mock('@nestjs/common', () => ({
...jest.requireActual('@nestjs/common'),
Logger: jest.fn().mockReturnValue({
verbose: jest.fn(),
debug: jest.fn(),
log: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
}),
}));
describe('AuthService', () => {
let sut: AuthService;
@ -61,19 +71,7 @@ describe('AuthService', () => {
getLogoutEndpoint: jest.fn(),
} as unknown as jest.Mocked<OAuthService>;
const moduleRef = await Test.createTestingModule({
providers: [
AuthService,
{ provide: ImmichJwtService, useValue: immichJwtServiceMock },
{ provide: OAuthService, useValue: oauthServiceMock },
{
provide: USER_REPOSITORY,
useValue: userRepositoryMock,
},
],
}).compile();
sut = moduleRef.get(AuthService);
sut = new AuthService(oauthServiceMock, immichJwtServiceMock, userRepositoryMock);
});
it('should be defined', () => {
@ -104,6 +102,62 @@ describe('AuthService', () => {
});
});
describe('changePassword', () => {
it('should change the password', async () => {
const authUser = { email: 'test@imimch.com' } as UserEntity;
const dto = { password: 'old-password', newPassword: 'new-password' };
compare.mockResolvedValue(true);
userRepositoryMock.getByEmail.mockResolvedValue({
email: 'test@immich.com',
password: 'hash-password',
} as UserEntity);
await sut.changePassword(authUser, dto);
expect(userRepositoryMock.getByEmail).toHaveBeenCalledWith(authUser.email, true);
expect(compare).toHaveBeenCalledWith('old-password', 'hash-password');
});
it('should throw when auth user email is not found', async () => {
const authUser = { email: 'test@imimch.com' } as UserEntity;
const dto = { password: 'old-password', newPassword: 'new-password' };
userRepositoryMock.getByEmail.mockResolvedValue(null);
await expect(sut.changePassword(authUser, dto)).rejects.toBeInstanceOf(UnauthorizedException);
});
it('should throw when password does not match existing password', async () => {
const authUser = { email: 'test@imimch.com' } as UserEntity;
const dto = { password: 'old-password', newPassword: 'new-password' };
compare.mockResolvedValue(false);
userRepositoryMock.getByEmail.mockResolvedValue({
email: 'test@immich.com',
password: 'hash-password',
} as UserEntity);
await expect(sut.changePassword(authUser, dto)).rejects.toBeInstanceOf(BadRequestException);
});
it('should throw when user does not have a password', async () => {
const authUser = { email: 'test@imimch.com' } as UserEntity;
const dto = { password: 'old-password', newPassword: 'new-password' };
compare.mockResolvedValue(false);
userRepositoryMock.getByEmail.mockResolvedValue({
email: 'test@immich.com',
password: '',
} as UserEntity);
await expect(sut.changePassword(authUser, dto)).rejects.toBeInstanceOf(BadRequestException);
});
});
describe('logout', () => {
it('should return the end session endpoint', async () => {
oauthServiceMock.getLogoutEndpoint.mockResolvedValue('end-session-endpoint');

View File

@ -24,6 +24,7 @@ import { UserCore } from '../user/user.core';
@Injectable()
export class AuthService {
private userCore: UserCore;
private logger = new Logger(AuthService.name);
constructor(
private oauthService: OAuthService,
@ -44,7 +45,7 @@ export class AuthService {
}
if (!user) {
Logger.warn(`Failed login attempt for user ${loginCredential.email} from ip address ${clientIp}`);
this.logger.warn(`Failed login attempt for user ${loginCredential.email} from ip address ${clientIp}`);
throw new BadRequestException('Incorrect email or password');
}
@ -94,8 +95,8 @@ export class AuthService {
});
return mapAdminSignupResponse(admin);
} catch (e) {
Logger.error('e', 'signUp');
} catch (error) {
this.logger.error(`Unable to register admin user: ${error}`, (error as Error).stack);
throw new InternalServerErrorException('Failed to register new admin user');
}
}

View File

@ -1,7 +1,7 @@
import { SystemConfig } from '@app/database/entities/system-config.entity';
import { UserEntity } from '@app/database/entities/user.entity';
import { ImmichConfigService } from '@app/immich-config';
import { BadRequestException, Logger } from '@nestjs/common';
import { BadRequestException } from '@nestjs/common';
import { generators, Issuer } from 'openid-client';
import { AuthUserDto } from '../../decorators/auth-user.decorator';
import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
@ -32,20 +32,17 @@ const loginResponse = {
userEmail: 'user@immich.com,',
} as LoginResponseDto;
jest.mock('@nestjs/common', () => {
return {
...jest.requireActual('@nestjs/common'),
Logger: function MockLogger() {
Object.assign(this as Logger, {
verbose: jest.fn(),
debug: jest.fn(),
log: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
});
},
};
});
jest.mock('@nestjs/common', () => ({
...jest.requireActual('@nestjs/common'),
Logger: jest.fn().mockReturnValue({
verbose: jest.fn(),
debug: jest.fn(),
log: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
}),
}));
describe('OAuthService', () => {
let sut: OAuthService;