Fix some type issues

This commit is contained in:
Quantum 2025-02-10 15:05:02 -08:00
parent bd961a5768
commit cb79b1729f
8 changed files with 20 additions and 15 deletions

View file

@ -1,4 +1,4 @@
import React, {HTMLProps, SyntheticEvent, useCallback} from 'react';
import {HTMLProps, SyntheticEvent, useCallback} from 'react';
type HTMLAnchorProps = Omit<HTMLProps<HTMLAnchorElement>, 'href' | 'onClick'>;

View file

@ -1,4 +1,4 @@
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {useCallback, useEffect, useMemo, useState} from 'react';
import base32Decode from 'base32-decode';
import {NumberInput, TextInput} from './Input';
import OTPOutput from './OTPOutput';
@ -6,6 +6,7 @@ import Select from './Select';
import Collapsible from './Collapsible';
import ActionLink from './ActionLink';
import {defaults, serializeState, deserializeState} from './state';
import {HashAlgorithm} from './algorithms.tsx';
function parseState() {
if (window.location.hash.startsWith('#!')) {
@ -78,7 +79,7 @@ function App() {
);
const setAlgorithm = useCallback(
(algorithm: string) => setState((state) => ({...state, algorithm})),
(algorithm: HashAlgorithm) => setState((state) => ({...state, algorithm})),
[],
);
@ -107,7 +108,7 @@ function App() {
<div className="totp-settings">
<TextInput label="Secret key" value={secret} onChange={setSecret}
error={!validSecret && 'Secret must be a valid base32-encoded string'}/>
<progress class="totp-tick" value={validStep ? remaining : 0} max={validStep ? step : 0}/>
<progress className="totp-tick" value={validStep ? remaining : 0} max={validStep ? step : 0}/>
{advanced ?
<ActionLink onClick={hideAdvanced}>Hide advanced options</ActionLink> :
<ActionLink onClick={showAdvanced}>Show advanced options</ActionLink>}
@ -124,7 +125,7 @@ function App() {
<button type="button" className="btn btn-secondary" onClick={onReset}>Reset</button>
</Collapsible>
</div>
{valid && <OTPOutput secret={decoded} offset={offset} algorithm={algorithm} digits={digits}/>}
{valid && decoded && <OTPOutput secret={decoded} offset={offset} algorithm={algorithm} digits={digits}/>}
</div>
);
}

View file

@ -1,4 +1,4 @@
import React, {ReactNode, useEffect, useId} from 'react';
import {ReactNode, useEffect, useId} from 'react';
import {Collapse} from 'bootstrap';
export default function Collapsible({children, show}: { children: ReactNode; show: boolean }) {

View file

@ -1,4 +1,4 @@
import React, {useCallback, useEffect, useId, useState} from 'react';
import {useCallback, useEffect, useId, useState} from 'react';
import Copy from './copy.svg?react';
import {Popover} from 'bootstrap';

View file

@ -1,4 +1,4 @@
import React, {ReactNode, HTMLProps, useCallback, useId} from 'react';
import {ChangeEvent, ReactNode, HTMLProps, useCallback, useId} from 'react';
import classNames from 'classnames';
type CommonProps = {

View file

@ -1,4 +1,4 @@
import React, {useMemo} from 'react';
import {useMemo} from 'react';
import {HOTP, HOTPOptions} from '@otplib/core';
import {createDigest} from '@otplib/plugin-crypto-js';
import classNames from 'classnames';
@ -20,7 +20,7 @@ function OTPCode({code, delta}: { code: string; delta: number }) {
}
export default function OTPOutput({secret, offset, algorithm, digits}: {
secret: string;
secret: ArrayBuffer;
offset: number;
algorithm: HashAlgorithm;
digits: number;
@ -35,7 +35,12 @@ export default function OTPOutput({secret, offset, algorithm, digits}: {
{[...Array(21).keys()].map((i) => {
const delta = i - 10;
const current = offset + delta;
return <OTPCode key={current} code={otp.generate(secret, current)} delta={delta}/>;
return <OTPCode key={current} code={otp.generate(
// they really wanted an ArrayBuffer or some similar binary type
// but misdeclared the type
secret as unknown as string,
current,
)} delta={delta}/>;
})}
</div>;
}

View file

@ -1,4 +1,4 @@
import React, {ChangeEvent, ReactNode, useCallback, useId} from 'react';
import {ChangeEvent, ReactNode, useCallback, useId} from 'react';
export default function Select<T extends string>({label, options, value, onChange}: {
label: ReactNode;

View file

@ -1,4 +1,3 @@
import {ALGORITHMS, HashAlgorithm} from './algorithms.tsx';
export type State = {
@ -16,7 +15,7 @@ export const defaults: State = {
} as const;
export function serializeState(state: State): string {
const values = ['secret', 'step', 'digits', 'algorithm'].map(
const values = (['secret', 'step', 'digits', 'algorithm'] as Array<keyof State>).map(
(key) => state[key] !== defaults[key] ? encodeURIComponent(state[key]) : '',
);
while (values[values.length - 1] === '') {
@ -31,6 +30,6 @@ export function deserializeState(data: string): State {
secret: values[0] || defaults.secret,
step: +values[1] || defaults.step,
digits: +values[2] || defaults.digits,
algorithm: ALGORITHMS[values[3]] !== undefined ? values[3] : defaults.algorithm,
algorithm: values[3] in ALGORITHMS !== undefined ? values[3] as HashAlgorithm : defaults.algorithm,
};
}