mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-29 22:02:57 +00:00
212 lines
7.1 KiB
TypeScript
212 lines
7.1 KiB
TypeScript
import { SecretDataProps } from 'public/data/frequentInterfaces';
|
|
|
|
import Aes256Gcm from '~/components/utilities/cryptography/aes-256-gcm';
|
|
import login1 from '~/pages/api/auth/Login1';
|
|
import login2 from '~/pages/api/auth/Login2';
|
|
import addSecrets from '~/pages/api/files/AddSecrets';
|
|
import getOrganizations from '~/pages/api/organization/getOrgs';
|
|
import getOrganizationUserProjects from '~/pages/api/organization/GetOrgUserProjects';
|
|
import getUser from '~/pages/api/user/getUser';
|
|
import uploadKeys from '~/pages/api/workspace/uploadKeys';
|
|
|
|
import { encryptAssymmetric } from './cryptography/crypto';
|
|
import encryptSecrets from './secrets/encryptSecrets';
|
|
import Telemetry from './telemetry/Telemetry';
|
|
import { saveTokenToLocalStorage } from './saveTokenToLocalStorage';
|
|
import SecurityClient from './SecurityClient';
|
|
|
|
|
|
const crypto = require("crypto");
|
|
const nacl = require('tweetnacl');
|
|
nacl.util = require('tweetnacl-util');
|
|
const jsrp = require('jsrp');
|
|
const client = new jsrp.client();
|
|
|
|
/**
|
|
* This function logs in the user (whether it's right after signup, or a normal login)
|
|
* @param {string} email - email of the user logging in
|
|
* @param {string} password - password of the user logging in
|
|
* @param {function} setErrorLogin - function that visually dispay an error is something is wrong
|
|
* @param {*} router
|
|
* @param {boolean} isSignUp - whether this log in is a part of signup
|
|
* @param {boolean} isLogin - ?
|
|
* @returns
|
|
*/
|
|
const attemptLogin = async (
|
|
email: string,
|
|
password: string,
|
|
setErrorLogin: (value: boolean) => void,
|
|
router: any,
|
|
isSignUp: boolean,
|
|
isLogin: boolean
|
|
) => {
|
|
try {
|
|
const telemetry = new Telemetry().getInstance();
|
|
|
|
client.init(
|
|
{
|
|
username: email,
|
|
password: password
|
|
},
|
|
async () => {
|
|
const clientPublicKey = client.getPublicKey();
|
|
|
|
try {
|
|
const { serverPublicKey, salt } = await login1(email, clientPublicKey);
|
|
|
|
client.setSalt(salt);
|
|
client.setServerPublicKey(serverPublicKey);
|
|
const clientProof = client.getProof(); // called M1
|
|
|
|
// if everything works, go the main dashboard page.
|
|
const { token, publicKey, encryptedPrivateKey, iv, tag } =
|
|
await login2(email, clientProof);
|
|
|
|
SecurityClient.setToken(token);
|
|
|
|
const privateKey = Aes256Gcm.decrypt({
|
|
ciphertext: encryptedPrivateKey,
|
|
iv,
|
|
tag,
|
|
secret: password
|
|
.slice(0, 32)
|
|
.padStart(
|
|
32 + (password.slice(0, 32).length - new Blob([password]).size),
|
|
'0'
|
|
)
|
|
});
|
|
|
|
saveTokenToLocalStorage({
|
|
publicKey,
|
|
encryptedPrivateKey,
|
|
iv,
|
|
tag,
|
|
privateKey
|
|
});
|
|
|
|
const userOrgs = await getOrganizations();
|
|
const userOrgsData = userOrgs.map((org: { _id: string; }) => org._id);
|
|
|
|
let orgToLogin;
|
|
if (userOrgsData.includes(localStorage.getItem('orgData.id'))) {
|
|
orgToLogin = localStorage.getItem('orgData.id');
|
|
} else {
|
|
orgToLogin = userOrgsData[0];
|
|
localStorage.setItem('orgData.id', orgToLogin);
|
|
}
|
|
|
|
let orgUserProjects = await getOrganizationUserProjects({
|
|
orgId: orgToLogin
|
|
});
|
|
|
|
orgUserProjects = orgUserProjects?.map((project: { _id: string; }) => project._id);
|
|
let projectToLogin;
|
|
if (
|
|
orgUserProjects.includes(localStorage.getItem('projectData.id'))
|
|
) {
|
|
projectToLogin = localStorage.getItem('projectData.id');
|
|
} else {
|
|
try {
|
|
projectToLogin = orgUserProjects[0];
|
|
localStorage.setItem('projectData.id', projectToLogin);
|
|
} catch (error) {
|
|
console.log('ERROR: User likely has no projects. ', error);
|
|
}
|
|
}
|
|
|
|
if (email) {
|
|
telemetry.identify(email);
|
|
telemetry.capture('User Logged In');
|
|
}
|
|
|
|
if (isSignUp) {
|
|
const randomBytes = crypto.randomBytes(16).toString("hex");
|
|
const PRIVATE_KEY = String(localStorage.getItem("PRIVATE_KEY"));
|
|
|
|
const myUser = await getUser();
|
|
|
|
const { ciphertext, nonce } = encryptAssymmetric({
|
|
plaintext: randomBytes,
|
|
publicKey: myUser.publicKey,
|
|
privateKey: PRIVATE_KEY,
|
|
}) as { ciphertext: string; nonce: string };
|
|
|
|
await uploadKeys(
|
|
projectToLogin,
|
|
myUser._id,
|
|
ciphertext,
|
|
nonce
|
|
);
|
|
|
|
const secretsToBeAdded: SecretDataProps[] = [{
|
|
pos: 0,
|
|
key: "DATABASE_URL",
|
|
value: "mongodb+srv://${DB_USERNAME}:${DB_PASSWORD}@mongodb.net",
|
|
valueOverride: undefined,
|
|
comment: "This is an example of secret referencing.",
|
|
id: ''
|
|
}, {
|
|
pos: 1,
|
|
key: "DB_USERNAME",
|
|
value: "OVERRIDE_THIS",
|
|
valueOverride: undefined,
|
|
comment: "This is an example of secret overriding. Your team can have a shared value of a secret, while you can override it to whatever value you need",
|
|
id: ''
|
|
}, {
|
|
pos: 2,
|
|
key: "DB_PASSWORD",
|
|
value: "OVERRIDE_THIS",
|
|
valueOverride: undefined,
|
|
comment: "This is an example of secret overriding. Your team can have a shared value of a secret, while you can override it to whatever value you need",
|
|
id: ''
|
|
}, {
|
|
pos: 3,
|
|
key: "DB_USERNAME",
|
|
value: "user1234",
|
|
valueOverride: "user1234",
|
|
comment: "",
|
|
id: ''
|
|
}, {
|
|
pos: 4,
|
|
key: "DB_PASSWORD",
|
|
value: "example_password",
|
|
valueOverride: "example_password",
|
|
comment: "",
|
|
id: ''
|
|
}, {
|
|
pos: 5,
|
|
key: "TWILIO_AUTH_TOKEN",
|
|
value: "example_twillio_token",
|
|
valueOverride: undefined,
|
|
comment: "",
|
|
id: ''
|
|
}, {
|
|
pos: 6,
|
|
key: "WEBSITE_URL",
|
|
value: "http://localhost:3000",
|
|
valueOverride: undefined,
|
|
comment: "",
|
|
id: ''
|
|
}]
|
|
const secrets = await encryptSecrets({ secretsToEncrypt: secretsToBeAdded, workspaceId: String(localStorage.getItem('projectData.id')), env: 'dev' })
|
|
await addSecrets({ secrets: secrets ?? [], env: "dev", workspaceId: String(localStorage.getItem('projectData.id')) });
|
|
}
|
|
|
|
if (isLogin) {
|
|
router.push('/dashboard/' + localStorage.getItem('projectData.id'));
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
setErrorLogin(true);
|
|
console.log('Login response not available');
|
|
}
|
|
}
|
|
);
|
|
} catch (error) {
|
|
console.log('Something went wrong during authentication');
|
|
}
|
|
return true;
|
|
};
|
|
|
|
export default attemptLogin;
|