diff --git a/frontend/components/basic/dialog/AddServiceTokenDialog.js b/frontend/components/basic/dialog/AddServiceTokenDialog.js index 8147253b5..7ff1789b8 100644 --- a/frontend/components/basic/dialog/AddServiceTokenDialog.js +++ b/frontend/components/basic/dialog/AddServiceTokenDialog.js @@ -37,7 +37,7 @@ const AddServiceTokenDialog = ({ const [serviceTokenCopied, setServiceTokenCopied] = useState(false); const generateServiceToken = async () => { - const latestFileKey = await getLatestFileKey(workspaceId); + const latestFileKey = await getLatestFileKey({ workspaceId }); const key = decryptAssymmetric({ ciphertext: latestFileKey.latestKey.encryptedKey, diff --git a/frontend/components/basic/layout.js b/frontend/components/basic/layout.js index 6482c57ac..effe38942 100644 --- a/frontend/components/basic/layout.js +++ b/frontend/components/basic/layout.js @@ -56,10 +56,10 @@ export default function Layout({ children }) { const workspaces = await getWorkspaces(); const currentWorkspaces = workspaces.map((workspace) => workspace.name); if (!currentWorkspaces.includes(workspaceName)) { - const newWorkspace = await createWorkspace( + const newWorkspace = await createWorkspace({ workspaceName, - localStorage.getItem("orgData.id") - ); + organizationId: localStorage.getItem("orgData.id") + }); let newWorkspaceId; try { newWorkspaceId = newWorkspace._id; diff --git a/frontend/components/basic/table/UserTable.js b/frontend/components/basic/table/UserTable.js index 5b2634d94..881556b70 100644 --- a/frontend/components/basic/table/UserTable.js +++ b/frontend/components/basic/table/UserTable.js @@ -88,7 +88,7 @@ const UserTable = ({ }, [userData, myUser]); const grantAccess = async (id, publicKey) => { - let result = await getLatestFileKey(router.query.id); + let result = await getLatestFileKey({workspaceId: router.query.id}); const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY"); diff --git a/frontend/components/navigation/NavHeader.tsx b/frontend/components/navigation/NavHeader.tsx index d6d8713ba..3d64c2eda 100644 --- a/frontend/components/navigation/NavHeader.tsx +++ b/frontend/components/navigation/NavHeader.tsx @@ -25,12 +25,12 @@ export default function NavHeader({ pageName, isProjectRelated } : { pageName: s useEffect(() => { (async () => { const orgId = localStorage.getItem("orgData.id") - let org = await getOrganization({ + const org = await getOrganization({ orgId: orgId ? orgId : "", }); setOrgName(org.name); - let workspace = await getProjectInfo({ + const workspace = await getProjectInfo({ projectId: String(router.query.id), }); setWorkspaceName(workspace.name); diff --git a/frontend/components/utilities/secrets/pushKeys.js b/frontend/components/utilities/secrets/pushKeys.ts similarity index 69% rename from frontend/components/utilities/secrets/pushKeys.js rename to frontend/components/utilities/secrets/pushKeys.ts index fde5b45a4..a4954e8c3 100644 --- a/frontend/components/utilities/secrets/pushKeys.js +++ b/frontend/components/utilities/secrets/pushKeys.ts @@ -7,20 +7,30 @@ import { envMapping } from "../../../public/data/frequentConstants"; const crypto = require("crypto"); const { decryptAssymmetric, - decryptSymmetric, encryptSymmetric, encryptAssymmetric, } = require("../cryptography/crypto"); const nacl = require("tweetnacl"); nacl.util = require("tweetnacl-util"); +export interface IK { + publicKey: string; + userId: string; +} -const pushKeys = async (obj, workspaceId, env) => { - let sharedKey = await getLatestFileKey(workspaceId); +/** + * This function pushes the keys to the database after decrypting them end-to-end + * @param {object} obj + * @param {object} obj.obj - object with all the key pairs + * @param {object} obj.workspaceId - the id of a project to which a user is pushing + * @param {object} obj.env - which environment a user is pushing to + */ +const pushKeys = async({ obj, workspaceId, env }: { obj: object; workspaceId: string; env: string; }) => { + let sharedKey = await getLatestFileKey({ workspaceId }); const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY"); - let randomBytes; + let randomBytes: string; if (Object.keys(sharedKey).length > 0) { // case: a (shared) key exists for the workspace randomBytes = decryptAssymmetric({ @@ -51,11 +61,11 @@ const pushKeys = async (obj, workspaceId, env) => { iv: ivValue, tag: tagValue, } = encryptSymmetric({ - plaintext: obj[key][0], + plaintext: obj[key as keyof typeof obj][0], key: randomBytes, }); - const visibility = obj[key][1] != null ? obj[key][1] : "personal"; + const visibility = obj[key as keyof typeof obj][1] != null ? obj[key as keyof typeof obj][1] : "personal"; return { ciphertextKey, @@ -65,7 +75,7 @@ const pushKeys = async (obj, workspaceId, env) => { ciphertextValue, ivValue, tagValue, - hashValue: crypto.createHash("sha256").update(obj[key][0]).digest("hex"), + hashValue: crypto.createHash("sha256").update(obj[key as keyof typeof obj][0]).digest("hex"), type: visibility, }; }); @@ -76,7 +86,7 @@ const pushKeys = async (obj, workspaceId, env) => { }); // assymmetrically encrypt key with each receiver public keys - const keys = publicKeys.map((k) => { + const keys = publicKeys.map((k: IK) => { const { ciphertext, nonce } = encryptAssymmetric({ plaintext: randomBytes, publicKey: k.publicKey, @@ -95,7 +105,7 @@ const pushKeys = async (obj, workspaceId, env) => { workspaceId, secrets, keys, - environment: envMapping[env], + environment: envMapping[env as keyof typeof envMapping], }); }; diff --git a/frontend/pages/api/organization/GetOrgUsers.js b/frontend/pages/api/organization/GetOrgUsers.ts similarity index 85% rename from frontend/pages/api/organization/GetOrgUsers.js rename to frontend/pages/api/organization/GetOrgUsers.ts index 81e9caa4d..53b9518cf 100644 --- a/frontend/pages/api/organization/GetOrgUsers.js +++ b/frontend/pages/api/organization/GetOrgUsers.ts @@ -6,7 +6,7 @@ import SecurityClient from "~/utilities/SecurityClient"; * @param {string} obj.orgId - organization Id * @returns */ -const getOrganizationUsers = ({ orgId }) => { +const getOrganizationUsers = ({ orgId }: { orgId: string; }) => { return SecurityClient.fetchCall( "/api/v1/organization/" + orgId + "/users", { @@ -16,7 +16,7 @@ const getOrganizationUsers = ({ orgId }) => { }, } ).then(async (res) => { - if (res.status == 200) { + if (res?.status == 200) { return (await res.json()).users; } else { console.log("Failed to get org users"); diff --git a/frontend/pages/api/workspace/createWorkspace.js b/frontend/pages/api/workspace/createWorkspace.ts similarity index 61% rename from frontend/pages/api/workspace/createWorkspace.js rename to frontend/pages/api/workspace/createWorkspace.ts index d5c44e2a6..0cedb0a57 100644 --- a/frontend/pages/api/workspace/createWorkspace.js +++ b/frontend/pages/api/workspace/createWorkspace.ts @@ -1,11 +1,12 @@ import SecurityClient from "~/utilities/SecurityClient"; /** - * This route creates a new workspace for a user. - * @param {*} workspaceName + * This route creates a new workspace for a user within a certain organization. + * @param {string} workspaceName - project Name + * @param {string} organizationId - org ID * @returns */ -const createWorkspace = (workspaceName, organizationId) => { +const createWorkspace = ( { workspaceName, organizationId }: { workspaceName: string; organizationId: string; }) => { return SecurityClient.fetchCall("/api/v1/workspace", { method: "POST", headers: { @@ -16,7 +17,7 @@ const createWorkspace = (workspaceName, organizationId) => { organizationId: organizationId, }), }).then(async (res) => { - if (res.status == 200) { + if (res?.status == 200) { return (await res.json()).workspace; } else { console.log("Failed to create a project"); diff --git a/frontend/pages/api/workspace/getLatestFileKey.js b/frontend/pages/api/workspace/getLatestFileKey.ts similarity index 79% rename from frontend/pages/api/workspace/getLatestFileKey.js rename to frontend/pages/api/workspace/getLatestFileKey.ts index a5b14520a..86ecb7456 100644 --- a/frontend/pages/api/workspace/getLatestFileKey.js +++ b/frontend/pages/api/workspace/getLatestFileKey.ts @@ -2,10 +2,10 @@ import SecurityClient from "~/utilities/SecurityClient"; /** * Get the latest key pairs from a certain workspace - * @param {*} workspaceId + * @param {string} workspaceId * @returns */ -const getLatestFileKey = (workspaceId) => { +const getLatestFileKey = ({ workspaceId } : { workspaceId: string; }) => { return SecurityClient.fetchCall( "/api/v1/key/" + workspaceId + "/latest", { @@ -15,7 +15,7 @@ const getLatestFileKey = (workspaceId) => { }, } ).then(async (res) => { - if (res.status == 200) { + if (res?.status == 200) { return await res.json(); } else { console.log("Failed to get the latest key pairs for a certain project"); diff --git a/frontend/pages/api/workspace/getWorkspaceKeys.js b/frontend/pages/api/workspace/getWorkspaceKeys.ts similarity index 73% rename from frontend/pages/api/workspace/getWorkspaceKeys.js rename to frontend/pages/api/workspace/getWorkspaceKeys.ts index 368d00fa0..09b468662 100644 --- a/frontend/pages/api/workspace/getWorkspaceKeys.js +++ b/frontend/pages/api/workspace/getWorkspaceKeys.ts @@ -2,13 +2,12 @@ import SecurityClient from "~/utilities/SecurityClient"; /** * This route lets us get the public keys of everyone in your workspace. - * @param {*} req - * @param {*} res + * @param {string} workspaceId * @returns */ -const getWorkspaceKeys = (req, res) => { +const getWorkspaceKeys = ({ workspaceId }: { workspaceId: string; }) => { return SecurityClient.fetchCall( - "/api/v1/workspace/" + req.workspaceId + "/keys", + "/api/v1/workspace/" + workspaceId + "/keys", { method: "GET", headers: { @@ -16,7 +15,7 @@ const getWorkspaceKeys = (req, res) => { }, } ).then(async (res) => { - if (res.status == 200) { + if (res?.status == 200) { return (await res.json()).publicKeys; } else { console.log("Failed to get the public keys of everyone in the workspace"); diff --git a/frontend/pages/api/workspace/getWorkspaceUsers.js b/frontend/pages/api/workspace/getWorkspaceUsers.ts similarity index 69% rename from frontend/pages/api/workspace/getWorkspaceUsers.js rename to frontend/pages/api/workspace/getWorkspaceUsers.ts index 4d87836c7..9805c2695 100644 --- a/frontend/pages/api/workspace/getWorkspaceUsers.js +++ b/frontend/pages/api/workspace/getWorkspaceUsers.ts @@ -2,13 +2,12 @@ import SecurityClient from "~/utilities/SecurityClient"; /** * This route lets us get all the users in the workspace. - * @param {*} req - * @param {*} res + * @param {string} workspaceId - workspace ID * @returns */ -const getWorkspaceUsers = (req, res) => { +const getWorkspaceUsers = ({ workspaceId }: { workspaceId: string; }) => { return SecurityClient.fetchCall( - "/api/v1/workspace/" + req.workspaceId + "/users", + "/api/v1/workspace/" + workspaceId + "/users", { method: "GET", headers: { @@ -16,7 +15,7 @@ const getWorkspaceUsers = (req, res) => { }, } ).then(async (res) => { - if (res.status == 200) { + if (res?.status == 200) { return (await res.json()).users; } else { console.log("Failed to get Project Users"); diff --git a/frontend/pages/api/workspace/getWorkspaces.js b/frontend/pages/api/workspace/getWorkspaces.ts similarity index 69% rename from frontend/pages/api/workspace/getWorkspaces.js rename to frontend/pages/api/workspace/getWorkspaces.ts index ccaf49e9b..9427c03d0 100644 --- a/frontend/pages/api/workspace/getWorkspaces.js +++ b/frontend/pages/api/workspace/getWorkspaces.ts @@ -1,19 +1,17 @@ import SecurityClient from "~/utilities/SecurityClient"; /** - * This route lets us get the public keys of everyone in your workspace. - * @param {*} req - * @param {*} res + * This route lets us get the workspaces of a certain user * @returns */ -const getWorkspaces = (req, res) => { +const getWorkspaces = () => { return SecurityClient.fetchCall("/api/v1/workspace", { method: "GET", headers: { "Content-Type": "application/json", }, }).then(async (res) => { - if (res.status == 200) { + if (res?.status == 200) { return (await res.json()).workspaces; } else { console.log("Failed to get projects"); diff --git a/frontend/pages/dashboard/[id].js b/frontend/pages/dashboard/[id].js index 42abf24db..b2dfd70f4 100644 --- a/frontend/pages/dashboard/[id].js +++ b/frontend/pages/dashboard/[id].js @@ -378,9 +378,9 @@ export default function Dashboard() { } else if (duplicatesExist) { console.log("Remove the duplicated entries first!"); } else { - // Once "Save changed is clicked", disable that button + // Once "Save changes is clicked", disable that button setButtonReady(false); - pushKeys(obj, router.query.id, env); + pushKeys({obj, workspaceId: router.query.id, env}); /** * Check which integrations are active for this project and environment