Skip to content

Commit

Permalink
allow emails without a tld (immich-app#2762)
Browse files Browse the repository at this point in the history
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 immich-app#2667
  • Loading branch information
uhthomas authored Jun 14, 2023
1 parent eed1243 commit 408fa45
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 7 deletions.
9 changes: 9 additions & 0 deletions server/src/domain/auth/dto/login-credential.dto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import { validateSync } from 'class-validator';
import { LoginCredentialDto } from './login-credential.dto';

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', () => {
const dto = plainToInstance(LoginCredentialDto, { password: 'password' });
const errors = validateSync(dto);
Expand Down
2 changes: 1 addition & 1 deletion server/src/domain/auth/dto/login-credential.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Transform } from 'class-transformer';
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';

export class LoginCredentialDto {
@IsEmail()
@IsEmail({ require_tld: false })
@ApiProperty({ example: '[email protected]' })
@Transform(({ value }) => value.toLowerCase())
email!: string;
Expand Down
14 changes: 14 additions & 0 deletions server/src/domain/auth/dto/sign-up.dto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ describe('SignUpDto', () => {
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', () => {
const dto = plainToInstance(SignUpDto, {
email: '[email protected]',
Expand Down
2 changes: 1 addition & 1 deletion server/src/domain/auth/dto/sign-up.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Transform } from 'class-transformer';
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';

export class SignUpDto {
@IsEmail()
@IsEmail({ require_tld: false })
@ApiProperty({ example: '[email protected]' })
@Transform(({ value }) => value.toLowerCase())
email!: string;
Expand Down
49 changes: 48 additions & 1 deletion server/src/domain/user/dto/create-user.dto.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
import { CreateUserDto } from './create-user.dto';
import { CreateAdminDto, CreateUserDto, CreateUserOAuthDto } from './create-user.dto';

describe('create user DTO', () => {
it('validates the email', async () => {
Expand All @@ -24,4 +24,51 @@ describe('create user DTO', () => {
errors = await validate(dto);
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);
});
});
6 changes: 3 additions & 3 deletions server/src/domain/user/dto/create-user.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { toEmail, toSanitized } from '@app/immich/utils/transform.util';

export class CreateUserDto {
@IsEmail()
@IsEmail({ require_tld: false })
@Transform(toEmail)
email!: string;

Expand All @@ -29,7 +29,7 @@ export class CreateAdminDto {
@IsNotEmpty()
isAdmin!: true;

@IsEmail()
@IsEmail({ require_tld: false })
@Transform(({ value }) => value?.toLowerCase())
email!: string;

Expand All @@ -44,7 +44,7 @@ export class CreateAdminDto {
}

export class CreateUserOAuthDto {
@IsEmail()
@IsEmail({ require_tld: false })
@Transform(({ value }) => value?.toLowerCase())
email!: string;

Expand Down
17 changes: 17 additions & 0 deletions server/src/domain/user/dto/update-user.dto.spec.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});
2 changes: 1 addition & 1 deletion server/src/domain/user/dto/update-user.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { toEmail, toSanitized } from '@app/immich/utils/transform.util';

export class UpdateUserDto {
@IsOptional()
@IsEmail()
@IsEmail({ require_tld: false })
@Transform(toEmail)
email?: string;

Expand Down

0 comments on commit 408fa45

Please sign in to comment.