({
hashes,
input,
}: {
hashes: string[];
input: string;
})
| 83 | } |
| 84 | |
| 85 | export async function consumeRecoveryCode({ |
| 86 | hashes, |
| 87 | input, |
| 88 | }: { |
| 89 | hashes: string[]; |
| 90 | input: string; |
| 91 | }): Promise<{ valid: boolean; remaining: string[] }> { |
| 92 | const normalized = normalizeRecoveryCode(input); |
| 93 | for (let i = 0; i < hashes.length; i++) { |
| 94 | const hash = hashes[i]!; |
| 95 | // Sequential verify is fine — argon2 is slow on purpose and the list is 10 entries. |
| 96 | const matched = await verifyPasswordHash(hash, normalized); |
| 97 | if (matched) { |
| 98 | const remaining = hashes.slice(0, i).concat(hashes.slice(i + 1)); |
| 99 | return { valid: true, remaining }; |
| 100 | } |
| 101 | } |
| 102 | return { valid: false, remaining: hashes }; |
| 103 | } |
no test coverage detected