1
0
mirror of https://github.com/immich-app/immich.git synced 2025-06-16 03:40:33 +02:00

feat: readonly album sharing (#8720)

* rename albums_shared_users_users to album_permissions and add readonly column

* disable synchronize on the original join table

* remove unnecessary FK names

* set readonly=true as default for new album shares

* separate and implement album READ and WRITE permission

* expose albumPermissions on the API, deprecate sharedUsers

* generate openapi

* create readonly view on frontend

* ??? move slideshow button out from ellipsis menu so that non-owners can have access too

* correct sharedUsers joins

* add album permission repository

* remove a log

* fix assetCount getting reset when adding users

* fix lint

* add set permission endpoint and UI

* sort users

* remove log

* Revert "??? move slideshow button out from ellipsis menu so that non-owners can have access too"

This reverts commit 1343bfa311.

* rename stuff

* fix db schema annotations

* sql generate

* change readonly default to follow migration

* fix deprecation notice

* change readonly boolean to role enum

* fix joincolumn as primary key

* rename albumUserRepository in album service

* clean up userId and albumId

* add write access to shared link

* fix existing tests

* switch to vitest

* format and fix tests on web

* add new test

* fix one e2e test

* rename new API field to albumUsers

* capitalize serverside enum

* remove unused ReadWrite type

* missed rename from previous commit

* rename to albumUsers in album entity as well

* remove outdated Equals calls

* unnecessary relation

* rename to updateUser in album service

* minor renamery

* move sorting to backend

* rename and separate ALBUM_WRITE as ADD_ASSET and REMOVE_ASSET

* fix tests

* fix "should migrate single moving picture" test failing on European system timezone

* generated changes after merge

* lint fix

* fix correct page to open after removing user from album

* fix e2e tests and some bugs

* rename updateAlbumUser rest endpoint

* add new e2e tests for updateAlbumUser endpoint

* small optimizations

* refactor album e2e test, add new album shared with viewer

* add new test to check if viewer can see the album

* add new e2e tests for readonly share

* failing test: User delete doesn't cascade to UserAlbum entity

* fix: handle deleted users

* use lodash for sort

* add role to addUsersToAlbum endpoint

* add UI for adding editors

* lint fixes

* change role back to editor as DB default

* fix server tests

* redesign user selection modal editor selector

* style tweaks

* fix type error

* Revert "style tweaks"

This reverts commit ab604f4c8f.

* Revert "redesign user selection modal editor selector"

This reverts commit e6f344856c.

* chore: cleanup and improve add user modal

* chore: open api

* small styling

---------

Co-authored-by: mgabor <>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
mgabor
2024-04-25 06:19:49 +02:00
committed by GitHub
parent 0b3373c552
commit 2943f93098
56 changed files with 1778 additions and 370 deletions

View File

@ -38,6 +38,28 @@ export type ActivityCreateDto = {
export type ActivityStatisticsResponseDto = {
comments: number;
};
export type UserResponseDto = {
avatarColor: UserAvatarColor;
createdAt: string;
deletedAt: string | null;
email: string;
id: string;
isAdmin: boolean;
memoriesEnabled?: boolean;
name: string;
oauthId: string;
profileImagePath: string;
quotaSizeInBytes: number | null;
quotaUsageInBytes: number | null;
shouldChangePassword: boolean;
status: UserStatus;
storageLabel: string | null;
updatedAt: string;
};
export type AlbumUserResponseDto = {
role: AlbumUserRole;
user: UserResponseDto;
};
export type ExifResponseDto = {
city?: string | null;
country?: string | null;
@ -61,24 +83,6 @@ export type ExifResponseDto = {
state?: string | null;
timeZone?: string | null;
};
export type UserResponseDto = {
avatarColor: UserAvatarColor;
createdAt: string;
deletedAt: string | null;
email: string;
id: string;
isAdmin: boolean;
memoriesEnabled?: boolean;
name: string;
oauthId: string;
profileImagePath: string;
quotaSizeInBytes: number | null;
quotaUsageInBytes: number | null;
shouldChangePassword: boolean;
status: UserStatus;
storageLabel: string | null;
updatedAt: string;
};
export type AssetFaceWithoutPersonResponseDto = {
boundingBoxX1: number;
boundingBoxX2: number;
@ -144,6 +148,7 @@ export type AssetResponseDto = {
export type AlbumResponseDto = {
albumName: string;
albumThumbnailAssetId: string | null;
albumUsers: AlbumUserResponseDto[];
assetCount: number;
assets: AssetResponseDto[];
createdAt: string;
@ -157,6 +162,7 @@ export type AlbumResponseDto = {
owner: UserResponseDto;
ownerId: string;
shared: boolean;
/** Deprecated in favor of albumUsers */
sharedUsers: UserResponseDto[];
startDate?: string;
updatedAt: string;
@ -187,8 +193,17 @@ export type BulkIdResponseDto = {
id: string;
success: boolean;
};
export type UpdateAlbumUserDto = {
role: AlbumUserRole;
};
export type AlbumUserAddDto = {
role?: AlbumUserRole;
userId: string;
};
export type AddUsersDto = {
sharedUserIds: string[];
albumUsers: AlbumUserAddDto[];
/** Deprecated in favor of albumUsers */
sharedUserIds?: string[];
};
export type ApiKeyResponseDto = {
createdAt: string;
@ -1209,6 +1224,17 @@ export function removeUserFromAlbum({ id, userId }: {
method: "DELETE"
}));
}
export function updateAlbumUser({ id, userId, updateAlbumUserDto }: {
id: string;
userId: string;
updateAlbumUserDto: UpdateAlbumUserDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText(`/album/${encodeURIComponent(id)}/user/${encodeURIComponent(userId)}`, oazapfts.json({
...opts,
method: "PUT",
body: updateAlbumUserDto
})));
}
export function addUsersToAlbum({ id, addUsersDto }: {
id: string;
addUsersDto: AddUsersDto;
@ -2927,6 +2953,10 @@ export enum UserAvatarColor {
Gray = "gray",
Amber = "amber"
}
export enum AlbumUserRole {
Editor = "editor",
Viewer = "viewer"
}
export enum UserStatus {
Active = "active",
Removing = "removing",