refactor: auth manager (#27638)

This commit is contained in:
Jason Rasmussen
2026-04-14 08:49:24 -04:00
committed by GitHub
parent daed3f0966
commit 1ba0989e15
77 changed files with 387 additions and 379 deletions
@@ -2,7 +2,9 @@ import { getAnimateMock } from '$lib/__mocks__/animate.mock';
import { getIntersectionObserverMock } from '$lib/__mocks__/intersection-observer.mock';
import { sdkMock } from '$lib/__mocks__/sdk.mock';
import { getVisualViewportMock } from '$lib/__mocks__/visual-viewport.mock';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { calcNewDate } from '$lib/modals/timezone-utils';
import { userAdminFactory } from '@test-data/factories/user-factory';
import { fireEvent, render, screen, waitFor } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import { DateTime } from 'luxon';
@@ -25,6 +27,8 @@ describe('DateSelectionModal component', () => {
vi.stubGlobal('visualViewport', getVisualViewportMock());
vi.resetAllMocks();
Element.prototype.animate = getAnimateMock();
authManager.setUser(userAdminFactory.build());
});
afterAll(async () => {
@@ -2,9 +2,9 @@
import Combobox from '$lib/components/shared-components/combobox.svelte';
import DateInput from '$lib/elements/DateInput.svelte';
import DurationInput from '$lib/elements/DurationInput.svelte';
import { authManager } from '$lib/managers/auth-manager.svelte';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
import { getPreferredTimeZone, getTimezones, toIsoDate, type ZoneOption } from '$lib/modals/timezone-utils';
import { user } from '$lib/stores/user.store';
import { getOwnedAssetsWithWarning } from '$lib/utils/asset-utils';
import { handleError } from '$lib/utils/handle-error';
import { updateAssets } from '@immich/sdk';
@@ -31,7 +31,7 @@
let selectedOption = $derived(getPreferredTimeZone(initialDate, initialTimeZone, timezones, lastSelectedTimezone));
const onSubmit = async () => {
const ids = getOwnedAssetsWithWarning(assets, $user);
const ids = getOwnedAssetsWithWarning(assets, authManager.user);
try {
if (showRelative && (selectedDuration || selectedOption)) {
await updateAssets({
+9 -4
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
import { user } from '$lib/stores/user.store';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { handleError } from '$lib/utils/handle-error';
import { deleteProfileImage, updateMyUser, UserAvatarColor } from '@immich/sdk';
import { Modal, ModalBody, toastManager } from '@immich/ui';
@@ -16,13 +16,14 @@
const onSave = async (color: UserAvatarColor) => {
try {
if ($user.profileImagePath !== '') {
if (authManager.user.profileImagePath !== '') {
await deleteProfileImage();
}
toastManager.primary($t('saved_profile'));
$user = await updateMyUser({ userUpdateMeDto: { avatarColor: color } });
const response = await updateMyUser({ userUpdateMeDto: { avatarColor: color } });
authManager.setUser(response);
onClose();
} catch (error) {
handleError(error, $t('errors.unable_to_save_profile'));
@@ -35,7 +36,11 @@
<div class="grid grid-cols-2 sm:grid-cols-5 gap-4 place-items-center">
{#each colors as color (color)}
<button type="button" onclick={() => onSave(color)}>
<UserAvatar label={color} user={{ ...$user, profileImagePath: '', avatarColor: color }} size="xl" />
<UserAvatar
label={color}
user={{ ...authManager.user, profileImagePath: '', avatarColor: color }}
size="xl"
/>
</button>
{/each}
</div>
@@ -1,15 +1,15 @@
<script lang="ts">
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { getPartners, PartnerDirection, searchUsers, type UserResponseDto } from '@immich/sdk';
import { Button, ListButton, LoadingSpinner, Modal, ModalBody, ModalFooter, Text } from '@immich/ui';
import { t } from 'svelte-i18n';
interface Props {
user: UserResponseDto;
onClose: (users?: UserResponseDto[]) => void;
}
let { user, onClose }: Props = $props();
let { onClose }: Props = $props();
let availableUsers: UserResponseDto[] = $state([]);
let selectedUsers: UserResponseDto[] = $state([]);
@@ -18,7 +18,7 @@
let users = await searchUsers();
// remove current user
users = users.filter((_user) => _user.id !== user.id);
users = users.filter(({ id }) => id !== authManager.user.id);
// exclude partners from the list of users available for selection
const partners = await getPartners({ direction: PartnerDirection.SharedBy });
@@ -1,5 +1,5 @@
<script lang="ts">
import { user } from '$lib/stores/user.store';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { handleError } from '$lib/utils/handle-error';
import { createProfileImage, type AssetResponseDto } from '@immich/sdk';
import { FormModal, toastManager } from '@immich/ui';
@@ -68,10 +68,10 @@
return;
}
const file = new File([blob], 'profile-picture.png', { type: 'image/png' });
const { profileImagePath, profileChangedAt } = await createProfileImage({ createProfileImageDto: { file } });
await createProfileImage({ createProfileImageDto: { file } });
toastManager.primary($t('profile_picture_set'));
$user.profileImagePath = profileImagePath;
$user.profileChangedAt = profileChangedAt;
await authManager.refresh();
onClose();
} catch (error) {
+2 -2
View File
@@ -9,7 +9,7 @@
import SearchTagsSection from '$lib/components/shared-components/search-bar/search-tags-section.svelte';
import SearchTextSection from '$lib/components/shared-components/search-bar/search-text-section.svelte';
import { MediaType, QueryType, validQueryTypes } from '$lib/constants';
import { preferences } from '$lib/stores/user.store';
import { authManager } from '$lib/managers/auth-manager.svelte';
import type { SearchFilter } from '$lib/types';
import { parseUtcDate } from '$lib/utils/date-time';
import { generateId } from '$lib/utils/generate-id';
@@ -193,7 +193,7 @@
<SearchDateSection bind:filters={filter.date} />
<!-- RATING -->
{#if $preferences?.ratings.enabled}
{#if authManager.authenticated && authManager.preferences.ratings.enabled}
<SearchRatingsSection bind:rating={filter.rating} />
{/if}
+2 -2
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { preferences } from '$lib/stores/user.store';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { Icon, Modal, ModalBody } from '@immich/ui';
import { mdiInformationOutline } from '@mdi/js';
import { t } from 'svelte-i18n';
@@ -45,7 +45,7 @@
{ key: ['⇧', 'd'], action: $t('download') },
{ key: ['Space'], action: $t('play_or_pause_video') },
{ key: ['Del'], action: $t('trash_delete_asset'), info: $t('shift_to_permanent_delete') },
...($preferences?.ratings.enabled
...(authManager.authenticated && authManager.preferences.ratings.enabled
? [{ key: ['1-5'], action: $t('rate_asset'), info: $t('zero_to_clear_rating') }]
: []),
],