diff --git a/web/apps/photos/src/components/Sidebar/index.tsx b/web/apps/photos/src/components/Sidebar/index.tsx index 92a69b1ae1..489536e085 100644 --- a/web/apps/photos/src/components/Sidebar/index.tsx +++ b/web/apps/photos/src/components/Sidebar/index.tsx @@ -83,7 +83,6 @@ import { } from "utils/billing"; import { openLink } from "utils/common"; import { getDownloadAppMessage } from "utils/ui"; -import { isInternalUser } from "utils/user"; import { isFamilyAdmin, isPartOfFamily } from "utils/user/family"; import { testUpload } from "../../../tests/upload.test"; import { MemberSubscriptionManage } from "../MemberSubscriptionManage"; @@ -553,7 +552,7 @@ const UtilitySection: React.FC = ({ closeSidebar }) => { onClick={openRecoveryKeyModal} label={t("RECOVERY_KEY")} /> - {isInternalUser() && ( + {isInternalUserViaEmailCheck() && ( = ({ closeSidebar }) => { label={t("TWO_FACTOR")} /> - {isInternalUser() && ( + {isInternalUserViaEmailCheck() && ( { {appVersion} )} - {isInternalUser() && ( + {isInternalUserViaEmailCheck() && ( { ); }; + +// TODO: Legacy synchronous check, use the one for feature-flags.ts instead. +const isInternalUserViaEmailCheck = () => { + const userEmail = getData(LS_KEYS.USER)?.email; + if (!userEmail) return false; + + return userEmail.endsWith("@ente.io"); +}; diff --git a/web/apps/photos/src/pages/gallery/index.tsx b/web/apps/photos/src/pages/gallery/index.tsx index 130c66141b..d63a33c14e 100644 --- a/web/apps/photos/src/pages/gallery/index.tsx +++ b/web/apps/photos/src/pages/gallery/index.tsx @@ -1,3 +1,4 @@ +import { fetchAndSaveFeatureFlagsIfNeeded } from "@/new/photos/services/feature-flags"; import log from "@/next/log"; import { APPS } from "@ente/shared/apps/constants"; import { CenteredFlex } from "@ente/shared/components/Container"; @@ -87,7 +88,6 @@ import { import downloadManager from "services/download"; import { syncCLIPEmbeddings } from "services/embeddingService"; import { syncEntities } from "services/entityService"; -import { fetchAndSaveFeatureFlagsIfNeeded } from "@/new/photos/services/feature-flags"; import { getLocalFiles, syncFiles } from "services/fileService"; import locationSearchService from "services/locationSearchService"; import { getLocalTrashedFiles, syncTrash } from "services/trashService"; @@ -720,7 +720,7 @@ export default function Gallery() { await syncCLIPEmbeddings(); // TODO-ML(MR): Disable fetch until we start storing it in the // same place as the local ones. - // if (isInternalUserForML()) await syncFaceEmbeddings(); + // if (isFaceIndexingEnabled()) await syncFaceEmbeddings(); } if (clipService.isPlatformSupported()) { void clipService.scheduleImageEmbeddingExtraction(); diff --git a/web/apps/photos/src/services/face/indexer.ts b/web/apps/photos/src/services/face/indexer.ts index b49c4dc053..5314a15e0b 100644 --- a/web/apps/photos/src/services/face/indexer.ts +++ b/web/apps/photos/src/services/face/indexer.ts @@ -7,7 +7,6 @@ import { ensure } from "@/utils/ensure"; import type { Remote } from "comlink"; import { getAllLocalFiles } from "services/fileService"; import type { EnteFile } from "types/file"; -import { isInternalUserForML } from "utils/user"; import { faceIndex, indexableFileIDs, @@ -202,7 +201,7 @@ export const unidentifiedFaceIDs = async ( * face search in the UI. */ export const canEnableFaceIndexing = async () => - isInternalUserForML() || (await isInternalUser()) || (await isBetaUser()); + (await isInternalUser()) || (await isBetaUser()); /** * Return true if the user has enabled face indexing in the app's settings. diff --git a/web/apps/photos/src/utils/user/index.ts b/web/apps/photos/src/utils/user/index.ts index 0f8ef142fb..adb463b502 100644 --- a/web/apps/photos/src/utils/user/index.ts +++ b/web/apps/photos/src/utils/user/index.ts @@ -1,21 +1,7 @@ import { getData, LS_KEYS } from "@ente/shared/storage/localStorage"; -import type { User } from "@ente/shared/user/types"; import { UserDetails } from "types/user"; export function getLocalUserDetails(): UserDetails { return getData(LS_KEYS.USER_DETAILS)?.value; } -export const isInternalUser = () => { - const userEmail = getData(LS_KEYS.USER)?.email; - if (!userEmail) return false; - - return userEmail.endsWith("@ente.io"); -}; - -export const isInternalUserForML = () => { - const userID = (getData(LS_KEYS.USER) as User)?.id; - if (userID == 1 || userID == 2) return true; - - return isInternalUser(); -}; diff --git a/web/packages/new/photos/services/feature-flags.ts b/web/packages/new/photos/services/feature-flags.ts index ae71343b98..419c6baf26 100644 --- a/web/packages/new/photos/services/feature-flags.ts +++ b/web/packages/new/photos/services/feature-flags.ts @@ -1,3 +1,5 @@ +import { isDevBuild } from "@/next/env"; +import { localUser } from "@/next/local-user"; import log from "@/next/log"; import { ensure } from "@/utils/ensure"; import { nullToUndefined } from "@/utils/transform"; @@ -105,14 +107,28 @@ const remoteFeatureFlagsFetchingIfNeeded = async () => { /** * Return `true` if the current user is marked as an "internal" user. + * + * 1. Everyone is considered as an internal user in dev builds. + * 2. Emails that end in `@ente.io` are always considered as internal users. + * 3. If the "internalUser" remote feature flag is set, the user is internal. + * 4. Otherwise false. + * + * See also: [Note: Feature Flags]. */ export const isInternalUser = async () => { + if (isDevBuild) return true; + + const user = localUser(); + if (user?.email.endsWith("@ente.io")) return true; + const flags = await remoteFeatureFlagsFetchingIfNeeded(); return flags?.internalUser ?? false; }; /** * Return `true` if the current user is marked as a "beta" user. + * + * See also: [Note: Feature Flags]. */ export const isBetaUser = async () => { const flags = await remoteFeatureFlagsFetchingIfNeeded();