Update
This commit is contained in:
@@ -35,7 +35,7 @@ import { useBaseContext } from "ente-base/context";
|
||||
import log from "ente-base/log";
|
||||
import {
|
||||
clearSessionStorage,
|
||||
haveCredentialsInSession,
|
||||
haveMasterKeyInSession,
|
||||
masterKeyFromSession,
|
||||
} from "ente-base/session";
|
||||
import { savedAuthToken } from "ente-base/token";
|
||||
@@ -282,7 +282,7 @@ const Page: React.FC = () => {
|
||||
let syncIntervalID: ReturnType<typeof setInterval> | undefined;
|
||||
|
||||
void (async () => {
|
||||
if (!haveCredentialsInSession() || !(await savedAuthToken())) {
|
||||
if (!haveMasterKeyInSession() || !(await savedAuthToken())) {
|
||||
// If we don't have master key or auth token, reauthenticate.
|
||||
stashRedirect("/gallery");
|
||||
router.push("/");
|
||||
@@ -376,7 +376,7 @@ const Page: React.FC = () => {
|
||||
}, [activeCollectionID, router.isReady]);
|
||||
|
||||
useEffect(() => {
|
||||
if (router.isReady && haveCredentialsInSession()) {
|
||||
if (router.isReady && haveMasterKeyInSession()) {
|
||||
handleSubscriptionCompletionRedirectIfNeeded(
|
||||
showMiniDialog,
|
||||
showLoadingBar,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { haveCredentialsInSession } from "ente-base/session";
|
||||
import { haveMasterKeyInSession } from "ente-base/session";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect } from "react";
|
||||
import { stashRedirect } from "../../services/redirect";
|
||||
@@ -16,7 +16,7 @@ export const useRedirectIfNeedsCredentials = (currentPageSlug: string) => {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (!haveCredentialsInSession()) {
|
||||
if (!haveMasterKeyInSession()) {
|
||||
stashRedirect(currentPageSlug);
|
||||
void router.push("/");
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
generateSRPSetupAttributes,
|
||||
setupSRP,
|
||||
} from "ente-accounts/services/srp";
|
||||
import type { PartialLocalUser } from "ente-accounts/services/user";
|
||||
import {
|
||||
generateAndSaveInteractiveKeyAttributes,
|
||||
generateKeysAndAttributes,
|
||||
@@ -28,12 +27,12 @@ import { useBaseContext } from "ente-base/context";
|
||||
import { deriveKeyInsufficientMemoryErrorMessage } from "ente-base/crypto/types";
|
||||
import log from "ente-base/log";
|
||||
import {
|
||||
haveCredentialsInSession,
|
||||
haveMasterKeyInSession,
|
||||
saveMasterKeyInSessionAndSafeStore,
|
||||
} from "ente-base/session";
|
||||
import { t } from "i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
NewPasswordForm,
|
||||
type NewPasswordFormProps,
|
||||
@@ -41,79 +40,76 @@ import {
|
||||
|
||||
/**
|
||||
* A page that allows the user to generate key attributes if needed, and shows
|
||||
* them their recovery key.
|
||||
* them their recovery key if they just signed up.
|
||||
*
|
||||
* See: [Note: Login pages]
|
||||
*/
|
||||
const Page: React.FC = () => {
|
||||
const { logout, showMiniDialog } = useBaseContext();
|
||||
|
||||
const [user, setUser] = useState<PartialLocalUser | undefined>(undefined);
|
||||
const [userEmail, setUserEmail] = useState("");
|
||||
const [openRecoveryKey, setOpenRecoveryKey] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const user = savedPartialLocalUser();
|
||||
if (!user?.token) {
|
||||
if (!user?.email || !user?.token) {
|
||||
void router.push("/");
|
||||
} else if (haveCredentialsInSession()) {
|
||||
} else if (haveMasterKeyInSession()) {
|
||||
if (savedJustSignedUp()) {
|
||||
setOpenRecoveryKey(true);
|
||||
setUser(user);
|
||||
} else {
|
||||
void router.push(appHomeRoute);
|
||||
}
|
||||
} else if (savedOriginalKeyAttributes()?.encryptedKey) {
|
||||
} else if (savedOriginalKeyAttributes()) {
|
||||
void router.push("/credentials");
|
||||
} else {
|
||||
setUser(user);
|
||||
setUserEmail(user.email);
|
||||
}
|
||||
}, [router]);
|
||||
|
||||
const handleSubmit: NewPasswordFormProps["onSubmit"] = async (
|
||||
password,
|
||||
setPasswordsFieldError,
|
||||
) => {
|
||||
try {
|
||||
const { masterKey, kek, keyAttributes } =
|
||||
await generateKeysAndAttributes(password);
|
||||
await putUserKeyAttributes(keyAttributes);
|
||||
await setupSRP(await generateSRPSetupAttributes(kek));
|
||||
await generateAndSaveInteractiveKeyAttributes(
|
||||
password,
|
||||
keyAttributes,
|
||||
masterKey,
|
||||
);
|
||||
await saveMasterKeyInSessionAndSafeStore(masterKey);
|
||||
saveJustSignedUp();
|
||||
setOpenRecoveryKey(true);
|
||||
} catch (e) {
|
||||
log.error("failed to generate password", e);
|
||||
setPasswordsFieldError(
|
||||
e instanceof Error &&
|
||||
e.message == deriveKeyInsufficientMemoryErrorMessage
|
||||
? t("password_generation_failed")
|
||||
: t("generic_error"),
|
||||
);
|
||||
}
|
||||
};
|
||||
const handleSubmit: NewPasswordFormProps["onSubmit"] = useCallback(
|
||||
async (password, setPasswordsFieldError) => {
|
||||
try {
|
||||
const { masterKey, kek, keyAttributes } =
|
||||
await generateKeysAndAttributes(password);
|
||||
await putUserKeyAttributes(keyAttributes);
|
||||
await setupSRP(await generateSRPSetupAttributes(kek));
|
||||
await generateAndSaveInteractiveKeyAttributes(
|
||||
password,
|
||||
keyAttributes,
|
||||
masterKey,
|
||||
);
|
||||
await saveMasterKeyInSessionAndSafeStore(masterKey);
|
||||
saveJustSignedUp();
|
||||
setOpenRecoveryKey(true);
|
||||
} catch (e) {
|
||||
log.error("Could not generate key attributes from password", e);
|
||||
setPasswordsFieldError(
|
||||
e instanceof Error &&
|
||||
e.message == deriveKeyInsufficientMemoryErrorMessage
|
||||
? t("password_generation_failed")
|
||||
: t("generic_error"),
|
||||
);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!user ? (
|
||||
<LoadingIndicator />
|
||||
) : openRecoveryKey ? (
|
||||
{openRecoveryKey ? (
|
||||
<RecoveryKey
|
||||
open={openRecoveryKey}
|
||||
onClose={() => void router.push(appHomeRoute)}
|
||||
showMiniDialog={showMiniDialog}
|
||||
/>
|
||||
) : (
|
||||
) : userEmail ? (
|
||||
<AccountsPageContents>
|
||||
<AccountsPageTitle>{t("set_password")}</AccountsPageTitle>
|
||||
<NewPasswordForm
|
||||
userEmail={user.email!}
|
||||
userEmail={userEmail}
|
||||
submitButtonTitle={t("set_password")}
|
||||
onSubmit={handleSubmit}
|
||||
/>
|
||||
@@ -122,6 +118,8 @@ const Page: React.FC = () => {
|
||||
<LinkButton onClick={logout}>{t("go_back")}</LinkButton>
|
||||
</AccountsPageFooter>
|
||||
</AccountsPageContents>
|
||||
) : (
|
||||
<LoadingIndicator />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -74,14 +74,17 @@ import React, { useCallback, useEffect, useState } from "react";
|
||||
* complete**.
|
||||
*
|
||||
* - "/generate" - A page that allows the user to generate key attributes if
|
||||
* needed, and shows them their recovery key.
|
||||
* needed, and shows them their recovery key if they just signed up.
|
||||
*
|
||||
* - Redirects to "/" if there is no `email` present in the saved partial
|
||||
* local user, or after viewing the recovery key, or after the user sets
|
||||
* their password (if they did no have key attributes).
|
||||
* - Redirects to "/" if there is no `email` or `token` present in the saved
|
||||
* partial user.
|
||||
*
|
||||
* - Redirects to "/credentials" if they already have the original key
|
||||
* attributes.
|
||||
* - Redirects to `appHomeRoute` after viewing the recovery key if they have a
|
||||
* master key in session, or after setting the password and then viewing the
|
||||
* recovery key (if they did not have a master key in session store).
|
||||
*
|
||||
* - Redirects to "/credentials" if if they don't have a master key in session
|
||||
* store but have saved original key attributes.
|
||||
*
|
||||
* - "/recover" - A page that allows the user to recover their master key using
|
||||
* their recovery key.
|
||||
|
||||
@@ -21,7 +21,7 @@ import { useBaseContext } from "ente-base/context";
|
||||
import { decryptBox } from "ente-base/crypto";
|
||||
import log from "ente-base/log";
|
||||
import {
|
||||
haveCredentialsInSession,
|
||||
haveMasterKeyInSession,
|
||||
saveMasterKeyInSessionAndSafeStore,
|
||||
} from "ente-base/session";
|
||||
import { t } from "i18next";
|
||||
@@ -59,7 +59,7 @@ const Page: React.FC = () => {
|
||||
const keyAttributes = savedKeyAttributes();
|
||||
if (!keyAttributes) {
|
||||
void router.push("/generate");
|
||||
} else if (haveCredentialsInSession()) {
|
||||
} else if (haveMasterKeyInSession()) {
|
||||
void router.push(appHomeRoute);
|
||||
} else {
|
||||
setKeyAttributes(keyAttributes);
|
||||
|
||||
@@ -51,7 +51,7 @@ export const ensureMasterKeyFromSession = async () => {
|
||||
* have credentials at hand or not, however it doesn't attempt to verify that
|
||||
* the key present in the session can actually be decrypted.
|
||||
*/
|
||||
export const haveCredentialsInSession = () =>
|
||||
export const haveMasterKeyInSession = () =>
|
||||
!!sessionStorage.getItem("encryptionKey");
|
||||
|
||||
/**
|
||||
@@ -140,7 +140,7 @@ export const updateSessionFromElectronSafeStorageIfNeeded = async () => {
|
||||
const electron = globalThis.electron;
|
||||
if (!electron) return;
|
||||
|
||||
if (haveCredentialsInSession()) return;
|
||||
if (haveMasterKeyInSession()) return;
|
||||
|
||||
let masterKey: string | undefined;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user