mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
refactor: auth manager (#27638)
This commit is contained in:
@@ -6,11 +6,9 @@ import AlbumAddUsersModal from '$lib/modals/AlbumAddUsersModal.svelte';
|
||||
import AlbumOptionsModal from '$lib/modals/AlbumOptionsModal.svelte';
|
||||
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { createAlbumAndRedirect } from '$lib/utils/album-utils';
|
||||
import { downloadArchive } from '$lib/utils/asset-utils';
|
||||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
import {
|
||||
@@ -32,7 +30,6 @@ import {
|
||||
import { modalManager, toastManager, type ActionItem } from '@immich/ui';
|
||||
import { mdiLink, mdiPlus, mdiPlusBoxOutline, mdiShareVariantOutline, mdiUpload } from '@mdi/js';
|
||||
import { type MessageFormatter } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
export const getAlbumsActions = ($t: MessageFormatter) => {
|
||||
const Create: ActionItem = {
|
||||
@@ -45,7 +42,7 @@ export const getAlbumsActions = ($t: MessageFormatter) => {
|
||||
};
|
||||
|
||||
export const getAlbumActions = ($t: MessageFormatter, album: AlbumResponseDto) => {
|
||||
const isOwned = get(user).id === album.ownerId;
|
||||
const isOwned = authManager.user.id === album.ownerId;
|
||||
|
||||
const Share: ActionItem = {
|
||||
title: $t('share'),
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||
import { getAssetActions, handleDownloadAsset } from '$lib/services/asset.service';
|
||||
import { user as userStore } from '$lib/stores/user.store';
|
||||
import { setSharedLink } from '$lib/utils';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
import { getAssetInfo } from '@immich/sdk';
|
||||
import { toastManager } from '@immich/ui';
|
||||
import { assetFactory } from '@test-data/factories/asset-factory';
|
||||
import { preferencesFactory } from '@test-data/factories/preferences-factory';
|
||||
import { sharedLinkFactory } from '@test-data/factories/shared-link-factory';
|
||||
import { userAdminFactory } from '@test-data/factories/user-factory';
|
||||
import { vitest } from 'vitest';
|
||||
@@ -32,11 +33,15 @@ vitest.mock('$lib/utils', async () => {
|
||||
|
||||
describe('AssetService', () => {
|
||||
describe('getAssetActions', () => {
|
||||
beforeEach(() => {
|
||||
authManager.setPreferences(preferencesFactory.build());
|
||||
});
|
||||
|
||||
it('should allow shared link downloads if the user owns the asset and shared link downloads are disabled', () => {
|
||||
const ownerId = 'owner';
|
||||
const user = userAdminFactory.build({ id: ownerId });
|
||||
const asset = assetFactory.build({ ownerId });
|
||||
userStore.set(user);
|
||||
authManager.setUser(user);
|
||||
setSharedLink(sharedLinkFactory.build({ allowDownload: false }));
|
||||
const assetActions = getAssetActions(() => '', asset);
|
||||
expect(assetActions.SharedLinkDownload.$if?.()).toStrictEqual(true);
|
||||
@@ -46,7 +51,7 @@ describe('AssetService', () => {
|
||||
const ownerId = 'owner';
|
||||
const user = userAdminFactory.build({ id: 'non-owner' });
|
||||
const asset = assetFactory.build({ ownerId });
|
||||
userStore.set(user);
|
||||
authManager.setUser(user);
|
||||
setSharedLink(sharedLinkFactory.build({ allowDownload: false }));
|
||||
const assetActions = getAssetActions(() => '', asset);
|
||||
expect(assetActions.SharedLinkDownload.$if?.()).toStrictEqual(false);
|
||||
|
||||
@@ -6,7 +6,6 @@ import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||
import AssetAddToAlbumModal from '$lib/modals/AssetAddToAlbumModal.svelte';
|
||||
import AssetTagModal from '$lib/modals/AssetTagModal.svelte';
|
||||
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
||||
import { user as authUser, preferences } from '$lib/stores/user.store';
|
||||
import { getAssetMediaUrl, getSharedLink, sleep } from '$lib/utils';
|
||||
import { downloadUrl } from '$lib/utils/asset-utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
@@ -46,7 +45,6 @@ import {
|
||||
mdiTune,
|
||||
} from '@mdi/js';
|
||||
import type { MessageFormatter } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
export const getAssetBulkActions = ($t: MessageFormatter) => {
|
||||
const ownedAssets = assetMultiSelectManager.ownedAssets;
|
||||
@@ -95,15 +93,14 @@ export const getAssetBulkActions = ($t: MessageFormatter) => {
|
||||
|
||||
export const getAssetActions = ($t: MessageFormatter, asset: AssetResponseDto) => {
|
||||
const sharedLink = getSharedLink();
|
||||
const currentAuthUser = get(authUser);
|
||||
const userPreferences = get(preferences);
|
||||
const isOwner = !!(currentAuthUser && currentAuthUser.id === asset.ownerId);
|
||||
const authUser = authManager.authenticated ? authManager.user : undefined;
|
||||
const isOwner = !!(authUser && authUser.id === asset.ownerId);
|
||||
|
||||
const Share: ActionItem = {
|
||||
title: $t('share'),
|
||||
icon: mdiShareVariantOutline,
|
||||
type: $t('assets'),
|
||||
$if: () => !!(currentAuthUser && !asset.isTrashed && asset.visibility !== AssetVisibility.Locked),
|
||||
$if: () => !!(authUser && !asset.isTrashed && asset.visibility !== AssetVisibility.Locked),
|
||||
onAction: () => modalManager.show(SharedLinkCreateModal, { assetIds: [asset.id] }),
|
||||
};
|
||||
|
||||
@@ -112,7 +109,7 @@ export const getAssetActions = ($t: MessageFormatter, asset: AssetResponseDto) =
|
||||
icon: mdiDownload,
|
||||
shortcuts: { key: 'd', shift: true },
|
||||
type: $t('assets'),
|
||||
$if: () => !!currentAuthUser,
|
||||
$if: () => !!authUser,
|
||||
onAction: () => handleDownloadAsset(asset, { edited: true }),
|
||||
};
|
||||
|
||||
@@ -120,7 +117,7 @@ export const getAssetActions = ($t: MessageFormatter, asset: AssetResponseDto) =
|
||||
title: $t('download_original'),
|
||||
icon: mdiDownloadBox,
|
||||
type: $t('assets'),
|
||||
$if: () => !!currentAuthUser && asset.isEdited,
|
||||
$if: () => !!authUser && asset.isEdited,
|
||||
onAction: () => handleDownloadAsset(asset, { edited: false }),
|
||||
};
|
||||
|
||||
@@ -218,7 +215,7 @@ export const getAssetActions = ($t: MessageFormatter, asset: AssetResponseDto) =
|
||||
title: $t('add_tag'),
|
||||
icon: mdiTagPlusOutline,
|
||||
type: $t('assets'),
|
||||
$if: () => userPreferences.tags.enabled,
|
||||
$if: () => authManager.authenticated && authManager.preferences.tags.enabled,
|
||||
onAction: () => modalManager.show(AssetTagModal, { assetIds: [asset.id] }),
|
||||
shortcuts: { key: 't' },
|
||||
};
|
||||
@@ -315,7 +312,10 @@ export const handleDownloadAsset = async (asset: AssetResponseDto, { edited }: {
|
||||
|
||||
if (asset.livePhotoVideoId) {
|
||||
const motionAsset = await getAssetInfo({ ...authManager.params, id: asset.livePhotoVideoId });
|
||||
if (!isAndroidMotionVideo(motionAsset) || get(preferences)?.download.includeEmbeddedVideos) {
|
||||
if (
|
||||
!isAndroidMotionVideo(motionAsset) ||
|
||||
(authManager.authenticated && authManager.preferences.download.includeEmbeddedVideos)
|
||||
) {
|
||||
const motionFilename = motionAsset.originalFileName;
|
||||
const lastDotIndex = motionFilename.lastIndexOf('.');
|
||||
const motionDownloadFilename =
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
|
||||
import PasswordResetSuccessModal from '$lib/modals/PasswordResetSuccessModal.svelte';
|
||||
import UserDeleteConfirmModal from '$lib/modals/UserDeleteConfirmModal.svelte';
|
||||
import UserRestoreConfirmModal from '$lib/modals/UserRestoreConfirmModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { user as authUser } from '$lib/stores/user.store';
|
||||
import type { HeaderButtonActionItem } from '$lib/types';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
@@ -32,7 +32,6 @@ import {
|
||||
} from '@mdi/js';
|
||||
import { DateTime } from 'luxon';
|
||||
import type { MessageFormatter } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
export const getUserAdminsActions = ($t: MessageFormatter) => {
|
||||
const Create: ActionItem = {
|
||||
@@ -64,7 +63,7 @@ export const getUserAdminActions = ($t: MessageFormatter, user: UserAdminRespons
|
||||
title: $t('delete'),
|
||||
type: $t('command'),
|
||||
color: 'danger',
|
||||
$if: () => get(authUser).id !== user.id && !user.deletedAt,
|
||||
$if: () => authManager.user.id !== user.id && !user.deletedAt,
|
||||
onAction: () => modalManager.show(UserDeleteConfirmModal, { user }),
|
||||
shortcuts: { key: 'Backspace' },
|
||||
shortcutOptions: { ignoreInputFields: true },
|
||||
@@ -89,7 +88,7 @@ export const getUserAdminActions = ($t: MessageFormatter, user: UserAdminRespons
|
||||
icon: mdiLockReset,
|
||||
title: $t('reset_password'),
|
||||
type: $t('command'),
|
||||
$if: () => get(authUser).id !== user.id,
|
||||
$if: () => authManager.user.id !== user.id,
|
||||
onAction: () => handleResetPasswordUserAdmin(user),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user