fix: replace first and last name with single field (#4915)
This commit is contained in:
@@ -6844,15 +6844,12 @@
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"memoriesEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -6864,8 +6861,7 @@
|
||||
"required": [
|
||||
"email",
|
||||
"password",
|
||||
"firstName",
|
||||
"lastName"
|
||||
"name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
@@ -7463,13 +7459,10 @@
|
||||
"accessToken": {
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"isAdmin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"lastName": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"profileImagePath": {
|
||||
@@ -7489,8 +7482,7 @@
|
||||
"accessToken",
|
||||
"userId",
|
||||
"userEmail",
|
||||
"firstName",
|
||||
"lastName",
|
||||
"name",
|
||||
"profileImagePath",
|
||||
"isAdmin",
|
||||
"shouldChangePassword"
|
||||
@@ -7656,9 +7648,6 @@
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7668,12 +7657,12 @@
|
||||
"isAdmin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"memoriesEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"oauthId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -7694,8 +7683,7 @@
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"firstName",
|
||||
"lastName",
|
||||
"name",
|
||||
"email",
|
||||
"profileImagePath",
|
||||
"storageLabel",
|
||||
@@ -8464,14 +8452,10 @@
|
||||
"example": "testuser@email.com",
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"name": {
|
||||
"example": "Admin",
|
||||
"type": "string"
|
||||
},
|
||||
"lastName": {
|
||||
"example": "Doe",
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"example": "password",
|
||||
"type": "string"
|
||||
@@ -8480,8 +8464,7 @@
|
||||
"required": [
|
||||
"email",
|
||||
"password",
|
||||
"firstName",
|
||||
"lastName"
|
||||
"name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
@@ -9163,9 +9146,6 @@
|
||||
"externalPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
@@ -9173,12 +9153,12 @@
|
||||
"isAdmin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"memoriesEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -9203,13 +9183,10 @@
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"userFirstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"userId": {
|
||||
"type": "string"
|
||||
},
|
||||
"userLastName": {
|
||||
"userName": {
|
||||
"type": "string"
|
||||
},
|
||||
"videos": {
|
||||
@@ -9218,8 +9195,7 @@
|
||||
},
|
||||
"required": [
|
||||
"userId",
|
||||
"userFirstName",
|
||||
"userLastName",
|
||||
"userName",
|
||||
"photos",
|
||||
"videos",
|
||||
"usage"
|
||||
@@ -9231,13 +9207,10 @@
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastName": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"profileImagePath": {
|
||||
@@ -9246,8 +9219,7 @@
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"firstName",
|
||||
"lastName",
|
||||
"name",
|
||||
"email",
|
||||
"profileImagePath"
|
||||
],
|
||||
@@ -9271,21 +9243,18 @@
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"isAdmin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"memoriesEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"oauthId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -9306,8 +9275,7 @@
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"firstName",
|
||||
"lastName",
|
||||
"name",
|
||||
"email",
|
||||
"profileImagePath",
|
||||
"storageLabel",
|
||||
|
||||
Generated
-5
@@ -16845,11 +16845,6 @@
|
||||
"luxon": "^3.2.1"
|
||||
}
|
||||
},
|
||||
"cron-validator": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cron-validator/-/cron-validator-1.3.1.tgz",
|
||||
"integrity": "sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A=="
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
|
||||
@@ -15,12 +15,12 @@ export class ResetAdminPasswordCommand extends CommandRunner {
|
||||
|
||||
async run(): Promise<void> {
|
||||
const ask = (admin: UserResponseDto) => {
|
||||
const { id, oauthId, email, firstName, lastName } = admin;
|
||||
const { id, oauthId, email, name } = admin;
|
||||
console.log(`Found Admin:
|
||||
- ID=${id}
|
||||
- OAuth ID=${oauthId}
|
||||
- Email=${email}
|
||||
- Name=${firstName} ${lastName}`);
|
||||
- Name=${name}`);
|
||||
|
||||
return this.inquirer.ask<{ password: string }>('prompt-password', undefined).then(({ password }) => password);
|
||||
};
|
||||
|
||||
@@ -33,8 +33,7 @@ export class LoginResponseDto {
|
||||
accessToken!: string;
|
||||
userId!: string;
|
||||
userEmail!: string;
|
||||
firstName!: string;
|
||||
lastName!: string;
|
||||
name!: string;
|
||||
profileImagePath!: string;
|
||||
isAdmin!: boolean;
|
||||
shouldChangePassword!: boolean;
|
||||
@@ -45,8 +44,7 @@ export function mapLoginResponse(entity: UserEntity, accessToken: string): Login
|
||||
accessToken: accessToken,
|
||||
userId: entity.id,
|
||||
userEmail: entity.email,
|
||||
firstName: entity.firstName,
|
||||
lastName: entity.lastName,
|
||||
name: entity.name,
|
||||
isAdmin: entity.isAdmin,
|
||||
profileImagePath: entity.profileImagePath,
|
||||
shouldChangePassword: entity.shouldChangePassword,
|
||||
@@ -62,12 +60,7 @@ export class SignUpDto extends LoginCredentialDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@ApiProperty({ example: 'Admin' })
|
||||
firstName!: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@ApiProperty({ example: 'Doe' })
|
||||
lastName!: string;
|
||||
name!: string;
|
||||
}
|
||||
|
||||
export class ChangePasswordDto {
|
||||
|
||||
@@ -236,7 +236,7 @@ describe('AuthService', () => {
|
||||
});
|
||||
|
||||
describe('adminSignUp', () => {
|
||||
const dto: SignUpDto = { email: 'test@immich.com', password: 'password', firstName: 'immich', lastName: 'admin' };
|
||||
const dto: SignUpDto = { email: 'test@immich.com', password: 'password', name: 'immich admin' };
|
||||
|
||||
it('should only allow one admin', async () => {
|
||||
userMock.getAdmin.mockResolvedValue({} as UserEntity);
|
||||
@@ -251,8 +251,7 @@ describe('AuthService', () => {
|
||||
id: 'admin',
|
||||
createdAt: new Date('2021-01-01'),
|
||||
email: 'test@immich.com',
|
||||
firstName: 'immich',
|
||||
lastName: 'admin',
|
||||
name: 'immich admin',
|
||||
});
|
||||
expect(userMock.getAdmin).toHaveBeenCalled();
|
||||
expect(userMock.create).toHaveBeenCalled();
|
||||
|
||||
@@ -146,8 +146,7 @@ export class AuthService {
|
||||
const admin = await this.userCore.createUser({
|
||||
isAdmin: true,
|
||||
email: dto.email,
|
||||
firstName: dto.firstName,
|
||||
lastName: dto.lastName,
|
||||
name: dto.name,
|
||||
password: dto.password,
|
||||
storageLabel: 'admin',
|
||||
});
|
||||
@@ -273,9 +272,9 @@ export class AuthService {
|
||||
storageLabel = null;
|
||||
}
|
||||
|
||||
const userName = profile.name ?? `${profile.given_name || ''} ${profile.family_name || ''}`;
|
||||
user = await this.userCore.createUser({
|
||||
firstName: profile.given_name || '',
|
||||
lastName: profile.family_name || '',
|
||||
name: userName,
|
||||
email: profile.email,
|
||||
oauthId: profile.sub,
|
||||
storageLabel,
|
||||
|
||||
@@ -7,10 +7,9 @@ import { PartnerService } from './partner.service';
|
||||
const responseDto = {
|
||||
admin: <PartnerResponseDto>{
|
||||
email: 'admin@test.com',
|
||||
firstName: 'admin_first_name',
|
||||
name: 'admin_name',
|
||||
id: 'admin_id',
|
||||
isAdmin: true,
|
||||
lastName: 'admin_last_name',
|
||||
oauthId: '',
|
||||
profileImagePath: '',
|
||||
shouldChangePassword: false,
|
||||
@@ -24,10 +23,9 @@ const responseDto = {
|
||||
},
|
||||
user1: <PartnerResponseDto>{
|
||||
email: 'immich@test.com',
|
||||
firstName: 'immich_first_name',
|
||||
name: 'immich_name',
|
||||
id: 'user-id',
|
||||
isAdmin: false,
|
||||
lastName: 'immich_last_name',
|
||||
oauthId: '',
|
||||
profileImagePath: '',
|
||||
shouldChangePassword: false,
|
||||
|
||||
@@ -6,8 +6,7 @@ export interface UserListFilter {
|
||||
|
||||
export interface UserStatsQueryResponse {
|
||||
userId: string;
|
||||
userFirstName: string;
|
||||
userLastName: string;
|
||||
userName: string;
|
||||
photos: number;
|
||||
videos: number;
|
||||
usage: number;
|
||||
|
||||
@@ -38,9 +38,7 @@ export class UsageByUserDto {
|
||||
@ApiProperty({ type: 'string' })
|
||||
userId!: string;
|
||||
@ApiProperty({ type: 'string' })
|
||||
userFirstName!: string;
|
||||
@ApiProperty({ type: 'string' })
|
||||
userLastName!: string;
|
||||
userName!: string;
|
||||
@ApiProperty({ type: 'integer' })
|
||||
photos!: number;
|
||||
@ApiProperty({ type: 'integer' })
|
||||
|
||||
@@ -195,24 +195,21 @@ describe(ServerInfoService.name, () => {
|
||||
userMock.getUserStats.mockResolvedValue([
|
||||
{
|
||||
userId: 'user1',
|
||||
userFirstName: '1',
|
||||
userLastName: 'User',
|
||||
userName: '1 User',
|
||||
photos: 10,
|
||||
videos: 11,
|
||||
usage: 12345,
|
||||
},
|
||||
{
|
||||
userId: 'user2',
|
||||
userFirstName: '2',
|
||||
userLastName: 'User',
|
||||
userName: '2 User',
|
||||
photos: 10,
|
||||
videos: 20,
|
||||
usage: 123456,
|
||||
},
|
||||
{
|
||||
userId: 'user3',
|
||||
userFirstName: '3',
|
||||
userLastName: 'User',
|
||||
userName: '3 User',
|
||||
photos: 100,
|
||||
videos: 0,
|
||||
usage: 987654,
|
||||
@@ -227,25 +224,22 @@ describe(ServerInfoService.name, () => {
|
||||
{
|
||||
photos: 10,
|
||||
usage: 12345,
|
||||
userFirstName: '1',
|
||||
userName: '1 User',
|
||||
userId: 'user1',
|
||||
userLastName: 'User',
|
||||
videos: 11,
|
||||
},
|
||||
{
|
||||
photos: 10,
|
||||
usage: 123456,
|
||||
userFirstName: '2',
|
||||
userName: '2 User',
|
||||
userId: 'user2',
|
||||
userLastName: 'User',
|
||||
videos: 20,
|
||||
},
|
||||
{
|
||||
photos: 100,
|
||||
usage: 987654,
|
||||
userFirstName: '3',
|
||||
userName: '3 User',
|
||||
userId: 'user3',
|
||||
userLastName: 'User',
|
||||
videos: 0,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -98,8 +98,7 @@ export class ServerInfoService {
|
||||
for (const user of userStats) {
|
||||
const usage = new UsageByUserDto();
|
||||
usage.userId = user.userId;
|
||||
usage.userFirstName = user.userFirstName;
|
||||
usage.userLastName = user.userLastName;
|
||||
usage.userName = user.userName;
|
||||
usage.photos = user.photos;
|
||||
usage.videos = user.videos;
|
||||
usage.usage = user.usage;
|
||||
|
||||
@@ -7,8 +7,7 @@ describe('create user DTO', () => {
|
||||
const params: Partial<CreateUserDto> = {
|
||||
email: undefined,
|
||||
password: 'password',
|
||||
firstName: 'first name',
|
||||
lastName: 'last name',
|
||||
name: 'name',
|
||||
};
|
||||
let dto: CreateUserDto = plainToInstance(CreateUserDto, params);
|
||||
let errors = await validate(dto);
|
||||
@@ -31,8 +30,7 @@ describe('create user DTO', () => {
|
||||
const dto = plainToInstance(CreateUserDto, {
|
||||
email: someEmail,
|
||||
password: 'some password',
|
||||
firstName: 'some first name',
|
||||
lastName: 'some last name',
|
||||
name: 'some name',
|
||||
});
|
||||
const errors = await validate(dto);
|
||||
expect(errors).toHaveLength(0);
|
||||
@@ -48,8 +46,7 @@ describe('create admin DTO', () => {
|
||||
isAdmin: true,
|
||||
email: someEmail,
|
||||
password: 'some password',
|
||||
firstName: 'some first name',
|
||||
lastName: 'some last name',
|
||||
name: 'some name',
|
||||
});
|
||||
const errors = await validate(dto);
|
||||
expect(errors).toHaveLength(0);
|
||||
@@ -64,8 +61,7 @@ describe('create user oauth DTO', () => {
|
||||
const dto = plainToInstance(CreateUserOAuthDto, {
|
||||
email: someEmail,
|
||||
oauthId: 'some oauth id',
|
||||
firstName: 'some first name',
|
||||
lastName: 'some last name',
|
||||
name: 'some name',
|
||||
});
|
||||
const errors = await validate(dto);
|
||||
expect(errors).toHaveLength(0);
|
||||
|
||||
@@ -13,11 +13,7 @@ export class CreateUserDto {
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
firstName!: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
lastName!: string;
|
||||
name!: string;
|
||||
|
||||
@Optional({ nullable: true })
|
||||
@IsString()
|
||||
@@ -45,10 +41,7 @@ export class CreateAdminDto {
|
||||
password!: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
firstName!: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
lastName!: string;
|
||||
name!: string;
|
||||
}
|
||||
|
||||
export class CreateUserOAuthDto {
|
||||
@@ -59,7 +52,5 @@ export class CreateUserOAuthDto {
|
||||
@IsNotEmpty()
|
||||
oauthId!: string;
|
||||
|
||||
firstName?: string;
|
||||
|
||||
lastName?: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
@@ -17,12 +17,7 @@ export class UpdateUserDto {
|
||||
@Optional()
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
firstName?: string;
|
||||
|
||||
@Optional()
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
lastName?: string;
|
||||
name?: string;
|
||||
|
||||
@Optional()
|
||||
@IsString()
|
||||
|
||||
@@ -2,8 +2,7 @@ import { UserEntity } from '@app/infra/entities';
|
||||
|
||||
export class UserDto {
|
||||
id!: string;
|
||||
firstName!: string;
|
||||
lastName!: string;
|
||||
name!: string;
|
||||
email!: string;
|
||||
profileImagePath!: string;
|
||||
}
|
||||
@@ -24,8 +23,7 @@ export const mapSimpleUser = (entity: UserEntity): UserDto => {
|
||||
return {
|
||||
id: entity.id,
|
||||
email: entity.email,
|
||||
firstName: entity.firstName,
|
||||
lastName: entity.lastName,
|
||||
name: entity.name,
|
||||
profileImagePath: entity.profileImagePath,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -289,8 +289,7 @@ describe(UserService.name, () => {
|
||||
await expect(
|
||||
sut.create({
|
||||
email: 'john_smith@email.com',
|
||||
firstName: 'John',
|
||||
lastName: 'Smith',
|
||||
name: 'John Smith',
|
||||
password: 'password',
|
||||
}),
|
||||
).rejects.toBeInstanceOf(BadRequestException);
|
||||
@@ -303,8 +302,7 @@ describe(UserService.name, () => {
|
||||
await expect(
|
||||
sut.create({
|
||||
email: userStub.user1.email,
|
||||
firstName: userStub.user1.firstName,
|
||||
lastName: userStub.user1.lastName,
|
||||
name: userStub.user1.name,
|
||||
password: 'password',
|
||||
storageLabel: 'label',
|
||||
}),
|
||||
@@ -313,8 +311,7 @@ describe(UserService.name, () => {
|
||||
expect(userMock.getAdmin).toBeCalled();
|
||||
expect(userMock.create).toBeCalledWith({
|
||||
email: userStub.user1.email,
|
||||
firstName: userStub.user1.firstName,
|
||||
lastName: userStub.user1.lastName,
|
||||
name: userStub.user1.name,
|
||||
storageLabel: 'label',
|
||||
password: expect.anything(),
|
||||
});
|
||||
|
||||
@@ -16,10 +16,7 @@ export class UserEntity {
|
||||
id!: string;
|
||||
|
||||
@Column({ default: '' })
|
||||
firstName!: string;
|
||||
|
||||
@Column({ default: '' })
|
||||
lastName!: string;
|
||||
name!: string;
|
||||
|
||||
@Column({ default: false })
|
||||
isAdmin!: boolean;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddUsername1699322864544 implements MigrationInterface {
|
||||
name = 'AddUsername1699322864544'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "users" ADD "name" character varying NOT NULL DEFAULT ''`);
|
||||
await queryRunner.query(`UPDATE "users" SET "name" = CONCAT(COALESCE("firstName", ''), ' ', COALESCE("lastName", ''))`);
|
||||
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "firstName"`);
|
||||
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "lastName"`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "name"`);
|
||||
await queryRunner.query(`ALTER TABLE "users" ADD "lastName" character varying NOT NULL DEFAULT ''`);
|
||||
await queryRunner.query(`ALTER TABLE "users" ADD "firstName" character varying NOT NULL DEFAULT ''`);
|
||||
await queryRunner.query(`UPDATE "users" SET "lastName" = COALESCE("email", '')`);
|
||||
await queryRunner.query(`UPDATE "users" SET "firstName" = COALESCE("email", '')`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -80,8 +80,7 @@ export class UserRepository implements IUserRepository {
|
||||
const stats = await this.userRepository
|
||||
.createQueryBuilder('users')
|
||||
.select('users.id', 'userId')
|
||||
.addSelect('users.firstName', 'userFirstName')
|
||||
.addSelect('users.lastName', 'userLastName')
|
||||
.addSelect('users.name', 'userName')
|
||||
.addSelect(`COUNT(assets.id) FILTER (WHERE assets.type = 'IMAGE' AND assets.isVisible)`, 'photos')
|
||||
.addSelect(`COUNT(assets.id) FILTER (WHERE assets.type = 'VIDEO' AND assets.isVisible)`, 'videos')
|
||||
.addSelect('COALESCE(SUM(exif.fileSizeInByte), 0)', 'usage')
|
||||
|
||||
@@ -350,8 +350,7 @@ describe(`${ActivityController.name} (e2e)`, () => {
|
||||
const { id: userId } = await api.userApi.create(server, admin.accessToken, {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
});
|
||||
await api.albumApi.addUsers(server, admin.accessToken, album.id, { sharedUserIds: [userId] });
|
||||
const nonOwner = await api.authApi.login(server, { email: 'user1@immich.app', password: 'Password123' });
|
||||
@@ -371,8 +370,7 @@ describe(`${ActivityController.name} (e2e)`, () => {
|
||||
const { id: userId } = await api.userApi.create(server, admin.accessToken, {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
});
|
||||
await api.albumApi.addUsers(server, admin.accessToken, album.id, { sharedUserIds: [userId] });
|
||||
const nonOwner = await api.authApi.login(server, { email: 'user1@immich.app', password: 'Password123' });
|
||||
@@ -393,8 +391,7 @@ describe(`${ActivityController.name} (e2e)`, () => {
|
||||
const { id: userId } = await api.userApi.create(server, admin.accessToken, {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
});
|
||||
await api.albumApi.addUsers(server, admin.accessToken, album.id, { sharedUserIds: [userId] });
|
||||
const nonOwner = await api.authApi.login(server, { email: 'user1@immich.app', password: 'Password123' });
|
||||
|
||||
@@ -41,14 +41,12 @@ describe(`${AlbumController.name} (e2e)`, () => {
|
||||
api.userApi.create(server, admin.accessToken, {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
}),
|
||||
api.userApi.create(server, admin.accessToken, {
|
||||
email: 'user2@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 2',
|
||||
lastName: 'Test',
|
||||
name: 'User 2',
|
||||
}),
|
||||
]);
|
||||
|
||||
|
||||
@@ -22,15 +22,13 @@ import request from 'supertest';
|
||||
const user1Dto = {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
};
|
||||
|
||||
const user2Dto = {
|
||||
email: 'user2@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 2',
|
||||
lastName: 'Test',
|
||||
name: 'User 2',
|
||||
};
|
||||
|
||||
const makeUploadDto = (options?: { omit: string }): Record<string, any> => {
|
||||
|
||||
@@ -13,15 +13,13 @@ import {
|
||||
import { testApp } from '@test/test-utils';
|
||||
import request from 'supertest';
|
||||
|
||||
const firstName = 'Immich';
|
||||
const lastName = 'Admin';
|
||||
const name = 'Immich Admin';
|
||||
const password = 'Password123';
|
||||
const email = 'admin@immich.app';
|
||||
|
||||
const adminSignupResponse = {
|
||||
id: expect.any(String),
|
||||
firstName: 'Immich',
|
||||
lastName: 'Admin',
|
||||
name: 'Immich Admin',
|
||||
email: 'admin@immich.app',
|
||||
storageLabel: 'admin',
|
||||
externalPath: null,
|
||||
@@ -64,23 +62,19 @@ describe(`${AuthController.name} (e2e)`, () => {
|
||||
const invalid = [
|
||||
{
|
||||
should: 'require an email address',
|
||||
data: { firstName, lastName, password },
|
||||
data: { name, password },
|
||||
},
|
||||
{
|
||||
should: 'require a password',
|
||||
data: { firstName, lastName, email },
|
||||
data: { name, email },
|
||||
},
|
||||
{
|
||||
should: 'require a first name ',
|
||||
data: { lastName, email, password },
|
||||
},
|
||||
{
|
||||
should: 'require a last name ',
|
||||
data: { firstName, email, password },
|
||||
should: 'require a name',
|
||||
data: { email, password },
|
||||
},
|
||||
{
|
||||
should: 'require a valid email',
|
||||
data: { firstName, lastName, email: 'immich', password },
|
||||
data: { name, email: 'immich', password },
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -15,15 +15,13 @@ describe(`${LibraryController.name} (e2e)`, () => {
|
||||
const user1Dto = {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
};
|
||||
|
||||
const user2Dto = {
|
||||
email: 'user2@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 2',
|
||||
lastName: 'Test',
|
||||
name: 'User 2',
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
|
||||
@@ -10,15 +10,13 @@ import request from 'supertest';
|
||||
const user1Dto = {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
};
|
||||
|
||||
const user2Dto = {
|
||||
email: 'user2@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 2',
|
||||
lastName: 'Test',
|
||||
name: 'User 2',
|
||||
};
|
||||
|
||||
describe(`${PartnerController.name} (e2e)`, () => {
|
||||
|
||||
@@ -111,7 +111,7 @@ describe(`${ServerInfoController.name} (e2e)`, () => {
|
||||
|
||||
it('should only work for admins', async () => {
|
||||
const loginDto = { email: 'test@immich.app', password: 'Immich123' };
|
||||
await api.userApi.create(server, accessToken, { ...loginDto, firstName: 'test', lastName: 'test' });
|
||||
await api.userApi.create(server, accessToken, { ...loginDto, name: 'test' });
|
||||
const { accessToken: userAccessToken } = await api.authApi.login(server, loginDto);
|
||||
const { status, body } = await request(server)
|
||||
.get('/server-info/statistics')
|
||||
@@ -132,9 +132,8 @@ describe(`${ServerInfoController.name} (e2e)`, () => {
|
||||
{
|
||||
photos: 0,
|
||||
usage: 0,
|
||||
userFirstName: 'Immich',
|
||||
userName: 'Immich Admin',
|
||||
userId: loginResponse.userId,
|
||||
userLastName: 'Admin',
|
||||
videos: 0,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -11,8 +11,7 @@ import request from 'supertest';
|
||||
const user1Dto = {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
};
|
||||
|
||||
describe(`${PartnerController.name} (e2e)`, () => {
|
||||
|
||||
@@ -64,8 +64,7 @@ describe(`${SystemConfigController.name} (e2e)`, () => {
|
||||
const credentials = { email: 'user1@immich.app', password: 'Password123' };
|
||||
await api.userApi.create(server, admin.accessToken, {
|
||||
...credentials,
|
||||
firstName: 'User 1',
|
||||
lastName: 'Test',
|
||||
name: 'User 1',
|
||||
});
|
||||
const { accessToken } = await api.authApi.login(server, credentials);
|
||||
const { status, body } = await request(server)
|
||||
|
||||
@@ -59,8 +59,7 @@ describe(`${UserController.name}`, () => {
|
||||
const user1 = await api.userApi.create(server, accessToken, {
|
||||
email: `user1@immich.app`,
|
||||
password: 'Password123',
|
||||
firstName: `User 1`,
|
||||
lastName: 'Test',
|
||||
name: `User 1`,
|
||||
});
|
||||
|
||||
await api.userApi.delete(server, accessToken, user1.id);
|
||||
@@ -78,8 +77,7 @@ describe(`${UserController.name}`, () => {
|
||||
const user1 = await api.userApi.create(server, accessToken, {
|
||||
email: `user1@immich.app`,
|
||||
password: 'Password123',
|
||||
firstName: `User 1`,
|
||||
lastName: 'Test',
|
||||
name: `User 1`,
|
||||
});
|
||||
|
||||
await api.userApi.delete(server, accessToken, user1.id);
|
||||
@@ -149,8 +147,7 @@ describe(`${UserController.name}`, () => {
|
||||
isAdmin: true,
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'Immich',
|
||||
lastName: 'User',
|
||||
name: 'Immich',
|
||||
})
|
||||
.set('Authorization', `Bearer ${accessToken}`);
|
||||
expect(body).toMatchObject({
|
||||
@@ -167,8 +164,7 @@ describe(`${UserController.name}`, () => {
|
||||
.send({
|
||||
email: 'no-memories@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'No Memories',
|
||||
lastName: 'User',
|
||||
name: 'No Memories',
|
||||
memoriesEnabled: false,
|
||||
})
|
||||
.set('Authorization', `Bearer ${accessToken}`);
|
||||
@@ -186,8 +182,7 @@ describe(`${UserController.name}`, () => {
|
||||
beforeEach(async () => {
|
||||
userToDelete = await api.userApi.create(server, accessToken, {
|
||||
email: userStub.user1.email,
|
||||
firstName: userStub.user1.firstName,
|
||||
lastName: userStub.user1.lastName,
|
||||
name: userStub.user1.name,
|
||||
password: 'superSecurePassword',
|
||||
});
|
||||
});
|
||||
@@ -246,8 +241,7 @@ describe(`${UserController.name}`, () => {
|
||||
const user = await api.userApi.create(server, accessToken, {
|
||||
email: 'user1@immich.app',
|
||||
password: 'Password123',
|
||||
firstName: 'Immich',
|
||||
lastName: 'User',
|
||||
name: 'Immich User',
|
||||
});
|
||||
|
||||
const { status, body } = await request(server)
|
||||
@@ -284,15 +278,13 @@ describe(`${UserController.name}`, () => {
|
||||
const before = await api.userApi.get(server, accessToken, loginResponse.userId);
|
||||
const after = await api.userApi.update(server, accessToken, {
|
||||
id: before.id,
|
||||
firstName: 'First Name',
|
||||
lastName: 'Last Name',
|
||||
name: 'Name',
|
||||
});
|
||||
|
||||
expect(after).toEqual({
|
||||
...before,
|
||||
updatedAt: expect.any(String),
|
||||
firstName: 'First Name',
|
||||
lastName: 'Last Name',
|
||||
name: 'Name',
|
||||
});
|
||||
expect(before.updatedAt).not.toEqual(after.updatedAt);
|
||||
});
|
||||
|
||||
Vendored
+5
-10
@@ -1,8 +1,7 @@
|
||||
import { AuthUserDto } from '@app/domain';
|
||||
|
||||
export const adminSignupStub = {
|
||||
firstName: 'Immich',
|
||||
lastName: 'Admin',
|
||||
name: 'Immich Admin',
|
||||
email: 'admin@immich.app',
|
||||
password: 'Password123',
|
||||
};
|
||||
@@ -103,9 +102,8 @@ export const loginResponseStub = {
|
||||
admin: {
|
||||
response: {
|
||||
accessToken: expect.any(String),
|
||||
firstName: 'Immich',
|
||||
name: 'Immich Admin',
|
||||
isAdmin: true,
|
||||
lastName: 'Admin',
|
||||
profileImagePath: '',
|
||||
shouldChangePassword: true,
|
||||
userEmail: 'admin@immich.app',
|
||||
@@ -117,8 +115,7 @@ export const loginResponseStub = {
|
||||
accessToken: 'cmFuZG9tLWJ5dGVz',
|
||||
userId: 'user-id',
|
||||
userEmail: 'immich@test.com',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
profileImagePath: '',
|
||||
isAdmin: false,
|
||||
shouldChangePassword: false,
|
||||
@@ -133,8 +130,7 @@ export const loginResponseStub = {
|
||||
accessToken: 'cmFuZG9tLWJ5dGVz',
|
||||
userId: 'user-id',
|
||||
userEmail: 'immich@test.com',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
profileImagePath: '',
|
||||
isAdmin: false,
|
||||
shouldChangePassword: false,
|
||||
@@ -149,8 +145,7 @@ export const loginResponseStub = {
|
||||
accessToken: 'cmFuZG9tLWJ5dGVz',
|
||||
userId: 'user-id',
|
||||
userEmail: 'immich@test.com',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
profileImagePath: '',
|
||||
isAdmin: false,
|
||||
shouldChangePassword: false,
|
||||
|
||||
Vendored
+7
-14
@@ -5,8 +5,7 @@ export const userStub = {
|
||||
admin: Object.freeze<UserEntity>({
|
||||
...authStub.admin,
|
||||
password: 'admin_password',
|
||||
firstName: 'admin_first_name',
|
||||
lastName: 'admin_last_name',
|
||||
name: 'admin_name',
|
||||
storageLabel: 'admin',
|
||||
externalPath: null,
|
||||
oauthId: '',
|
||||
@@ -22,8 +21,7 @@ export const userStub = {
|
||||
user1: Object.freeze<UserEntity>({
|
||||
...authStub.user1,
|
||||
password: 'immich_password',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
storageLabel: null,
|
||||
externalPath: null,
|
||||
oauthId: '',
|
||||
@@ -39,8 +37,7 @@ export const userStub = {
|
||||
user2: Object.freeze<UserEntity>({
|
||||
...authStub.user2,
|
||||
password: 'immich_password',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
storageLabel: null,
|
||||
externalPath: null,
|
||||
oauthId: '',
|
||||
@@ -56,8 +53,7 @@ export const userStub = {
|
||||
storageLabel: Object.freeze<UserEntity>({
|
||||
...authStub.user1,
|
||||
password: 'immich_password',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
storageLabel: 'label-1',
|
||||
externalPath: null,
|
||||
oauthId: '',
|
||||
@@ -73,8 +69,7 @@ export const userStub = {
|
||||
externalPath1: Object.freeze<UserEntity>({
|
||||
...authStub.user1,
|
||||
password: 'immich_password',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
storageLabel: 'label-1',
|
||||
externalPath: '/data/user1',
|
||||
oauthId: '',
|
||||
@@ -90,8 +85,7 @@ export const userStub = {
|
||||
externalPath2: Object.freeze<UserEntity>({
|
||||
...authStub.user1,
|
||||
password: 'immich_password',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
storageLabel: 'label-1',
|
||||
externalPath: '/data/user2',
|
||||
oauthId: '',
|
||||
@@ -107,8 +101,7 @@ export const userStub = {
|
||||
profilePath: Object.freeze<UserEntity>({
|
||||
...authStub.user1,
|
||||
password: 'immich_password',
|
||||
firstName: 'immich_first_name',
|
||||
lastName: 'immich_last_name',
|
||||
name: 'immich_name',
|
||||
storageLabel: 'label-1',
|
||||
externalPath: null,
|
||||
oauthId: '',
|
||||
|
||||
Reference in New Issue
Block a user