diff --git a/public/DGC.combined-schema.json b/public/DGC.combined-schema.json index 7c9d94c..2994ef5 100644 --- a/public/DGC.combined-schema.json +++ b/public/DGC.combined-schema.json @@ -1,15 +1,36 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://id.uvci.eu/DGC.combined-schema.json", - "title": "EU DGC", - "description": "EU Digital Green Certificate", - "$comment": "Schema version 1.0.0", - "required": [ - "ver", - "nam", - "dob" - ], + "$id": "https://id.uvci.eu/DCC.combined-schema.json", + "title": "EU DCC", + "description": "EU Digital Covid Certificate", + "$comment": "Schema version 1.3.0", "type": "object", + "oneOf": [ + { + "required": [ + "ver", + "nam", + "dob", + "v" + ] + }, + { + "required": [ + "ver", + "nam", + "dob", + "t" + ] + }, + { + "required": [ + "ver", + "nam", + "dob", + "r" + ] + } + ], "properties": { "ver": { "title": "Schema version", @@ -17,21 +38,23 @@ "type": "string", "pattern": "^\\d+.\\d+.\\d+$", "examples": [ - "1.0.0" + "1.3.0" ] }, "nam": { - "description": "Surname(s), given name(s) - in that order", + "description": "Surname(s), forename(s) - in that order", "$ref": "#/$defs/person_name" }, "dob": { "title": "Date of birth", - "description": "Date of Birth of the person addressed in the DGC. ISO 8601 date format restricted to range 1900-2099", + "description": "Date of Birth of the person addressed in the DCC. ISO 8601 date format restricted to range 1900-2099 or empty", "type": "string", - "format": "date", - "pattern": "(19|20)\\d{2}-\\d{2}-\\d{2}", + "pattern": "^((19|20)\\d\\d(-\\d\\d){0,2}){0,1}$", "examples": [ - "1979-04-14" + "1979-04-14", + "1950", + "1901-08", + "" ] }, "v": { @@ -40,7 +63,8 @@ "items": { "$ref": "#/$defs/vaccination_entry" }, - "minItems": 1 + "minItems": 1, + "maxItems": 1 }, "t": { "description": "Test Group", @@ -48,7 +72,8 @@ "items": { "$ref": "#/$defs/test_entry" }, - "minItems": 1 + "minItems": 1, + "maxItems": 1 }, "r": { "description": "Recovery Group", @@ -56,67 +81,62 @@ "items": { "$ref": "#/$defs/recovery_entry" }, - "minItems": 1 + "minItems": 1, + "maxItems": 1 } }, "$defs": { "dose_posint": { - "description": "Dose Number / Total doses in Series: positive integer, range: [1,9]", + "description": "Dose Number / Total doses in Series: positive integer", "type": "integer", - "minimum": 1, - "maximum": 9 - }, - "country_vt": { - "description": "Country of Vaccination / Test, ISO 3166 where possible", - "type": "string", - "pattern": "[A-Z]{1,10}" + "minimum": 1 }, "issuer": { "description": "Certificate Issuer", "type": "string", - "maxLength": 50 + "maxLength": 80 }, "person_name": { - "description": "Person name: Surname(s), given name(s) - in that order", + "description": "Person name: Surname(s), forename(s) - in that order", "required": [ "fnt" ], "type": "object", "properties": { "fn": { - "title": "Family name", - "description": "The family or primary name(s) of the person addressed in the certificate", + "title": "Surname", + "description": "The surname or primary name(s) of the person addressed in the certificate", "type": "string", - "maxLength": 50, + "maxLength": 80, "examples": [ "d'Červenková Panklová" ] }, "fnt": { - "title": "Standardised family name", - "description": "The family name(s) of the person transliterated", + "title": "Standardised surname", + "description": "The surname(s) of the person, transliterated ICAO 9303", "type": "string", "pattern": "^[A-Z<]*$", - "maxLength": 50, + "maxLength": 80, "examples": [ "DCERVENKOVA { setGivenName(evt.target.value)} - maxLength={50} + maxLength={80} /> {/* name input */} setFamilyName(evt.target.value)} - maxLength={50} + maxLength={80} />
@@ -232,7 +232,7 @@ export const PersonInputs = (props: any) => { value={standardisedGivenName} onChange={(evt: any) => handleStandardisedNameChanged(evt.target.value, setStandardisedGivenName)} pattern={utils.pattern.standardisedName} - maxLength={50} + maxLength={80} /> {/*standardised name input */} @@ -241,7 +241,7 @@ export const PersonInputs = (props: any) => { onChange={(evt: any) => handleStandardisedNameChanged(evt.target.value, setStandardisedFamilyName)} required pattern={utils.pattern.standardisedName} - maxLength={50} + maxLength={80} />
@@ -274,7 +274,6 @@ export const PersonInputs = (props: any) => { maxDate={new Date()} minDate={new Date(1900, 0, 1, 12)} openToDate={new Date(1990, 0, 1)} - required /> diff --git a/src/components/pdf-generater.component.tsx b/src/components/pdf-generater.component.tsx index 662eaa1..1f1ab26 100644 --- a/src/components/pdf-generater.component.tsx +++ b/src/components/pdf-generater.component.tsx @@ -32,7 +32,7 @@ import flag_seperator from '../assets/images/flag_seperator.png'; import yellow_seperator from '../assets/images/yellow_seperator.png'; import folding_instruction from '../assets/images/folding-instruction.png'; -import { EUDGC, RecoveryEntry, TestEntry, VaccinationEntry } from '../generated-files/dgc-combined-schema'; +import { EUDCC1, RecoveryEntry, TestEntry, VaccinationEntry } from '../generated-files/dgc-combined-schema'; import { useGetDiseaseAgents, useGetVaccineManufacturers, useGetVaccines, useGetVaccinMedicalData, useGetTestManufacturers, useGetTestResult, useGetTestType @@ -87,7 +87,7 @@ interface IPageParameter { space: number } -const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefined, onIsInit: (isInit: boolean) => void, onIsReady: (isReady: boolean) => void) => { +const usePdfGenerator = (qrCodeCanvasElementProp: any, eudccProp: EUDCC1 | undefined, onIsInit: (isInit: boolean) => void, onIsReady: (isReady: boolean) => void) => { const { t } = useTranslation(); const french = i18n.getDataByLanguage('fr'); @@ -153,7 +153,7 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi const [pdf, setPdf] = React.useState(); - const [eudgc, setEudgc] = React.useState(); + const [eudcc, setEudcc] = React.useState(); const [vaccinationSet, setVaccinationSet] = React.useState(); const [testSet, setTestSet] = React.useState(); const [recoverySet, setRecoverySet] = React.useState(); @@ -206,15 +206,20 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi } }, [firstPageIsReady, secondPageIsReady, thirdPageIsReady, fourthPageIsReady]) - // on receiving eudgc obj set specific ValueSet + // on receiving eudcc obj set specific ValueSet React.useEffect(() => { - if (eudgcProp) { - setEudgc(eudgcProp); - setVaccinationSet(eudgcProp.v ? eudgcProp.v[0] : undefined); - setTestSet(eudgcProp.t ? eudgcProp.t[0] : undefined); - setRecoverySet(eudgcProp.r ? eudgcProp.r[0] : undefined); + if (eudccProp) { + setEudcc(eudccProp); + + const vacc : [VaccinationEntry] = eudccProp.v as [VaccinationEntry]; + const test : [TestEntry] = eudccProp.t as [TestEntry]; + const recovery: [RecoveryEntry] = eudccProp.r as [RecoveryEntry]; + + setVaccinationSet(vacc ? vacc[0] : undefined); + setTestSet(test ? test[0] : undefined); + setRecoverySet(recovery ? recovery[0] : undefined); } - }, [eudgcProp]) + }, [eudccProp]) // set qrcode element from props React.useEffect(() => { @@ -254,18 +259,18 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi }, [recoverySet, isInit]) React.useEffect(() => { - if (qrCodeCanvasElement && ci && isInit && eudgc) { + if (qrCodeCanvasElement && ci && isInit && eudcc) { prepareSecondPage(); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [qrCodeCanvasElement, ci, isInit, eudgc]); + }, [qrCodeCanvasElement, ci, isInit, eudcc]); React.useEffect(() => { - if (co && isInit && eudgc) { + if (co && isInit && eudcc) { prepareFirstPage(); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [co, isInit, eudgc]); + }, [co, isInit, eudcc]); const printDottedLine = () => { if (pdf) { @@ -308,7 +313,7 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi } const prepareFirstPage = () => { - if (pdf && french && eudgc && co) { + if (pdf && french && eudcc && co) { for (let page = 1; page < 3; page++) { let x = 0; let y = 0; @@ -380,7 +385,7 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi } const prepareSecondPage = () => { - if (pdf && eudgc && ci && qrCodeCanvasElement && french) { + if (pdf && eudcc && ci && qrCodeCanvasElement && french) { const space = mm2point(5); @@ -424,12 +429,12 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi y = printHorizontalBlockPerson(x, y, t('translation:pdfSurname'), french.translation.pdfSurname, - (eudgc.nam.fnt + ' ') + (eudgc.nam.gnt ? eudgc.nam.gnt : '')); + (eudcc!.nam!.fnt + ' ') + (eudcc!.nam!.gnt ? eudcc!.nam!.gnt : '')); y = printHorizontalBlockPerson(x, y, t('translation:pdfDateOfBirth'), french.translation.pdfDateOfBirth, - eudgc.dob); + eudcc.dob); y = printHorizontalBlockPerson(x, y, t('translation:pdfCi'), @@ -749,12 +754,6 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi convertDateToOutputFormat(testSet.sc), lineHeight, true); - y = printVerticalBlock(x, y, - t('translation:pdfDateTestResult'), - french.translation.pdfDateTestResult, - testSet.dr ? convertDateToOutputFormat(testSet.dr) : '', - lineHeight, true); - y = printVerticalBlock(x, y, t('translation:pdfTestResult'), french.translation.pdfTestResult, @@ -826,12 +825,6 @@ const usePdfGenerator = (qrCodeCanvasElementProp: any, eudgcProp: EUDGC | undefi convertDateToOutputFormat(testSet.sc), lineHeight, true); - y = printVerticalBlockRotated(x, y, - t('translation:pdfDateTestResult'), - french.translation.pdfDateTestResult, - convertDateToOutputFormat(testSet.dr ? testSet.dr : ' '), - lineHeight, true); - y = printVerticalBlockRotated(x, y, t('translation:pdfTestResult'), french.translation.pdfTestResult, diff --git a/src/components/record-recovery-cert-data.component.tsx b/src/components/record-recovery-cert-data.component.tsx index f8f23a9..612e6f8 100644 --- a/src/components/record-recovery-cert-data.component.tsx +++ b/src/components/record-recovery-cert-data.component.tsx @@ -32,7 +32,7 @@ import Spinner from './spinner/spinner.component'; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; -import { EUDGC, RecoveryEntry } from '../generated-files/dgc-combined-schema'; +import { EUDCC1, RecoveryEntry } from '../generated-files/dgc-combined-schema'; import { useGetDiseaseAgents } from '../api'; import schema from '../generated-files/DGC.combined-schema.json'; @@ -136,7 +136,7 @@ const RecordRecoveryCertData = (props: any) => { const form = event.currentTarget; - if (form.checkValidity()) { + if (form.checkValidity() && person) { const r: RecoveryEntry = { tg: disease, @@ -148,16 +148,17 @@ const RecordRecoveryCertData = (props: any) => { ci: '' }; - const eudgc: EUDGC = { - ver: '1.0.0', + const eudgc: EUDCC1 = { + ver: '1.3.0', nam: { - fn: person!.familyName, - fnt: person!.standardisedFamilyName!, - gn: person!.givenName, - gnt: person!.standardisedGivenName + fn: person.familyName, + fnt: person.standardisedFamilyName!, + gn: person.givenName, + gnt: person.standardisedGivenName }, - dob: moment(person!.dateOfBirth!) - .format(person!.dobFormat === 'yyyy-MM-dd' ? 'yyyy-MM-DD' : person!.dobFormat), + dob: person.dateOfBirth + ? moment(person.dateOfBirth).format(person.dobFormat === 'yyyy-MM-dd' ? 'yyyy-MM-DD' : person.dobFormat) + : '', r: [r] } @@ -246,7 +247,7 @@ const RecordRecoveryCertData = (props: any) => { value={certificateIssuer} onChange={(evt: any) => setCertificateIssuer(evt.target.value)} required - maxLength={50} + maxLength={80} /> {/* Date: Certificate Valid From - To */} diff --git a/src/components/record-test-cert-data.component.tsx b/src/components/record-test-cert-data.component.tsx index 4aa9b6e..b8ad08b 100644 --- a/src/components/record-test-cert-data.component.tsx +++ b/src/components/record-test-cert-data.component.tsx @@ -31,7 +31,7 @@ import Spinner from './spinner/spinner.component'; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; -import { EUDGC, TestEntry } from '../generated-files/dgc-combined-schema'; +import { EUDCC1, TestEntry } from '../generated-files/dgc-combined-schema'; import { useGetDiseaseAgents, useGetTestManufacturers, useGetTestResult, useGetTestType } from '../api'; import schema from '../generated-files/DGC.combined-schema.json'; @@ -61,7 +61,6 @@ const RecordTestCertData = (props: any) => { const [testManufacturers, setTestManufacturers] = useLocalStorage('testManufacturers', ''); const [sampleDateTime, setSampleDateTime] = React.useState(); - const [testDateTime, setTestDateTime] = React.useState(); const [testResult, setTestResult] = React.useState(''); const [testCenter, setTestCenter] = useLocalStorage('testCenter', ''); @@ -90,10 +89,6 @@ const RecordTestCertData = (props: any) => { setSampleDateTime(new Date(test.sc)); - if (test.dr) { - setTestDateTime(new Date(test.dr)); - } - setTestResult(test.tr); setTestCenter(test.tc); @@ -114,11 +109,6 @@ const RecordTestCertData = (props: any) => { setSampleDateTime(date); } - const handleTestDateTimeChange = (evt: Date | [Date, Date] | null) => { - const date = handleDateTimeChange(evt); - setTestDateTime(date); - } - const handleDateTimeChange = (evt: Date | [Date, Date] | null) => { let date: Date; @@ -142,7 +132,7 @@ const RecordTestCertData = (props: any) => { const form = event.currentTarget; - if (form.checkValidity()) { + if (form.checkValidity() && person) { const test: TestEntry = { tg: disease, @@ -150,7 +140,6 @@ const RecordTestCertData = (props: any) => { nm: testName ? testName : undefined, ma: testManufacturers ? testManufacturers : undefined, sc: sampleDateTime!.toISOString(), - dr: testDateTime ? testDateTime.toISOString() : undefined, tr: testResult, tc: testCenter, co: issuerCountryCode, @@ -158,16 +147,17 @@ const RecordTestCertData = (props: any) => { ci: '' }; - const eudgc: EUDGC = { - ver: '1.0.0', + const eudgc: EUDCC1 = { + ver: '1.3.0', nam: { - fn: person!.familyName, - fnt: person!.standardisedFamilyName!, - gn: person!.givenName, - gnt: person!.standardisedGivenName + fn: person.familyName, + fnt: person.standardisedFamilyName!, + gn: person.givenName, + gnt: person.standardisedGivenName }, - dob: moment(person!.dateOfBirth!) - .format(person!.dobFormat === 'yyyy-MM-dd' ? 'yyyy-MM-DD' : person!.dobFormat), + dob: person.dateOfBirth + ? moment(person.dateOfBirth).format(person.dobFormat === 'yyyy-MM-dd' ? 'yyyy-MM-DD' : person.dobFormat) + : '', t: [test] } @@ -225,7 +215,7 @@ const RecordTestCertData = (props: any) => { setTestName(evt.target.value)} - maxLength={50} + maxLength={80} /> {/* combobox testManufacturers */} @@ -238,7 +228,7 @@ const RecordTestCertData = (props: any) => {
{/* sampleDateTime */} - + {t('translation:sampleDateTime') + '*'} @@ -260,28 +250,6 @@ const RecordTestCertData = (props: any) => { - {/* testDateTime */} - - {t('translation:testDateTime')} - - - - - - {/* combobox testResult */} { value={testCenter} onChange={(evt: any) => setTestCenter(evt.target.value)} required - maxLength={50} + maxLength={80} />
@@ -312,7 +280,7 @@ const RecordTestCertData = (props: any) => { value={certificateIssuer} onChange={(evt: any) => setCertificateIssuer(evt.target.value)} required - maxLength={50} + maxLength={80} />
diff --git a/src/components/record-vaccination-cert-data.component.tsx b/src/components/record-vaccination-cert-data.component.tsx index cabd2b8..0dbade9 100644 --- a/src/components/record-vaccination-cert-data.component.tsx +++ b/src/components/record-vaccination-cert-data.component.tsx @@ -32,7 +32,7 @@ import Spinner from './spinner/spinner.component'; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; -import { EUDGC, VaccinationEntry } from '../generated-files/dgc-combined-schema'; +import { EUDCC1, VaccinationEntry } from '../generated-files/dgc-combined-schema'; import { useGetDiseaseAgents, useGetVaccineManufacturers, useGetVaccines, useGetVaccinMedicalData } from '../api'; import schema from '../generated-files/DGC.combined-schema.json'; @@ -132,7 +132,7 @@ const RecordVaccinationCertData = (props: any) => { const form = event.currentTarget; - if (form.checkValidity()) { + if (form.checkValidity() && person) { const vacc: VaccinationEntry = { tg: disease, @@ -147,19 +147,25 @@ const RecordVaccinationCertData = (props: any) => { ci: '' }; - const eudgc: EUDGC = { - ver: '1.0.0', + const eudgc: EUDCC1 = { + ver: '1.3.0', nam: { - fn: person!.familyName, - fnt: person!.standardisedFamilyName!, - gn: person!.givenName, - gnt: person!.standardisedGivenName + fn: person.familyName, + fnt: person.standardisedFamilyName!, + gn: person.givenName, + gnt: person.standardisedGivenName }, - dob: moment(person!.dateOfBirth!) - .format(person!.dobFormat === 'yyyy-MM-dd' ? 'yyyy-MM-DD' : person!.dobFormat), + dob: person.dateOfBirth + ? moment(person.dateOfBirth).format(person.dobFormat === 'yyyy-MM-dd' ? 'yyyy-MM-DD' : person.dobFormat) + : '', v: [vacc] } + // console.log(JSON.stringify(eudgc)); + // let vac = eudgc.v[0]; + // console.log(vac); + // console.log(vac.tg); + var result = validator.validate(eudgc, schema); if (result.valid) { @@ -284,7 +290,7 @@ const RecordVaccinationCertData = (props: any) => { value={certificateIssuer} onChange={(evt: any) => setCertificateIssuer(evt.target.value)} required - maxLength={50} + maxLength={80} />
diff --git a/src/components/show-certificate.component.tsx b/src/components/show-certificate.component.tsx index ba4600e..9a8218c 100644 --- a/src/components/show-certificate.component.tsx +++ b/src/components/show-certificate.component.tsx @@ -30,7 +30,7 @@ import useNavigation from '../misc/navigation'; import QRCode from 'qrcode.react'; import Spinner from './spinner/spinner.component'; -import { EUDGC } from '../generated-files/dgc-combined-schema'; +import { EUDCC1 } from '../generated-files/dgc-combined-schema'; import genEDGCQR, { CertResult } from '../misc/edgcQRGenerator'; import ShowCertificateData from '../misc/ShowCertificateData'; @@ -46,13 +46,13 @@ const ShowCertificate = (props: any) => { const [isInit, setIsInit] = React.useState(false) const [pdfIsInit, setPdfIsInit] = React.useState(false) const [pdfIsReady, setPdfIsReady] = React.useState(false) - const [eudgc, setEudgc] = React.useState(); + const [eudgc, setEudgc] = React.useState(); const [qrCodeValue, setQrCodeValue] = React.useState(''); const [tan, setTAN] = React.useState(''); const [qrCodeForPDF, setQrCodeForPDF] = React.useState(); - const [eudgcForPDF, setEudgcForPDF] = React.useState(); + const [eudgcForPDF, setEudgcForPDF] = React.useState(); const pdf = usePdfGenerator(qrCodeForPDF, eudgcForPDF, (isInit) => setPdfIsInit(isInit), (isReady) => setPdfIsReady(isReady)); // set patient data on mount and set hash from uuid diff --git a/src/generated-files/DGC.combined-schema.json b/src/generated-files/DGC.combined-schema.json index 6500bbf..2994ef5 100644 --- a/src/generated-files/DGC.combined-schema.json +++ b/src/generated-files/DGC.combined-schema.json @@ -1,15 +1,36 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://id.uvci.eu/DGC.combined-schema.json", - "title": "EU DGC", - "description": "EU Digital Green Certificate", - "$comment": "Schema version 1.0.0", - "required": [ - "ver", - "nam", - "dob" - ], + "$id": "https://id.uvci.eu/DCC.combined-schema.json", + "title": "EU DCC", + "description": "EU Digital Covid Certificate", + "$comment": "Schema version 1.3.0", "type": "object", + "oneOf": [ + { + "required": [ + "ver", + "nam", + "dob", + "v" + ] + }, + { + "required": [ + "ver", + "nam", + "dob", + "t" + ] + }, + { + "required": [ + "ver", + "nam", + "dob", + "r" + ] + } + ], "properties": { "ver": { "title": "Schema version", @@ -17,21 +38,23 @@ "type": "string", "pattern": "^\\d+.\\d+.\\d+$", "examples": [ - "1.0.0" + "1.3.0" ] }, "nam": { - "description": "Surname(s), given name(s) - in that order", + "description": "Surname(s), forename(s) - in that order", "$ref": "#/$defs/person_name" }, "dob": { "title": "Date of birth", - "description": "Date of Birth of the person addressed in the DGC. ISO 8601 date format restricted to range 1900-2099", + "description": "Date of Birth of the person addressed in the DCC. ISO 8601 date format restricted to range 1900-2099 or empty", "type": "string", - "format": "string", - "pattern": "(19|20)\\d{2}(-\\d{2})?(-\\d{2})?", + "pattern": "^((19|20)\\d\\d(-\\d\\d){0,2}){0,1}$", "examples": [ - "1979-04-14" + "1979-04-14", + "1950", + "1901-08", + "" ] }, "v": { @@ -40,7 +63,8 @@ "items": { "$ref": "#/$defs/vaccination_entry" }, - "minItems": 1 + "minItems": 1, + "maxItems": 1 }, "t": { "description": "Test Group", @@ -48,7 +72,8 @@ "items": { "$ref": "#/$defs/test_entry" }, - "minItems": 1 + "minItems": 1, + "maxItems": 1 }, "r": { "description": "Recovery Group", @@ -56,67 +81,62 @@ "items": { "$ref": "#/$defs/recovery_entry" }, - "minItems": 1 + "minItems": 1, + "maxItems": 1 } }, "$defs": { "dose_posint": { - "description": "Dose Number / Total doses in Series: positive integer, range: [1,9]", + "description": "Dose Number / Total doses in Series: positive integer", "type": "integer", - "minimum": 1, - "maximum": 9 - }, - "country_vt": { - "description": "Country of Vaccination / Test, ISO 3166 where possible", - "type": "string", - "pattern": "[A-Z]{1,10}" + "minimum": 1 }, "issuer": { "description": "Certificate Issuer", "type": "string", - "maxLength": 50 + "maxLength": 80 }, "person_name": { - "description": "Person name: Surname(s), given name(s) - in that order", + "description": "Person name: Surname(s), forename(s) - in that order", "required": [ "fnt" ], "type": "object", "properties": { "fn": { - "title": "Family name", - "description": "The family or primary name(s) of the person addressed in the certificate", + "title": "Surname", + "description": "The surname or primary name(s) of the person addressed in the certificate", "type": "string", - "maxLength": 50, + "maxLength": 80, "examples": [ "d'Červenková Panklová" ] }, "fnt": { - "title": "Standardised family name", - "description": "The family name(s) of the person transliterated", + "title": "Standardised surname", + "description": "The surname(s) of the person, transliterated ICAO 9303", "type": "string", "pattern": "^[A-Z<]*$", - "maxLength": 50, + "maxLength": 80, "examples": [ "DCERVENKOVA { const testResultValueSet = useGetTestResult(); const testTypeValueSet = useGetTestType(); - const [eudgc, setEudgc] = React.useState(); + const [eudgc, setEudgc] = React.useState(); const [vaccinationSet, setVaccinationSet] = React.useState(); const [testSet, setTestSet] = React.useState(); const [recoverySet, setRecoverySet] = React.useState(); @@ -46,9 +46,13 @@ export const ShowCertificateData = (props: any) => { React.useEffect(() => { if (eudgc) { - setVaccinationSet(eudgc.v ? eudgc.v[0] : undefined); - setTestSet(eudgc.t ? eudgc.t[0] : undefined); - setRecoverySet(eudgc.r ? eudgc.r[0] : undefined); + const vacc : [VaccinationEntry] = eudgc.v as [VaccinationEntry]; + const test : [TestEntry] = eudgc.t as [TestEntry]; + const recovery: [RecoveryEntry] = eudgc.r as [RecoveryEntry]; + + setVaccinationSet(vacc ? vacc[0] : undefined); + setTestSet(test ? test[0] : undefined); + setRecoverySet(recovery ? recovery[0] : undefined); setPersonalData(getPersonalData()); } @@ -81,8 +85,8 @@ export const ShowCertificateData = (props: any) => { { title: i18n.t('translation:personal-data'), entries: [ - { label: i18n.t('translation:name'), data: eudgc?.nam.fn || defaultString }, - { label: i18n.t('translation:first-name'), data: eudgc?.nam.gn || defaultString }, + { label: i18n.t('translation:name'), data: eudgc?.nam?.fn || defaultString }, + { label: i18n.t('translation:first-name'), data: eudgc?.nam?.gn || defaultString }, { label: i18n.t('translation:date-of-birth'), data: eudgc?.dob || defaultString }, ] } @@ -134,7 +138,7 @@ export const ShowCertificateData = (props: any) => { title: i18n.t('translation:test-data'), entries: [ { label: i18n.t('translation:sampleDateTime'), data: convertDateToOutputFormat(testSet?.sc || '') }, - { label: i18n.t('translation:testDateTime'), data: convertDateToOutputFormat(testSet?.dr || defaultString) }, + // { label: i18n.t('translation:testDateTime'), data: convertDateToOutputFormat(testSet?.dr || defaultString) }, { label: i18n.t('translation:testResult'), data: getValueSetDisplay(testSet?.tr, testResultValueSet) || defaultString }, { label: i18n.t('translation:testCenter'), data: testSet?.tc || defaultString } ] diff --git a/src/misc/edgcProcessor.tsx b/src/misc/edgcProcessor.tsx index 2953c84..35110f5 100644 --- a/src/misc/edgcProcessor.tsx +++ b/src/misc/edgcProcessor.tsx @@ -24,7 +24,7 @@ import base45 from './wbase45' import CryptoJS from 'crypto-js'; import zlib from 'browserify-zlib' -import { EUDGC } from '../generated-files/dgc-combined-schema'; +import { EUDCC1 } from '../generated-files/dgc-combined-schema'; const edgcPrefix = 'HC1:' @@ -43,7 +43,7 @@ export interface SignService { (hash: string): Promise; } -const encodeCBOR = (certData: EUDGC, certMetaData: CertificateMetaData): Buffer => { +const encodeCBOR = (certData: EUDCC1, certMetaData: CertificateMetaData): Buffer => { const cborMap = new cbor.Map(); const issuedAtSec = Date.now() / 1000 | 0; @@ -62,7 +62,7 @@ const encodeCBOR = (certData: EUDGC, certMetaData: CertificateMetaData): Buffer return cbor.encodeOne(cborMap, { omitUndefinedProperties: true }); } -const getExpiration = (certData: EUDGC, certMetaData: CertificateMetaData) => { +const getExpiration = (certData: EUDCC1, certMetaData: CertificateMetaData) => { let result = certMetaData.expired; if (certData) { @@ -136,7 +136,7 @@ const dataPrefix = (data: string): string => { } -export const createCertificateQRData = (certData: EUDGC, certMetaData: CertificateMetaData, signService: SignService): Promise => { +export const createCertificateQRData = (certData: EUDCC1, certMetaData: CertificateMetaData, signService: SignService): Promise => { let cbor = encodeCBOR(certData, certMetaData); diff --git a/src/misc/edgcQRGenerator.tsx b/src/misc/edgcQRGenerator.tsx index d0e920d..16f0044 100644 --- a/src/misc/edgcQRGenerator.tsx +++ b/src/misc/edgcQRGenerator.tsx @@ -21,7 +21,7 @@ import { createCertificateQRData, CertificateMetaData } from '../misc/edgcProcessor' import axios from 'axios'; -import { EUDGC } from '../generated-files/dgc-combined-schema'; +import { EUDCC1 } from '../generated-files/dgc-combined-schema'; const api = axios.create({ baseURL: '', @@ -62,25 +62,28 @@ const signerCall = (id: string, hash: string): Promise => { }); } -const setDgci = (dgcPayload: EUDGC, dgci: string) => { - if (dgcPayload.v) { - for (let vac of dgcPayload.v) { - vac.ci = dgci; +const setDgci = (dgcPayload: EUDCC1, dgci: string) => { + if (dgcPayload) { + + if (dgcPayload.v) { + for (let vac of dgcPayload.v) { + vac.ci = dgci; + } } - } - if (dgcPayload.r) { - for (let recovery of dgcPayload.r) { - recovery.ci = dgci; + if (dgcPayload.r) { + for (let rec of dgcPayload.r) { + rec.ci = dgci; + } } - } - if (dgcPayload.t) { - for (let test of dgcPayload.t) { - test.ci = dgci; + if (dgcPayload.t) { + for (let tst of dgcPayload.t) { + tst.ci = dgci; + } } } } -const getEdgcType = (edgcPayload: EUDGC) : CertType => { +const getEdgcType = (edgcPayload: EUDCC1): CertType => { return edgcPayload.r ? CertType.Recovery : edgcPayload.t ? CertType.Test @@ -88,7 +91,7 @@ const getEdgcType = (edgcPayload: EUDGC) : CertType => { } -const generateQRCode = (edgcPayload: EUDGC): Promise => { +const generateQRCode = (edgcPayload: EUDCC1): Promise => { const certInit: CertificateInit = { greenCertificateType: getEdgcType(edgcPayload) } diff --git a/src/routing.component.tsx b/src/routing.component.tsx index 37bf662..50bafe5 100644 --- a/src/routing.component.tsx +++ b/src/routing.component.tsx @@ -37,7 +37,7 @@ import IError from './misc/error'; import ErrorPage from './components/error-page.component'; import RecordVaccinationCertData from './components/record-vaccination-cert-data.component'; import ShowCertificate from './components/show-certificate.component'; -import { EUDGC } from './generated-files/dgc-combined-schema'; +import { EUDCC1 } from './generated-files/dgc-combined-schema'; import RecordTestCertData from './components/record-test-cert-data.component'; import RecordRecoveryCertData from './components/record-recovery-cert-data.component'; import Header from './components/header.component'; @@ -48,7 +48,7 @@ const Routing = (props: any) => { const navigation = useNavigation(); const { t } = useTranslation(); - const [eudgc, setEudgc] = React.useState(); + const [eudgc, setEudgc] = React.useState(); const [error, setError] = React.useState(); const [errorShow, setErrorShow] = React.useState(false); const [dataPrivacyShow, setDataPrivacyShow] = React.useState(false);