diff --git a/frontend/components/utilities/attemptLogin.js b/frontend/components/utilities/attemptLogin.js index 45cee1f945..7a8cbf96fb 100644 --- a/frontend/components/utilities/attemptLogin.js +++ b/frontend/components/utilities/attemptLogin.js @@ -7,6 +7,7 @@ import getOrganizationUserProjects from "~/pages/api/organization/GetOrgUserProj import { initPostHog } from "../analytics/posthog"; import pushKeys from "./secrets/pushKeys"; import { ENV } from "./config"; +import { saveTokenToLocalStorage } from "./saveTokenToLocalStorage"; import SecurityClient from "./SecurityClient"; const nacl = require("tweetnacl"); @@ -40,66 +41,38 @@ const attemptLogin = async ( async () => { const clientPublicKey = client.getPublicKey(); - let serverPublicKey, salt; - try { - let res = await login1(email, clientPublicKey); - res = await res.json(); - serverPublicKey = res.serverPublicKey; - salt = res.salt; - } catch (err) { - setErrorLogin(true); - console.log("Wrong password", err); - } + const { serverPublicKey, salt } = await login1(email, clientPublicKey); - let response; try { client.setSalt(salt); client.setServerPublicKey(serverPublicKey); const clientProof = client.getProof(); // called M1 - response = await login2(email, clientProof); - } catch (err) { - setErrorLogin(true); - console.log("Password verification failed"); - } - // if everything works, go the main dashboard page. - try { - if (response.status == "200") { - response = await response.json(); - SecurityClient.setToken(response["token"]); - const publicKey = response["publicKey"]; - const encryptedPrivateKey = response["encryptedPrivateKey"]; - const iv = response["iv"]; - const tag = response["tag"]; + // if everything works, go the main dashboard page. + const { token, publicKey, encryptedPrivateKey, iv, tag } = + await login2(email, clientProof); + SecurityClient.setToken(token); - const PRIVATE_KEY = Aes256Gcm.decrypt( - encryptedPrivateKey, - iv, - tag, - password - .slice(0, 32) - .padStart( - 32 + - (password.slice(0, 32).length - new Blob([password]).size), - "0" - ) - ); + const privateKey = Aes256Gcm.decrypt( + encryptedPrivateKey, + iv, + tag, + password + .slice(0, 32) + .padStart( + 32 + (password.slice(0, 32).length - new Blob([password]).size), + "0" + ) + ); - try { - localStorage.setItem("publicKey", publicKey); - localStorage.setItem("encryptedPrivateKey", encryptedPrivateKey); - localStorage.setItem("iv", iv); - localStorage.setItem("tag", tag); - localStorage.setItem("PRIVATE_KEY", PRIVATE_KEY); - } catch (err) { - setErrorLogin(true); - console.error( - "Unable to send the tokens in local storage:" + err.message - ); - } - } else { - setErrorLogin(true); - } + saveTokenToLocalStorage({ + token, + publicKey, + encryptedPrivateKey, + iv, + tag, + privateKey, + }); const userOrgs = await getOrganizations(); const userOrgsData = userOrgs.map((org) => org._id); @@ -149,7 +122,7 @@ const attemptLogin = async ( STRIPE_SECRET_KEY: ["sk_test_7348oyho4hfq398HIUOH78", "shared"], }, workspaceId: projectToLogin, - env: "Development" + env: "Development", }); } try { diff --git a/frontend/components/utilities/saveTokenToLocalStorage.ts b/frontend/components/utilities/saveTokenToLocalStorage.ts new file mode 100644 index 0000000000..13e50b2c47 --- /dev/null +++ b/frontend/components/utilities/saveTokenToLocalStorage.ts @@ -0,0 +1,29 @@ +interface Props { + publicKey: string; + encryptedPrivateKey: string; + iv: string; + tag: string; + privateTag: string; +} + +export const saveTokenToLocalStorage = ({ + publicKey, + encryptedPrivateKey, + iv, + tag, + privateTag, +}: Props) => { + try { + localStorage.setItem("publicKey", publicKey); + localStorage.setItem("encryptedPrivateKey", encryptedPrivateKey); + localStorage.setItem("iv", iv); + localStorage.setItem("tag", tag); + localStorage.setItem("PRIVATE_KEY", privateTag); + } catch (err) { + if (err instanceof Error) { + throw new Error( + "Unable to send the tokens in local storage:" + err.message + ); + } + } +}; diff --git a/frontend/pages/api/auth/Login1.js b/frontend/pages/api/auth/Login1.js deleted file mode 100644 index 3f3493f77c..0000000000 --- a/frontend/pages/api/auth/Login1.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * This is the first step of the login process (pake) - * @param {*} email - * @param {*} clientPublicKey - * @returns - */ -const login1 = (email, clientPublicKey) => { - return fetch("/api/v1/auth/login1", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: email, - clientPublicKey, - }), - }); -}; - -export default login1; diff --git a/frontend/pages/api/auth/Login1.ts b/frontend/pages/api/auth/Login1.ts new file mode 100644 index 0000000000..818a2d1572 --- /dev/null +++ b/frontend/pages/api/auth/Login1.ts @@ -0,0 +1,32 @@ +interface Login1 { + serverPublicKey: string; + salt: string; +} + +/** + * This is the first step of the login process (pake) + * @param {*} email + * @param {*} clientPublicKey + * @returns + */ +const login1 = async (email: string, clientPublicKey: string) => { + const response = await fetch("/api/v1/auth/login1", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: email, + clientPublicKey, + }), + }); + // need precise error handling about the status code + if (response?.status === 200) { + const data = (await response.json()) as unknown as Login1; + return data; + } + + throw new Error("Wrong password"); +}; + +export default login1; diff --git a/frontend/pages/api/auth/Login2.js b/frontend/pages/api/auth/Login2.js deleted file mode 100644 index 923e261dfd..0000000000 --- a/frontend/pages/api/auth/Login2.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * This is the second step of the login process - * @param {*} email - * @param {*} clientPublicKey - * @returns - */ -const login2 = (email, clientProof) => { - return fetch("/api/v1/auth/login2", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: email, - clientProof, - }), - credentials: "include", - }).then((res) => { - if (res.status == 200) { - console.log("User logged in", res); - return res; - } else { - console.log("Failed to log in"); - } - }); -}; - -export default login2; diff --git a/frontend/pages/api/auth/Login2.ts b/frontend/pages/api/auth/Login2.ts new file mode 100644 index 0000000000..3adcb695f8 --- /dev/null +++ b/frontend/pages/api/auth/Login2.ts @@ -0,0 +1,36 @@ +interface Login2Response { + encryptedPrivateKey: string; + iv: string; + publicKey: string; + tag: string; + token: string; +} + +/** + * This is the second step of the login process + * @param {*} email + * @param {*} clientPublicKey + * @returns + */ +const login2 = async (email: string, clientProof: string) => { + const response = await fetch("/api/v1/auth/login2", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: email, + clientProof, + }), + credentials: "include", + }); + // need precise error handling about the status code + if (response.status == 200) { + const data = (await response.json()) as unknown as Login2Response; + return data; + } + + throw new Error("Password verification failed"); +}; + +export default login2;