Skip to content

Commit

Permalink
fix: handle backup key error and success feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
kali committed Nov 13, 2024
1 parent bfce102 commit d14f1bc
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 76 deletions.
138 changes: 68 additions & 70 deletions frontend/src/components/utilities/cryptography/issueBackupKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { issueBackupPrivateKey, srp1 } from "@app/hooks/api/auth/queries";
import generateBackupPDF from "../generateBackupPDF";
import Aes256Gcm from "./aes-256-gcm";

const clientPassword = new jsrp.client();
const clientKey = new jsrp.client();
const ClientPassword = new jsrp.client();
const ClientKey = new jsrp.client();

interface BackupKeyProps {
email: string;
Expand All @@ -20,95 +20,93 @@ interface BackupKeyProps {
}

/**
* This function issue a backup key for a user
* @param {obkect} obj
* This function issues a backup key for a user
* @param {object} obj
* @param {string} obj.email - email of a user issuing a backup key
* @param {string} obj.password - password of a user issuing a backup key
* @param {string} obj.personalName - name of a user issuing a backup key
* @param {function} obj.setBackupKeyError - state function that turns true if there is an erorr with a backup key
* @param {function} obj.setBackupKeyIssued - state function that turns true if a backup key was issued correctly
* @returns
* @param {function} obj.setBackupKeyError - state function to indicate an error
* @param {function} obj.setBackupKeyIssued - state function to indicate success
* @returns {Promise<void>}
*/

const issueBackupKey = async ({
email,
password,
personalName,
setBackupKeyError,
setBackupKeyIssued
}: BackupKeyProps) => {
}: BackupKeyProps): Promise<void> => {
try {
setBackupKeyError(false);
setBackupKeyIssued(false);
clientPassword.init(
{
username: email,
password
},
async () => {
const clientPublicKey = clientPassword.getPublicKey();

let serverPublicKey;
let salt;

ClientPassword.init({ username: email, password }, async () => {
const clientPublicKey = ClientPassword.getPublicKey();

let serverPublicKey: string | undefined;
let salt: string | undefined;

try {
const res = await srp1({ clientPublicKey });
serverPublicKey = res.serverPublicKey;
salt = res.salt;
} catch (err) {
setBackupKeyError(true);
console.error("Error during SRP exchange:", err);
}

ClientPassword.setSalt(salt as string);
ClientPassword.setServerPublicKey(serverPublicKey as string);
const clientProof = ClientPassword.getProof(); // M1

const generatedKey = crypto.randomBytes(16).toString("hex");

ClientKey.init({ username: email, password: generatedKey }, async () => {
try {
const res = await srp1({
clientPublicKey
ClientKey.createVerifier(async (createVerifierErr: any, result: { salt: string; verifier: string }) => {
if (createVerifierErr) {
setBackupKeyError(true);
console.error("Error during verifier creation:", createVerifierErr);
}

const { ciphertext, iv, tag } = Aes256Gcm.encrypt({
text: String(localStorage.getItem("PRIVATE_KEY")),
secret: generatedKey
});

try {
await issueBackupPrivateKey({
encryptedPrivateKey: ciphertext,
iv,
tag,
salt: result.salt,
verifier: result.verifier,
clientProof
});

await generateBackupPDF({
personalName,
personalEmail: email,
generatedKey
});

setBackupKeyIssued(true);
} catch (err) {
setBackupKeyError(true);
console.error("Error issuing backup private key:", err);
}
});
serverPublicKey = res.serverPublicKey;
salt = res.salt;
} catch (err) {
setBackupKeyError(true);
console.log("Wrong current password", err, 1);
console.error("Error creating verifier:", err);
}

clientPassword.setSalt(salt as string);
clientPassword.setServerPublicKey(serverPublicKey as string);
const clientProof = clientPassword.getProof(); // called M1

const generatedKey = crypto.randomBytes(16).toString("hex");

clientKey.init(
{
username: email,
password: generatedKey
},
async () => {
clientKey.createVerifier(
async (err: any, result: { salt: string; verifier: string }) => {
const { ciphertext, iv, tag } = Aes256Gcm.encrypt({
text: String(localStorage.getItem("PRIVATE_KEY")),
secret: generatedKey
});

try {
await issueBackupPrivateKey({
encryptedPrivateKey: ciphertext,
iv,
tag,
salt: result.salt,
verifier: result.verifier,
clientProof
});

generateBackupPDF({
personalName,
personalEmail: email,
generatedKey
});
setBackupKeyIssued(true);
} catch {
setBackupKeyError(true);
}
}
);
}
);
}
);
});
});
} catch (error) {
setBackupKeyError(true);
console.log("Failed to issue a backup key");
console.error("Failed to issue a backup key:", error);
}
return true;
};

export default issueBackupKey;
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const schema = yup
export type FormData = yup.InferType<typeof schema>;

export const EmergencyKitSection = () => {

const { user } = useUser();
const { reset, control, handleSubmit } = useForm({
defaultValues: {
Expand All @@ -33,17 +32,32 @@ export const EmergencyKitSection = () => {
email: user.email,
password,
personalName: `${user.firstName} ${user.lastName}`,
setBackupKeyError: () => {},
setBackupKeyIssued: () => {}
setBackupKeyError: (value) => {
if (value) {
createNotification({
text: "Failed to download emergency kit",
type: "error"
});
}
},
setBackupKeyIssued: (value) => {
if (value) {
createNotification({
text: "Emergency kit successfully downloaded",
type: "success"
});
}
}
});

reset();
} catch (err) {
console.error(err);
createNotification({
text: "Failed to download emergency kit",
text: "An unexpected error occurred",
type: "error"
});
} finally {
reset();
}
};

Expand Down Expand Up @@ -78,4 +92,4 @@ export const EmergencyKitSection = () => {
</Button>
</form>
);
};
};

0 comments on commit d14f1bc

Please sign in to comment.