Bind domain access to registered node type
This commit is contained in:
parent
f3a1ee82a2
commit
8807b99d98
15 changed files with 168 additions and 63 deletions
|
|
@ -8,6 +8,7 @@ import { TrustedSignerSnapshotLoader } from './trusted-signer-snapshot.js';
|
|||
const NOW = 1_786_291_200_000;
|
||||
const DOMAIN_ID = 'DOM-FIFTH-0001';
|
||||
const NODE_ID = 'LOCAL-001';
|
||||
const NODE_TYPE = 'local-terminal' as const;
|
||||
const COMMIT = 'a'.repeat(40);
|
||||
const ANCHOR_URL = 'https://guanghulab.com/api/ai/v1/anchor';
|
||||
const REGISTRY_URL = `https://guanghulab.com/code/bingshuo/guanghu-ice-heart/raw/commit/${COMMIT}/routing/trusted-domain-manifest-signers.json`;
|
||||
|
|
@ -85,6 +86,7 @@ function validHandoff() {
|
|||
domainId: DOMAIN_ID,
|
||||
manifestDigest: digest,
|
||||
nodeId: NODE_ID,
|
||||
nodeType: NODE_TYPE,
|
||||
receiptId: 'RECEIPT-001',
|
||||
state: 'online',
|
||||
},
|
||||
|
|
@ -98,6 +100,7 @@ function validHandoff() {
|
|||
domainId: DOMAIN_ID,
|
||||
expiresAt: NOW + 60_000,
|
||||
nodeId: NODE_ID,
|
||||
nodeType: NODE_TYPE,
|
||||
scopes: ['domain:enter'],
|
||||
},
|
||||
};
|
||||
|
|
@ -107,11 +110,11 @@ test('projects public trust health without asking for a handoff before login', a
|
|||
let handoffReads = 0;
|
||||
const orchestrator = new DomainAccessOrchestrator(
|
||||
loader(),
|
||||
{ async read() { return { accountVerified: false, nodeId: '' }; } },
|
||||
{ async read() { return { accountVerified: false, nodeId: '', nodeRegistrationVerified: false }; } },
|
||||
{ async read() { handoffReads += 1; return null; } },
|
||||
);
|
||||
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NOW);
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NODE_TYPE, NOW);
|
||||
|
||||
assert.equal(handoffReads, 0);
|
||||
assert.equal(status.stage, 'login-required');
|
||||
|
|
@ -128,21 +131,36 @@ test('projects public trust health without asking for a handoff before login', a
|
|||
test('an authenticated node without a verified handoff remains identity-only', async () => {
|
||||
const orchestrator = new DomainAccessOrchestrator(
|
||||
loader(),
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID }; } },
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID, nodeRegistrationVerified: true }; } },
|
||||
{ async read() { return null; } },
|
||||
);
|
||||
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NOW);
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NODE_TYPE, NOW);
|
||||
|
||||
assert.equal(status.stage, 'identity-verified');
|
||||
assert.equal(status.runtimeReady, false);
|
||||
assert.ok(status.blockers.includes('verified_domain_manifest_missing'));
|
||||
});
|
||||
|
||||
test('a code-channel account without node registration never contacts a domain handoff route', async () => {
|
||||
let handoffReads = 0;
|
||||
const orchestrator = new DomainAccessOrchestrator(
|
||||
loader(),
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID, nodeRegistrationVerified: false }; } },
|
||||
{ async read() { handoffReads += 1; return validHandoff() as never; } },
|
||||
);
|
||||
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NODE_TYPE, NOW);
|
||||
|
||||
assert.equal(handoffReads, 0);
|
||||
assert.equal(status.stage, 'login-required');
|
||||
assert.ok(status.blockers.includes('verified_node_registration_missing'));
|
||||
});
|
||||
|
||||
test('a loaded signer snapshot and verified handoff project runtime-ready', async () => {
|
||||
const orchestrator = new DomainAccessOrchestrator(
|
||||
loader(() => registry([activeSigner()])),
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID }; } },
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID, nodeRegistrationVerified: true }; } },
|
||||
{ async read() {
|
||||
return {
|
||||
handoff: validHandoff(),
|
||||
|
|
@ -151,7 +169,7 @@ test('a loaded signer snapshot and verified handoff project runtime-ready', asyn
|
|||
} },
|
||||
);
|
||||
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NOW);
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NODE_TYPE, NOW);
|
||||
|
||||
assert.equal(status.stage, 'runtime-ready');
|
||||
assert.equal(status.runtimeReady, true);
|
||||
|
|
@ -162,11 +180,11 @@ test('a loaded signer snapshot and verified handoff project runtime-ready', asyn
|
|||
test('source and handoff failures are reduced to safe status without raw details', async () => {
|
||||
const orchestrator = new DomainAccessOrchestrator(
|
||||
new TrustedSignerSnapshotLoader({ async fetchJson() { throw new Error('secret source detail'); } }),
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID }; } },
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID, nodeRegistrationVerified: true }; } },
|
||||
{ async read() { throw new Error('secret handoff detail'); } },
|
||||
);
|
||||
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NOW);
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NODE_TYPE, NOW);
|
||||
|
||||
assert.equal(status.stage, 'identity-verified');
|
||||
assert.equal(status.runtimeReady, false);
|
||||
|
|
@ -182,7 +200,7 @@ test('a last-known-good signer can project access while preserving degraded heal
|
|||
currentRegistry = { ...registry([activeSigner()]), version: 'invalid' };
|
||||
const orchestrator = new DomainAccessOrchestrator(
|
||||
signerLoader,
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID }; } },
|
||||
{ async read() { return { accountVerified: true, nodeId: NODE_ID, nodeRegistrationVerified: true }; } },
|
||||
{ async read() {
|
||||
return {
|
||||
handoff: validHandoff(),
|
||||
|
|
@ -191,7 +209,7 @@ test('a last-known-good signer can project access while preserving degraded heal
|
|||
} },
|
||||
);
|
||||
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NOW);
|
||||
const status = await orchestrator.domainAccess(DOMAIN_ID, NODE_TYPE, NOW);
|
||||
|
||||
assert.equal(status.runtimeReady, true);
|
||||
assert.equal(status.trustSource.status, 'DEGRADED_LAST_KNOWN_GOOD');
|
||||
|
|
|
|||
Loading…
Reference in a new issue