import { evaluateDomainAccess, verifyDomainAccessHandoffFromSnapshot, type DomainAccessEvidence, type DomainNodeType, type DomainAccessStatus, } from './domain-access.js'; import { TrustedSignerSnapshotLoader, type TrustedSignerSnapshotReceipt, } from './trusted-signer-snapshot.js'; import { resolveNodeRegistrationEndpoint, verifyNodeRegistrationClaim, } from './node-registration.js'; import { assertLoadedNodeRegistrationSnapshot, NodeRegistrationSnapshotLoader, type NodeRegistrationSnapshotReceipt, } from './node-registration-snapshot.js'; import type { NodeRegistrationClaimSource } from './node-registration-client.js'; import { createNodePossessionChallenge, verifyNodePossessionResponse, type NodePossessionProofSource, type VerifiedNodePossession, } from './node-possession-proof.js'; const IDENTIFIER_PATTERN = /^[A-Z0-9][A-Z0-9._:-]{1,159}$/; export interface DomainIdentityProjection { accountId: string; accountVerified: boolean; nodeId: string; } export interface DomainIdentitySource { read(domainId: string, nodeType: DomainNodeType): Promise; } export interface DomainRuntimeHandoffCandidate { handoff: unknown; signerLookup: { repositoryId: string; signerId: string; }; } export interface DomainRuntimeHandoffSource { read(possession: VerifiedNodePossession): Promise; } export interface DomainAccessProjection { blockers: readonly string[]; domainId: string; localWorkspaceAllowed: true; nodeId: string; nodeType: DomainNodeType; nodeRegistrationSource: Readonly; runtimeReady: boolean; stage: DomainAccessStatus['stage']; trustSource: Readonly; } function safeIdentity(input: unknown): DomainIdentityProjection { if (typeof input !== 'object' || input === null || Array.isArray(input)) { return { accountId: '', accountVerified: false, nodeId: '' }; } const candidate = input as Record; const accountId = typeof candidate.accountId === 'string' && /^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$/.test(candidate.accountId) ? candidate.accountId : ''; const nodeId = typeof candidate.nodeId === 'string' && IDENTIFIER_PATTERN.test(candidate.nodeId) ? candidate.nodeId : ''; return { accountId, accountVerified: candidate.accountVerified === true && Boolean(accountId) && Boolean(nodeId), nodeId, }; } export class DomainAccessOrchestrator { constructor( private readonly signerSnapshots: TrustedSignerSnapshotLoader, private readonly nodeRegistrationSnapshots: NodeRegistrationSnapshotLoader, private readonly identities: DomainIdentitySource, private readonly nodeRegistrations: NodeRegistrationClaimSource, private readonly nodePossessions: NodePossessionProofSource, private readonly handoffs: DomainRuntimeHandoffSource, private readonly clock: () => number = Date.now, ) {} async domainAccess(domainId: string, nodeType: DomainNodeType, at?: number): Promise> { let now = at ?? this.clock(); if (!IDENTIFIER_PATTERN.test(domainId)) throw new Error('domain_access_domain_invalid'); if (nodeType !== 'local-terminal' && nodeType !== 'cloud-resident') throw new Error('domain_access_node_type_invalid'); const [snapshot, nodeRegistrationSnapshot, identity] = await Promise.all([ this.signerSnapshots.refresh(), this.nodeRegistrationSnapshots.refresh(), this.identities.read(domainId, nodeType).then(safeIdentity, () => safeIdentity(null)), ]); let nodeRegistrationVerified = false; let nodePossessionVerified = false; let possession: VerifiedNodePossession | null = null; if (identity.accountVerified && nodeRegistrationSnapshot.receipt.status === 'CURRENT') { try { const loaded = assertLoadedNodeRegistrationSnapshot(nodeRegistrationSnapshot); const endpoint = loaded.registry && resolveNodeRegistrationEndpoint(loaded.registry, { domainId, nodeType }); if (endpoint) { const claim = await this.nodeRegistrations.read(Object.freeze({ accountId: identity.accountId, domainId, endpoint, nodeId: identity.nodeId, nodeType, })); if (claim) { const registration = verifyNodeRegistrationClaim(claim, { accountId: identity.accountId, domainId, nodeId: identity.nodeId, nodeType, }, endpoint, now); nodeRegistrationVerified = true; const challenge = createNodePossessionChallenge(registration, now); const response = await this.nodePossessions.prove(challenge); if (response) { if (at === undefined) now = this.clock(); possession = verifyNodePossessionResponse(response, challenge, registration, now); nodePossessionVerified = true; } } } } catch { nodeRegistrationVerified = false; } } const evidence: DomainAccessEvidence = { accountVerified: identity.accountVerified, domainId, nodeId: identity.nodeId, nodePossessionVerified, nodeRegistrationVerified, nodeType, }; if (identity.accountVerified && nodeRegistrationVerified && nodePossessionVerified && possession) { let candidate: DomainRuntimeHandoffCandidate | null = null; try { candidate = await this.handoffs.read(possession); } catch { candidate = null; } if (candidate) { try { const verified = verifyDomainAccessHandoffFromSnapshot( candidate.handoff, domainId, identity.nodeId, nodeType, candidate.signerLookup, snapshot, now, ); Object.assign(evidence, verified.handoff); } catch { // Untrusted or incomplete handoffs remain absent from the projection. } } } const status = evaluateDomainAccess(evidence, now); return Object.freeze({ ...status, blockers: Object.freeze([...status.blockers]), nodeRegistrationSource: nodeRegistrationSnapshot.receipt, trustSource: snapshot.receipt, }); } }