* Upgrade to fhir r4 (#35)

* Add C19 immunization example

* Add summary examples for immunization status

* Clarify role of issuer in examples

* Update FHIR R2 -> R4

* Update sidetree v1.0 (#37)

* Update to sidetree 1.0

* Update date -> occurrenceDateTime for Immunizations

* Update canonical domain to smarthealth.cards (#39)
This commit is contained in:
Josh Mandel 2021-01-26 17:36:44 -06:00 коммит произвёл GitHub
Родитель 62bed14615
Коммит 5ed3496122
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
27 изменённых файлов: 1360 добавлений и 6594 удалений

7656
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -20,7 +20,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@decentralized-identity/sidetree": "^0.9.1",
"@decentralized-identity/sidetree": "^1.0.0",
"@types/node-jose": "^1.1.5",
"@types/react": "^16.9.55",
"@types/react-dom": "^16.9.9",
@ -29,6 +29,7 @@
"base-64": "^0.1.0",
"base64url": "^3.0.1",
"bootstrap": "^4.5.3",
"canonicalize": "^1.0.5",
"cbor": "^5.1.0",
"cheerio": "^1.0.0-rc.3",
"cors": "^2.8.5",

Просмотреть файл

@ -53,10 +53,10 @@ const CovidCard: React.FC<{
if (smartState?.access_token && issuerInteraction?.siopResponse && holderState.vcStore.length === 0) {
/*
const credentials = axios.get(uiState.fhirClient.server + `/DiagnosticReport?patient=${smartState.patient}&_tag=https://healthwallet.cards|covid19`)
const credentials = axios.get(uiState.fhirClient.server + `/DiagnosticReport?patient=${smartState.patient}&_tag=https://smarthealth.cards|covid19`)
credentials.then(response => {
const vcs = response.data.entry[0].resource.extension
.filter(e => e.url === 'https://healthwallet.cards#vc-attachment')
.filter(e => e.url === 'https://smarthealth.cards#vc-attachment')
.map(e => base64.decode(e.valueAttachment.data))
dispatchToHolder(retrieveVcs(vcs, holderState))
@ -67,10 +67,10 @@ const CovidCard: React.FC<{
"resourceType": "Parameters",
"parameter": [{
"name": "credentialType",
"valueUri": "https://healthwallet.cards#health-card"
"valueUri": "https://smarthealth.cards#health-card"
},{
"name": "presentationContext",
"valueUri": "https://healthwallet.cards#presentation-context-online"
"valueUri": "https://smarthealth.cards#presentation-context-online"
}, {
"name": "encryptForKeyId",
"valueString": "#encryption-key-1"
@ -84,7 +84,7 @@ const CovidCard: React.FC<{
}, [smartState, holderState.interactions])
const covidVcs = holderState.vcStore.filter(vc => vc.type.includes("https://healthwallet.cards#covid19"));
const covidVcs = holderState.vcStore.filter(vc => vc.type.includes("https://smarthealth.cards#covid19"));
const conclusions = covidVcs.flatMap(vc =>
vc.vcPayload.vc.credentialSubject.fhirBundle.entry
.filter(e => e.resource.resourceType === 'DiagnosticReport')

Просмотреть файл

@ -102,10 +102,10 @@ export const SiopApprovalModal: React.FC<SiopApprovalProps | null> = (props) =>
<ModalBody>The following details will be shared:
<ul>
<li><b>Your ID Card:</b> allows secure communications</li>
{props.share.includes('https://healthwallet.cards#covid19') && <li>
{props.share.includes('https://smarthealth.cards#covid19') && <li>
<b>Your COVID Card:</b> labs and vaccines for COVID-19
</li>}
{props.share.includes('https://healthwallet.cards#immunization') && <li>
{props.share.includes('https://smarthealth.cards#immunization') && <li>
<b>Your Immunizations Card:</b> full vaccine history
</li>}
</ul>

Просмотреть файл

@ -82,19 +82,19 @@ export interface CredentialGenerationDetals {
}
export const defaultIdentityClaims = {
"https://healthwallet.cards#presentation-context-online": [
"https://smarthealth.cards#presentation-context-online": [
"Patient.telecom",
"Patient.name",
],
"https://healthwallet.cards#presentation-context-in-person": [
"https://smarthealth.cards#presentation-context-in-person": [
"Patient.name",
"Patient.photo"
]
}
export const issueVcsToHolder = async (state: VerifierState, details: CredentialGenerationDetals = {
type: 'https://healthwallet.cards#covid19',
presentationContext: 'https://healthwallet.cards#presentation-context-online',
type: 'https://smarthealth.cards#covid19',
presentationContext: 'https://smarthealth.cards#presentation-context-online',
identityClaims: null,
encryptVc: true,
}): Promise<{

Просмотреть файл

@ -1,5 +1,5 @@
import { EncryptionKey, SigningKey, KeyGenerators } from './KeyTypes';
export type ClaimType = 'https://healthwallet.cards#covid19' | 'https://healthwallet.cards#immunization' | 'https://healthwallet.cards#tdap';
export type ClaimType = 'https://smarthealth.cards#covid19' | 'https://smarthealth.cards#immunization' | 'https://smarthealth.cards#tdap';
export type SiopResponseMode = 'form_post' | 'fragment';
export interface VerifierState {

Просмотреть файл

@ -21,11 +21,9 @@ export async function verifyJws(jws: string, {
const ENCRYPTION_KEY_TYPES = ['JsonWebKey2020', 'JwsVerificationKey2020'];
export async function encryptFor(jws: string, did: string, { generateEncryptionKey }: KeyGenerators, keyIdIn?: string) {
const didDoc = (await axios.get(resolveUrl + encodeURIComponent(did))).data;
const encryptionKeys = didDoc.publicKey.filter(k => k.publicKeyJwk.alg === 'ECDH-ES');
const keyId = keyIdIn ? keyIdIn : encryptionKeys[0].id;
const encryptionKey = encryptionKeys.filter(k => k.id === keyId)[0]
const didDoc = (await axios.get(resolveUrl +did)).data;
const keyId = keyIdIn ? keyIdIn : '#' + didDoc.keyAgreement[0].split("#")[1];
const encryptionKey = didDoc.verificationMethod.filter(k => k.id == keyId)[0];
const ek = await generateEncryptionKey({
...encryptionKey.publicKeyJwk,
@ -35,63 +33,70 @@ export async function encryptFor(jws: string, did: string, { generateEncryptionK
}
const resolveKeyId = async (kid: string): Promise<JsonWebKey> => {
const fragment = '#' + kid.split('#')[1];
const didDoc = (await axios.get(resolveUrl + encodeURIComponent(kid))).data;
return didDoc.publicKey.filter(k => k.id === fragment)[0].publicKeyJwk;
const didDoc = (await axios.get(resolveUrl +kid)).data;
return didDoc.verificationMethod.filter(k => k.id === fragment)[0].publicKeyJwk;
};
export async function generateDid({ signingPublicJwk, encryptionPublicJwk, recoveryPublicJwk, updatePublicJwk, domains = [] as string[]}) {
const hashAlgorithmName = multihashes.codes[18];
const hash = (b: string|Buffer) => multihashes.encode(crypto.createHash('sha256').update(b).digest(), hashAlgorithmName);
const revealCommitPair = (publicKey: SigningKey) => {
const revealValueEncodedString = canonicalize(publicKey)
const commitmentHash = hash(revealValueEncodedString);
const commitmentHashEncodedString = base64url.encode(commitmentHash);
return [revealValueEncodedString, commitmentHashEncodedString];
const revealValueEncodedString = canonicalize(publicKey);
const commitmentHashHash = hash(hash(revealValueEncodedString));
const commitmentHashHashEncodedString = base64url.encode(commitmentHashHash);
return [revealValueEncodedString, commitmentHashHashEncodedString];
};
const [recoveryValue, recoveryCommitment] = revealCommitPair(recoveryPublicJwk);
const [updateValue, updateCommitment] = revealCommitPair(updatePublicJwk);
let patches: {action: string, public_keys?: any, service_endpoints?: any}[] = [{
let patches: {action: string, publicKeys?: any, services?: any}[] = [{
action: 'add-public-keys',
public_keys: [{
publicKeys: [{
id: 'signing-key-1',
purpose: ['general', 'auth'],
purposes: ['authentication', 'assertionMethod'],
type: 'JsonWebKey2020',
jwk: signingPublicJwk
publicKeyJwk: JSON.parse(JSON.stringify({...signingPublicJwk, kid: undefined}))
}, {
id: 'encryption-key-1',
purpose: ['general', 'auth'],
purposes: ['keyAgreement', 'assertionMethod'],
type: 'JsonWebKey2020',
jwk: encryptionPublicJwk
publicKeyJwk: JSON.parse(JSON.stringify({...encryptionPublicJwk, kid: undefined}))
}]
}]
if (domains.length > 0) {
patches.push({
"action": "add-service-endpoints",
"service_endpoints": [{
"action": "add-services",
"services": [{
"id": "linked-domain",
"type": "LinkedDomains",
"endpoint": domains[0]
"serviceEndpoint": domains[0]
}]
});
}
console.log("Patches", JSON.stringify(patches, null, 2));
const delta: Record<string, any> = {
'update_commitment': updateCommitment,
updateCommitment,
patches
};
const deltaCanonical = JSON.stringify(delta);
const deltaEncoded = base64url.encode(deltaCanonical);
const suffixData = {
delta_hash: base64url.encode(hash(Buffer.from(deltaCanonical))),
recovery_commitment: recoveryCommitment
};
const suffixDataCanonical = JSON.stringify(suffixData);
const suffix = base64url.encode(hash(Buffer.from(suffixDataCanonical)));
const deltaCanonical = canonicalize(delta);
const suffixData = {
deltaHash: base64url.encode(hash(Buffer.from(deltaCanonical))),
recoveryCommitment: recoveryCommitment
};
const suffixDataCanonical = canonicalize(suffixData);
const suffix = base64url.encode(hash(Buffer.from(suffixDataCanonical)));
const didShort = `did:ion:${suffix}`;
const suffixDataEncoded = base64url.encode(suffixDataCanonical);
const didLong = `did:ion:${suffix}?-ion-initial-state=${suffixDataEncoded}.${deltaEncoded}`;
return {
const longFormPayload = { suffixData, delta };
const longFormPayloadCanonical = canonicalize(longFormPayload);
const longFormFinalSegment = base64url.encode(longFormPayloadCanonical);
const didLong = `${didShort}:${longFormFinalSegment}`;
let ret = {
did: didLong,
recoveryValue,
recoveryCommitment,
@ -99,12 +104,13 @@ export async function generateDid({ signingPublicJwk, encryptionPublicJwk, recov
updateCommitment,
delta,
deltaCanonical,
deltaEncoded,
suffixData,
suffixDataCanonical,
suffixDataEncoded,
didShort,
didLong
}
};
console.log("Key deets", ret);
return ret;
}
const jwtHeader = (jwt) => JSON.parse(base64url.decode(jwt.split('.')[0]));

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -10,12 +10,12 @@
],
"type": [
"VerifiableCredential",
"https://healthwallet.cards#health-card",
"https://healthwallet.cards#covid19",
"https://healthwallet.cards#presentation-context-online"
"https://smarthealth.cards#health-card",
"https://smarthealth.cards#covid19",
"https://smarthealth.cards#presentation-context-online"
],
"credentialSubject": {
"fhirVersion": "1.0.2",
"fhirVersion": "4.0.1",
"fhirBundle": {
"resourceType": "Bundle",
"type": "collection",
@ -32,9 +32,7 @@
],
"name": [
{
"family": [
"Everywoman"
],
"family": "Everywoman",
"given": [
"Eve"
]

Просмотреть файл

@ -10,12 +10,12 @@
],
"type": [
"VerifiableCredential",
"https://healthwallet.cards#health-card",
"https://healthwallet.cards#immunization",
"https://healthwallet.cards#covid19"
"https://smarthealth.cards#health-card",
"https://smarthealth.cards#immunization",
"https://smarthealth.cards#covid19"
],
"credentialSubject": {
"fhirVersion": "1.0.2",
"fhirVersion": "4.0.1",
"fhirBundle": {
"resourceType": "Bundle",
"type": "collection",
@ -32,9 +32,7 @@
],
"name": [
{
"family": [
"Everywoman"
],
"family": "Everywoman",
"given": [
"Evelyn"
]
@ -53,7 +51,7 @@
"resource": {
"resourceType": "Immunization",
"status": "completed",
"date": "2020-12-18",
"occurrenceDateTime": "2020-12-18",
"vaccineCode": {
"coding": [
{
@ -78,7 +76,7 @@
"resource": {
"resourceType": "Immunization",
"status": "completed",
"date": "2021-01-14",
"occurrenceDateTime": "2021-01-14",
"vaccineCode": {
"coding": [
{

Просмотреть файл

@ -2,12 +2,12 @@
"@context": [
"https://www.w3.org/2018/credentials/v1"
],
"type": [ "VerifiableCredential", "https://healthwallet.cards#health-card"],
"type": [ "VerifiableCredential", "https://smarthealth.cards#health-card"],
"issuer": "<<did:ion identifier for issuer>>",
"issuanceDate": "2020-06-01T11:59:00-07:00",
"credentialSubject": {
"id": "<<did:identifier for subject if known>>",
"fhirVersion": "1.0.2",
"fhirVersion": "4.0.1",
"fhirBundle":{
"resourceType": "Bundle",
"type": "collection",

Просмотреть файл

@ -10,12 +10,12 @@
],
"type": [
"VerifiableCredential",
"https://healthwallet.cards#health-card",
"https://healthwallet.cards#covid19",
"https://healthwallet.cards#presentation-context-online"
"https://smarthealth.cards#health-card",
"https://smarthealth.cards#covid19",
"https://smarthealth.cards#presentation-context-online"
],
"credentialSubject": {
"fhirVersion": "1.0.2",
"fhirVersion": "4.0.1",
"fhirBundle": {
"resourceType": "Bundle",
"type": "collection",
@ -32,9 +32,7 @@
],
"name": [
{
"family": [
"Everywoman"
],
"family": "Everywoman",
"given": [
"Eve"
]

Просмотреть файл

@ -10,13 +10,13 @@
],
"type": [
"VerifiableCredential",
"https://healthwallet.cards#health-card",
"https://healthwallet.cards#immunization",
"https://healthwallet.cards#tdap",
"https://healthwallet.cards#presentation-context-online"
"https://smarthealth.cards#health-card",
"https://smarthealth.cards#immunization",
"https://smarthealth.cards#tdap",
"https://smarthealth.cards#presentation-context-online"
],
"credentialSubject": {
"fhirVersion": "1.0.2",
"fhirVersion": "4.0.1",
"fhirBundle": {
"resourceType": "Bundle",
"type": "collection",
@ -33,9 +33,7 @@
],
"name": [
{
"family": [
"Everywoman"
],
"family": "Everywoman",
"given": [
"Evelyn"
]
@ -55,7 +53,7 @@
"resource": {
"resourceType": "Immunization",
"status": "completed",
"date": "2020-04-28",
"occurrenceDateTime": "2020-04-28",
"vaccineCode": {
"coding": [
{

Просмотреть файл

@ -4,13 +4,13 @@
],
"type": [
"VerifiableCredential",
"https://healthwallet.cards#covid19",
"https://healthwallet.cards#presentation-context-online"],
"https://smarthealth.cards#covid19",
"https://smarthealth.cards#presentation-context-online"],
"issuer": "<<did:ion identifier for issuer>>",
"issuanceDate": "2020-06-01T11:59:00-07:00",
"credentialSubject": {
"id": "<<did:identifier for subject if known>>",
"fhirVersion": "1.0.2",
"fhirVersion": "4.0.1",
"fhirBundle":{
"resourceType": "Bundle",
"type": "collection",
@ -23,7 +23,7 @@
"valueCode": "P2"
}],
"name": [{
"family": ["Everywoman"],
"family": "Everywoman",
"given": ["Eve"]
}],
"telecom": [{

Просмотреть файл

@ -4,14 +4,14 @@
],
"type": [
"VerifiableCredential",
"https://healthwallet.cards#covid19",
"https://healthwallet.cards#presentation-context-online"],
"https://smarthealth.cards#covid19",
"https://smarthealth.cards#presentation-context-online"],
"issuer": "<<did:ion identifier for issuer>>",
"issuanceDate": "2020-05-01T11:59:00-07:00",
"display": "COVID-19 Card for Eve Everywoman",
"credentialSubject": {
"id": "<<did:identifier for subject if known>>",
"fhirVersion": "1.0.2",
"fhirVersion": "4.0.1",
"fhirBundle":{
"resourceType": "Bundle",
"type": "collection",
@ -24,7 +24,7 @@
"valueCode": "P2"
}],
"name": [{
"family": ["Everywoman"],
"family": "Everywoman",
"given": ["Eve"]
}],
"telecom": [{

Просмотреть файл

@ -191,7 +191,7 @@ const App: React.FC<AppProps> = (props) => {
ID Card
</CardTitle>
<CardSubtitle className="text-muted">This identifier is all yours, with keys stored safely on your device.</CardSubtitle>
<CardText style={{ fontFamily: "monospace" }}> {holderState.did.split('?')[0]}</CardText>
<CardText style={{ fontFamily: "monospace" }}> {holderState.did.split(':').slice(0,3).join(':')+':...'}</CardText>
</Card>
<CovidCard
holderState={holderState}
@ -270,4 +270,4 @@ export default async function main() {
);
}
main().then(r => console.log('Finished Holder Page,', r));
main().then(r => console.log('Finished Holder Page,', r));

Просмотреть файл

@ -11,7 +11,7 @@ export const keyGenerators: KeyGenerators = {
generateSigningKey
};
const encryptionKeyPros = {
const encryptionKeyProps = {
"kty": "EC",
"crv": "P-256",
"alg": 'ECDH-ES',
@ -33,7 +33,7 @@ export async function generateEncryptionKey(inputPublic?: JsonWebKey, inputPriva
privateKey = await jose.JWK.asKey(inputPrivate)
}
} else {
publicKey = privateKey = await keystore.generate("EC", "P-256", encryptionKeyPros);
publicKey = privateKey = await keystore.generate("EC", "P-256", encryptionKeyProps);
}
const publicJwk = publicKey.toJSON(false);

Просмотреть файл

@ -20,8 +20,6 @@ import { generateDid, verifyJws, encryptFor } from './dids';
import { issuerReducer, prepareSiopRequest, issueVcsToHolder, parseSiopResponse, CredentialGenerationDetals } from './VerifierLogic';
import * as s1 from '@decentralized-identity/sidetree/dist/lib/core/versions/latest/protocol-parameters.json';
import * as s2 from '@decentralized-identity/sidetree/dist/lib/bitcoin/protocol-parameters.json';
const app = express();
app.use(express.raw({ type: 'application/x-www-form-urlencoded', limit: '5000kb' }));
@ -34,7 +32,9 @@ const port = 8080; // default port to listen
const fhirBase = 'https://hapi.fhir.org/baseR4';
async function resolveDid(did: string) {
console.log("preparsed", did);
const parsedDid = await Did.create(did, 'ion');
console.log("Parsed", parsedDid);
const operationWithMockedAnchorTime: AnchoredOperationModel = {
didUniqueSuffix: parsedDid.uniqueSuffix,
type: OperationType.Create,
@ -47,7 +47,7 @@ async function resolveDid(did: string) {
const processor = new OperationProcessor();
const newDidState = await processor.apply(operationWithMockedAnchorTime, undefined);
const document = DocumentComposer.transformToExternalDocument(newDidState, did);
const document = DocumentComposer.transformToExternalDocument(newDidState, parsedDid, false);
return document;
}
@ -196,8 +196,8 @@ app.get('/api/fhir/Patient/:patientID/[\$]HealthWallet.connect', async (req, res
});
async function getVcsForPatient(patientId, details: CredentialGenerationDetals = {
type: 'https://healthwallet.cards#covid19',
presentationContext: 'https://healthwallet.cards#presentation-context-online',
type: 'https://smarthealth.cards#covid19',
presentationContext: 'https://smarthealth.cards#presentation-context-online',
identityClaims: null,
encryptVc: false
}) {
@ -235,12 +235,12 @@ app.get('/api/fhir/DiagnosticReport', async (req, res, err) => {
resource: {
meta: {
tag: [{
system: "https://healthwallet.cards",
system: "https://smarthealth.cards",
code: "covid19"
}]
},
extension: vc ? [{
"url": "https://healthwallet.cards#vc-attachment",
"url": "https://smarthealth.cards#vc-attachment",
"valueAttachment": {
"title": "COVID-19 Card for online presentation",
"data": base64.encode(vc)
@ -564,7 +564,7 @@ app.use(function(err, req, res, next) {
"diagnostics": err + "\n" + err.message + "\n" + err.stack,
"details": {
coding: err.code ? [{
"system": "https://healthwallet.cards",
"system": "https://smarthealth.cards",
"code": err.code,
"display": err.display
}] : undefined

Просмотреть файл

@ -11,7 +11,7 @@ LOINC PCR Tests in DB [
FHIR Bundle size 1225
Summary JSON {
alg: 'https://healthwallet.cards#c19-status',
alg: 'https://smarthealth.cards#c19-status',
ver: '0.0.1',
ptName: 'Eve Everywoman',
ptPhone: '000-000-0000',

Просмотреть файл

@ -1,11 +1,11 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://healthwallet.cards/c19-status.schema.json",
"$id": "https://smarthealth.cards/c19-status.schema.json",
"type": "object",
"title": "Summarize Covid Status",
"description": "Represents a summary of FHIR data to determine COVID-19 infection status as at specific points in time.",
"examples": [{
"alg": "https://healthwallet.cards#c19-status",
"alg": "https://smarthealth.cards#c19-status",
"ver": "0.0.1",
"ial": 2,
"ptName": "Eve Everywoman",
@ -28,7 +28,7 @@
"type": "string",
"title": "Algorithm",
"description": "Algorithm used to produce this summary",
"const": "https://healthwallet.cards#c19-status"
"const": "https://smarthealth.cards#c19-status"
},
"ver": {
"$id": "#/properties/ver",

Просмотреть файл

@ -48,12 +48,12 @@ const hasCodeFrom = (codes) => (cc) => (cc.coding || [] as { code: string }[])
const patient = fhirBundle.entry.map(e => e.resource).filter(r => r.resourceType === 'Patient')[0]
const output = {
alg: "https://healthwallet.cards#c19-status",
alg: "https://smarthealth.cards#c19-status",
ver: "0.0.1",
ptName: patient.name.map(n =>
[n.prefix || ""]
.concat(n.given)
.concat(n.family)
.concat([n.family])
.concat([n.suffix || ""])
.filter(n => n).join(" "))
[0],

Просмотреть файл

@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://healthwallet.cards/algorithms/2-c19-immunization-status.schema.json",
"$id": "https://smarthealth.cards/algorithms/2-c19-immunization-status.schema.json",
"type": "object",
"title": "Summarize Covid-19 Immunization Status",
"description": "Represents a summary of FHIR data to determine COVID-19 immunization status at a specifie point in time.",

Просмотреть файл

@ -21,7 +21,7 @@ const modernaImmunizations: [any] = fhirBundle.entry
.map(e => e.resource)
.filter(r => r.resourceType === 'Immunization')
.filter(r => r.vaccineCode.coding.filter(c => c.system === CVX && c.code === MODERNA).length > 0)
.sort((i1, i2) => new Date(i2.date).getTime() - new Date(i1.date).getTime());
.sort((i1, i2) => new Date(i2.occurrenceDateTime).getTime() - new Date(i1.occurrenceDateTime).getTime());
enum ImmunizationStatus {
Never = 0,
@ -42,7 +42,7 @@ const output = {
ptName: patient.name.map(n =>
[n.prefix || ""]
.concat(n.given)
.concat(n.family)
.concat([n.family])
.concat([n.suffix || ""])
.filter(n => n).join(" "))
[0],
@ -62,7 +62,7 @@ const output = {
})
[0],
result: [{
effective: modernaImmunizations[0].date,
effective: modernaImmunizations[0].occurrenceDateTime,
status: modernaImmunizations.length
}]
}

Просмотреть файл

@ -1,4 +1,3 @@
import * as crypto from 'crypto';
import { issuerWorld } from './issuer';
import { holderWorld } from './holder';
import { verifierWorld } from './verifier';

Просмотреть файл

@ -72,7 +72,7 @@ const App: React.FC<{
if (displayResponse) {
did = displayResponse.idTokenPayload.did.replace(/\?.*/, "");
const fhirName = displayResponse?.idTokenVcs[0].vc.credentialSubject.fhirBundle.entry[0].resource.name[0]
name = fhirName?.given[0] + " " + fhirName?.family[0]
name = fhirName?.given[0] + " " + fhirName?.family
conclusion = displayResponse?.idTokenVcs.map(jwtPayload => jwtPayload.vc.credentialSubject.fhirBundle.entry[1].resource.conclusion)
}
@ -130,7 +130,7 @@ const App: React.FC<{
export default async function main() {
const state = await initializeVerifier({
role: 'venue',
claimsRequired: ['https://healthwallet.cards#covid19'],
claimsRequired: ['https://smarthealth.cards#covid19'],
responseMode: 'form_post',
postRequest: async (url, r) => (await axios.post(url, r)).data,
serverBase,

Просмотреть файл

@ -12,7 +12,7 @@ import { verifierReducer, prepareSiopRequest, parseSiopResponse } from './Verifi
export async function verifierWorld (role = 'verifier', responseMode: SiopResponseMode = 'form_post', reset = false) {
let state = await initializeVerifier({
role,
claimsRequired: ['https://healthwallet.cards#covid19'],
claimsRequired: ['https://smarthealth.cards#covid19'],
responseMode: responseMode,
reset,
displayQr: false,

Просмотреть файл

@ -18,7 +18,7 @@ const clinicalResource = {
describe('CredentialManager', () => {
test('Does not alter inputs', () => {
const asVc = CredentialManager.createVc(issuer, subject, idResource, [clinicalResource])
const asVc = CredentialManager.createVc("", [], issuer, subject, idResource, [clinicalResource])
expect(asVc.issuer).toEqual(issuer)
expect(asVc.credentialSubject.id).toEqual(subject)
@ -32,7 +32,8 @@ describe('CredentialManager', () => {
})
test('creates a VC from FHIR payloads', () => {
const asVc = CredentialManager.createVc(issuer, subject, idResource, [clinicalResource])
const asVc = CredentialManager.createVc("", [], issuer, subject, idResource, [clinicalResource])
expect(asVc.issuer).toEqual(issuer)
expect(asVc.credentialSubject.id).toEqual(subject)
@ -44,7 +45,7 @@ describe('CredentialManager', () => {
})
test('creates a JWT payload from a VC', () => {
const asVc = CredentialManager.createVc(issuer, subject, idResource, [clinicalResource])
const asVc = CredentialManager.createVc("sample-context-type", ["sample-type-1", "sample-type-2"], issuer, subject, idResource, [clinicalResource])
const asJwtPayload = CredentialManager.vcToJwtPayload(asVc) as any;
expect(asJwtPayload.id).toBeUndefined()
@ -69,7 +70,7 @@ describe('CredentialManager', () => {
})
test('recovers a VC from JWT payload', () => {
const asVc = CredentialManager.createVc(issuer, subject, idResource, [clinicalResource])
const asVc = CredentialManager.createVc("", [], issuer, subject, idResource, [clinicalResource])
const asVcCloned = deepcopy(asVc)
const asJwtPayload = CredentialManager.vcToJwtPayload(asVc) as any;