mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat: lock auth session (#18322)
This commit is contained in:
parent
ecb66fdb2c
commit
c1150fe7e3
37 changed files with 765 additions and 123 deletions
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import ChangeDate from '$lib/components/photos-page/actions/change-date-action.svelte';
|
||||
import ChangeLocation from '$lib/components/photos-page/actions/change-location-action.svelte';
|
||||
|
|
@ -10,11 +11,12 @@
|
|||
import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
|
||||
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import { AssetAction } from '$lib/constants';
|
||||
import { AppRoute, AssetAction } from '$lib/constants';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetStore } from '$lib/stores/assets-store.svelte';
|
||||
import { AssetVisibility } from '@immich/sdk';
|
||||
import { mdiDotsVertical } from '@mdi/js';
|
||||
import { AssetVisibility, lockAuthSession } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
import { mdiDotsVertical, mdiLockOutline } from '@mdi/js';
|
||||
import { onDestroy } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import type { PageData } from './$types';
|
||||
|
|
@ -42,6 +44,11 @@
|
|||
assetInteraction.clearMultiselect();
|
||||
assetStore.removeAssets(assetIds);
|
||||
};
|
||||
|
||||
const handleLock = async () => {
|
||||
await lockAuthSession();
|
||||
await goto(AppRoute.PHOTOS);
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Multi-selection mode app bar -->
|
||||
|
|
@ -62,6 +69,12 @@
|
|||
{/if}
|
||||
|
||||
<UserPageLayout hideNavbar={assetInteraction.selectionActive} title={data.meta.title} scrollbar={false}>
|
||||
{#snippet buttons()}
|
||||
<Button size="small" variant="filled" color="warning" leadingIcon={mdiLockOutline} onclick={handleLock}>
|
||||
{$t('lock')}
|
||||
</Button>
|
||||
{/snippet}
|
||||
|
||||
<AssetGrid
|
||||
enableRouting={true}
|
||||
{assetStore}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,12 @@ import type { PageLoad } from './$types';
|
|||
|
||||
export const load = (async ({ params, url }) => {
|
||||
await authenticate(url);
|
||||
|
||||
const { isElevated, pinCode } = await getAuthStatus();
|
||||
|
||||
if (!isElevated || !pinCode) {
|
||||
const continuePath = encodeURIComponent(url.pathname);
|
||||
const redirectPath = `${AppRoute.AUTH_PIN_PROMPT}?continue=${continuePath}`;
|
||||
|
||||
redirect(302, redirectPath);
|
||||
redirect(302, `${AppRoute.AUTH_PIN_PROMPT}?continue=${encodeURIComponent(url.pathname + url.search)}`);
|
||||
}
|
||||
|
||||
const asset = await getAssetInfoFromParam(params);
|
||||
const $t = await getFormatter();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@
|
|||
import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte';
|
||||
import PinCodeCreateForm from '$lib/components/user-settings-page/PinCodeCreateForm.svelte';
|
||||
import PincodeInput from '$lib/components/user-settings-page/PinCodeInput.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { verifyPinCode } from '@immich/sdk';
|
||||
import { unlockAuthSession } from '@immich/sdk';
|
||||
import { Icon } from '@immich/ui';
|
||||
import { mdiLockOpenVariantOutline, mdiLockOutline, mdiLockSmart } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
|
@ -23,17 +22,15 @@
|
|||
let hasPinCode = $derived(data.hasPinCode);
|
||||
let pinCode = $state('');
|
||||
|
||||
const onPinFilled = async (code: string, withDelay = false) => {
|
||||
const handleUnlockSession = async (code: string) => {
|
||||
try {
|
||||
await verifyPinCode({ pinCodeSetupDto: { pinCode: code } });
|
||||
await unlockAuthSession({ sessionUnlockDto: { pinCode: code } });
|
||||
|
||||
isVerified = true;
|
||||
|
||||
if (withDelay) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
|
||||
void goto(data.continuePath ?? AppRoute.LOCKED);
|
||||
await goto(data.continueUrl);
|
||||
} catch (error) {
|
||||
handleError(error, $t('wrong_pin_code'));
|
||||
isBadPinCode = true;
|
||||
|
|
@ -64,7 +61,7 @@
|
|||
bind:value={pinCode}
|
||||
tabindexStart={1}
|
||||
pinLength={6}
|
||||
onFilled={(pinCode) => onPinFilled(pinCode, true)}
|
||||
onFilled={handleUnlockSession}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { AppRoute } from '$lib/constants';
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
import { getAuthStatus } from '@immich/sdk';
|
||||
|
|
@ -8,8 +9,6 @@ export const load = (async ({ url }) => {
|
|||
|
||||
const { pinCode } = await getAuthStatus();
|
||||
|
||||
const continuePath = url.searchParams.get('continue');
|
||||
|
||||
const $t = await getFormatter();
|
||||
|
||||
return {
|
||||
|
|
@ -17,6 +16,6 @@ export const load = (async ({ url }) => {
|
|||
title: $t('pin_verification'),
|
||||
},
|
||||
hasPinCode: !!pinCode,
|
||||
continuePath,
|
||||
continueUrl: url.searchParams.get('continue') || AppRoute.LOCKED,
|
||||
};
|
||||
}) satisfies PageLoad;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue