mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 16:14:07 +00:00
fix: ask to clear a desktop app lock this profile has no PIN for
This commit is contained in:
@@ -84,6 +84,7 @@ function bridge(overrides: Record<string, unknown> = {}) {
|
||||
prove: vi.fn(async () => true),
|
||||
disable: vi.fn(async () => true),
|
||||
forget: vi.fn(async () => true),
|
||||
clearOrphan: vi.fn(async () => true),
|
||||
osEnroll: vi.fn(async () => true),
|
||||
osRemove: vi.fn(async () => {}),
|
||||
osUnlock: vi.fn(async () => ({ ok: false as const, reason: 'denied' as const })),
|
||||
@@ -439,6 +440,32 @@ describe('the store when a tab inherits it without the key', () => {
|
||||
});
|
||||
|
||||
describe('the desktop app', () => {
|
||||
const settled = () => new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
it('asks main to clear a lock this profile has no PIN for', async () => {
|
||||
const appLock = bridge({ status: vi.fn(async () => ({ locked: true, enrolled: true, os: null, osEnrolled: false })) });
|
||||
bootAppLock();
|
||||
await settled();
|
||||
expect(appLock.clearOrphan).toHaveBeenCalledTimes(1);
|
||||
expect(appLock.forget).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('leaves main alone when there is a vault, so a real lock is never questioned', async () => {
|
||||
const raw = await createVault(PIN);
|
||||
raw.fill(0);
|
||||
const appLock = bridge({ status: vi.fn(async () => ({ locked: true, enrolled: true, os: null, osEnrolled: false })) });
|
||||
bootAppLock();
|
||||
await settled();
|
||||
expect(appLock.clearOrphan).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('asks nothing when main has no lock', async () => {
|
||||
const appLock = bridge({ status: vi.fn(async () => ({ locked: false, enrolled: false, os: null, osEnrolled: false })) });
|
||||
bootAppLock();
|
||||
await settled();
|
||||
expect(appLock.clearOrphan).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('a PIN unlock proves itself to main, and nothing can just say unlocked', async () => {
|
||||
const appLock = bridge();
|
||||
await enableAppLock(PIN);
|
||||
|
||||
@@ -191,6 +191,7 @@ export function bootAppLock(): void {
|
||||
return;
|
||||
}
|
||||
markDocument(false);
|
||||
void clearOrphanedDesktopLock();
|
||||
// The look already came back empty: nothing to hold back for.
|
||||
if (headScriptFoundNoVault() && !setupNeeded()) return;
|
||||
hold = newHold();
|
||||
@@ -203,6 +204,19 @@ export function bootAppLock(): void {
|
||||
void settleNoFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main keeps a lock and there is no vault for it: a same-origin plugin frame enrolled one, or
|
||||
* this profile's storage went. Nothing here could ever prove it, so tray, toasts and titles would
|
||||
* stay blank for good. No page can lift main's lock on its word, so main asks the user.
|
||||
*/
|
||||
async function clearOrphanedDesktopLock(): Promise<void> {
|
||||
const member = getDesktopBridge()?.appLock;
|
||||
if (!member?.clearOrphan) return;
|
||||
const status = await member.status().catch(() => null);
|
||||
if (!status?.enrolled || await vaultExists() || enabling || readAppLockFile().on) return;
|
||||
await member.clearOrphan().catch(() => false);
|
||||
}
|
||||
|
||||
function lockedFromNow(): void {
|
||||
writeAppLockFile({ ...readAppLockFile(), on: true, locked: true });
|
||||
setLockedHere(true);
|
||||
|
||||
@@ -367,6 +367,8 @@ export interface DesktopAppLockBridge {
|
||||
disable: (proof: Uint8Array) => Promise<boolean>;
|
||||
/** The PIN is lost, or everyone signed out. With no proof, main asks the user natively. */
|
||||
forget: (proof?: Uint8Array) => Promise<boolean>;
|
||||
/** Main keeps a lock and this profile has no PIN for it. Main asks the user natively, once a run. */
|
||||
clearOrphan?: () => Promise<boolean>;
|
||||
/** Through safeStorage, for this origin only. Null where the OS has no real key store. */
|
||||
wrap: (data: Uint8Array) => Promise<Uint8Array | null>;
|
||||
unwrap: (data: Uint8Array) => Promise<Uint8Array | null>;
|
||||
|
||||
Reference in New Issue
Block a user