From d96608bf394f7c9f64668c59b4539c7788eb914c Mon Sep 17 00:00:00 2001 From: Tejas Varade Date: Tue, 22 Feb 2022 19:52:27 +0530 Subject: [PATCH 1/3] DIV-8002 | Use configuration layer to get fields used in certificate / generation of QR code --- .../src/routes/certificate_controller.js | 11 +-- .../certificate_signer/config/constants.js | 11 ++- .../configuration_service.js | 57 +++++++++---- backend/certificate_signer/main.js | 85 ++++++++----------- .../test/configuration_service.test.js | 18 ++-- e2e/test_certify_api.py | 12 +++ .../test_data/ddcc_w3c_payload.template | 0 e2e/test_data/fields_key_path.json | 24 ++++++ .../test_data/w3c_payload.template | 0 9 files changed, 134 insertions(+), 84 deletions(-) rename backend/certificate_signer/config/templates/ddcc_w3c_certificate_payload.template => e2e/test_data/ddcc_w3c_payload.template (100%) create mode 100644 e2e/test_data/fields_key_path.json rename backend/certificate_signer/config/templates/w3c_certificate_payload.template => e2e/test_data/w3c_payload.template (100%) diff --git a/backend/certificate_api/src/routes/certificate_controller.js b/backend/certificate_api/src/routes/certificate_controller.js index 3d1165923..a4d82d615 100644 --- a/backend/certificate_api/src/routes/certificate_controller.js +++ b/backend/certificate_api/src/routes/certificate_controller.js @@ -27,8 +27,9 @@ function getNumberWithOrdinal(n) { } function appendCommaIfNotEmpty(address, suffix) { - if (address.trim().length > 0) { - if (suffix.trim().length > 0) { + console.log(address); + if (address?.trim().length > 0) { + if (suffix?.trim().length > 0) { return address + ", " + suffix } else { return address @@ -41,14 +42,14 @@ function concatenateReadableString(a, b) { let address = ""; address = appendCommaIfNotEmpty(address, a); address = appendCommaIfNotEmpty(address, b); - if (address.length > 0) { + if (address?.length > 0) { return address } return "NA" } function formatRecipientAddress(address) { - return concatenateReadableString(address.streetAddress, address.district) + return concatenateReadableString(address?.streetAddress, address?.district) } function formatFacilityAddress(evidence) { @@ -775,7 +776,7 @@ function prepareDataForVaccineCertificateTemplate(certificateRaw, dataURL, doseT vaccine: evidence[0].vaccine, vaccinationDate: formatDate(evidence[0].date) + ` (Batch no. ${evidence[0].batch} )`, vaccineValidDays: `after ${getVaccineValidDays(evidence[0].effectiveStart, evidence[0].effectiveUntil)} days`, - vaccinatedBy: evidence[0].verifier.name, + vaccinatedBy: evidence[0].verifier?.name, vaccinatedAt: formatFacilityAddress(evidence[0]), qrCode: dataURL, dose: evidence[0].dose, diff --git a/backend/certificate_signer/config/constants.js b/backend/certificate_signer/config/constants.js index 6dfeed901..7006dbc30 100644 --- a/backend/certificate_signer/config/constants.js +++ b/backend/certificate_signer/config/constants.js @@ -1,9 +1,12 @@ -const ICD_MAPPINGS_KEYS = { +const CONFIG_KEYS = { ICD: "ICD", - VACCINE_ICD: "VACCINE_ICD" + VACCINE_ICD: "VACCINE_ICD", + FIELDS_KEY_PATH: "fieldsKeyPath", + DDCC_TEMPLATE: "DDCC_TEMPLATE", + W3C_TEMPLATE: "W3C_TEMPLATE" }; -Object.freeze(ICD_MAPPINGS_KEYS); +Object.freeze(CONFIG_KEYS); module.exports = { - ICD_MAPPINGS_KEYS + CONFIG_KEYS } \ No newline at end of file diff --git a/backend/certificate_signer/configuration_service.js b/backend/certificate_signer/configuration_service.js index dafd42341..180973169 100644 --- a/backend/certificate_signer/configuration_service.js +++ b/backend/certificate_signer/configuration_service.js @@ -1,15 +1,18 @@ const {Etcd3} = require('etcd3'); const config = require('./config/config'); -const {ICD_MAPPINGS_KEYS} = require('./config/constants'); +const {CONFIG_KEYS} = require('./config/constants'); -let ICD11_MAPPINGS = null, VACCINE_ICD11_MAPPINGS = null; +let ICD11_MAPPINGS = null, VACCINE_ICD11_MAPPINGS = null, DDCC_TEMPLATE = null, W3C_TEMPLATE = null, FIELDS_KEY_PATH = null; let etcdClient; let configuration; function init() { etcdClient = new Etcd3({hosts: config.ETCD_URL}); - setUpWatcher(ICD_MAPPINGS_KEYS.ICD); - setUpWatcher(ICD_MAPPINGS_KEYS.VACCINE_ICD); + setUpWatcher(CONFIG_KEYS.ICD); + setUpWatcher(CONFIG_KEYS.VACCINE_ICD); + setUpWatcher(CONFIG_KEYS.DDCC_TEMPLATE); + setUpWatcher(CONFIG_KEYS.W3C_TEMPLATE); + setUpWatcher(CONFIG_KEYS.FIELDS_KEY_PATH); configuration = config.CONFIGURATION_LAYER.toLowerCase() === 'etcd' ? new etcd() : null } @@ -26,7 +29,7 @@ function setUpWatcher(key) { console.log('connected'); }) .on('put', res => { - updateMappingValues(key, res.value.toString()) + updateConfigValues(key, res.value.toString()) }); }) .catch(err => { @@ -34,47 +37,65 @@ function setUpWatcher(key) { }); } -function loadMappings(key) { +function loadConfigValues(key) { let mapping; switch(key) { - case ICD_MAPPINGS_KEYS.ICD: + case CONFIG_KEYS.ICD: mapping = ICD11_MAPPINGS; break; - case ICD_MAPPINGS_KEYS.VACCINE_ICD: + case CONFIG_KEYS.VACCINE_ICD: mapping = VACCINE_ICD11_MAPPINGS; break; + case CONFIG_KEYS.DDCC_TEMPLATE: + mapping = DDCC_TEMPLATE; + break; + case CONFIG_KEYS.FIELDS_KEY_PATH: + mapping = FIELDS_KEY_PATH; + break; + case CONFIG_KEYS.W3C_TEMPLATE: + mapping = W3C_TEMPLATE; + break; } return mapping; } class ConfigLayer{ - async getICDMappings(key) { - let mapping = loadMappings(key) + async getConfigValue(key) { + let mapping = loadConfigValues(key) if(mapping === null || mapping === undefined) { if(configuration === null || configuration === null) { return null; } - mapping = configuration.getICDMappings(key); - updateMappingValues(key, mapping); + mapping = configuration.getConfigValue(key); + updateConfigValues(key, mapping); } return mapping; } } const etcd = function() { - this.getICDMappings = async function(key) { + this.getConfigValue = async function(key) { let mappingValue = (await etcdClient.get(key).string()); return mappingValue; } } -function updateMappingValues(key, value) { +function updateConfigValues(key, value) { switch(key) { - case ICD_MAPPINGS_KEYS.ICD: - ICD11_MAPPINGS = value + case CONFIG_KEYS.ICD: + ICD11_MAPPINGS = value; + break; + case CONFIG_KEYS.VACCINE_ICD: + VACCINE_ICD11_MAPPINGS = value; + break; + case CONFIG_KEYS.DDCC_TEMPLATE: + DDCC_TEMPLATE = value; + break; + case CONFIG_KEYS.W3C_TEMPLATE: + W3C_TEMPLATE = value; break; - case ICD_MAPPINGS_KEYS.VACCINE_ICD: - VACCINE_ICD11_MAPPINGS = value + case CONFIG_KEYS.FIELDS_KEY_PATH: + FIELDS_KEY_PATH = value; break; } } diff --git a/backend/certificate_signer/main.js b/backend/certificate_signer/main.js index 9fae058a0..34a963e2f 100644 --- a/backend/certificate_signer/main.js +++ b/backend/certificate_signer/main.js @@ -20,7 +20,7 @@ const signer = require('certificate-signer-library'); const Mustache = require("mustache"); const {publicKeyPem, privateKeyPem, signingKeyType} = require('./config/keys'); const identityRejectionRegex = new RegExp(IDENTITY_REJECTION_PATTERN); -const {ICD_MAPPINGS_KEYS} = require('./config/constants'); +const {CONFIG_KEYS} = require('./config/constants'); console.log('Using ' + config.KAFKA_BOOTSTRAP_SERVER); console.log('Using ' + publicKeyPem); @@ -35,9 +35,8 @@ Mustache.escape = function (value) const CERTIFICATE_TYPE_V2 = "certifyV2"; const CERTIFICATE_TYPE_V3 = "certifyV3"; -const TEMPLATES_FOLDER = __dirname +'/config/templates/'; -const DDCC_TEMPLATE_FILEPATH = TEMPLATES_FOLDER+"ddcc_w3c_certificate_payload.template"; -const W3C_TEMPLATE_FILEPATH = TEMPLATES_FOLDER+"w3c_certificate_payload.template"; +let DDCC_TEMPLATE; +let W3C_TEMPLATE; const kafka = new Kafka({ clientId: 'divoc-cert', @@ -82,6 +81,7 @@ let signingConfig = { let ICD11_MAPPINGS; let VACCINE_ICD11_MAPPINGS; +let fieldsKeyPath; let configLayerObj; const documentLoader = {}; documentLoader[CERTIFICATE_NAMESPACE] = vaccinationContext; @@ -102,8 +102,11 @@ documentLoader[CERTIFICATE_NAMESPACE_V2] = vaccinationContextV2; uploadId: message.headers.uploadId ? message.headers.uploadId.toString():'', rowId: message.headers.rowId ? message.headers.rowId.toString():'', }); - ICD11_MAPPINGS = JSON.parse(await configLayerObj.getICDMappings(ICD_MAPPINGS_KEYS.ICD)); - VACCINE_ICD11_MAPPINGS = JSON.parse( await configLayerObj.getICDMappings(ICD_MAPPINGS_KEYS.VACCINE_ICD)) + ICD11_MAPPINGS = JSON.parse(await configLayerObj.getConfigValue(CONFIG_KEYS.ICD)); + VACCINE_ICD11_MAPPINGS = JSON.parse( await configLayerObj.getConfigValue(CONFIG_KEYS.VACCINE_ICD)) + fieldsKeyPath = JSON.parse(await configLayerObj.getConfigValue(CONFIG_KEYS.FIELDS_KEY_PATH)) + DDCC_TEMPLATE = await configLayerObj.getConfigValue(CONFIG_KEYS.DDCC_TEMPLATE); + W3C_TEMPLATE = await configLayerObj.getConfigValue(CONFIG_KEYS.W3C_TEMPLATE); let jsonMessage = {}; try { jsonMessage = JSON.parse(message.value.toString()); @@ -136,8 +139,7 @@ documentLoader[CERTIFICATE_NAMESPACE_V2] = vaccinationContextV2; }) })(); -function populateIdentity(cert, preEnrollmentCode) { - let identity = R.pathOr('', ['recipient', 'identity'], cert); +function populateIdentity(identity, preEnrollmentCode) { let isURI = isURIFormat(identity); return isURI ? identity : reinitIdentityFromPayload(identity, preEnrollmentCode); } @@ -187,61 +189,48 @@ function render(template, data) { return JSON.parse(Mustache.render(template, data)) } -function transformW3(cert, certificateId) { +function transformW3(cert, certificateID) { const certificateType = R.pathOr('', ['meta', 'certificateType'], cert); - const namespace = certificateType === CERTIFICATE_TYPE_V3 ? CERTIFICATE_NAMESPACE_V2 : CERTIFICATE_NAMESPACE; const preEnrollmentCode = R.pathOr('', ['preEnrollmentCode'], cert); - const recipientIdentifier = populateIdentity(cert, preEnrollmentCode); const recipientName = R.pathOr('', ['recipient', 'name'], cert); - const recipientGender = R.pathOr('', ['recipient', 'gender'], cert); - const recipientNationality = R.pathOr('', ['recipient', 'nationality'], cert); - const recipientAge = ageOfRecipient(cert.recipient); //from dob const recipientDob = dobOfRecipient(cert.recipient); - const recipientAddressLine1 = R.pathOr('', ['recipient', 'address', 'addressLine1'], cert); - const recipientAddressLine2 = R.pathOr('', ['recipient', 'address', 'addressLine2'], cert); - const recipientAddressDistrict = R.pathOr('', ['recipient', 'address', 'district'], cert); - const recipientAddressCity = R.pathOr('', ['recipient', 'address', 'city'], cert); - const recipientAddressRegion = R.pathOr('', ['recipient', 'address', 'state'], cert); - const recipientAddressCountry = R.pathOr('', ['recipient', 'address', 'country'], cert); - const recipientAddressPostalCode = R.pathOr('', ['recipient', 'address', 'pincode'], cert); - - const issuer = CERTIFICATE_ISSUER; - const issuanceDate = new Date().toISOString(); - - const evidenceId = CERTIFICATE_BASE_URL + certificateId; - const InfoUrl = CERTIFICATE_INFO_BASE_URL + certificateId; - const feedbackUrl = CERTIFICATE_FEEDBACK_BASE_URL + certificateId; - - const batch = R.pathOr('', ['vaccination', 'batch'], cert); const vaccine = R.pathOr('', ['vaccination', 'name'], cert); const icd11Code = vaccine ? VACCINE_ICD11_MAPPINGS.filter(a => vaccine.toLowerCase().includes(a.vaccineName)).map(a => a.icd11Code)[0]: ''; const prophylaxis = icd11Code ? ICD11_MAPPINGS[icd11Code]["icd11Term"]: ''; - const manufacturer = R.pathOr('', ['vaccination', 'manufacturer'], cert); + const batch = R.pathOr('', ['vaccination', 'batch'], cert); const vaccinationDate = R.pathOr('', ['vaccination', 'date'], cert); - const effectiveStart = R.pathOr('', ['vaccination', 'effectiveStart'], cert); - const effectiveUntil = R.pathOr('', ['vaccination', 'effectiveUntil'], cert); const dose = R.pathOr('', ['vaccination', 'dose'], cert); const totalDoses = R.pathOr('', ['vaccination', 'totalDoses'], cert); - const verifierName = R.pathOr('', ['vaccinator', 'name'], cert); - const facilityName = R.pathOr('', ['facility', 'name'], cert); - const facilityAddressLine1 = R.pathOr('', ['facility', 'address', 'addressLine1'], cert); - const facilityAddressLine2 = R.pathOr('', ['facility', 'address', 'addressLine2'], cert); - const facilityAddressDistrict = R.pathOr('', ['facility', 'address', 'district'], cert); - const facilityAddressCity = R.pathOr('', ['facility', 'address', 'city'], cert); - const facilityAddressRegion = R.pathOr('', ['facility', 'address', 'state'], cert); const facilityAddressCountry = R.pathOr(config.FACILITY_COUNTRY_CODE, ['facility', 'address', 'country'], cert); - const facilityAddressPostalCode = R.pathOr('', ['facility', 'address', 'pincode'], cert); + const issuer = CERTIFICATE_ISSUER; + const certificateId = certificateID; + + const evidenceId = CERTIFICATE_BASE_URL + certificateId; + const InfoUrl = CERTIFICATE_INFO_BASE_URL + certificateId; + const feedbackUrl = CERTIFICATE_FEEDBACK_BASE_URL + certificateId; + + const issuanceDate = new Date().toISOString(); + let parsed = {}; + for(const [key, value] of Object.entries(fieldsKeyPath)) { + let abc = R.pathOr('', value, cert); + if(key === "recipientIdentifier") { + abc = populateIdentity(abc, preEnrollmentCode); + } + else if(key === "recipientAge") { + abc = ageOfRecipient(cert.recipient); + } + parsed[key] = abc; + } let data = { - namespace, recipientIdentifier, preEnrollmentCode, recipientName, recipientGender, recipientDob, recipientAge, recipientNationality, - recipientAddressLine1, recipientAddressLine2, recipientAddressDistrict, recipientAddressCity, recipientAddressRegion, recipientAddressCountry, recipientAddressPostalCode, + namespace, preEnrollmentCode, + recipientName, recipientDob, issuer, issuanceDate, evidenceId, InfoUrl, feedbackUrl, - certificateId, batch, vaccine, icd11Code, prophylaxis, manufacturer, vaccinationDate, effectiveStart, effectiveUntil, dose, totalDoses, - verifierName, - facilityName, facilityAddressLine1, facilityAddressLine2, facilityAddressDistrict, facilityAddressCity, facilityAddressRegion, facilityAddressCountry, facilityAddressPostalCode + certificateId, batch, vaccine, icd11Code, prophylaxis, vaccinationDate, dose, totalDoses, + facilityAddressCountry, + ...parsed }; - - const template = certificateType === CERTIFICATE_TYPE_V3 ? fs.readFileSync(DDCC_TEMPLATE_FILEPATH, 'utf8') : fs.readFileSync(W3C_TEMPLATE_FILEPATH, 'utf8'); + const template = certificateType === CERTIFICATE_TYPE_V3 ? DDCC_TEMPLATE : W3C_TEMPLATE; return render(template, data); } diff --git a/backend/certificate_signer/test/configuration_service.test.js b/backend/certificate_signer/test/configuration_service.test.js index 56db5007a..3d7f6e53b 100644 --- a/backend/certificate_signer/test/configuration_service.test.js +++ b/backend/certificate_signer/test/configuration_service.test.js @@ -1,7 +1,7 @@ describe('should retrieve all mappings if correct configuration layer passed', () => { const etcd3 = require('etcd3'); const config = require('../config/config'); - const { ICD_MAPPINGS_KEYS } = require('../config/constants'); + const { CONFIG_KEYS } = require('../config/constants'); var mockConfig = { CONFIGURATION_LAYER: 'etcd', ETCD_URL: 'etcd:2379' @@ -53,24 +53,24 @@ describe('should retrieve all mappings if correct configuration layer passed', ( init(); }); - test('should initialise two watchers each for ICD and VACCINE_ICD mapping keys', () => { + test('should initialise five times watchers each for ICD, VACCINE_ICD, DDCC_TEMPLATE, W3C_TEMPLATE and FIELDS_KEY_PATH ', () => { expect(etcd3.Etcd3).toHaveBeenCalled(); - expect(mockEtcd3Constructor.watch).toHaveBeenCalledTimes(2); + expect(mockEtcd3Constructor.watch).toHaveBeenCalledTimes(5); }); test('should fetch values of ICD Mapping and VACCINE_ICD mapping from etcd', async() => { - const ICD = await (new ConfigLayer()).getICDMappings(ICD_MAPPINGS_KEYS.ICD); - const VACCINE_ICD = await (new ConfigLayer()).getICDMappings(ICD_MAPPINGS_KEYS.VACCINE_ICD); + const ICD = await (new ConfigLayer()).getConfigValue(CONFIG_KEYS.ICD); + const VACCINE_ICD = await (new ConfigLayer()).getConfigValue(CONFIG_KEYS.VACCINE_ICD); expect(ICD).toEqual({}) expect(VACCINE_ICD).toEqual([]) expect(mockEtcd3Constructor.get).toHaveBeenCalledTimes(2); - expect(mockEtcd3Constructor.get).toHaveBeenCalledWith(ICD_MAPPINGS_KEYS.ICD); - expect(mockEtcd3Constructor.get).toHaveBeenCalledWith(ICD_MAPPINGS_KEYS.VACCINE_ICD); + expect(mockEtcd3Constructor.get).toHaveBeenCalledWith(CONFIG_KEYS.ICD); + expect(mockEtcd3Constructor.get).toHaveBeenCalledWith(CONFIG_KEYS.VACCINE_ICD); }); }); describe('wrong environment variable for configuration layer', () => { - const { ICD_MAPPINGS_KEYS } = require('../config/constants'); + const { CONFIG_KEYS } = require('../config/constants'); const OLD_ENV = process.env; jest.resetModules(); var mockConfig = { @@ -89,7 +89,7 @@ describe('wrong environment variable for configuration layer', () => { }); test('should return null if wrong configuration passed', async() => { - const mapping = await (new services.ConfigLayer()).getICDMappings(ICD_MAPPINGS_KEYS.ICD); + const mapping = await (new services.ConfigLayer()).getConfigValue(CONFIG_KEYS.ICD); expect(mapping).toEqual(null); }) }); \ No newline at end of file diff --git a/e2e/test_certify_api.py b/e2e/test_certify_api.py index 6e85939e8..3e5b05cd4 100644 --- a/e2e/test_certify_api.py +++ b/e2e/test_certify_api.py @@ -10,6 +10,9 @@ CERTIFY_REQUEST_BODY = "test_data/certify.json" ICD_REQUEST_BODY = "test_data/icd.json" VACCINE_ICD_REQUEST_BODY = "test_data/vaccine_icd.json" +DDCC_TEMPLATE = "test_data/ddcc_w3c_payload.template" +W3C_TEMPLATE = "test_data/w3c_payload.template" +FIELDS_KEY_PATH = "test_data/fields_key_path.json" def service_check(): try: @@ -32,9 +35,15 @@ def call_and_verify(): } icd_data = json.load(open(ICD_REQUEST_BODY)) vaccine_icd_data = json.load(open(VACCINE_ICD_REQUEST_BODY)) + w3c_template = open(W3C_TEMPLATE) + ddcc_template = open(DDCC_TEMPLATE) + fields_key_path = json.load(open(FIELDS_KEY_PATH)) etcd = etcd3.client(host='etcd') etcd.put('ICD', str(icd_data).replace("'", '"')) etcd.put('VACCINE_ICD', str(vaccine_icd_data).replace("'", '"')) + etcd.put('W3C_TEMPLATE', str(w3c_template.read())) + etcd.put('DDCC_TEMPLATE', str(ddcc_template.read())) + etcd.put('fieldsKeyPath', str(fields_key_path).replace("'", '"')) certify_data = json.load(open(CERTIFY_REQUEST_BODY))[0] certify_data["preEnrollmentCode"] = cid certify_res = r.post(VACCINATION_API + "certify", headers=headers, json=[certify_data]) @@ -57,6 +66,9 @@ def call_and_verify(): assert len(new_certs) == len(old_certs) + 1, "Cerrificate creation failed" etcd.delete('ICD') etcd.delete('VACCINE_ICD') + etcd.delete('W3C_TEMPLATE') + etcd.delete('DDCC_TEMPLATE') + etcd.delete('fieldsKeyPath') def test_certify(): test_ran = False diff --git a/backend/certificate_signer/config/templates/ddcc_w3c_certificate_payload.template b/e2e/test_data/ddcc_w3c_payload.template similarity index 100% rename from backend/certificate_signer/config/templates/ddcc_w3c_certificate_payload.template rename to e2e/test_data/ddcc_w3c_payload.template diff --git a/e2e/test_data/fields_key_path.json b/e2e/test_data/fields_key_path.json new file mode 100644 index 000000000..4d282630d --- /dev/null +++ b/e2e/test_data/fields_key_path.json @@ -0,0 +1,24 @@ +{ + "recipientGender": ["recipient", "gender"], + "recipientNationality": ["recipient", "nationality"], + "recipientAddressLine1": ["recipient", "address", "addressLine1"], + "recipientAddressLine2": ["recipient", "address", "addressLine2"], + "recipientAddressDistrict": ["recipient", "address", "district"], + "recipientAddressCity": ["recipient", "address", "city"], + "recipientAddressRegion": ["recipient", "address", "state"], + "recipientAddressCountry": ["recipient", "address", "country"], + "recipientAddressPostalCode": ["recipient", "address", "pincode"], + "manufacturer": ["vaccination", "manufacturer"], + "effectiveStart": ["vaccination", "effectiveStart"], + "effectiveUntil": ["vaccination", "effectiveUntil"], + "verifierName": ["vaccinator", "name"], + "facilityName": ["facility", "name"], + "facilityAddressLine1": ["facility", "address", "addressLine1"], + "facilityAddressLine2": ["facility", "address", "addressLine2"], + "facilityAddressDistrict": ["facility", "address", "district"], + "facilityAddressCity": ["facility", "address", "city"], + "facilityAddressRegion": ["facility", "address", "state"], + "facilityAddressPostalCode": ["facility", "address", "pincode"], + "recipientIdentifier": ["recipient", "identity"], + "recipientAge": ["recipient", "age"] +} \ No newline at end of file diff --git a/backend/certificate_signer/config/templates/w3c_certificate_payload.template b/e2e/test_data/w3c_payload.template similarity index 100% rename from backend/certificate_signer/config/templates/w3c_certificate_payload.template rename to e2e/test_data/w3c_payload.template From 79156148ea85a54ce3fa47a23d05e8c011def891 Mon Sep 17 00:00:00 2001 From: Tejas Varade Date: Tue, 22 Feb 2022 20:05:12 +0530 Subject: [PATCH 2/3] DIV-8002 | Remove log and Fix for EUCertificateConverter if manufacturer not present --- backend/certificate_api/src/routes/certificate_controller.js | 1 - backend/certificate_api/src/services/certificate_service.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/certificate_api/src/routes/certificate_controller.js b/backend/certificate_api/src/routes/certificate_controller.js index a4d82d615..bb161e9c6 100644 --- a/backend/certificate_api/src/routes/certificate_controller.js +++ b/backend/certificate_api/src/routes/certificate_controller.js @@ -27,7 +27,6 @@ function getNumberWithOrdinal(n) { } function appendCommaIfNotEmpty(address, suffix) { - console.log(address); if (address?.trim().length > 0) { if (suffix?.trim().length > 0) { return address + ", " + suffix diff --git a/backend/certificate_api/src/services/certificate_service.js b/backend/certificate_api/src/services/certificate_service.js index 8002f79d3..e59b1f0da 100644 --- a/backend/certificate_api/src/services/certificate_service.js +++ b/backend/certificate_api/src/services/certificate_service.js @@ -38,8 +38,8 @@ const convertCertificateToDCCPayload = async(certificateRaw) => { throw new Error("EU Vaccine Details are missing from Configuration"); } const {credentialSubject, evidence} = certificate; - const manufacturerCode = Object.keys(VACCINE_MANUF).filter(a => evidence[0].manufacturer.toLowerCase().includes(a)).length > 0 ? - Object.entries(VACCINE_MANUF).filter(([k, v]) => evidence[0].manufacturer.toLowerCase().includes(k))[0][1] : ""; + const manufacturerCode = Object.keys(VACCINE_MANUF).filter(a => evidence[0].manufacturer?.toLowerCase().includes(a)).length > 0 ? + Object.entries(VACCINE_MANUF).filter(([k, v]) => evidence[0].manufacturer?.toLowerCase().includes(k))[0][1] : ""; const prophylaxisCode = Object.keys(EU_VACCINE_PROPH).filter(a => evidence[0].vaccine.toLowerCase().includes(a)).length > 0 ? Object.entries(EU_VACCINE_PROPH).filter(([k, v]) => evidence[0].vaccine.toLowerCase().includes(k))[0][1] : ""; const vaccineCode = Object.keys(EU_VACCINE_CODE).filter(a => evidence[0].vaccine.toLowerCase().includes(a)).length > 0 ? From a3dc2c478e01c562b190ba1be6d4b5af8075979a Mon Sep 17 00:00:00 2001 From: Tejas Varade Date: Wed, 2 Mar 2022 10:49:03 +0530 Subject: [PATCH 3/3] DIV-8002 | Code refactor --- .../certificate_signer/config/constants.js | 2 +- .../configuration_service.js | 12 ++++---- backend/certificate_signer/main.js | 30 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/backend/certificate_signer/config/constants.js b/backend/certificate_signer/config/constants.js index 7006dbc30..a8ae1de8d 100644 --- a/backend/certificate_signer/config/constants.js +++ b/backend/certificate_signer/config/constants.js @@ -1,7 +1,7 @@ const CONFIG_KEYS = { ICD: "ICD", VACCINE_ICD: "VACCINE_ICD", - FIELDS_KEY_PATH: "fieldsKeyPath", + CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH: "fieldsKeyPath", DDCC_TEMPLATE: "DDCC_TEMPLATE", W3C_TEMPLATE: "W3C_TEMPLATE" }; diff --git a/backend/certificate_signer/configuration_service.js b/backend/certificate_signer/configuration_service.js index 180973169..83e999df8 100644 --- a/backend/certificate_signer/configuration_service.js +++ b/backend/certificate_signer/configuration_service.js @@ -2,7 +2,7 @@ const {Etcd3} = require('etcd3'); const config = require('./config/config'); const {CONFIG_KEYS} = require('./config/constants'); -let ICD11_MAPPINGS = null, VACCINE_ICD11_MAPPINGS = null, DDCC_TEMPLATE = null, W3C_TEMPLATE = null, FIELDS_KEY_PATH = null; +let ICD11_MAPPINGS = null, VACCINE_ICD11_MAPPINGS = null, DDCC_TEMPLATE = null, W3C_TEMPLATE = null, CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH = null; let etcdClient; let configuration; @@ -12,7 +12,7 @@ function init() { setUpWatcher(CONFIG_KEYS.VACCINE_ICD); setUpWatcher(CONFIG_KEYS.DDCC_TEMPLATE); setUpWatcher(CONFIG_KEYS.W3C_TEMPLATE); - setUpWatcher(CONFIG_KEYS.FIELDS_KEY_PATH); + setUpWatcher(CONFIG_KEYS.CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH); configuration = config.CONFIGURATION_LAYER.toLowerCase() === 'etcd' ? new etcd() : null } @@ -49,8 +49,8 @@ function loadConfigValues(key) { case CONFIG_KEYS.DDCC_TEMPLATE: mapping = DDCC_TEMPLATE; break; - case CONFIG_KEYS.FIELDS_KEY_PATH: - mapping = FIELDS_KEY_PATH; + case CONFIG_KEYS.CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH: + mapping = CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH; break; case CONFIG_KEYS.W3C_TEMPLATE: mapping = W3C_TEMPLATE; @@ -94,8 +94,8 @@ function updateConfigValues(key, value) { case CONFIG_KEYS.W3C_TEMPLATE: W3C_TEMPLATE = value; break; - case CONFIG_KEYS.FIELDS_KEY_PATH: - FIELDS_KEY_PATH = value; + case CONFIG_KEYS.CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH: + CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH = value; break; } } diff --git a/backend/certificate_signer/main.js b/backend/certificate_signer/main.js index 34a963e2f..204e876f0 100644 --- a/backend/certificate_signer/main.js +++ b/backend/certificate_signer/main.js @@ -81,7 +81,7 @@ let signingConfig = { let ICD11_MAPPINGS; let VACCINE_ICD11_MAPPINGS; -let fieldsKeyPath; +let certificateFieldsKeyPath; let configLayerObj; const documentLoader = {}; documentLoader[CERTIFICATE_NAMESPACE] = vaccinationContext; @@ -103,8 +103,8 @@ documentLoader[CERTIFICATE_NAMESPACE_V2] = vaccinationContextV2; rowId: message.headers.rowId ? message.headers.rowId.toString():'', }); ICD11_MAPPINGS = JSON.parse(await configLayerObj.getConfigValue(CONFIG_KEYS.ICD)); - VACCINE_ICD11_MAPPINGS = JSON.parse( await configLayerObj.getConfigValue(CONFIG_KEYS.VACCINE_ICD)) - fieldsKeyPath = JSON.parse(await configLayerObj.getConfigValue(CONFIG_KEYS.FIELDS_KEY_PATH)) + VACCINE_ICD11_MAPPINGS = JSON.parse( await configLayerObj.getConfigValue(CONFIG_KEYS.VACCINE_ICD)); + certificateFieldsKeyPath = JSON.parse(await configLayerObj.getConfigValue(CONFIG_KEYS.CERTIFICATES_OPTIONAL_FIELDS_KEY_PATH)); DDCC_TEMPLATE = await configLayerObj.getConfigValue(CONFIG_KEYS.DDCC_TEMPLATE); W3C_TEMPLATE = await configLayerObj.getConfigValue(CONFIG_KEYS.W3C_TEMPLATE); let jsonMessage = {}; @@ -145,16 +145,16 @@ function populateIdentity(identity, preEnrollmentCode) { } function isURIFormat(param) { - let parsed; + let optionalCertificateFieldsObj; let isURI; try { - parsed = new URL(param); + optionalCertificateFieldsObj = new URL(param); isURI = true; } catch (e) { isURI = false; } - if (isURI && !parsed.protocol) { + if (isURI && !optionalCertificateFieldsObj.protocol) { isURI = false; } return isURI; @@ -211,16 +211,16 @@ function transformW3(cert, certificateID) { const feedbackUrl = CERTIFICATE_FEEDBACK_BASE_URL + certificateId; const issuanceDate = new Date().toISOString(); - let parsed = {}; - for(const [key, value] of Object.entries(fieldsKeyPath)) { - let abc = R.pathOr('', value, cert); - if(key === "recipientIdentifier") { - abc = populateIdentity(abc, preEnrollmentCode); + let optionalCertificateFields = {}; + for(const [fieldName, certificatePath] of Object.entries(certificateFieldsKeyPath)) { + let fieldValue = R.pathOr('', certificatePath, cert); + if(fieldName === "recipientIdentifier") { + fieldValue = populateIdentity(fieldValue, preEnrollmentCode); } - else if(key === "recipientAge") { - abc = ageOfRecipient(cert.recipient); + else if(fieldName === "recipientAge") { + fieldValue = ageOfRecipient(cert.recipient); } - parsed[key] = abc; + optionalCertificateFields[fieldName] = fieldValue; } let data = { @@ -229,7 +229,7 @@ function transformW3(cert, certificateID) { issuer, issuanceDate, evidenceId, InfoUrl, feedbackUrl, certificateId, batch, vaccine, icd11Code, prophylaxis, vaccinationDate, dose, totalDoses, facilityAddressCountry, - ...parsed + ...optionalCertificateFields }; const template = certificateType === CERTIFICATE_TYPE_V3 ? DDCC_TEMPLATE : W3C_TEMPLATE; return render(template, data);