mirror of
https://github.com/immich-app/immich.git
synced 2025-01-19 18:26:46 +01:00
allow emails without a tld (#2762)
It's perfectly valid to have an email address without a TLD, for instance: - test@localhost - test@svc-in-same-k8s-namespace - test@internal-corp Fixes #2667
This commit is contained in:
parent
eed1243263
commit
408fa45c51
8 changed files with 94 additions and 7 deletions
|
@ -3,6 +3,15 @@ import { validateSync } from 'class-validator';
|
||||||
import { LoginCredentialDto } from './login-credential.dto';
|
import { LoginCredentialDto } from './login-credential.dto';
|
||||||
|
|
||||||
describe('LoginCredentialDto', () => {
|
describe('LoginCredentialDto', () => {
|
||||||
|
it('should allow emails without a tld', () => {
|
||||||
|
const someEmail = 'test@test';
|
||||||
|
|
||||||
|
const dto = plainToInstance(LoginCredentialDto, { email: someEmail, password: 'password' });
|
||||||
|
const errors = validateSync(dto);
|
||||||
|
expect(errors).toHaveLength(0);
|
||||||
|
expect(dto.email).toEqual(someEmail);
|
||||||
|
});
|
||||||
|
|
||||||
it('should fail without an email', () => {
|
it('should fail without an email', () => {
|
||||||
const dto = plainToInstance(LoginCredentialDto, { password: 'password' });
|
const dto = plainToInstance(LoginCredentialDto, { password: 'password' });
|
||||||
const errors = validateSync(dto);
|
const errors = validateSync(dto);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Transform } from 'class-transformer';
|
||||||
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class LoginCredentialDto {
|
export class LoginCredentialDto {
|
||||||
@IsEmail()
|
@IsEmail({ require_tld: false })
|
||||||
@ApiProperty({ example: 'testuser@email.com' })
|
@ApiProperty({ example: 'testuser@email.com' })
|
||||||
@Transform(({ value }) => value.toLowerCase())
|
@Transform(({ value }) => value.toLowerCase())
|
||||||
email!: string;
|
email!: string;
|
||||||
|
|
|
@ -30,6 +30,20 @@ describe('SignUpDto', () => {
|
||||||
expect(errors[0].property).toEqual('email');
|
expect(errors[0].property).toEqual('email');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow emails without a tld', () => {
|
||||||
|
const someEmail = 'test@test';
|
||||||
|
|
||||||
|
const dto = plainToInstance(SignUpDto, {
|
||||||
|
email: someEmail,
|
||||||
|
password: 'password',
|
||||||
|
firstName: 'first name',
|
||||||
|
lastName: 'last name',
|
||||||
|
});
|
||||||
|
const errors = validateSync(dto);
|
||||||
|
expect(errors).toHaveLength(0);
|
||||||
|
expect(dto.email).toEqual(someEmail);
|
||||||
|
});
|
||||||
|
|
||||||
it('should make the email all lowercase', () => {
|
it('should make the email all lowercase', () => {
|
||||||
const dto = plainToInstance(SignUpDto, {
|
const dto = plainToInstance(SignUpDto, {
|
||||||
email: 'TeSt@ImMiCh.com',
|
email: 'TeSt@ImMiCh.com',
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Transform } from 'class-transformer';
|
||||||
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class SignUpDto {
|
export class SignUpDto {
|
||||||
@IsEmail()
|
@IsEmail({ require_tld: false })
|
||||||
@ApiProperty({ example: 'testuser@email.com' })
|
@ApiProperty({ example: 'testuser@email.com' })
|
||||||
@Transform(({ value }) => value.toLowerCase())
|
@Transform(({ value }) => value.toLowerCase())
|
||||||
email!: string;
|
email!: string;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { plainToInstance } from 'class-transformer';
|
import { plainToInstance } from 'class-transformer';
|
||||||
import { validate } from 'class-validator';
|
import { validate } from 'class-validator';
|
||||||
import { CreateUserDto } from './create-user.dto';
|
import { CreateAdminDto, CreateUserDto, CreateUserOAuthDto } from './create-user.dto';
|
||||||
|
|
||||||
describe('create user DTO', () => {
|
describe('create user DTO', () => {
|
||||||
it('validates the email', async () => {
|
it('validates the email', async () => {
|
||||||
|
@ -24,4 +24,51 @@ describe('create user DTO', () => {
|
||||||
errors = await validate(dto);
|
errors = await validate(dto);
|
||||||
expect(errors).toHaveLength(0);
|
expect(errors).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow emails without a tld', async () => {
|
||||||
|
const someEmail = 'test@test';
|
||||||
|
|
||||||
|
const dto = plainToInstance(CreateUserDto, {
|
||||||
|
email: someEmail,
|
||||||
|
password: 'some password',
|
||||||
|
firstName: 'some first name',
|
||||||
|
lastName: 'some last name',
|
||||||
|
});
|
||||||
|
const errors = await validate(dto);
|
||||||
|
expect(errors).toHaveLength(0);
|
||||||
|
expect(dto.email).toEqual(someEmail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('create admin DTO', () => {
|
||||||
|
it('should allow emails without a tld', async () => {
|
||||||
|
const someEmail = 'test@test';
|
||||||
|
|
||||||
|
const dto = plainToInstance(CreateAdminDto, {
|
||||||
|
isAdmin: true,
|
||||||
|
email: someEmail,
|
||||||
|
password: 'some password',
|
||||||
|
firstName: 'some first name',
|
||||||
|
lastName: 'some last name',
|
||||||
|
});
|
||||||
|
const errors = await validate(dto);
|
||||||
|
expect(errors).toHaveLength(0);
|
||||||
|
expect(dto.email).toEqual(someEmail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('create user oauth DTO', () => {
|
||||||
|
it('should allow emails without a tld', async () => {
|
||||||
|
const someEmail = 'test@test';
|
||||||
|
|
||||||
|
const dto = plainToInstance(CreateUserOAuthDto, {
|
||||||
|
email: someEmail,
|
||||||
|
oauthId: 'some oauth id',
|
||||||
|
firstName: 'some first name',
|
||||||
|
lastName: 'some last name',
|
||||||
|
});
|
||||||
|
const errors = await validate(dto);
|
||||||
|
expect(errors).toHaveLength(0);
|
||||||
|
expect(dto.email).toEqual(someEmail);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
import { toEmail, toSanitized } from '@app/immich/utils/transform.util';
|
import { toEmail, toSanitized } from '@app/immich/utils/transform.util';
|
||||||
|
|
||||||
export class CreateUserDto {
|
export class CreateUserDto {
|
||||||
@IsEmail()
|
@IsEmail({ require_tld: false })
|
||||||
@Transform(toEmail)
|
@Transform(toEmail)
|
||||||
email!: string;
|
email!: string;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ export class CreateAdminDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
isAdmin!: true;
|
isAdmin!: true;
|
||||||
|
|
||||||
@IsEmail()
|
@IsEmail({ require_tld: false })
|
||||||
@Transform(({ value }) => value?.toLowerCase())
|
@Transform(({ value }) => value?.toLowerCase())
|
||||||
email!: string;
|
email!: string;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ export class CreateAdminDto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CreateUserOAuthDto {
|
export class CreateUserOAuthDto {
|
||||||
@IsEmail()
|
@IsEmail({ require_tld: false })
|
||||||
@Transform(({ value }) => value?.toLowerCase())
|
@Transform(({ value }) => value?.toLowerCase())
|
||||||
email!: string;
|
email!: string;
|
||||||
|
|
||||||
|
|
17
server/src/domain/user/dto/update-user.dto.spec.ts
Normal file
17
server/src/domain/user/dto/update-user.dto.spec.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { plainToInstance } from 'class-transformer';
|
||||||
|
import { validate } from 'class-validator';
|
||||||
|
import { UpdateUserDto } from './update-user.dto';
|
||||||
|
|
||||||
|
describe('update user DTO', () => {
|
||||||
|
it('should allow emails without a tld', async () => {
|
||||||
|
const someEmail = 'test@test';
|
||||||
|
|
||||||
|
const dto = plainToInstance(UpdateUserDto, {
|
||||||
|
email: someEmail,
|
||||||
|
id: '3fe388e4-2078-44d7-b36c-39d9dee3a657',
|
||||||
|
});
|
||||||
|
const errors = await validate(dto);
|
||||||
|
expect(errors).toHaveLength(0);
|
||||||
|
expect(dto.email).toEqual(someEmail);
|
||||||
|
});
|
||||||
|
});
|
|
@ -5,7 +5,7 @@ import { toEmail, toSanitized } from '@app/immich/utils/transform.util';
|
||||||
|
|
||||||
export class UpdateUserDto {
|
export class UpdateUserDto {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsEmail()
|
@IsEmail({ require_tld: false })
|
||||||
@Transform(toEmail)
|
@Transform(toEmail)
|
||||||
email?: string;
|
email?: string;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue