mirror of
https://github.com/quantum5/totp.git
synced 2025-04-24 05:31:59 -04:00
49 lines
1.3 KiB
TypeScript
49 lines
1.3 KiB
TypeScript
import React from 'react';
|
|
import {HashAlgorithms, HOTP, HOTPOptions} from '@otplib/core';
|
|
import {createDigest} from '@otplib/plugin-crypto-js';
|
|
import classNames from 'classnames';
|
|
import CopyButton from './CopyButton.tsx';
|
|
|
|
const ALGORITHMS = {
|
|
sha1: HashAlgorithms.SHA1,
|
|
sha256: HashAlgorithms.SHA256,
|
|
sha512: HashAlgorithms.SHA512,
|
|
};
|
|
|
|
export type HashAlgorithm = keyof typeof ALGORITHMS;
|
|
|
|
function OTPCode({code, delta}: { code: string; delta: number }) {
|
|
return <div className={classNames('totp-code', {
|
|
'totp-older': delta < 0,
|
|
'totp-newer': delta > 0,
|
|
'totp-current': delta === 0,
|
|
'totp-far': Math.abs(delta) > 5,
|
|
'totp-near-first': delta === -5,
|
|
'totp-near-last': delta === 5,
|
|
})}>
|
|
{code}
|
|
<CopyButton text={code}/>
|
|
</div>;
|
|
}
|
|
|
|
export default function OTPOutput({secret, offset, algorithm, digits}: {
|
|
secret: string;
|
|
offset: number;
|
|
algorithm: HashAlgorithm;
|
|
digits: number;
|
|
}) {
|
|
const otp = React.useMemo(() => new HOTP<HOTPOptions>({
|
|
createDigest,
|
|
digits,
|
|
algorithm: ALGORITHMS[algorithm],
|
|
}), [digits, algorithm]);
|
|
|
|
return <div className="totp-output">
|
|
{[...Array(21).keys()].map((i) => {
|
|
const delta = i - 10;
|
|
const current = offset + delta;
|
|
return <OTPCode key={current} code={otp.generate(secret, current)} delta={delta}/>;
|
|
})}
|
|
</div>;
|
|
}
|