mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:39:37 -05:00 
			
		
		
		
	fix(server): use luxon for maxdate validator (#11651)
This commit is contained in:
		
							parent
							
								
									66f2ac8ce3
								
							
						
					
					
						commit
						4a42a72bd3
					
				@ -1,6 +1,7 @@
 | 
				
			|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
 | 
					import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
 | 
				
			||||||
import { Type } from 'class-transformer';
 | 
					import { Type } from 'class-transformer';
 | 
				
			||||||
import { IsArray, IsInt, IsNotEmpty, IsString, Max, Min, ValidateNested } from 'class-validator';
 | 
					import { IsArray, IsInt, IsNotEmpty, IsString, Max, Min, ValidateNested } from 'class-validator';
 | 
				
			||||||
 | 
					import { DateTime } from 'luxon';
 | 
				
			||||||
import { PropertyLifecycle } from 'src/decorators';
 | 
					import { PropertyLifecycle } from 'src/decorators';
 | 
				
			||||||
import { AuthDto } from 'src/dtos/auth.dto';
 | 
					import { AuthDto } from 'src/dtos/auth.dto';
 | 
				
			||||||
import { AssetFaceEntity } from 'src/entities/asset-face.entity';
 | 
					import { AssetFaceEntity } from 'src/entities/asset-face.entity';
 | 
				
			||||||
@ -20,7 +21,7 @@ export class PersonCreateDto {
 | 
				
			|||||||
   * Note: the mobile app cannot currently set the birth date to null.
 | 
					   * Note: the mobile app cannot currently set the birth date to null.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  @ApiProperty({ format: 'date' })
 | 
					  @ApiProperty({ format: 'date' })
 | 
				
			||||||
  @MaxDateString(() => new Date(), { message: 'Birth date cannot be in the future' })
 | 
					  @MaxDateString(() => DateTime.now(), { message: 'Birth date cannot be in the future' })
 | 
				
			||||||
  @IsDateStringFormat('yyyy-MM-dd')
 | 
					  @IsDateStringFormat('yyyy-MM-dd')
 | 
				
			||||||
  @Optional({ nullable: true })
 | 
					  @Optional({ nullable: true })
 | 
				
			||||||
  birthDate?: string | null;
 | 
					  birthDate?: string | null;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
import { plainToInstance } from 'class-transformer';
 | 
					import { plainToInstance } from 'class-transformer';
 | 
				
			||||||
import { validate } from 'class-validator';
 | 
					import { validate } from 'class-validator';
 | 
				
			||||||
 | 
					import { DateTime } from 'luxon';
 | 
				
			||||||
import { IsDateStringFormat, MaxDateString } from 'src/validation';
 | 
					import { IsDateStringFormat, MaxDateString } from 'src/validation';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Validation', () => {
 | 
					describe('Validation', () => {
 | 
				
			||||||
  describe('MaxDateString', () => {
 | 
					  describe('MaxDateString', () => {
 | 
				
			||||||
    const maxDate = new Date(2000, 0, 1);
 | 
					    const maxDate = DateTime.fromISO('2000-01-01', { zone: 'utc' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class MyDto {
 | 
					    class MyDto {
 | 
				
			||||||
      @MaxDateString(maxDate)
 | 
					      @MaxDateString(maxDate)
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,6 @@ import {
 | 
				
			|||||||
  ValidationOptions,
 | 
					  ValidationOptions,
 | 
				
			||||||
  buildMessage,
 | 
					  buildMessage,
 | 
				
			||||||
  isDateString,
 | 
					  isDateString,
 | 
				
			||||||
  maxDate,
 | 
					 | 
				
			||||||
} from 'class-validator';
 | 
					} from 'class-validator';
 | 
				
			||||||
import { CronJob } from 'cron';
 | 
					import { CronJob } from 'cron';
 | 
				
			||||||
import { DateTime } from 'luxon';
 | 
					import { DateTime } from 'luxon';
 | 
				
			||||||
@ -203,14 +202,21 @@ export function IsDateStringFormat(format: string, validationOptions?: Validatio
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function MaxDateString(date: Date | (() => Date), validationOptions?: ValidationOptions): PropertyDecorator {
 | 
					function maxDate(date: DateTime, maxDate: DateTime | (() => DateTime)) {
 | 
				
			||||||
 | 
					  return date <= (maxDate instanceof DateTime ? maxDate : maxDate());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function MaxDateString(
 | 
				
			||||||
 | 
					  date: DateTime | (() => DateTime),
 | 
				
			||||||
 | 
					  validationOptions?: ValidationOptions,
 | 
				
			||||||
 | 
					): PropertyDecorator {
 | 
				
			||||||
  return ValidateBy(
 | 
					  return ValidateBy(
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      name: 'maxDateString',
 | 
					      name: 'maxDateString',
 | 
				
			||||||
      constraints: [date],
 | 
					      constraints: [date],
 | 
				
			||||||
      validator: {
 | 
					      validator: {
 | 
				
			||||||
        validate: (value, args) => {
 | 
					        validate: (value, args) => {
 | 
				
			||||||
          const date = DateTime.fromISO(value, { zone: 'utc' }).toJSDate();
 | 
					          const date = DateTime.fromISO(value, { zone: 'utc' });
 | 
				
			||||||
          return maxDate(date, args?.constraints[0]);
 | 
					          return maxDate(date, args?.constraints[0]);
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        defaultMessage: buildMessage(
 | 
					        defaultMessage: buildMessage(
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user