Merge remote-tracking branch 'origin' into stripe-error

This commit is contained in:
Tuan Dang
2023-06-22 16:38:46 +07:00
15 changed files with 777 additions and 278 deletions
@@ -0,0 +1,164 @@
/* eslint-disable prefer-destructuring */
import jsrp from "jsrp";
import login1 from "@app/pages/api/auth/Login1";
import login2 from "@app/pages/api/auth/Login2";
import getOrganizations from "@app/pages/api/organization/getOrgs";
import getOrganizationUserProjects from "@app/pages/api/organization/GetOrgUserProjects";
import KeyService from "@app/services/KeyService";
import Telemetry from "./telemetry/Telemetry";
import { saveTokenToLocalStorage } from "./saveTokenToLocalStorage";
import SecurityClient from "./SecurityClient";
// eslint-disable-next-line new-cap
const client = new jsrp.client();
interface IsCliLoginSuccessful {
mfaEnabled: boolean;
loginResponse?: {
email: string;
privateKey: string;
JTWToken: string;
};
success: boolean;
}
/**
* Return whether or not login is successful for user with email [email]
* and password [password]
* @param {string} email - email of user to log in
* @param {string} password - password of user to log in
*/
const attemptLogin = async (
{
email,
password,
providerAuthToken,
}: {
email: string;
password: string;
providerAuthToken?: string;
}
): Promise<IsCliLoginSuccessful> => {
const telemetry = new Telemetry().getInstance();
return new Promise((resolve, reject) => {
client.init(
{
username: email,
password
},
async () => {
try {
const clientPublicKey = client.getPublicKey();
const { serverPublicKey, salt } = await login1({
email,
clientPublicKey,
providerAuthToken,
});
client.setSalt(salt);
client.setServerPublicKey(serverPublicKey);
const clientProof = client.getProof(); // called M1
const {
mfaEnabled,
encryptionVersion,
protectedKey,
protectedKeyIV,
protectedKeyTag,
token,
publicKey,
encryptedPrivateKey,
iv,
tag
} = await login2(
{
email,
clientProof,
providerAuthToken,
}
);
if (mfaEnabled) {
// case: MFA is enabled
// set temporary (MFA) JWT token
SecurityClient.setMfaToken(token);
resolve({
mfaEnabled,
success: true
});
} else if (
!mfaEnabled &&
encryptionVersion &&
encryptedPrivateKey &&
iv &&
tag &&
token
) {
// case: MFA is not enabled
// unset provider auth token in case it was used
SecurityClient.setProviderAuthToken("");
// set JWT token
SecurityClient.setToken(token);
const privateKey = await KeyService.decryptPrivateKey({
encryptionVersion,
encryptedPrivateKey,
iv,
tag,
password,
salt,
protectedKey,
protectedKeyIV,
protectedKeyTag
});
saveTokenToLocalStorage({
publicKey,
encryptedPrivateKey,
iv,
tag,
privateKey
});
const userOrgs = await getOrganizations();
const orgId = userOrgs[0]._id;
localStorage.setItem("orgData.id", orgId);
const orgUserProjects = await getOrganizationUserProjects({
orgId
});
if (orgUserProjects.length > 0) {
localStorage.setItem("projectData.id", orgUserProjects[0]._id);
}
if (email) {
telemetry.identify(email, email);
telemetry.capture("User Logged In");
}
resolve({
mfaEnabled: false,
loginResponse: {
email,
privateKey,
JTWToken: token
},
success: true
})
}
} catch (err) {
reject(err);
}
}
);
});
};
export default attemptLogin;
@@ -0,0 +1,122 @@
/* eslint-disable prefer-destructuring */
import jsrp from "jsrp";
import login1 from "@app/pages/api/auth/Login1";
import verifyMfaToken from "@app/pages/api/auth/verifyMfaToken";
import getOrganizations from "@app/pages/api/organization/getOrgs";
import getOrganizationUserProjects from "@app/pages/api/organization/GetOrgUserProjects";
import KeyService from "@app/services/KeyService";
import { saveTokenToLocalStorage } from "./saveTokenToLocalStorage";
import SecurityClient from "./SecurityClient";
// eslint-disable-next-line new-cap
const client = new jsrp.client();
interface IsMfaLoginSuccessful {
success: boolean;
loginResponse:{
privateKey: string;
JTWToken: string;
}
}
/**
* Return whether or not MFA-login is successful for user with email [email]
* and MFA token [mfaToken]
* @param {Object} obj
* @param {String} obj.email - email of user
* @param {String} obj.mfaToken - MFA code/token
*/
const attemptLoginMfa = async ({
email,
password,
providerAuthToken,
mfaToken
}: {
email: string;
password: string;
providerAuthToken?: string,
mfaToken: string;
}): Promise<IsMfaLoginSuccessful> => {
return new Promise((resolve, reject) => {
client.init({
username: email,
password
}, async () => {
try {
const clientPublicKey = client.getPublicKey();
const { salt } = await login1({
email,
clientPublicKey,
providerAuthToken,
});
const {
encryptionVersion,
protectedKey,
protectedKeyIV,
protectedKeyTag,
token,
publicKey,
encryptedPrivateKey,
iv,
tag
} = await verifyMfaToken({
email,
mfaToken
});
// unset temporary (MFA) JWT token and set JWT token
SecurityClient.setMfaToken("");
SecurityClient.setToken(token);
SecurityClient.setProviderAuthToken("");
const privateKey = await KeyService.decryptPrivateKey({
encryptionVersion,
encryptedPrivateKey,
iv,
tag,
password,
salt,
protectedKey,
protectedKeyIV,
protectedKeyTag
});
saveTokenToLocalStorage({
publicKey,
encryptedPrivateKey,
iv,
tag,
privateKey
});
// TODO: in the future - move this logic elsewhere
// because this function is about logging the user in
// and not initializing the login details
const userOrgs = await getOrganizations();
const orgId = userOrgs[0]._id;
localStorage.setItem("orgData.id", orgId);
const orgUserProjects = await getOrganizationUserProjects({
orgId
});
localStorage.setItem("projectData.id", orgUserProjects[0]._id);
resolve({
success: true,
loginResponse:{
privateKey,
JTWToken: token
}
});
} catch (err) {
reject(err);
}
});
});
}
export default attemptLoginMfa;