mirror of
https://github.com/immich-app/immich.git
synced 2024-12-28 22:51:59 +00:00
fix(server): keep full datetime precision from database
This commit is contained in:
parent
d7a33c8ec2
commit
94b9013da5
44 changed files with 120 additions and 99 deletions
|
@ -18,7 +18,8 @@ export type MaybeDuplicate<T> = { duplicate: boolean; value: T };
|
||||||
|
|
||||||
export class ActivityResponseDto {
|
export class ActivityResponseDto {
|
||||||
id!: string;
|
id!: string;
|
||||||
createdAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
createdAt!: string;
|
||||||
type!: ReactionType;
|
type!: ReactionType;
|
||||||
user!: UserResponseDto;
|
user!: UserResponseDto;
|
||||||
assetId!: string | null;
|
assetId!: string | null;
|
||||||
|
|
|
@ -123,8 +123,10 @@ export class AlbumResponseDto {
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
albumName!: string;
|
albumName!: string;
|
||||||
description!: string;
|
description!: string;
|
||||||
createdAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
updatedAt!: Date;
|
createdAt!: string;
|
||||||
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
updatedAt!: string;
|
||||||
albumThumbnailAssetId!: string | null;
|
albumThumbnailAssetId!: string | null;
|
||||||
shared!: boolean;
|
shared!: boolean;
|
||||||
albumUsers!: AlbumUserResponseDto[];
|
albumUsers!: AlbumUserResponseDto[];
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsNotEmpty, IsString } from 'class-validator';
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
import { Optional } from 'src/validation';
|
import { Optional } from 'src/validation';
|
||||||
export class APIKeyCreateDto {
|
export class APIKeyCreateDto {
|
||||||
|
@ -21,6 +22,8 @@ export class APIKeyCreateResponseDto {
|
||||||
export class APIKeyResponseDto {
|
export class APIKeyResponseDto {
|
||||||
id!: string;
|
id!: string;
|
||||||
name!: string;
|
name!: string;
|
||||||
createdAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
updatedAt!: Date;
|
createdAt!: string;
|
||||||
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
updatedAt!: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ export class AssetResponseDto extends SanitizedAssetResponseDto {
|
||||||
originalFileName!: string;
|
originalFileName!: string;
|
||||||
fileCreatedAt!: Date;
|
fileCreatedAt!: Date;
|
||||||
fileModifiedAt!: Date;
|
fileModifiedAt!: Date;
|
||||||
updatedAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
updatedAt!: string;
|
||||||
isFavorite!: boolean;
|
isFavorite!: boolean;
|
||||||
isArchived!: boolean;
|
isArchived!: boolean;
|
||||||
isTrashed!: boolean;
|
isTrashed!: boolean;
|
||||||
|
|
|
@ -3,13 +3,13 @@ import { Type } from 'class-transformer';
|
||||||
import { IsArray, IsEnum, IsString, IsUUID, ValidateNested } from 'class-validator';
|
import { IsArray, IsEnum, IsString, IsUUID, ValidateNested } from 'class-validator';
|
||||||
import { EntityType } from 'src/entities/audit.entity';
|
import { EntityType } from 'src/entities/audit.entity';
|
||||||
import { AssetPathType, PathType, PersonPathType, UserPathType } from 'src/entities/move.entity';
|
import { AssetPathType, PathType, PersonPathType, UserPathType } from 'src/entities/move.entity';
|
||||||
import { Optional, ValidateDate, ValidateUUID } from 'src/validation';
|
import { Optional, ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
const PathEnum = Object.values({ ...AssetPathType, ...PersonPathType, ...UserPathType });
|
const PathEnum = Object.values({ ...AssetPathType, ...PersonPathType, ...UserPathType });
|
||||||
|
|
||||||
export class AuditDeletesDto {
|
export class AuditDeletesDto {
|
||||||
@ValidateDate()
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
after!: Date;
|
after!: string;
|
||||||
|
|
||||||
@ApiProperty({ enum: EntityType, enumName: 'EntityType' })
|
@ApiProperty({ enum: EntityType, enumName: 'EntityType' })
|
||||||
@IsEnum(EntityType)
|
@IsEnum(EntityType)
|
||||||
|
|
|
@ -105,8 +105,10 @@ export class LibraryResponseDto {
|
||||||
|
|
||||||
exclusionPatterns!: string[];
|
exclusionPatterns!: string[];
|
||||||
|
|
||||||
createdAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
updatedAt!: Date;
|
createdAt!: string;
|
||||||
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
updatedAt!: string;
|
||||||
refreshedAt!: Date | null;
|
refreshedAt!: Date | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,9 +55,12 @@ export class MemoryCreateDto extends MemoryBaseDto {
|
||||||
|
|
||||||
export class MemoryResponseDto {
|
export class MemoryResponseDto {
|
||||||
id!: string;
|
id!: string;
|
||||||
createdAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
updatedAt!: Date;
|
createdAt!: string;
|
||||||
deletedAt?: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
updatedAt!: string;
|
||||||
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
deletedAt?: string;
|
||||||
memoryAt!: Date;
|
memoryAt!: Date;
|
||||||
seenAt?: Date;
|
seenAt?: Date;
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
|
@ -11,8 +11,8 @@ export class SessionResponseDto {
|
||||||
|
|
||||||
export const mapSession = (entity: SessionEntity, currentId?: string): SessionResponseDto => ({
|
export const mapSession = (entity: SessionEntity, currentId?: string): SessionResponseDto => ({
|
||||||
id: entity.id,
|
id: entity.id,
|
||||||
createdAt: entity.createdAt.toISOString(),
|
createdAt: entity.createdAt,
|
||||||
updatedAt: entity.updatedAt.toISOString(),
|
updatedAt: entity.updatedAt,
|
||||||
current: currentId === entity.id,
|
current: currentId === entity.id,
|
||||||
deviceOS: entity.deviceOS,
|
deviceOS: entity.deviceOS,
|
||||||
deviceType: entity.deviceType,
|
deviceType: entity.deviceType,
|
||||||
|
|
|
@ -86,7 +86,8 @@ export class SharedLinkResponseDto {
|
||||||
|
|
||||||
@ApiProperty({ enumName: 'SharedLinkType', enum: SharedLinkType })
|
@ApiProperty({ enumName: 'SharedLinkType', enum: SharedLinkType })
|
||||||
type!: SharedLinkType;
|
type!: SharedLinkType;
|
||||||
createdAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
createdAt!: string;
|
||||||
expiresAt!: Date | null;
|
expiresAt!: Date | null;
|
||||||
assets!: AssetResponseDto[];
|
assets!: AssetResponseDto[];
|
||||||
album?: AlbumResponseDto;
|
album?: AlbumResponseDto;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsInt, IsPositive } from 'class-validator';
|
import { IsInt, IsPositive } from 'class-validator';
|
||||||
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
||||||
import { ValidateDate, ValidateUUID } from 'src/validation';
|
import { ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
export class AssetFullSyncDto {
|
export class AssetFullSyncDto {
|
||||||
@ValidateUUID({ optional: true })
|
@ValidateUUID({ optional: true })
|
||||||
lastId?: string;
|
lastId?: string;
|
||||||
|
|
||||||
@ValidateDate()
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
updatedUntil!: Date;
|
updatedUntil!: string;
|
||||||
|
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
|
@ -20,8 +20,8 @@ export class AssetFullSyncDto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AssetDeltaSyncDto {
|
export class AssetDeltaSyncDto {
|
||||||
@ValidateDate()
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
updatedAfter!: Date;
|
updatedAfter!: string;
|
||||||
|
|
||||||
@ValidateUUID({ each: true })
|
@ValidateUUID({ each: true })
|
||||||
userIds!: string[];
|
userIds!: string[];
|
||||||
|
|
|
@ -120,9 +120,12 @@ export class UserAdminResponseDto extends UserResponseDto {
|
||||||
storageLabel!: string | null;
|
storageLabel!: string | null;
|
||||||
shouldChangePassword!: boolean;
|
shouldChangePassword!: boolean;
|
||||||
isAdmin!: boolean;
|
isAdmin!: boolean;
|
||||||
createdAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
deletedAt!: Date | null;
|
createdAt!: string;
|
||||||
updatedAt!: Date;
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
deletedAt!: string | null;
|
||||||
|
@ApiProperty({ type: 'string', format: 'date-time' })
|
||||||
|
updatedAt!: string;
|
||||||
oauthId!: string;
|
oauthId!: string;
|
||||||
@ApiProperty({ type: 'integer', format: 'int64' })
|
@ApiProperty({ type: 'integer', format: 'int64' })
|
||||||
quotaSizeInBytes!: number | null;
|
quotaSizeInBytes!: number | null;
|
||||||
|
|
|
@ -20,10 +20,10 @@ export class ActivityEntity {
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
albumId!: string;
|
albumId!: string;
|
||||||
|
|
|
@ -39,13 +39,13 @@ export class AlbumEntity {
|
||||||
description!: string;
|
description!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz' })
|
@DeleteDateColumn({ type: 'timestamptz' })
|
||||||
deletedAt!: Date | null;
|
deletedAt!: string | null;
|
||||||
|
|
||||||
@ManyToOne(() => AssetEntity, { nullable: true, onDelete: 'SET NULL', onUpdate: 'CASCADE' })
|
@ManyToOne(() => AssetEntity, { nullable: true, onDelete: 'SET NULL', onUpdate: 'CASCADE' })
|
||||||
albumThumbnailAsset!: AssetEntity | null;
|
albumThumbnailAsset!: AssetEntity | null;
|
||||||
|
|
|
@ -19,8 +19,8 @@ export class APIKeyEntity {
|
||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,13 +84,13 @@ export class AssetEntity {
|
||||||
encodedVideoPath!: string | null;
|
encodedVideoPath!: string | null;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz', nullable: true })
|
@DeleteDateColumn({ type: 'timestamptz', nullable: true })
|
||||||
deletedAt!: Date | null;
|
deletedAt!: string | null;
|
||||||
|
|
||||||
@Index('idx_asset_file_created_at')
|
@Index('idx_asset_file_created_at')
|
||||||
@Column({ type: 'timestamptz' })
|
@Column({ type: 'timestamptz' })
|
||||||
|
|
|
@ -30,5 +30,5 @@ export class AuditEntity {
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ export class LibraryEntity {
|
||||||
exclusionPatterns!: string[];
|
exclusionPatterns!: string[];
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz' })
|
@DeleteDateColumn({ type: 'timestamptz' })
|
||||||
deletedAt?: Date;
|
deletedAt?: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamptz', nullable: true })
|
@Column({ type: 'timestamptz', nullable: true })
|
||||||
refreshedAt!: Date | null;
|
refreshedAt!: Date | null;
|
||||||
|
|
|
@ -29,13 +29,13 @@ export class MemoryEntity<T extends MemoryType = MemoryType> {
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz' })
|
@DeleteDateColumn({ type: 'timestamptz' })
|
||||||
deletedAt?: Date;
|
deletedAt?: string;
|
||||||
|
|
||||||
@ManyToOne(() => UserEntity, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
@ManyToOne(() => UserEntity, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
||||||
owner!: UserEntity;
|
owner!: UserEntity;
|
||||||
|
|
|
@ -18,10 +18,10 @@ export class PartnerEntity {
|
||||||
sharedWith!: UserEntity;
|
sharedWith!: UserEntity;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
inTimeline!: boolean;
|
inTimeline!: boolean;
|
||||||
|
|
|
@ -18,10 +18,10 @@ export class PersonEntity {
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
|
@ -16,10 +16,10 @@ export class SessionEntity {
|
||||||
user!: UserEntity;
|
user!: UserEntity;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@Column({ default: '' })
|
@Column({ default: '' })
|
||||||
deviceType!: string;
|
deviceType!: string;
|
||||||
|
|
|
@ -38,7 +38,7 @@ export class SharedLinkEntity {
|
||||||
type!: SharedLinkType;
|
type!: SharedLinkType;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamptz', nullable: true })
|
@Column({ type: 'timestamptz', nullable: true })
|
||||||
expiresAt!: Date | null;
|
expiresAt!: Date | null;
|
||||||
|
|
|
@ -47,16 +47,16 @@ export class UserEntity {
|
||||||
shouldChangePassword!: boolean;
|
shouldChangePassword!: boolean;
|
||||||
|
|
||||||
@CreateDateColumn({ type: 'timestamptz' })
|
@CreateDateColumn({ type: 'timestamptz' })
|
||||||
createdAt!: Date;
|
createdAt!: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz' })
|
@DeleteDateColumn({ type: 'timestamptz' })
|
||||||
deletedAt!: Date | null;
|
deletedAt!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'varchar', default: UserStatus.ACTIVE })
|
@Column({ type: 'varchar', default: UserStatus.ACTIVE })
|
||||||
status!: UserStatus;
|
status!: UserStatus;
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: string;
|
||||||
|
|
||||||
@OneToMany(() => TagEntity, (tag) => tag.user)
|
@OneToMany(() => TagEntity, (tag) => tag.user)
|
||||||
tags!: TagEntity[];
|
tags!: TagEntity[];
|
||||||
|
|
|
@ -123,13 +123,13 @@ export interface AssetExploreOptions extends AssetExploreFieldOptions {
|
||||||
export interface AssetFullSyncOptions {
|
export interface AssetFullSyncOptions {
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
lastId?: string;
|
lastId?: string;
|
||||||
updatedUntil: Date;
|
updatedUntil: string;
|
||||||
limit: number;
|
limit: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AssetDeltaSyncOptions {
|
export interface AssetDeltaSyncOptions {
|
||||||
userIds: string[];
|
userIds: string[];
|
||||||
updatedAfter: Date;
|
updatedAfter: string;
|
||||||
limit: number;
|
limit: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,6 @@ export interface AuditSearch {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAuditRepository {
|
export interface IAuditRepository {
|
||||||
getAfter(since: Date, options: AuditSearch): Promise<string[]>;
|
getAfter(since: string, options: AuditSearch): Promise<string[]>;
|
||||||
removeBefore(before: Date): Promise<void>;
|
removeBefore(before: Date): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { In, LessThan, MoreThan, Repository } from 'typeorm';
|
||||||
export class AuditRepository implements IAuditRepository {
|
export class AuditRepository implements IAuditRepository {
|
||||||
constructor(@InjectRepository(AuditEntity) private repository: Repository<AuditEntity>) {}
|
constructor(@InjectRepository(AuditEntity) private repository: Repository<AuditEntity>) {}
|
||||||
|
|
||||||
async getAfter(since: Date, options: AuditSearch): Promise<string[]> {
|
async getAfter(since: string, options: AuditSearch): Promise<string[]> {
|
||||||
const records = await this.repository
|
const records = await this.repository
|
||||||
.createQueryBuilder('audit')
|
.createQueryBuilder('audit')
|
||||||
.where({
|
.where({
|
||||||
|
@ -28,6 +28,6 @@ export class AuditRepository implements IAuditRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeBefore(before: Date): Promise<void> {
|
async removeBefore(before: Date): Promise<void> {
|
||||||
await this.repository.delete({ createdAt: LessThan(before) });
|
await this.repository.delete({ createdAt: LessThan(before.toISOString()) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ export class SessionRepository implements ISessionRepository {
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.DATE] })
|
@GenerateSql({ params: [DummyValue.DATE] })
|
||||||
search(options: SessionSearchOptions): Promise<SessionEntity[]> {
|
search(options: SessionSearchOptions): Promise<SessionEntity[]> {
|
||||||
return this.repository.find({ where: { updatedAt: LessThanOrEqual(options.updatedBefore) } });
|
return this.repository.find({ where: { updatedAt: LessThanOrEqual(options.updatedBefore.toISOString()) } });
|
||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.STRING] })
|
@GenerateSql({ params: [DummyValue.STRING] })
|
||||||
|
|
|
@ -569,7 +569,7 @@ describe(AlbumService.name, () => {
|
||||||
|
|
||||||
expect(albumMock.update).toHaveBeenCalledWith({
|
expect(albumMock.update).toHaveBeenCalledWith({
|
||||||
id: 'album-123',
|
id: 'album-123',
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
albumThumbnailAssetId: 'asset-1',
|
albumThumbnailAssetId: 'asset-1',
|
||||||
});
|
});
|
||||||
expect(albumMock.addAssetIds).toHaveBeenCalledWith('album-123', ['asset-1', 'asset-2', 'asset-3']);
|
expect(albumMock.addAssetIds).toHaveBeenCalledWith('album-123', ['asset-1', 'asset-2', 'asset-3']);
|
||||||
|
@ -595,7 +595,7 @@ describe(AlbumService.name, () => {
|
||||||
|
|
||||||
expect(albumMock.update).toHaveBeenCalledWith({
|
expect(albumMock.update).toHaveBeenCalledWith({
|
||||||
id: 'album-123',
|
id: 'album-123',
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
albumThumbnailAssetId: 'asset-id',
|
albumThumbnailAssetId: 'asset-id',
|
||||||
});
|
});
|
||||||
expect(albumMock.addAssetIds).toHaveBeenCalled();
|
expect(albumMock.addAssetIds).toHaveBeenCalled();
|
||||||
|
@ -617,7 +617,7 @@ describe(AlbumService.name, () => {
|
||||||
|
|
||||||
expect(albumMock.update).toHaveBeenCalledWith({
|
expect(albumMock.update).toHaveBeenCalledWith({
|
||||||
id: 'album-123',
|
id: 'album-123',
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
albumThumbnailAssetId: 'asset-1',
|
albumThumbnailAssetId: 'asset-1',
|
||||||
});
|
});
|
||||||
expect(albumMock.addAssetIds).toHaveBeenCalledWith('album-123', ['asset-1', 'asset-2', 'asset-3']);
|
expect(albumMock.addAssetIds).toHaveBeenCalledWith('album-123', ['asset-1', 'asset-2', 'asset-3']);
|
||||||
|
@ -658,7 +658,7 @@ describe(AlbumService.name, () => {
|
||||||
|
|
||||||
expect(albumMock.update).toHaveBeenCalledWith({
|
expect(albumMock.update).toHaveBeenCalledWith({
|
||||||
id: 'album-123',
|
id: 'album-123',
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
albumThumbnailAssetId: 'asset-1',
|
albumThumbnailAssetId: 'asset-1',
|
||||||
});
|
});
|
||||||
expect(albumMock.addAssetIds).toHaveBeenCalledWith('album-123', ['asset-1', 'asset-2', 'asset-3']);
|
expect(albumMock.addAssetIds).toHaveBeenCalledWith('album-123', ['asset-1', 'asset-2', 'asset-3']);
|
||||||
|
@ -681,7 +681,7 @@ describe(AlbumService.name, () => {
|
||||||
|
|
||||||
expect(albumMock.update).toHaveBeenCalledWith({
|
expect(albumMock.update).toHaveBeenCalledWith({
|
||||||
id: 'album-123',
|
id: 'album-123',
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
albumThumbnailAssetId: 'asset-1',
|
albumThumbnailAssetId: 'asset-1',
|
||||||
});
|
});
|
||||||
expect(accessMock.asset.checkPartnerAccess).toHaveBeenCalledWith(authStub.admin.user.id, new Set(['asset-1']));
|
expect(accessMock.asset.checkPartnerAccess).toHaveBeenCalledWith(authStub.admin.user.id, new Set(['asset-1']));
|
||||||
|
@ -746,7 +746,7 @@ describe(AlbumService.name, () => {
|
||||||
{ success: true, id: 'asset-id' },
|
{ success: true, id: 'asset-id' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(albumMock.update).toHaveBeenCalledWith({ id: 'album-123', updatedAt: expect.any(Date) });
|
expect(albumMock.update).toHaveBeenCalledWith({ id: 'album-123', updatedAt: expect.any(String) });
|
||||||
expect(albumMock.removeAssetIds).toHaveBeenCalledWith('album-123', ['asset-id']);
|
expect(albumMock.removeAssetIds).toHaveBeenCalledWith('album-123', ['asset-id']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -790,7 +790,7 @@ describe(AlbumService.name, () => {
|
||||||
|
|
||||||
expect(albumMock.update).toHaveBeenCalledWith({
|
expect(albumMock.update).toHaveBeenCalledWith({
|
||||||
id: 'album-123',
|
id: 'album-123',
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
});
|
});
|
||||||
expect(albumMock.updateThumbnails).toHaveBeenCalled();
|
expect(albumMock.updateThumbnails).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
|
@ -185,7 +185,7 @@ export class AlbumService {
|
||||||
if (firstNewAssetId) {
|
if (firstNewAssetId) {
|
||||||
await this.albumRepository.update({
|
await this.albumRepository.update({
|
||||||
id,
|
id,
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date().toISOString(),
|
||||||
albumThumbnailAssetId: album.albumThumbnailAssetId ?? firstNewAssetId,
|
albumThumbnailAssetId: album.albumThumbnailAssetId ?? firstNewAssetId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ export class AlbumService {
|
||||||
|
|
||||||
const removedIds = results.filter(({ success }) => success).map(({ id }) => id);
|
const removedIds = results.filter(({ success }) => success).map(({ id }) => id);
|
||||||
if (removedIds.length > 0) {
|
if (removedIds.length > 0) {
|
||||||
await this.albumRepository.update({ id, updatedAt: new Date() });
|
await this.albumRepository.update({ id, updatedAt: new Date().toISOString() });
|
||||||
if (album.albumThumbnailAssetId && removedIds.includes(album.albumThumbnailAssetId)) {
|
if (album.albumThumbnailAssetId && removedIds.includes(album.albumThumbnailAssetId)) {
|
||||||
await this.albumRepository.updateThumbnails();
|
await this.albumRepository.updateThumbnails();
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,7 @@ describe(AssetService.name, () => {
|
||||||
ids: [],
|
ids: [],
|
||||||
stackParentId: 'parent',
|
stackParentId: 'parent',
|
||||||
}),
|
}),
|
||||||
expect(assetMock.updateAll).toHaveBeenCalledWith(['parent'], { updatedAt: expect.any(Date) });
|
expect(assetMock.updateAll).toHaveBeenCalledWith(['parent'], { updatedAt: expect.any(String) });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update parent asset when children are removed', async () => {
|
it('should update parent asset when children are removed', async () => {
|
||||||
|
@ -285,7 +285,7 @@ describe(AssetService.name, () => {
|
||||||
});
|
});
|
||||||
expect(assetMock.updateAll).toHaveBeenCalledWith(expect.arrayContaining(['child-1']), { stack: null });
|
expect(assetMock.updateAll).toHaveBeenCalledWith(expect.arrayContaining(['child-1']), { stack: null });
|
||||||
expect(assetMock.updateAll).toHaveBeenCalledWith(expect.arrayContaining(['parent']), {
|
expect(assetMock.updateAll).toHaveBeenCalledWith(expect.arrayContaining(['parent']), {
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
});
|
});
|
||||||
expect(assetStackMock.delete).toHaveBeenCalledWith('stack-1');
|
expect(assetStackMock.delete).toHaveBeenCalledWith('stack-1');
|
||||||
});
|
});
|
||||||
|
@ -316,7 +316,7 @@ describe(AssetService.name, () => {
|
||||||
]),
|
]),
|
||||||
primaryAsset: undefined,
|
primaryAsset: undefined,
|
||||||
});
|
});
|
||||||
expect(assetMock.updateAll).toBeCalledWith(['child-1', 'child-2', 'parent'], { updatedAt: expect.any(Date) });
|
expect(assetMock.updateAll).toBeCalledWith(['child-1', 'child-2', 'parent'], { updatedAt: expect.any(String) });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('remove stack for removed children', async () => {
|
it('remove stack for removed children', async () => {
|
||||||
|
@ -353,7 +353,7 @@ describe(AssetService.name, () => {
|
||||||
primaryAssetId: 'parent',
|
primaryAssetId: 'parent',
|
||||||
});
|
});
|
||||||
expect(assetMock.updateAll).toBeCalledWith(['child-1', 'parent', 'child-1', 'child-2'], {
|
expect(assetMock.updateAll).toBeCalledWith(['child-1', 'parent', 'child-1', 'child-2'], {
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ describe(AssetService.name, () => {
|
||||||
|
|
||||||
expect(assetStackMock.update).toBeCalledWith({ id: 'stack-1', primaryAssetId: 'new' });
|
expect(assetStackMock.update).toBeCalledWith({ id: 'stack-1', primaryAssetId: 'new' });
|
||||||
expect(assetMock.updateAll).toBeCalledWith([assetStub.image.id, 'new', assetStub.image.id], {
|
expect(assetMock.updateAll).toBeCalledWith([assetStub.image.id, 'new', assetStub.image.id], {
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -191,7 +191,7 @@ export class AssetService {
|
||||||
// All the unique parent's -> parent is set to null
|
// All the unique parent's -> parent is set to null
|
||||||
await this.assetRepository.updateAll(
|
await this.assetRepository.updateAll(
|
||||||
assets.filter((a) => !!a.stack?.primaryAssetId).map((a) => a.stack!.primaryAssetId!),
|
assets.filter((a) => !!a.stack?.primaryAssetId).map((a) => a.stack!.primaryAssetId!),
|
||||||
{ updatedAt: new Date() },
|
{ updatedAt: new Date().toISOString() },
|
||||||
);
|
);
|
||||||
} else if (options.stackParentId) {
|
} else if (options.stackParentId) {
|
||||||
//Creating new stack if parent doesn't have one already. If it does, then we add to the existing stack
|
//Creating new stack if parent doesn't have one already. If it does, then we add to the existing stack
|
||||||
|
@ -225,7 +225,7 @@ export class AssetService {
|
||||||
|
|
||||||
// Merge stacks
|
// Merge stacks
|
||||||
options.stackParentId = undefined;
|
options.stackParentId = undefined;
|
||||||
(options as Partial<AssetEntity>).updatedAt = new Date();
|
(options as Partial<AssetEntity>).updatedAt = new Date().toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
|
@ -372,7 +372,9 @@ export class AssetService {
|
||||||
newParentId,
|
newParentId,
|
||||||
oldParentId,
|
oldParentId,
|
||||||
]);
|
]);
|
||||||
await this.assetRepository.updateAll([oldParentId, newParentId, ...childIds], { updatedAt: new Date() });
|
await this.assetRepository.updateAll([oldParentId, newParentId, ...childIds], {
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(auth: AuthDto, dto: AssetJobsDto) {
|
async run(auth: AuthDto, dto: AssetJobsDto) {
|
||||||
|
|
|
@ -58,7 +58,7 @@ describe(AuditService.name, () => {
|
||||||
it('should require full sync if the request is older than 100 days', async () => {
|
it('should require full sync if the request is older than 100 days', async () => {
|
||||||
auditMock.getAfter.mockResolvedValue([]);
|
auditMock.getAfter.mockResolvedValue([]);
|
||||||
|
|
||||||
const date = new Date(2022, 0, 1);
|
const date = new Date(2022, 0, 1).toISOString();
|
||||||
await expect(sut.getDeletes(authStub.admin, { after: date, entityType: EntityType.ASSET })).resolves.toEqual({
|
await expect(sut.getDeletes(authStub.admin, { after: date, entityType: EntityType.ASSET })).resolves.toEqual({
|
||||||
needsFullSync: true,
|
needsFullSync: true,
|
||||||
ids: [],
|
ids: [],
|
||||||
|
|
|
@ -59,7 +59,7 @@ export class AuditService {
|
||||||
action: DatabaseAction.DELETE,
|
action: DatabaseAction.DELETE,
|
||||||
});
|
});
|
||||||
|
|
||||||
const duration = DateTime.now().diff(DateTime.fromJSDate(dto.after));
|
const duration = DateTime.now().diff(DateTime.fromISO(dto.after));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
needsFullSync: duration > AUDIT_LOG_MAX_DURATION,
|
needsFullSync: duration > AUDIT_LOG_MAX_DURATION,
|
||||||
|
|
|
@ -331,7 +331,7 @@ describe('AuthService', () => {
|
||||||
sessionMock.update.mockResolvedValue(sessionStub.valid);
|
sessionMock.update.mockResolvedValue(sessionStub.valid);
|
||||||
const headers: IncomingHttpHeaders = { cookie: 'immich_access_token=auth_token' };
|
const headers: IncomingHttpHeaders = { cookie: 'immich_access_token=auth_token' };
|
||||||
await expect(sut.validate(headers, {})).resolves.toBeDefined();
|
await expect(sut.validate(headers, {})).resolves.toBeDefined();
|
||||||
expect(sessionMock.update.mock.calls[0][0]).toMatchObject({ id: 'not_active', updatedAt: expect.any(Date) });
|
expect(sessionMock.update.mock.calls[0][0]).toMatchObject({ id: 'not_active', updatedAt: expect.any(String) });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -382,10 +382,10 @@ export class AuthService {
|
||||||
|
|
||||||
if (session?.user) {
|
if (session?.user) {
|
||||||
const now = DateTime.now();
|
const now = DateTime.now();
|
||||||
const updatedAt = DateTime.fromJSDate(session.updatedAt);
|
const updatedAt = DateTime.fromISO(session.updatedAt);
|
||||||
const diff = now.diff(updatedAt, ['hours']);
|
const diff = now.diff(updatedAt, ['hours']);
|
||||||
if (diff.hours > 1) {
|
if (diff.hours > 1) {
|
||||||
await this.sessionRepository.update({ id: session.id, updatedAt: new Date() });
|
await this.sessionRepository.update({ id: session.id, updatedAt: new Date().toISOString() });
|
||||||
}
|
}
|
||||||
|
|
||||||
return { user: session.user, session: session };
|
return { user: session.user, session: session };
|
||||||
|
|
|
@ -74,7 +74,7 @@ export class MemoryService {
|
||||||
|
|
||||||
const hasSuccess = results.find(({ success }) => success);
|
const hasSuccess = results.find(({ success }) => success);
|
||||||
if (hasSuccess) {
|
if (hasSuccess) {
|
||||||
await this.repository.update({ id, updatedAt: new Date() });
|
await this.repository.update({ id, updatedAt: new Date().toISOString() });
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
@ -89,7 +89,7 @@ export class MemoryService {
|
||||||
|
|
||||||
const hasSuccess = results.find(({ success }) => success);
|
const hasSuccess = results.find(({ success }) => success);
|
||||||
if (hasSuccess) {
|
if (hasSuccess) {
|
||||||
await this.repository.update({ id, updatedAt: new Date() });
|
await this.repository.update({ id, updatedAt: new Date().toISOString() });
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
|
|
@ -38,8 +38,8 @@ describe('SessionService', () => {
|
||||||
it('should delete sessions', async () => {
|
it('should delete sessions', async () => {
|
||||||
sessionMock.search.mockResolvedValue([
|
sessionMock.search.mockResolvedValue([
|
||||||
{
|
{
|
||||||
createdAt: new Date('1970-01-01T00:00:00.00Z'),
|
createdAt: new Date('1970-01-01T00:00:00.00Z').toISOString(),
|
||||||
updatedAt: new Date('1970-01-02T00:00:00.00Z'),
|
updatedAt: new Date('1970-01-02T00:00:00.00Z').toISOString(),
|
||||||
deviceOS: '',
|
deviceOS: '',
|
||||||
deviceType: '',
|
deviceType: '',
|
||||||
id: '123',
|
id: '123',
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { newAuditRepositoryMock } from 'test/repositories/audit.repository.mock'
|
||||||
import { newPartnerRepositoryMock } from 'test/repositories/partner.repository.mock';
|
import { newPartnerRepositoryMock } from 'test/repositories/partner.repository.mock';
|
||||||
import { Mocked } from 'vitest';
|
import { Mocked } from 'vitest';
|
||||||
|
|
||||||
const untilDate = new Date(2024);
|
const untilDate = new Date(2024).toISOString();
|
||||||
const mapAssetOpts = { auth: authStub.user1, stripMetadata: false, withStack: true };
|
const mapAssetOpts = { auth: authStub.user1, stripMetadata: false, withStack: true };
|
||||||
|
|
||||||
describe(SyncService.name, () => {
|
describe(SyncService.name, () => {
|
||||||
|
@ -55,7 +55,7 @@ describe(SyncService.name, () => {
|
||||||
it('should return a response requiring a full sync when partners are out of sync', async () => {
|
it('should return a response requiring a full sync when partners are out of sync', async () => {
|
||||||
partnerMock.getAll.mockResolvedValue([partnerStub.adminToUser1]);
|
partnerMock.getAll.mockResolvedValue([partnerStub.adminToUser1]);
|
||||||
await expect(
|
await expect(
|
||||||
sut.getDeltaSync(authStub.user1, { updatedAfter: new Date(), userIds: [authStub.user1.user.id] }),
|
sut.getDeltaSync(authStub.user1, { updatedAfter: new Date().toISOString(), userIds: [authStub.user1.user.id] }),
|
||||||
).resolves.toEqual({ needsFullSync: true, upserted: [], deleted: [] });
|
).resolves.toEqual({ needsFullSync: true, upserted: [], deleted: [] });
|
||||||
expect(assetMock.getChangedDeltaSync).toHaveBeenCalledTimes(0);
|
expect(assetMock.getChangedDeltaSync).toHaveBeenCalledTimes(0);
|
||||||
expect(auditMock.getAfter).toHaveBeenCalledTimes(0);
|
expect(auditMock.getAfter).toHaveBeenCalledTimes(0);
|
||||||
|
@ -64,7 +64,10 @@ describe(SyncService.name, () => {
|
||||||
it('should return a response requiring a full sync when last sync was too long ago', async () => {
|
it('should return a response requiring a full sync when last sync was too long ago', async () => {
|
||||||
partnerMock.getAll.mockResolvedValue([]);
|
partnerMock.getAll.mockResolvedValue([]);
|
||||||
await expect(
|
await expect(
|
||||||
sut.getDeltaSync(authStub.user1, { updatedAfter: new Date(2000), userIds: [authStub.user1.user.id] }),
|
sut.getDeltaSync(authStub.user1, {
|
||||||
|
updatedAfter: new Date(2000).toISOString(),
|
||||||
|
userIds: [authStub.user1.user.id],
|
||||||
|
}),
|
||||||
).resolves.toEqual({ needsFullSync: true, upserted: [], deleted: [] });
|
).resolves.toEqual({ needsFullSync: true, upserted: [], deleted: [] });
|
||||||
expect(assetMock.getChangedDeltaSync).toHaveBeenCalledTimes(0);
|
expect(assetMock.getChangedDeltaSync).toHaveBeenCalledTimes(0);
|
||||||
expect(auditMock.getAfter).toHaveBeenCalledTimes(0);
|
expect(auditMock.getAfter).toHaveBeenCalledTimes(0);
|
||||||
|
|
|
@ -42,7 +42,7 @@ export class SyncService {
|
||||||
|
|
||||||
async getDeltaSync(auth: AuthDto, dto: AssetDeltaSyncDto): Promise<AssetDeltaSyncResponseDto> {
|
async getDeltaSync(auth: AuthDto, dto: AssetDeltaSyncDto): Promise<AssetDeltaSyncResponseDto> {
|
||||||
// app has not synced in the last 100 days
|
// app has not synced in the last 100 days
|
||||||
const duration = DateTime.now().diff(DateTime.fromJSDate(dto.updatedAfter));
|
const duration = DateTime.now().diff(DateTime.fromISO(dto.updatedAfter));
|
||||||
if (duration > AUDIT_LOG_MAX_DURATION) {
|
if (duration > AUDIT_LOG_MAX_DURATION) {
|
||||||
return FULL_SYNC;
|
return FULL_SYNC;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ describe(UserAdminService.name, () => {
|
||||||
await sut.update(authStub.admin, userStub.user1.id, { storageLabel: '' });
|
await sut.update(authStub.admin, userStub.user1.id, { storageLabel: '' });
|
||||||
expect(userMock.update).toHaveBeenCalledWith(userStub.user1.id, {
|
expect(userMock.update).toHaveBeenCalledWith(userStub.user1.id, {
|
||||||
storageLabel: null,
|
storageLabel: null,
|
||||||
updatedAt: expect.any(Date),
|
updatedAt: expect.any(String),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ describe(UserAdminService.name, () => {
|
||||||
await expect(sut.delete(authStub.admin, userStub.user1.id, {})).resolves.toEqual(mapUserAdmin(userStub.user1));
|
await expect(sut.delete(authStub.admin, userStub.user1.id, {})).resolves.toEqual(mapUserAdmin(userStub.user1));
|
||||||
expect(userMock.update).toHaveBeenCalledWith(userStub.user1.id, {
|
expect(userMock.update).toHaveBeenCalledWith(userStub.user1.id, {
|
||||||
status: UserStatus.DELETED,
|
status: UserStatus.DELETED,
|
||||||
deletedAt: expect.any(Date),
|
deletedAt: expect.any(String),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ describe(UserAdminService.name, () => {
|
||||||
|
|
||||||
expect(userMock.update).toHaveBeenCalledWith(userStub.user1.id, {
|
expect(userMock.update).toHaveBeenCalledWith(userStub.user1.id, {
|
||||||
status: UserStatus.REMOVING,
|
status: UserStatus.REMOVING,
|
||||||
deletedAt: expect.any(Date),
|
deletedAt: expect.any(String),
|
||||||
});
|
});
|
||||||
expect(jobMock.queue).toHaveBeenCalledWith({
|
expect(jobMock.queue).toHaveBeenCalledWith({
|
||||||
name: JobName.USER_DELETION,
|
name: JobName.USER_DELETION,
|
||||||
|
|
|
@ -85,7 +85,7 @@ export class UserAdminService {
|
||||||
dto.storageLabel = null;
|
dto.storageLabel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedUser = await this.userRepository.update(id, { ...dto, updatedAt: new Date() });
|
const updatedUser = await this.userRepository.update(id, { ...dto, updatedAt: new Date().toISOString() });
|
||||||
|
|
||||||
return mapUserAdmin(updatedUser);
|
return mapUserAdmin(updatedUser);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ export class UserAdminService {
|
||||||
await this.albumRepository.softDeleteAll(id);
|
await this.albumRepository.softDeleteAll(id);
|
||||||
|
|
||||||
const status = force ? UserStatus.REMOVING : UserStatus.DELETED;
|
const status = force ? UserStatus.REMOVING : UserStatus.DELETED;
|
||||||
const user = await this.userRepository.update(id, { status, deletedAt: new Date() });
|
const user = await this.userRepository.update(id, { status, deletedAt: new Date().toISOString() });
|
||||||
|
|
||||||
if (force) {
|
if (force) {
|
||||||
await this.jobRepository.queue({ name: JobName.USER_DELETION, data: { id: user.id, force } });
|
await this.jobRepository.queue({ name: JobName.USER_DELETION, data: { id: user.id, force } });
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { Mocked } from 'vitest';
|
||||||
const makeDeletedAt = (daysAgo: number) => {
|
const makeDeletedAt = (daysAgo: number) => {
|
||||||
const deletedAt = new Date();
|
const deletedAt = new Date();
|
||||||
deletedAt.setDate(deletedAt.getDate() - daysAgo);
|
deletedAt.setDate(deletedAt.getDate() - daysAgo);
|
||||||
return deletedAt;
|
return deletedAt.toISOString();
|
||||||
};
|
};
|
||||||
|
|
||||||
describe(UserService.name, () => {
|
describe(UserService.name, () => {
|
||||||
|
|
|
@ -179,7 +179,7 @@ export class UserService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DateTime.now().minus({ days: deleteDelay }) > DateTime.fromJSDate(user.deletedAt);
|
return DateTime.now().minus({ days: deleteDelay }) > DateTime.fromISO(user.deletedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async findOrFail(id: string, options: UserFindOptions) {
|
private async findOrFail(id: string, options: UserFindOptions) {
|
||||||
|
|
8
server/test/fixtures/session.stub.ts
vendored
8
server/test/fixtures/session.stub.ts
vendored
|
@ -7,8 +7,8 @@ export const sessionStub = {
|
||||||
token: 'auth_token',
|
token: 'auth_token',
|
||||||
userId: userStub.user1.id,
|
userId: userStub.user1.id,
|
||||||
user: userStub.user1,
|
user: userStub.user1,
|
||||||
createdAt: new Date('2021-01-01'),
|
createdAt: new Date('2021-01-01').toISOString(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date().toISOString(),
|
||||||
deviceType: '',
|
deviceType: '',
|
||||||
deviceOS: '',
|
deviceOS: '',
|
||||||
}),
|
}),
|
||||||
|
@ -17,8 +17,8 @@ export const sessionStub = {
|
||||||
token: 'auth_token',
|
token: 'auth_token',
|
||||||
userId: userStub.user1.id,
|
userId: userStub.user1.id,
|
||||||
user: userStub.user1,
|
user: userStub.user1,
|
||||||
createdAt: new Date('2021-01-01'),
|
createdAt: new Date('2021-01-01').toISOString(),
|
||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01').toISOString(),
|
||||||
deviceType: 'Mobile',
|
deviceType: 'Mobile',
|
||||||
deviceOS: 'Android',
|
deviceOS: 'Android',
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in a new issue