diff --git a/extension/src/setup/__tests__/setup-steps.test.ts b/extension/src/setup/__tests__/setup-steps.test.ts new file mode 100644 index 0000000..e8212ad --- /dev/null +++ b/extension/src/setup/__tests__/setup-steps.test.ts @@ -0,0 +1,24 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { state, clearWizardState, renderVaultNew } from '../setup-steps'; + +describe('renderVaultNew — second-factor container choice', () => { + afterEach(() => clearWizardState()); + + it('default (image) mode shows the stego note', () => { + const html = renderVaultNew(); + expect(html).toContain('A 256-bit secret will be steganographically embedded'); + }); + + it('keyfile mode shows "Key File" and hides the carrier drop / stego note', () => { + state.secondFactor = 'keyfile'; + const html = renderVaultNew(); + expect(html).toContain('Key File'); + expect(html).not.toContain('A 256-bit secret will be steganographically embedded'); + }); + + it('keyfile mode shows the key-file note copy', () => { + state.secondFactor = 'keyfile'; + const html = renderVaultNew(); + expect(html).toContain('A 32-byte key file will be generated'); + }); +}); diff --git a/extension/src/setup/setup-steps.ts b/extension/src/setup/setup-steps.ts index 8382072..db8984b 100644 --- a/extension/src/setup/setup-steps.ts +++ b/extension/src/setup/setup-steps.ts @@ -45,6 +45,7 @@ export interface WizardState { connectionTested: boolean; vaultProbe: VaultProbe | null; carrierImageBytes: Uint8Array | null; + secondFactor: 'image' | 'keyfile'; referenceImageBytesAttach: Uint8Array | null; passphrase: string; passphraseConfirm: string; @@ -61,7 +62,7 @@ export interface WizardState { export const state: WizardState = { stepId: 'mode', mode: null, hostType: 'gitea', hostUrl: '', repoPath: '', apiToken: '', - connectionTested: false, vaultProbe: null, carrierImageBytes: null, referenceImageBytesAttach: null, + connectionTested: false, vaultProbe: null, carrierImageBytes: null, secondFactor: 'image', referenceImageBytesAttach: null, passphrase: '', passphraseConfirm: '', passphraseScore: -1, passphraseGuessesLog10: -1, passphraseVisible: false, confirmVisible: false, referenceImageBytes: null, creating: false, attaching: false, error: null, deviceName: '', @@ -375,7 +376,7 @@ function renderVaultAttach(): string { `; } -function renderVaultNew(): string { +export function renderVaultNew(): string { const score = state.passphraseScore; const hasScore = score >= 0; const meterClass = hasScore ? `s${score}` : ''; @@ -397,6 +398,14 @@ function renderVaultNew(): string { return `
image loaded
' : 'click to select a JPEG photo
'}A 256-bit secret will be steganographically embedded in this image.
-A 32-byte key file will be generated for you to save — it is your second factor.
+