mirror of
https://github.com/hanzoai/sign.git
synced 2026-10-21 01:21:51 +00:00
Emails, the signing page's title, the sealed PDF's reason, the sign-in refusal and the dialogs still said Hanzo Sign. The catalogs change with the strings, message for message, so every translation keeps its id.
39 lines
1.0 KiB
TypeScript
39 lines
1.0 KiB
TypeScript
import { hmac } from '@noble/hashes/hmac.js';
|
|
import { sha256 } from '@noble/hashes/sha2.js';
|
|
import { createTOTPKeyURI } from 'oslo/otp';
|
|
|
|
import { SIGN_ENCRYPTION_KEY } from '../../../constants/crypto';
|
|
|
|
const ISSUER = `${process.env.NEXT_PUBLIC_APP_NAME || 'Hanzo eSign'} Email 2FA`;
|
|
|
|
export type GenerateTwoFactorCredentialsFromEmailOptions = {
|
|
envelopeId: string;
|
|
email: string;
|
|
};
|
|
|
|
/**
|
|
* Generate an encrypted token containing a 6-digit 2FA code for email verification.
|
|
*
|
|
* @param options - The options for generating the token
|
|
* @returns Object containing the token and the 6-digit code
|
|
*/
|
|
export const generateTwoFactorCredentialsFromEmail = ({
|
|
envelopeId,
|
|
email,
|
|
}: GenerateTwoFactorCredentialsFromEmailOptions) => {
|
|
if (!SIGN_ENCRYPTION_KEY) {
|
|
throw new Error('Missing SIGN_ENCRYPTION_KEY');
|
|
}
|
|
|
|
const identity = `email-2fa|v1|email:${email}|id:${envelopeId}`;
|
|
|
|
const secret = hmac(sha256, SIGN_ENCRYPTION_KEY, identity);
|
|
|
|
const uri = createTOTPKeyURI(ISSUER, email, secret.buffer as ArrayBuffer);
|
|
|
|
return {
|
|
uri,
|
|
secret,
|
|
};
|
|
};
|