fix: update the profile picture in the navigation-bar (#12723)

* fix: update the profile picture in the navigation-bar

* chore: clean up

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
This commit is contained in:
martin 2024-09-17 03:48:15 +02:00 committed by GitHub
parent b0aafce16b
commit c468da589a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 147 additions and 36 deletions

View File

@ -94,6 +94,7 @@ export const signupResponseDto = {
quotaSizeInBytes: null, quotaSizeInBytes: null,
status: 'active', status: 'active',
license: null, license: null,
profileChangedAt: expect.any(String),
}, },
}; };

View File

@ -13,30 +13,36 @@ part of openapi.api;
class CreateProfileImageResponseDto { class CreateProfileImageResponseDto {
/// Returns a new [CreateProfileImageResponseDto] instance. /// Returns a new [CreateProfileImageResponseDto] instance.
CreateProfileImageResponseDto({ CreateProfileImageResponseDto({
required this.profileChangedAt,
required this.profileImagePath, required this.profileImagePath,
required this.userId, required this.userId,
}); });
DateTime profileChangedAt;
String profileImagePath; String profileImagePath;
String userId; String userId;
@override @override
bool operator ==(Object other) => identical(this, other) || other is CreateProfileImageResponseDto && bool operator ==(Object other) => identical(this, other) || other is CreateProfileImageResponseDto &&
other.profileChangedAt == profileChangedAt &&
other.profileImagePath == profileImagePath && other.profileImagePath == profileImagePath &&
other.userId == userId; other.userId == userId;
@override @override
int get hashCode => int get hashCode =>
// ignore: unnecessary_parenthesis // ignore: unnecessary_parenthesis
(profileChangedAt.hashCode) +
(profileImagePath.hashCode) + (profileImagePath.hashCode) +
(userId.hashCode); (userId.hashCode);
@override @override
String toString() => 'CreateProfileImageResponseDto[profileImagePath=$profileImagePath, userId=$userId]'; String toString() => 'CreateProfileImageResponseDto[profileChangedAt=$profileChangedAt, profileImagePath=$profileImagePath, userId=$userId]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
json[r'profileChangedAt'] = this.profileChangedAt.toUtc().toIso8601String();
json[r'profileImagePath'] = this.profileImagePath; json[r'profileImagePath'] = this.profileImagePath;
json[r'userId'] = this.userId; json[r'userId'] = this.userId;
return json; return json;
@ -50,6 +56,7 @@ class CreateProfileImageResponseDto {
final json = value.cast<String, dynamic>(); final json = value.cast<String, dynamic>();
return CreateProfileImageResponseDto( return CreateProfileImageResponseDto(
profileChangedAt: mapDateTime(json, r'profileChangedAt', r'')!,
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!, profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
userId: mapValueOfType<String>(json, r'userId')!, userId: mapValueOfType<String>(json, r'userId')!,
); );
@ -99,6 +106,7 @@ class CreateProfileImageResponseDto {
/// The list of required keys that must be present in a JSON. /// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{ static const requiredKeys = <String>{
'profileChangedAt',
'profileImagePath', 'profileImagePath',
'userId', 'userId',
}; };

View File

@ -18,6 +18,7 @@ class PartnerResponseDto {
required this.id, required this.id,
this.inTimeline, this.inTimeline,
required this.name, required this.name,
required this.profileChangedAt,
required this.profileImagePath, required this.profileImagePath,
}); });
@ -37,6 +38,8 @@ class PartnerResponseDto {
String name; String name;
DateTime profileChangedAt;
String profileImagePath; String profileImagePath;
@override @override
@ -46,6 +49,7 @@ class PartnerResponseDto {
other.id == id && other.id == id &&
other.inTimeline == inTimeline && other.inTimeline == inTimeline &&
other.name == name && other.name == name &&
other.profileChangedAt == profileChangedAt &&
other.profileImagePath == profileImagePath; other.profileImagePath == profileImagePath;
@override @override
@ -56,10 +60,11 @@ class PartnerResponseDto {
(id.hashCode) + (id.hashCode) +
(inTimeline == null ? 0 : inTimeline!.hashCode) + (inTimeline == null ? 0 : inTimeline!.hashCode) +
(name.hashCode) + (name.hashCode) +
(profileChangedAt.hashCode) +
(profileImagePath.hashCode); (profileImagePath.hashCode);
@override @override
String toString() => 'PartnerResponseDto[avatarColor=$avatarColor, email=$email, id=$id, inTimeline=$inTimeline, name=$name, profileImagePath=$profileImagePath]'; String toString() => 'PartnerResponseDto[avatarColor=$avatarColor, email=$email, id=$id, inTimeline=$inTimeline, name=$name, profileChangedAt=$profileChangedAt, profileImagePath=$profileImagePath]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -72,6 +77,7 @@ class PartnerResponseDto {
// json[r'inTimeline'] = null; // json[r'inTimeline'] = null;
} }
json[r'name'] = this.name; json[r'name'] = this.name;
json[r'profileChangedAt'] = this.profileChangedAt.toUtc().toIso8601String();
json[r'profileImagePath'] = this.profileImagePath; json[r'profileImagePath'] = this.profileImagePath;
return json; return json;
} }
@ -89,6 +95,7 @@ class PartnerResponseDto {
id: mapValueOfType<String>(json, r'id')!, id: mapValueOfType<String>(json, r'id')!,
inTimeline: mapValueOfType<bool>(json, r'inTimeline'), inTimeline: mapValueOfType<bool>(json, r'inTimeline'),
name: mapValueOfType<String>(json, r'name')!, name: mapValueOfType<String>(json, r'name')!,
profileChangedAt: mapDateTime(json, r'profileChangedAt', r'')!,
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!, profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
); );
} }
@ -141,6 +148,7 @@ class PartnerResponseDto {
'email', 'email',
'id', 'id',
'name', 'name',
'profileChangedAt',
'profileImagePath', 'profileImagePath',
}; };
} }

View File

@ -22,6 +22,7 @@ class UserAdminResponseDto {
required this.license, required this.license,
required this.name, required this.name,
required this.oauthId, required this.oauthId,
required this.profileChangedAt,
required this.profileImagePath, required this.profileImagePath,
required this.quotaSizeInBytes, required this.quotaSizeInBytes,
required this.quotaUsageInBytes, required this.quotaUsageInBytes,
@ -49,6 +50,8 @@ class UserAdminResponseDto {
String oauthId; String oauthId;
DateTime profileChangedAt;
String profileImagePath; String profileImagePath;
int? quotaSizeInBytes; int? quotaSizeInBytes;
@ -74,6 +77,7 @@ class UserAdminResponseDto {
other.license == license && other.license == license &&
other.name == name && other.name == name &&
other.oauthId == oauthId && other.oauthId == oauthId &&
other.profileChangedAt == profileChangedAt &&
other.profileImagePath == profileImagePath && other.profileImagePath == profileImagePath &&
other.quotaSizeInBytes == quotaSizeInBytes && other.quotaSizeInBytes == quotaSizeInBytes &&
other.quotaUsageInBytes == quotaUsageInBytes && other.quotaUsageInBytes == quotaUsageInBytes &&
@ -94,6 +98,7 @@ class UserAdminResponseDto {
(license == null ? 0 : license!.hashCode) + (license == null ? 0 : license!.hashCode) +
(name.hashCode) + (name.hashCode) +
(oauthId.hashCode) + (oauthId.hashCode) +
(profileChangedAt.hashCode) +
(profileImagePath.hashCode) + (profileImagePath.hashCode) +
(quotaSizeInBytes == null ? 0 : quotaSizeInBytes!.hashCode) + (quotaSizeInBytes == null ? 0 : quotaSizeInBytes!.hashCode) +
(quotaUsageInBytes == null ? 0 : quotaUsageInBytes!.hashCode) + (quotaUsageInBytes == null ? 0 : quotaUsageInBytes!.hashCode) +
@ -103,7 +108,7 @@ class UserAdminResponseDto {
(updatedAt.hashCode); (updatedAt.hashCode);
@override @override
String toString() => 'UserAdminResponseDto[avatarColor=$avatarColor, createdAt=$createdAt, deletedAt=$deletedAt, email=$email, id=$id, isAdmin=$isAdmin, license=$license, name=$name, oauthId=$oauthId, profileImagePath=$profileImagePath, quotaSizeInBytes=$quotaSizeInBytes, quotaUsageInBytes=$quotaUsageInBytes, shouldChangePassword=$shouldChangePassword, status=$status, storageLabel=$storageLabel, updatedAt=$updatedAt]'; String toString() => 'UserAdminResponseDto[avatarColor=$avatarColor, createdAt=$createdAt, deletedAt=$deletedAt, email=$email, id=$id, isAdmin=$isAdmin, license=$license, name=$name, oauthId=$oauthId, profileChangedAt=$profileChangedAt, profileImagePath=$profileImagePath, quotaSizeInBytes=$quotaSizeInBytes, quotaUsageInBytes=$quotaUsageInBytes, shouldChangePassword=$shouldChangePassword, status=$status, storageLabel=$storageLabel, updatedAt=$updatedAt]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -124,6 +129,7 @@ class UserAdminResponseDto {
} }
json[r'name'] = this.name; json[r'name'] = this.name;
json[r'oauthId'] = this.oauthId; json[r'oauthId'] = this.oauthId;
json[r'profileChangedAt'] = this.profileChangedAt.toUtc().toIso8601String();
json[r'profileImagePath'] = this.profileImagePath; json[r'profileImagePath'] = this.profileImagePath;
if (this.quotaSizeInBytes != null) { if (this.quotaSizeInBytes != null) {
json[r'quotaSizeInBytes'] = this.quotaSizeInBytes; json[r'quotaSizeInBytes'] = this.quotaSizeInBytes;
@ -163,6 +169,7 @@ class UserAdminResponseDto {
license: UserLicense.fromJson(json[r'license']), license: UserLicense.fromJson(json[r'license']),
name: mapValueOfType<String>(json, r'name')!, name: mapValueOfType<String>(json, r'name')!,
oauthId: mapValueOfType<String>(json, r'oauthId')!, oauthId: mapValueOfType<String>(json, r'oauthId')!,
profileChangedAt: mapDateTime(json, r'profileChangedAt', r'')!,
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!, profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
quotaSizeInBytes: mapValueOfType<int>(json, r'quotaSizeInBytes'), quotaSizeInBytes: mapValueOfType<int>(json, r'quotaSizeInBytes'),
quotaUsageInBytes: mapValueOfType<int>(json, r'quotaUsageInBytes'), quotaUsageInBytes: mapValueOfType<int>(json, r'quotaUsageInBytes'),
@ -226,6 +233,7 @@ class UserAdminResponseDto {
'license', 'license',
'name', 'name',
'oauthId', 'oauthId',
'profileChangedAt',
'profileImagePath', 'profileImagePath',
'quotaSizeInBytes', 'quotaSizeInBytes',
'quotaUsageInBytes', 'quotaUsageInBytes',

View File

@ -17,6 +17,7 @@ class UserResponseDto {
required this.email, required this.email,
required this.id, required this.id,
required this.name, required this.name,
required this.profileChangedAt,
required this.profileImagePath, required this.profileImagePath,
}); });
@ -28,6 +29,8 @@ class UserResponseDto {
String name; String name;
DateTime profileChangedAt;
String profileImagePath; String profileImagePath;
@override @override
@ -36,6 +39,7 @@ class UserResponseDto {
other.email == email && other.email == email &&
other.id == id && other.id == id &&
other.name == name && other.name == name &&
other.profileChangedAt == profileChangedAt &&
other.profileImagePath == profileImagePath; other.profileImagePath == profileImagePath;
@override @override
@ -45,10 +49,11 @@ class UserResponseDto {
(email.hashCode) + (email.hashCode) +
(id.hashCode) + (id.hashCode) +
(name.hashCode) + (name.hashCode) +
(profileChangedAt.hashCode) +
(profileImagePath.hashCode); (profileImagePath.hashCode);
@override @override
String toString() => 'UserResponseDto[avatarColor=$avatarColor, email=$email, id=$id, name=$name, profileImagePath=$profileImagePath]'; String toString() => 'UserResponseDto[avatarColor=$avatarColor, email=$email, id=$id, name=$name, profileChangedAt=$profileChangedAt, profileImagePath=$profileImagePath]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -56,6 +61,7 @@ class UserResponseDto {
json[r'email'] = this.email; json[r'email'] = this.email;
json[r'id'] = this.id; json[r'id'] = this.id;
json[r'name'] = this.name; json[r'name'] = this.name;
json[r'profileChangedAt'] = this.profileChangedAt.toUtc().toIso8601String();
json[r'profileImagePath'] = this.profileImagePath; json[r'profileImagePath'] = this.profileImagePath;
return json; return json;
} }
@ -72,6 +78,7 @@ class UserResponseDto {
email: mapValueOfType<String>(json, r'email')!, email: mapValueOfType<String>(json, r'email')!,
id: mapValueOfType<String>(json, r'id')!, id: mapValueOfType<String>(json, r'id')!,
name: mapValueOfType<String>(json, r'name')!, name: mapValueOfType<String>(json, r'name')!,
profileChangedAt: mapDateTime(json, r'profileChangedAt', r'')!,
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!, profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
); );
} }
@ -124,6 +131,7 @@ class UserResponseDto {
'email', 'email',
'id', 'id',
'name', 'name',
'profileChangedAt',
'profileImagePath', 'profileImagePath',
}; };
} }

View File

@ -8779,6 +8779,10 @@
}, },
"CreateProfileImageResponseDto": { "CreateProfileImageResponseDto": {
"properties": { "properties": {
"profileChangedAt": {
"format": "date-time",
"type": "string"
},
"profileImagePath": { "profileImagePath": {
"type": "string" "type": "string"
}, },
@ -8787,6 +8791,7 @@
} }
}, },
"required": [ "required": [
"profileChangedAt",
"profileImagePath", "profileImagePath",
"userId" "userId"
], ],
@ -10015,6 +10020,10 @@
"name": { "name": {
"type": "string" "type": "string"
}, },
"profileChangedAt": {
"format": "date-time",
"type": "string"
},
"profileImagePath": { "profileImagePath": {
"type": "string" "type": "string"
} }
@ -10024,6 +10033,7 @@
"email", "email",
"id", "id",
"name", "name",
"profileChangedAt",
"profileImagePath" "profileImagePath"
], ],
"type": "object" "type": "object"
@ -12454,6 +12464,10 @@
"oauthId": { "oauthId": {
"type": "string" "type": "string"
}, },
"profileChangedAt": {
"format": "date-time",
"type": "string"
},
"profileImagePath": { "profileImagePath": {
"type": "string" "type": "string"
}, },
@ -12492,6 +12506,7 @@
"license", "license",
"name", "name",
"oauthId", "oauthId",
"profileChangedAt",
"profileImagePath", "profileImagePath",
"quotaSizeInBytes", "quotaSizeInBytes",
"quotaUsageInBytes", "quotaUsageInBytes",
@ -12653,6 +12668,10 @@
"name": { "name": {
"type": "string" "type": "string"
}, },
"profileChangedAt": {
"format": "date-time",
"type": "string"
},
"profileImagePath": { "profileImagePath": {
"type": "string" "type": "string"
} }
@ -12662,6 +12681,7 @@
"email", "email",
"id", "id",
"name", "name",
"profileChangedAt",
"profileImagePath" "profileImagePath"
], ],
"type": "object" "type": "object"

View File

@ -19,6 +19,7 @@ export type UserResponseDto = {
email: string; email: string;
id: string; id: string;
name: string; name: string;
profileChangedAt: string;
profileImagePath: string; profileImagePath: string;
}; };
export type ActivityResponseDto = { export type ActivityResponseDto = {
@ -53,6 +54,7 @@ export type UserAdminResponseDto = {
license: (UserLicense) | null; license: (UserLicense) | null;
name: string; name: string;
oauthId: string; oauthId: string;
profileChangedAt: string;
profileImagePath: string; profileImagePath: string;
quotaSizeInBytes: number | null; quotaSizeInBytes: number | null;
quotaUsageInBytes: number | null; quotaUsageInBytes: number | null;
@ -669,6 +671,7 @@ export type PartnerResponseDto = {
id: string; id: string;
inTimeline?: boolean; inTimeline?: boolean;
name: string; name: string;
profileChangedAt: string;
profileImagePath: string; profileImagePath: string;
}; };
export type UpdatePartnerDto = { export type UpdatePartnerDto = {
@ -1252,6 +1255,7 @@ export type CreateProfileImageDto = {
file: Blob; file: Blob;
}; };
export type CreateProfileImageResponseDto = { export type CreateProfileImageResponseDto = {
profileChangedAt: string;
profileImagePath: string; profileImagePath: string;
userId: string; userId: string;
}; };

View File

@ -8,12 +8,6 @@ export class CreateProfileImageDto {
export class CreateProfileImageResponseDto { export class CreateProfileImageResponseDto {
userId!: string; userId!: string;
profileChangedAt!: Date;
profileImagePath!: string; profileImagePath!: string;
} }
export function mapCreateProfileImageResponse(userId: string, profileImagePath: string): CreateProfileImageResponseDto {
return {
userId,
profileImagePath,
};
}

View File

@ -32,6 +32,7 @@ export class UserResponseDto {
profileImagePath!: string; profileImagePath!: string;
@ApiProperty({ enumName: 'UserAvatarColor', enum: UserAvatarColor }) @ApiProperty({ enumName: 'UserAvatarColor', enum: UserAvatarColor })
avatarColor!: UserAvatarColor; avatarColor!: UserAvatarColor;
profileChangedAt!: Date;
} }
export class UserLicense { export class UserLicense {
@ -47,6 +48,7 @@ export const mapUser = (entity: UserEntity): UserResponseDto => {
name: entity.name, name: entity.name,
profileImagePath: entity.profileImagePath, profileImagePath: entity.profileImagePath,
avatarColor: getPreferences(entity).avatar.color, avatarColor: getPreferences(entity).avatar.color,
profileChangedAt: entity.profileChangedAt,
}; };
}; };

View File

@ -67,4 +67,7 @@ export class UserEntity {
@OneToMany(() => UserMetadataEntity, (metadata) => metadata.user) @OneToMany(() => UserMetadataEntity, (metadata) => metadata.user)
metadata!: UserMetadataEntity[]; metadata!: UserMetadataEntity[];
@Column({ type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
profileChangedAt!: Date;
} }

View File

@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class AddprofileChangedAt1726491047923 implements MigrationInterface {
name = 'AddprofileChangedAt1726491047923'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users" ADD "profileChangedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "profileChangedAt"`);
}
}

View File

@ -23,7 +23,8 @@ SELECT
"ActivityEntity__ActivityEntity_user"."status" AS "ActivityEntity__ActivityEntity_user_status", "ActivityEntity__ActivityEntity_user"."status" AS "ActivityEntity__ActivityEntity_user_status",
"ActivityEntity__ActivityEntity_user"."updatedAt" AS "ActivityEntity__ActivityEntity_user_updatedAt", "ActivityEntity__ActivityEntity_user"."updatedAt" AS "ActivityEntity__ActivityEntity_user_updatedAt",
"ActivityEntity__ActivityEntity_user"."quotaSizeInBytes" AS "ActivityEntity__ActivityEntity_user_quotaSizeInBytes", "ActivityEntity__ActivityEntity_user"."quotaSizeInBytes" AS "ActivityEntity__ActivityEntity_user_quotaSizeInBytes",
"ActivityEntity__ActivityEntity_user"."quotaUsageInBytes" AS "ActivityEntity__ActivityEntity_user_quotaUsageInBytes" "ActivityEntity__ActivityEntity_user"."quotaUsageInBytes" AS "ActivityEntity__ActivityEntity_user_quotaUsageInBytes",
"ActivityEntity__ActivityEntity_user"."profileChangedAt" AS "ActivityEntity__ActivityEntity_user_profileChangedAt"
FROM FROM
"activity" "ActivityEntity" "activity" "ActivityEntity"
LEFT JOIN "users" "ActivityEntity__ActivityEntity_user" ON "ActivityEntity__ActivityEntity_user"."id" = "ActivityEntity"."userId" LEFT JOIN "users" "ActivityEntity__ActivityEntity_user" ON "ActivityEntity__ActivityEntity_user"."id" = "ActivityEntity"."userId"

View File

@ -30,6 +30,7 @@ FROM
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes", "AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes", "AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt",
"AlbumEntity__AlbumEntity_albumUsers"."albumsId" AS "AlbumEntity__AlbumEntity_albumUsers_albumsId", "AlbumEntity__AlbumEntity_albumUsers"."albumsId" AS "AlbumEntity__AlbumEntity_albumUsers_albumsId",
"AlbumEntity__AlbumEntity_albumUsers"."usersId" AS "AlbumEntity__AlbumEntity_albumUsers_usersId", "AlbumEntity__AlbumEntity_albumUsers"."usersId" AS "AlbumEntity__AlbumEntity_albumUsers_usersId",
"AlbumEntity__AlbumEntity_albumUsers"."role" AS "AlbumEntity__AlbumEntity_albumUsers_role", "AlbumEntity__AlbumEntity_albumUsers"."role" AS "AlbumEntity__AlbumEntity_albumUsers_role",
@ -47,6 +48,7 @@ FROM
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."profileChangedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_profileChangedAt",
"AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id", "AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id",
"AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description", "AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description",
"AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password", "AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password",
@ -106,6 +108,7 @@ SELECT
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes", "AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes", "AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt",
"AlbumEntity__AlbumEntity_albumUsers"."albumsId" AS "AlbumEntity__AlbumEntity_albumUsers_albumsId", "AlbumEntity__AlbumEntity_albumUsers"."albumsId" AS "AlbumEntity__AlbumEntity_albumUsers_albumsId",
"AlbumEntity__AlbumEntity_albumUsers"."usersId" AS "AlbumEntity__AlbumEntity_albumUsers_usersId", "AlbumEntity__AlbumEntity_albumUsers"."usersId" AS "AlbumEntity__AlbumEntity_albumUsers_usersId",
"AlbumEntity__AlbumEntity_albumUsers"."role" AS "AlbumEntity__AlbumEntity_albumUsers_role", "AlbumEntity__AlbumEntity_albumUsers"."role" AS "AlbumEntity__AlbumEntity_albumUsers_role",
@ -122,7 +125,8 @@ SELECT
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."status" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_status", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."status" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_status",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes" "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."profileChangedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_profileChangedAt"
FROM FROM
"albums" "AlbumEntity" "albums" "AlbumEntity"
LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId"
@ -164,6 +168,7 @@ SELECT
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes", "AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes", "AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt",
"AlbumEntity__AlbumEntity_albumUsers"."albumsId" AS "AlbumEntity__AlbumEntity_albumUsers_albumsId", "AlbumEntity__AlbumEntity_albumUsers"."albumsId" AS "AlbumEntity__AlbumEntity_albumUsers_albumsId",
"AlbumEntity__AlbumEntity_albumUsers"."usersId" AS "AlbumEntity__AlbumEntity_albumUsers_usersId", "AlbumEntity__AlbumEntity_albumUsers"."usersId" AS "AlbumEntity__AlbumEntity_albumUsers_usersId",
"AlbumEntity__AlbumEntity_albumUsers"."role" AS "AlbumEntity__AlbumEntity_albumUsers_role", "AlbumEntity__AlbumEntity_albumUsers"."role" AS "AlbumEntity__AlbumEntity_albumUsers_role",
@ -180,7 +185,8 @@ SELECT
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."status" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_status", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."status" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_status",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes" "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."profileChangedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_profileChangedAt"
FROM FROM
"albums" "AlbumEntity" "albums" "AlbumEntity"
LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId"
@ -299,6 +305,7 @@ SELECT
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."profileChangedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_profileChangedAt",
"AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id", "AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id",
"AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description", "AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description",
"AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password", "AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password",
@ -324,7 +331,8 @@ SELECT
"AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status", "AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status",
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes", "AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes" "AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt"
FROM FROM
"albums" "AlbumEntity" "albums" "AlbumEntity"
LEFT JOIN "albums_shared_users_users" "AlbumEntity__AlbumEntity_albumUsers" ON "AlbumEntity__AlbumEntity_albumUsers"."albumsId" = "AlbumEntity"."id" LEFT JOIN "albums_shared_users_users" "AlbumEntity__AlbumEntity_albumUsers" ON "AlbumEntity__AlbumEntity_albumUsers"."albumsId" = "AlbumEntity"."id"
@ -372,6 +380,7 @@ SELECT
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes", "a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."profileChangedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_profileChangedAt",
"AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id", "AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id",
"AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description", "AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description",
"AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password", "AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password",
@ -397,7 +406,8 @@ SELECT
"AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status", "AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status",
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes", "AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes" "AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt"
FROM FROM
"albums" "AlbumEntity" "albums" "AlbumEntity"
LEFT JOIN "albums_shared_users_users" "AlbumEntity__AlbumEntity_albumUsers" ON "AlbumEntity__AlbumEntity_albumUsers"."albumsId" = "AlbumEntity"."id" LEFT JOIN "albums_shared_users_users" "AlbumEntity__AlbumEntity_albumUsers" ON "AlbumEntity__AlbumEntity_albumUsers"."albumsId" = "AlbumEntity"."id"
@ -495,7 +505,8 @@ SELECT
"AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status", "AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status",
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes", "AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes" "AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt"
FROM FROM
"albums" "AlbumEntity" "albums" "AlbumEntity"
LEFT JOIN "albums_shared_users_users" "AlbumEntity__AlbumEntity_albumUsers" ON "AlbumEntity__AlbumEntity_albumUsers"."albumsId" = "AlbumEntity"."id" LEFT JOIN "albums_shared_users_users" "AlbumEntity__AlbumEntity_albumUsers" ON "AlbumEntity__AlbumEntity_albumUsers"."albumsId" = "AlbumEntity"."id"
@ -553,7 +564,8 @@ SELECT
"AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status", "AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status",
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes", "AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes" "AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt"
FROM FROM
"albums" "AlbumEntity" "albums" "AlbumEntity"
LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId"

View File

@ -24,6 +24,7 @@ FROM
"APIKeyEntity__APIKeyEntity_user"."updatedAt" AS "APIKeyEntity__APIKeyEntity_user_updatedAt", "APIKeyEntity__APIKeyEntity_user"."updatedAt" AS "APIKeyEntity__APIKeyEntity_user_updatedAt",
"APIKeyEntity__APIKeyEntity_user"."quotaSizeInBytes" AS "APIKeyEntity__APIKeyEntity_user_quotaSizeInBytes", "APIKeyEntity__APIKeyEntity_user"."quotaSizeInBytes" AS "APIKeyEntity__APIKeyEntity_user_quotaSizeInBytes",
"APIKeyEntity__APIKeyEntity_user"."quotaUsageInBytes" AS "APIKeyEntity__APIKeyEntity_user_quotaUsageInBytes", "APIKeyEntity__APIKeyEntity_user"."quotaUsageInBytes" AS "APIKeyEntity__APIKeyEntity_user_quotaUsageInBytes",
"APIKeyEntity__APIKeyEntity_user"."profileChangedAt" AS "APIKeyEntity__APIKeyEntity_user_profileChangedAt",
"7f5f7a38bf327bfbbf826778460704c9a50fe6f4"."userId" AS "7f5f7a38bf327bfbbf826778460704c9a50fe6f4_userId", "7f5f7a38bf327bfbbf826778460704c9a50fe6f4"."userId" AS "7f5f7a38bf327bfbbf826778460704c9a50fe6f4_userId",
"7f5f7a38bf327bfbbf826778460704c9a50fe6f4"."key" AS "7f5f7a38bf327bfbbf826778460704c9a50fe6f4_key", "7f5f7a38bf327bfbbf826778460704c9a50fe6f4"."key" AS "7f5f7a38bf327bfbbf826778460704c9a50fe6f4_key",
"7f5f7a38bf327bfbbf826778460704c9a50fe6f4"."value" AS "7f5f7a38bf327bfbbf826778460704c9a50fe6f4_value" "7f5f7a38bf327bfbbf826778460704c9a50fe6f4"."value" AS "7f5f7a38bf327bfbbf826778460704c9a50fe6f4_value"

View File

@ -28,7 +28,8 @@ FROM
"LibraryEntity__LibraryEntity_owner"."status" AS "LibraryEntity__LibraryEntity_owner_status", "LibraryEntity__LibraryEntity_owner"."status" AS "LibraryEntity__LibraryEntity_owner_status",
"LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt", "LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt",
"LibraryEntity__LibraryEntity_owner"."quotaSizeInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaSizeInBytes", "LibraryEntity__LibraryEntity_owner"."quotaSizeInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaSizeInBytes",
"LibraryEntity__LibraryEntity_owner"."quotaUsageInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaUsageInBytes" "LibraryEntity__LibraryEntity_owner"."quotaUsageInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaUsageInBytes",
"LibraryEntity__LibraryEntity_owner"."profileChangedAt" AS "LibraryEntity__LibraryEntity_owner_profileChangedAt"
FROM FROM
"libraries" "LibraryEntity" "libraries" "LibraryEntity"
LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId"
@ -68,7 +69,8 @@ SELECT
"LibraryEntity__LibraryEntity_owner"."status" AS "LibraryEntity__LibraryEntity_owner_status", "LibraryEntity__LibraryEntity_owner"."status" AS "LibraryEntity__LibraryEntity_owner_status",
"LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt", "LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt",
"LibraryEntity__LibraryEntity_owner"."quotaSizeInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaSizeInBytes", "LibraryEntity__LibraryEntity_owner"."quotaSizeInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaSizeInBytes",
"LibraryEntity__LibraryEntity_owner"."quotaUsageInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaUsageInBytes" "LibraryEntity__LibraryEntity_owner"."quotaUsageInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaUsageInBytes",
"LibraryEntity__LibraryEntity_owner"."profileChangedAt" AS "LibraryEntity__LibraryEntity_owner_profileChangedAt"
FROM FROM
"libraries" "LibraryEntity" "libraries" "LibraryEntity"
LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId"
@ -104,7 +106,8 @@ SELECT
"LibraryEntity__LibraryEntity_owner"."status" AS "LibraryEntity__LibraryEntity_owner_status", "LibraryEntity__LibraryEntity_owner"."status" AS "LibraryEntity__LibraryEntity_owner_status",
"LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt", "LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt",
"LibraryEntity__LibraryEntity_owner"."quotaSizeInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaSizeInBytes", "LibraryEntity__LibraryEntity_owner"."quotaSizeInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaSizeInBytes",
"LibraryEntity__LibraryEntity_owner"."quotaUsageInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaUsageInBytes" "LibraryEntity__LibraryEntity_owner"."quotaUsageInBytes" AS "LibraryEntity__LibraryEntity_owner_quotaUsageInBytes",
"LibraryEntity__LibraryEntity_owner"."profileChangedAt" AS "LibraryEntity__LibraryEntity_owner_profileChangedAt"
FROM FROM
"libraries" "LibraryEntity" "libraries" "LibraryEntity"
LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId"

View File

@ -39,6 +39,7 @@ FROM
"SessionEntity__SessionEntity_user"."updatedAt" AS "SessionEntity__SessionEntity_user_updatedAt", "SessionEntity__SessionEntity_user"."updatedAt" AS "SessionEntity__SessionEntity_user_updatedAt",
"SessionEntity__SessionEntity_user"."quotaSizeInBytes" AS "SessionEntity__SessionEntity_user_quotaSizeInBytes", "SessionEntity__SessionEntity_user"."quotaSizeInBytes" AS "SessionEntity__SessionEntity_user_quotaSizeInBytes",
"SessionEntity__SessionEntity_user"."quotaUsageInBytes" AS "SessionEntity__SessionEntity_user_quotaUsageInBytes", "SessionEntity__SessionEntity_user"."quotaUsageInBytes" AS "SessionEntity__SessionEntity_user_quotaUsageInBytes",
"SessionEntity__SessionEntity_user"."profileChangedAt" AS "SessionEntity__SessionEntity_user_profileChangedAt",
"469e6aa7ff79eff78f8441f91ba15bb07d3634dd"."userId" AS "469e6aa7ff79eff78f8441f91ba15bb07d3634dd_userId", "469e6aa7ff79eff78f8441f91ba15bb07d3634dd"."userId" AS "469e6aa7ff79eff78f8441f91ba15bb07d3634dd_userId",
"469e6aa7ff79eff78f8441f91ba15bb07d3634dd"."key" AS "469e6aa7ff79eff78f8441f91ba15bb07d3634dd_key", "469e6aa7ff79eff78f8441f91ba15bb07d3634dd"."key" AS "469e6aa7ff79eff78f8441f91ba15bb07d3634dd_key",
"469e6aa7ff79eff78f8441f91ba15bb07d3634dd"."value" AS "469e6aa7ff79eff78f8441f91ba15bb07d3634dd_value" "469e6aa7ff79eff78f8441f91ba15bb07d3634dd"."value" AS "469e6aa7ff79eff78f8441f91ba15bb07d3634dd_value"

View File

@ -156,7 +156,8 @@ FROM
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."status" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_status", "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."status" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_status",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt", "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaSizeInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaSizeInBytes", "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaSizeInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaSizeInBytes",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaUsageInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaUsageInBytes" "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaUsageInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaUsageInBytes",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileChangedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileChangedAt"
FROM FROM
"shared_links" "SharedLinkEntity" "shared_links" "SharedLinkEntity"
LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id" LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id"
@ -257,7 +258,8 @@ SELECT
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."status" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_status", "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."status" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_status",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt", "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaSizeInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaSizeInBytes", "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaSizeInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaSizeInBytes",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaUsageInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaUsageInBytes" "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaUsageInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaUsageInBytes",
"6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileChangedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileChangedAt"
FROM FROM
"shared_links" "SharedLinkEntity" "shared_links" "SharedLinkEntity"
LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id" LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id"
@ -309,7 +311,8 @@ FROM
"SharedLinkEntity__SharedLinkEntity_user"."status" AS "SharedLinkEntity__SharedLinkEntity_user_status", "SharedLinkEntity__SharedLinkEntity_user"."status" AS "SharedLinkEntity__SharedLinkEntity_user_status",
"SharedLinkEntity__SharedLinkEntity_user"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_user_updatedAt", "SharedLinkEntity__SharedLinkEntity_user"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_user_updatedAt",
"SharedLinkEntity__SharedLinkEntity_user"."quotaSizeInBytes" AS "SharedLinkEntity__SharedLinkEntity_user_quotaSizeInBytes", "SharedLinkEntity__SharedLinkEntity_user"."quotaSizeInBytes" AS "SharedLinkEntity__SharedLinkEntity_user_quotaSizeInBytes",
"SharedLinkEntity__SharedLinkEntity_user"."quotaUsageInBytes" AS "SharedLinkEntity__SharedLinkEntity_user_quotaUsageInBytes" "SharedLinkEntity__SharedLinkEntity_user"."quotaUsageInBytes" AS "SharedLinkEntity__SharedLinkEntity_user_quotaUsageInBytes",
"SharedLinkEntity__SharedLinkEntity_user"."profileChangedAt" AS "SharedLinkEntity__SharedLinkEntity_user_profileChangedAt"
FROM FROM
"shared_links" "SharedLinkEntity" "shared_links" "SharedLinkEntity"
LEFT JOIN "users" "SharedLinkEntity__SharedLinkEntity_user" ON "SharedLinkEntity__SharedLinkEntity_user"."id" = "SharedLinkEntity"."userId" LEFT JOIN "users" "SharedLinkEntity__SharedLinkEntity_user" ON "SharedLinkEntity__SharedLinkEntity_user"."id" = "SharedLinkEntity"."userId"

View File

@ -15,7 +15,8 @@ SELECT
"UserEntity"."status" AS "UserEntity_status", "UserEntity"."status" AS "UserEntity_status",
"UserEntity"."updatedAt" AS "UserEntity_updatedAt", "UserEntity"."updatedAt" AS "UserEntity_updatedAt",
"UserEntity"."quotaSizeInBytes" AS "UserEntity_quotaSizeInBytes", "UserEntity"."quotaSizeInBytes" AS "UserEntity_quotaSizeInBytes",
"UserEntity"."quotaUsageInBytes" AS "UserEntity_quotaUsageInBytes" "UserEntity"."quotaUsageInBytes" AS "UserEntity_quotaUsageInBytes",
"UserEntity"."profileChangedAt" AS "UserEntity_profileChangedAt"
FROM FROM
"users" "UserEntity" "users" "UserEntity"
WHERE WHERE
@ -60,7 +61,8 @@ SELECT
"user"."status" AS "user_status", "user"."status" AS "user_status",
"user"."updatedAt" AS "user_updatedAt", "user"."updatedAt" AS "user_updatedAt",
"user"."quotaSizeInBytes" AS "user_quotaSizeInBytes", "user"."quotaSizeInBytes" AS "user_quotaSizeInBytes",
"user"."quotaUsageInBytes" AS "user_quotaUsageInBytes" "user"."quotaUsageInBytes" AS "user_quotaUsageInBytes",
"user"."profileChangedAt" AS "user_profileChangedAt"
FROM FROM
"users" "user" "users" "user"
WHERE WHERE
@ -82,7 +84,8 @@ SELECT
"UserEntity"."status" AS "UserEntity_status", "UserEntity"."status" AS "UserEntity_status",
"UserEntity"."updatedAt" AS "UserEntity_updatedAt", "UserEntity"."updatedAt" AS "UserEntity_updatedAt",
"UserEntity"."quotaSizeInBytes" AS "UserEntity_quotaSizeInBytes", "UserEntity"."quotaSizeInBytes" AS "UserEntity_quotaSizeInBytes",
"UserEntity"."quotaUsageInBytes" AS "UserEntity_quotaUsageInBytes" "UserEntity"."quotaUsageInBytes" AS "UserEntity_quotaUsageInBytes",
"UserEntity"."profileChangedAt" AS "UserEntity_profileChangedAt"
FROM FROM
"users" "UserEntity" "users" "UserEntity"
WHERE WHERE
@ -106,7 +109,8 @@ SELECT
"UserEntity"."status" AS "UserEntity_status", "UserEntity"."status" AS "UserEntity_status",
"UserEntity"."updatedAt" AS "UserEntity_updatedAt", "UserEntity"."updatedAt" AS "UserEntity_updatedAt",
"UserEntity"."quotaSizeInBytes" AS "UserEntity_quotaSizeInBytes", "UserEntity"."quotaSizeInBytes" AS "UserEntity_quotaSizeInBytes",
"UserEntity"."quotaUsageInBytes" AS "UserEntity_quotaUsageInBytes" "UserEntity"."quotaUsageInBytes" AS "UserEntity_quotaUsageInBytes",
"UserEntity"."profileChangedAt" AS "UserEntity_profileChangedAt"
FROM FROM
"users" "UserEntity" "users" "UserEntity"
WHERE WHERE

View File

@ -7,7 +7,7 @@ import { SystemConfigCore } from 'src/cores/system-config.core';
import { AuthDto } from 'src/dtos/auth.dto'; import { AuthDto } from 'src/dtos/auth.dto';
import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto'; import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto';
import { UserPreferencesResponseDto, UserPreferencesUpdateDto, mapPreferences } from 'src/dtos/user-preferences.dto'; import { UserPreferencesResponseDto, UserPreferencesUpdateDto, mapPreferences } from 'src/dtos/user-preferences.dto';
import { CreateProfileImageResponseDto, mapCreateProfileImageResponse } from 'src/dtos/user-profile.dto'; import { CreateProfileImageResponseDto } from 'src/dtos/user-profile.dto';
import { UserAdminResponseDto, UserResponseDto, UserUpdateMeDto, mapUser, mapUserAdmin } from 'src/dtos/user.dto'; import { UserAdminResponseDto, UserResponseDto, UserUpdateMeDto, mapUser, mapUserAdmin } from 'src/dtos/user.dto';
import { UserMetadataEntity } from 'src/entities/user-metadata.entity'; import { UserMetadataEntity } from 'src/entities/user-metadata.entity';
import { UserEntity } from 'src/entities/user.entity'; import { UserEntity } from 'src/entities/user.entity';
@ -93,13 +93,23 @@ export class UserService {
return mapUser(user); return mapUser(user);
} }
async createProfileImage(auth: AuthDto, fileInfo: Express.Multer.File): Promise<CreateProfileImageResponseDto> { async createProfileImage(auth: AuthDto, file: Express.Multer.File): Promise<CreateProfileImageResponseDto> {
const { profileImagePath: oldpath } = await this.findOrFail(auth.user.id, { withDeleted: false }); const { profileImagePath: oldpath } = await this.findOrFail(auth.user.id, { withDeleted: false });
const updatedUser = await this.userRepository.update(auth.user.id, { profileImagePath: fileInfo.path });
const user = await this.userRepository.update(auth.user.id, {
profileImagePath: file.path,
profileChangedAt: new Date(),
});
if (oldpath !== '') { if (oldpath !== '') {
await this.jobRepository.queue({ name: JobName.DELETE_FILES, data: { files: [oldpath] } }); await this.jobRepository.queue({ name: JobName.DELETE_FILES, data: { files: [oldpath] } });
} }
return mapCreateProfileImageResponse(updatedUser.id, updatedUser.profileImagePath);
return {
userId: user.id,
profileImagePath: user.profileImagePath,
profileChangedAt: user.profileChangedAt,
};
} }
async deleteProfileImage(auth: AuthDto): Promise<void> { async deleteProfileImage(auth: AuthDto): Promise<void> {
@ -107,7 +117,7 @@ export class UserService {
if (user.profileImagePath === '') { if (user.profileImagePath === '') {
throw new BadRequestException("Can't delete a missing profile Image"); throw new BadRequestException("Can't delete a missing profile Image");
} }
await this.userRepository.update(auth.user.id, { profileImagePath: '' }); await this.userRepository.update(auth.user.id, { profileImagePath: '', profileChangedAt: new Date() });
await this.jobRepository.queue({ name: JobName.DELETE_FILES, data: { files: [user.profileImagePath] } }); await this.jobRepository.queue({ name: JobName.DELETE_FILES, data: { files: [user.profileImagePath] } });
} }

View File

@ -56,13 +56,14 @@
return; return;
} }
const file = new File([blob], 'profile-picture.png', { type: 'image/png' }); const file = new File([blob], 'profile-picture.png', { type: 'image/png' });
const { profileImagePath } = await createProfileImage({ createProfileImageDto: { file } }); const { profileImagePath, profileChangedAt } = await createProfileImage({ createProfileImageDto: { file } });
notificationController.show({ notificationController.show({
type: NotificationType.Info, type: NotificationType.Info,
message: $t('profile_picture_set'), message: $t('profile_picture_set'),
timeout: 3000, timeout: 3000,
}); });
$user.profileImagePath = profileImagePath; $user.profileImagePath = profileImagePath;
$user.profileChangedAt = profileChangedAt;
} catch (error) { } catch (error) {
handleError(error, $t('errors.unable_to_set_profile_picture')); handleError(error, $t('errors.unable_to_set_profile_picture'));
} }

View File

@ -13,6 +13,7 @@
email: string; email: string;
profileImagePath: string; profileImagePath: string;
avatarColor: UserAvatarColor; avatarColor: UserAvatarColor;
profileChangedAt: string;
} }
export let user: User; export let user: User;
@ -79,7 +80,7 @@
{#if showProfileImage && user.profileImagePath} {#if showProfileImage && user.profileImagePath}
<img <img
bind:this={img} bind:this={img}
src={getProfileImageUrl(user.id)} src={getProfileImageUrl(user)}
alt={$t('profile_image_of_user', { values: { user: title } })} alt={$t('profile_image_of_user', { values: { user: title } })}
class="h-full w-full object-cover" class="h-full w-full object-cover"
class:hidden={showFallback} class:hidden={showFallback}

View File

@ -19,6 +19,7 @@ import {
type AssetResponseDto, type AssetResponseDto,
type PersonResponseDto, type PersonResponseDto,
type SharedLinkResponseDto, type SharedLinkResponseDto,
type UserResponseDto,
} from '@immich/sdk'; } from '@immich/sdk';
import { mdiCogRefreshOutline, mdiDatabaseRefreshOutline, mdiImageRefreshOutline } from '@mdi/js'; import { mdiCogRefreshOutline, mdiDatabaseRefreshOutline, mdiImageRefreshOutline } from '@mdi/js';
import { sortBy } from 'lodash-es'; import { sortBy } from 'lodash-es';
@ -204,7 +205,8 @@ export const getAssetPlaybackUrl = (options: string | { id: string; checksum?: s
return createUrl(getAssetPlaybackPath(id), { key: getKey(), c: checksum }); return createUrl(getAssetPlaybackPath(id), { key: getKey(), c: checksum });
}; };
export const getProfileImageUrl = (userId: string) => createUrl(getUserProfileImagePath(userId)); export const getProfileImageUrl = (user: UserResponseDto) =>
createUrl(getUserProfileImagePath(user.id), { updatedAt: user.profileChangedAt });
export const getPeopleThumbnailUrl = (person: PersonResponseDto, updatedAt?: string) => export const getPeopleThumbnailUrl = (person: PersonResponseDto, updatedAt?: string) =>
createUrl(getPeopleThumbnailPath(person.id), { updatedAt: updatedAt ?? person.updatedAt }); createUrl(getPeopleThumbnailPath(person.id), { updatedAt: updatedAt ?? person.updatedAt });

View File

@ -8,6 +8,7 @@ export const userFactory = Sync.makeFactory<UserResponseDto>({
name: Sync.each(() => faker.person.fullName()), name: Sync.each(() => faker.person.fullName()),
profileImagePath: '', profileImagePath: '',
avatarColor: UserAvatarColor.Primary, avatarColor: UserAvatarColor.Primary,
profileChangedAt: Sync.each(() => faker.date.recent().toISOString()),
}); });
export const userAdminFactory = Sync.makeFactory<UserAdminResponseDto>({ export const userAdminFactory = Sync.makeFactory<UserAdminResponseDto>({
@ -31,4 +32,5 @@ export const userAdminFactory = Sync.makeFactory<UserAdminResponseDto>({
activationKey: 'activation-key', activationKey: 'activation-key',
activatedAt: new Date().toISOString(), activatedAt: new Date().toISOString(),
}, },
profileChangedAt: Sync.each(() => faker.date.recent().toISOString()),
}); });