feat(ql3): authorize reconciliation reviews

This commit is contained in:
whyour
2026-08-21 19:34:29 +08:00
parent 827ba5294f
commit 22f58b1eff
19 changed files with 4293 additions and 107 deletions
@@ -0,0 +1,58 @@
// Security owns the read-only credential projection used by stopped-state commands.
import type { ApiCredentialRepository } from '@qinglong/runtime-core/api-credential';
import type { LocalOwnerPepperRepository } from '@qinglong/runtime-core/local-owner-pepper';
import { LocalSqliteOperationAuthority } from '../authority/operationAuthority';
import { LocalSqliteOwnerPepperRepository } from '../local-owner/ownerPepperRepository';
import {
assertLocalSqliteOptions,
assertLocalSqlitePathBoundary,
openLocalSqliteClient,
type LocalSqliteDatabaseOptions,
type LocalSqliteProfile,
} from '../storage/config';
import { LocalSqliteApiCredentialRepository } from './apiCredentialRepository';
import {
auditLocalSqliteReadiness,
type LocalSqliteReadinessEvidence,
} from '../readiness/readiness';
export interface LocalSqliteAuthenticationReadDatabase {
readonly profile: LocalSqliteProfile;
readonly readiness: LocalSqliteReadinessEvidence;
readonly apiCredentials: ApiCredentialRepository;
readonly ownerPepper: Pick<LocalOwnerPepperRepository, 'resolveKey'>;
close(): Promise<void>;
}
/**
* Opens only the repositories needed to authenticate a local User. The SQLite
* descriptor is read-only, so stopped-state review cannot change journals,
* schema, credential rows, or any other target state.
*/
export async function openLocalSqliteAuthenticationReadDatabase(
options: LocalSqliteDatabaseOptions,
): Promise<LocalSqliteAuthenticationReadDatabase> {
assertLocalSqliteOptions(options);
assertLocalSqlitePathBoundary(options.databasePath, false);
const client = openLocalSqliteClient(options, true);
try {
const readiness = await auditLocalSqliteReadiness(client);
const authority = new LocalSqliteOperationAuthority(client);
let closePromise: Promise<void> | undefined;
return Object.freeze({
profile: options.profile,
readiness,
apiCredentials: new LocalSqliteApiCredentialRepository(authority),
ownerPepper: new LocalSqliteOwnerPepperRepository(authority),
close() {
if (closePromise) return closePromise;
closePromise = authority.close();
return closePromise;
},
});
} catch (error) {
if (client.isOpen) client.close();
throw error;
}
}