fix(keychain): version startup consent policy

This commit is contained in:
NimBold
2026-07-15 21:21:35 +03:30
parent d2479f52be
commit ed54a048ab
4 changed files with 45 additions and 12 deletions
+19 -1
View File
@@ -1,7 +1,25 @@
import { describe, expect, it } from 'vitest';
import { getKeychainStartupDecision } from './keychainStartup';
import { getKeychainConsentVersion, getKeychainStartupDecision } from './keychainStartup';
describe('getKeychainStartupDecision', () => {
it('changes the consent identity when the credential-access policy changes', () => {
expect(getKeychainConsentVersion('1.1.0')).toBe('1.1.0|keychain-policy-2');
expect(getKeychainConsentVersion('')).toBe('');
});
it('re-prompts when the app build keeps the same semantic version', () => {
expect(getKeychainStartupDecision({
portable: false,
appVersion: getKeychainConsentVersion('1.1.0'),
approvedVersion: '1.1.0',
accessGranted: true,
promptDismissed: true
})).toEqual({
deferKeychainHydration: true,
showKeychainPrompt: true
});
});
it('defers persistent hydration and shows the explanation after an update', () => {
expect(getKeychainStartupDecision({
portable: false,
+13
View File
@@ -11,6 +11,19 @@ export type KeychainStartupDecision = {
showKeychainPrompt: boolean;
};
// The semantic app version can remain unchanged across release-candidate and
// packaging rebuilds. Bump this contract version whenever a build can require
// a fresh credential-store authorization, so an updated binary cannot skip
// Firelink's explanation and invoke the OS prompt directly.
const KEYCHAIN_CONSENT_POLICY_VERSION = '2';
export const getKeychainConsentVersion = (appVersion: string): string => {
const normalizedVersion = appVersion.trim();
return normalizedVersion
? `${normalizedVersion}|keychain-policy-${KEYCHAIN_CONSENT_POLICY_VERSION}`
: '';
};
export const getKeychainStartupDecision = ({
portable,
appVersion,