ext(sw): add preview_totp_from_secret popup handler
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
import type { PopupMessage, Response } from '../../shared/messages';
|
||||
import type { Item, ItemId, Manifest, VaultConfig, SetupState, DeviceSettings, TotpConfig, AttachmentRef } from '../../shared/types';
|
||||
import { DEFAULT_DEVICE_SETTINGS } from '../../shared/types';
|
||||
import { base32Decode } from '../../shared/base32';
|
||||
import type { GitHost } from '../git-host';
|
||||
import { createGitHost, base64ToUint8Array } from '../git-host';
|
||||
import * as vault from '../vault';
|
||||
@@ -169,6 +170,29 @@ export async function handle(
|
||||
return { ok: true, data: { groups: Array.from(set).sort() } };
|
||||
}
|
||||
|
||||
case 'preview_totp_from_secret': {
|
||||
const cleaned = msg.secret_b32.toUpperCase().replace(/\s+/g, '').replace(/=+$/, '');
|
||||
if (cleaned.length < 16 || !/^[A-Z2-7]+$/.test(cleaned)) {
|
||||
return { ok: false, error: 'invalid base32 secret' };
|
||||
}
|
||||
let secretBytes: Uint8Array;
|
||||
try {
|
||||
secretBytes = base32Decode(cleaned);
|
||||
} catch (e) {
|
||||
return { ok: false, error: `invalid base32: ${e instanceof Error ? e.message : String(e)}` };
|
||||
}
|
||||
const cfg = {
|
||||
secret: Array.from(secretBytes),
|
||||
algorithm: 'sha1',
|
||||
digits: 6,
|
||||
period_seconds: 30,
|
||||
kind: 'totp',
|
||||
};
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const result = state.wasm.totp_compute(JSON.stringify(cfg), BigInt(now));
|
||||
return { ok: true, data: { code: result.code, expires_at: result.expires_at } };
|
||||
}
|
||||
|
||||
case 'generate_password': {
|
||||
const password = state.wasm.generate_password(JSON.stringify(msg.request));
|
||||
return { ok: true, data: { password } };
|
||||
|
||||
Reference in New Issue
Block a user