Reference source · 0.1.0-dev.11
fixtures.ts
src/reference/fixtures.ts · Download original file
import { makeAuthority, makeIdentity, signCredential, signStatus, TrustStore } from '../identity.ts';
import type { DecisionProvider, Representative, AuthorizationOptions } from '../authorization.ts';
import { SCOPES } from '../authorization.ts';
import { ReferenceHost } from '../host.ts';
import { Client } from '../sdk.ts';
import { seconds } from '../core.ts';
export const PATIENT = 'synthetic-patient-001';
export const OTHER_PATIENT = 'synthetic-patient-002';
export function lab(patient = PATIENT): Record<string, any> {
return { resourceType: 'Observation', status: 'final', category: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/observation-category', code: 'laboratory' }] }],
code: { coding: [{ system: 'http://loinc.org', code: '2345-7' }] }, subject: { reference: `Patient/${patient}` }, valueQuantity: { value: 92, unit: 'mg/dL' } };
}
export function fixture(path = ':memory:', options: AuthorizationOptions = {}) {
let now = seconds(); const started = now;
const hostingAuthority = makeAuthority('authority-hosts.example');
const applicationAuthority = makeAuthority('authority-apps.example');
const hostIdentity = makeIdentity('urn:oprp:demo:host');
const appIdentity = makeIdentity('urn:oprp:demo:hospital');
const parentIdentity = makeIdentity('urn:oprp:demo:parent');
const trust = new TrustStore({
[hostingAuthority.issuer]: { publicKey: hostingAuthority.publicKey, kinds: ['host'], subjectPrefixes: ['urn:oprp:demo:'], roles: {}, maximumLifetime: 86400, maximumStatusAge: 600 },
[applicationAuthority.issuer]: { publicKey: applicationAuthority.publicKey, kinds: ['application', 'person'], subjectPrefixes: ['urn:oprp:demo:'], roles: { application: ['emergency-provider'] }, maximumLifetime: 86400, maximumStatusAge: 600 },
});
let statusSequence = 0;
const updateStatus = () => { statusSequence++; for (const authority of [hostingAuthority, applicationAuthority]) trust.ingestStatus(signStatus(authority, statusSequence, now), now); };
updateStatus();
const hostCredential = signCredential(hostingAuthority, hostIdentity.public, 'host', now);
const appCredential = signCredential(applicationAuthority, appIdentity.public, 'application', now, ['emergency-provider']);
const parentCredential = signCredential(applicationAuthority, parentIdentity.public, 'person', now);
const app = trust.validate(appCredential, now);
const representatives: Representative[] = [{ actor: parentIdentity.public.subject, patient: PATIENT, scopes: [SCOPES.demographicsRead], manageScopes: [SCOPES.demographicsRead], active: true, expiresAt: now + 7200 }];
const policy: DecisionProvider = (request, context) => ({ maximumDuration: 90 * 86400,
scopes: Object.fromEntries(request.scopes.map(scope => [scope,
request.patient !== PATIENT ? 'deny' : context.actor ? 'allow' : scope === SCOPES.demographicsRead && request.requested_duration_seconds <= 86400 ? 'allow' : 'approval_required'])) });
const host = new ReferenceHost(path, hostIdentity, hostCredential, trust, policy, representatives, options);
host.seed(PATIENT, { name: [{ text: 'Synthetic Example' }] });
host.seed(OTHER_PATIENT, { name: [{ text: 'Other Synthetic Example' }] });
const client = new Client({ identity: appIdentity, credential: appCredential, hostCredential, hostId: hostIdentity.public.subject, trust,
transport: async envelope => host.handle(envelope, now), clock: () => now });
return { host, client, app, appIdentity, hostIdentity, parentIdentity, parentCredential, hostCredential, appCredential,
trust, policy, representatives, hostingAuthority, applicationAuthority, started, clock: () => now, advance: (amount: number) => { now += amount; updateStatus(); } };
}