diff --git a/web/apps/photos/src/services/collectionService.ts b/web/apps/photos/src/services/collectionService.ts index 43646c8b45..8877158f3f 100644 --- a/web/apps/photos/src/services/collectionService.ts +++ b/web/apps/photos/src/services/collectionService.ts @@ -1,6 +1,6 @@ import type { User } from "ente-accounts/services/user"; import { encryptMetadataJSON, sharedCryptoWorker } from "ente-base/crypto"; -import { ensureLocalUser } from "ente-base/local-user"; +import { ensureLocalUser } from "ente-accounts/services/user"; import log from "ente-base/log"; import { apiURL } from "ente-base/origins"; import { UpdateMagicMetadataRequest } from "ente-gallery/services/file"; diff --git a/web/packages/accounts/services/session.ts b/web/packages/accounts/services/session.ts index ac6263395d..53abbdc4f7 100644 --- a/web/packages/accounts/services/session.ts +++ b/web/packages/accounts/services/session.ts @@ -1,14 +1,18 @@ import type { KeyAttributes } from "ente-accounts/services/user"; import { authenticatedRequestHeaders, HTTPError } from "ente-base/http"; -import { ensureLocalUser, getAuthToken } from "ente-base/local-user"; import log from "ente-base/log"; import { apiURL } from "ente-base/origins"; +import { getAuthToken } from "ente-base/token"; import { getData } from "ente-shared/storage/localStorage"; import { nullToUndefined } from "ente-utils/transform"; import { z } from "zod/v4"; import type { SRPAttributes } from "./srp-remote"; import { getSRPAttributes } from "./srp-remote"; -import { putUserKeyAttributes, RemoteKeyAttributes } from "./user"; +import { + ensureLocalUser, + putUserKeyAttributes, + RemoteKeyAttributes, +} from "./user"; type SessionValidity = | { status: "invalid" } diff --git a/web/packages/accounts/services/user.ts b/web/packages/accounts/services/user.ts index effb1e8f0a..440fc01045 100644 --- a/web/packages/accounts/services/user.ts +++ b/web/packages/accounts/services/user.ts @@ -18,6 +18,49 @@ export interface User { twoFactorSessionID: string; } +// TODO: During login the only field present is email. Which makes this +// optionality indicated by these types incorrect. +const LocalUser = z.object({ + /** The user's ID. */ + id: z.number(), + /** The user's email. */ + email: z.string(), + /** + * The user's (plaintext) auth token. + * + * It is used for making API calls on their behalf, by passing this token as + * the value of the X-Auth-Token header in the HTTP request. + */ + token: z.string(), +}); + +/** Locally available data for the logged in user */ +export type LocalUser = z.infer; + +/** + * Return the logged-in user, if someone is indeed logged in. Otherwise return + * `undefined`. + * + * The user's data is stored in the browser's localStorage. Thus, this function + * only works from the main thread, not from web workers (local storage is not + * accessible to web workers). + */ +export const localUser = (): LocalUser | undefined => { + // TODO: duplicate of getData("user") + const s = localStorage.getItem("user"); + if (!s) return undefined; + return LocalUser.parse(JSON.parse(s)); +}; + +/** + * A wrapper over {@link localUser} with that throws if no one is logged in. + */ +export const ensureLocalUser = (): LocalUser => { + const user = localUser(); + if (!user) throw new Error("Not logged in"); + return user; +}; + /** * The user's various encrypted keys and their related attributes. * diff --git a/web/packages/base/http.ts b/web/packages/base/http.ts index 9c073df3e0..2b8e189b74 100644 --- a/web/packages/base/http.ts +++ b/web/packages/base/http.ts @@ -2,8 +2,8 @@ import { desktopAppVersion, isDesktop } from "ente-base/app"; import { wait } from "ente-utils/promise"; import { z } from "zod/v4"; import { clientPackageName } from "./app"; -import { ensureAuthToken } from "./local-user"; import log from "./log"; +import { ensureAuthToken } from "./token"; /** * Return headers that should be passed alongwith (almost) all authenticated diff --git a/web/packages/base/local-user.ts b/web/packages/base/local-user.ts deleted file mode 100644 index 33dbcab27e..0000000000 --- a/web/packages/base/local-user.ts +++ /dev/null @@ -1,71 +0,0 @@ -// TODO: This file belongs to the accounts package - -import { z } from "zod/v4"; -import { getKVS } from "./kv"; - -// TODO: During login the only field present is email. Which makes this -// optionality indicated by these types incorrect. -const LocalUser = z.object({ - /** The user's ID. */ - id: z.number(), - /** The user's email. */ - email: z.string(), - /** - * The user's (plaintext) auth token. - * - * It is used for making API calls on their behalf, by passing this token as - * the value of the X-Auth-Token header in the HTTP request. - */ - token: z.string(), -}); - -/** Locally available data for the logged in user */ -export type LocalUser = z.infer; - -/** - * Return the logged-in user, if someone is indeed logged in. Otherwise return - * `undefined`. - * - * The user's data is stored in the browser's localStorage. Thus, this function - * only works from the main thread, not from web workers (local storage is not - * accessible to web workers). - */ -export const localUser = (): LocalUser | undefined => { - // TODO: duplicate of getData("user") - const s = localStorage.getItem("user"); - if (!s) return undefined; - return LocalUser.parse(JSON.parse(s)); -}; - -/** - * A wrapper over {@link localUser} with that throws if no one is logged in. - */ -export const ensureLocalUser = (): LocalUser => { - const user = localUser(); - if (!user) throw new Error("Not logged in"); - return user; -}; - -/** - * Return the user's auth token, if present. - * - * The user's auth token is stored in KV DB after they have successfully logged - * in. This function returns that saved auth token. - * - * The underlying data is stored in IndexedDB, and can be accessed from web - * workers. - */ -export const getAuthToken = () => getKVS("token"); - -/** - * Return the user's auth token, or throw an error. - * - * The user's auth token can be retrieved using {@link getAuthToken}. This - * function is a wrapper which throws an error if the token is not found (which - * should only happen if the user is not logged in). - */ -export const ensureAuthToken = async () => { - const token = await getAuthToken(); - if (!token) throw new Error("Not logged in"); - return token; -}; diff --git a/web/packages/base/token.ts b/web/packages/base/token.ts new file mode 100644 index 0000000000..f23d7866c7 --- /dev/null +++ b/web/packages/base/token.ts @@ -0,0 +1,25 @@ +import { getKVS } from "./kv"; + +/** + * Return the user's auth token, if present. + * + * The user's auth token is stored in KV DB after they have successfully logged + * in. This function returns that saved auth token. + * + * The underlying data is stored in IndexedDB, and can be accessed from web + * workers. + */ +export const getAuthToken = () => getKVS("token"); + +/** + * Return the user's auth token, or throw an error. + * + * The user's auth token can be retrieved using {@link getAuthToken}. This + * function is a wrapper which throws an error if the token is not found (which + * should only happen if the user is not logged in). + */ +export const ensureAuthToken = async () => { + const token = await getAuthToken(); + if (!token) throw new Error("Not logged in"); + return token; +}; diff --git a/web/packages/gallery/components/viewer/FileViewer.tsx b/web/packages/gallery/components/viewer/FileViewer.tsx index 2bae740a44..076cee8b6c 100644 --- a/web/packages/gallery/components/viewer/FileViewer.tsx +++ b/web/packages/gallery/components/viewer/FileViewer.tsx @@ -17,6 +17,7 @@ import { Typography, type ModalProps, } from "@mui/material"; +import type { LocalUser } from "ente-accounts/services/user"; import { isDesktop } from "ente-base/app"; import { SpacedRow } from "ente-base/components/containers"; import { InlineErrorIndicator } from "ente-base/components/ErrorIndicator"; @@ -29,7 +30,6 @@ import { type ModalVisibilityProps } from "ente-base/components/utils/modal"; import { useBaseContext } from "ente-base/context"; import { lowercaseExtension } from "ente-base/file-name"; import { formattedListJoin, ut } from "ente-base/i18n"; -import type { LocalUser } from "ente-base/local-user"; import log from "ente-base/log"; import { FileInfo, diff --git a/web/packages/gallery/services/download.ts b/web/packages/gallery/services/download.ts index 3da489fd90..b847b26326 100644 --- a/web/packages/gallery/services/download.ts +++ b/web/packages/gallery/services/download.ts @@ -12,9 +12,9 @@ import { retryEnsuringHTTPOk, type PublicAlbumsCredentials, } from "ente-base/http"; -import { ensureAuthToken } from "ente-base/local-user"; import log from "ente-base/log"; import { apiURL, customAPIOrigin } from "ente-base/origins"; +import { ensureAuthToken } from "ente-base/token"; import type { EnteFile } from "ente-media/file"; import { FileType } from "ente-media/file-type"; import { decodeLivePhoto } from "ente-media/live-photo"; diff --git a/web/packages/gallery/services/video.ts b/web/packages/gallery/services/video.ts index 0587ebc3af..7348ad028d 100644 --- a/web/packages/gallery/services/video.ts +++ b/web/packages/gallery/services/video.ts @@ -1,3 +1,4 @@ +import { ensureLocalUser } from "ente-accounts/services/user"; import { isDesktop } from "ente-base/app"; import { assertionFailed } from "ente-base/assert"; import { decryptBlobBytes, encryptBlob } from "ente-base/crypto"; @@ -5,9 +6,9 @@ import type { EncryptedBlob } from "ente-base/crypto/types"; import { ensureElectron } from "ente-base/electron"; import { isHTTP4xxError, type PublicAlbumsCredentials } from "ente-base/http"; import { getKV, getKVB, getKVN, setKV } from "ente-base/kv"; -import { ensureAuthToken, ensureLocalUser } from "ente-base/local-user"; import log from "ente-base/log"; import { apiURL } from "ente-base/origins"; +import { ensureAuthToken } from "ente-base/token"; import { fileLogID, type EnteFile } from "ente-media/file"; import { filePublicMagicMetadata, diff --git a/web/packages/new/photos/services/dedup.ts b/web/packages/new/photos/services/dedup.ts index 52ab0eb592..ba6538cbe7 100644 --- a/web/packages/new/photos/services/dedup.ts +++ b/web/packages/new/photos/services/dedup.ts @@ -1,6 +1,6 @@ import { assertionFailed } from "ente-base/assert"; import { newID } from "ente-base/id"; -import { ensureLocalUser } from "ente-base/local-user"; +import { ensureLocalUser } from "ente-accounts/services/user"; import type { EnteFile } from "ente-media/file"; import { filePublicMagicMetadata, diff --git a/web/packages/new/photos/services/settings.ts b/web/packages/new/photos/services/settings.ts index add0b72dd5..3d3649d211 100644 --- a/web/packages/new/photos/services/settings.ts +++ b/web/packages/new/photos/services/settings.ts @@ -2,8 +2,8 @@ * @file Storage (in-memory, local, remote) and update of various settings. */ +import { localUser } from "ente-accounts/services/user"; import { isDevBuild } from "ente-base/env"; -import { localUser } from "ente-base/local-user"; import log from "ente-base/log"; import { updateShouldDisableCFUploadProxy } from "ente-gallery/services/upload"; import { nullToUndefined } from "ente-utils/transform";