added readme
This commit is contained in:
parent
405bd9364f
commit
12f733ee86
36
README.md
Normal file
36
README.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# DGCServerVerifier
|
||||||
|
|
||||||
|
## what is it?
|
||||||
|
This web server takes a post request on /api/green with a json object as body.
|
||||||
|
|
||||||
|
Verifies if the data are correct:
|
||||||
|
* Downloads the last rules released on https://get.dgc.gov.it/v1/dgc/settings
|
||||||
|
* Downloads the valid keys on https://get.dgc.gov.it/v1/dgc/signercertificate/status and https://get.dgc.gov.it/v1/dgc/signercertificate/update.
|
||||||
|
* Verifies that the certificate is correctly encoded, as per standard.
|
||||||
|
* Verifies signature on the certificate is still valid as the day of the request.
|
||||||
|
* Verifies that DGC provided is still valid as today using the setting in the first point.
|
||||||
|
|
||||||
|
## how does it work?
|
||||||
|
To perform a request to the endpoint, preferably behind a reverse proxy in HTTPS, you should
|
||||||
|
build a JSON object with this structure:
|
||||||
|
|
||||||
|
|
||||||
|
{key:'HC1:6BFOXN%TS3DHPVO13J /G-/2YRVA.Q/R8VRU2FC1J9M$DI9C3K9$:L44HRJPC%OQHIZC4.OI1RM8ZA.A5:S9MKN4NN3F85QNCY0O%0VZ001HOC9JU0D0HT0HB2PL/IB*09B9LW4T*8+DC9I0%YB/VM$*SBAKYE9*FJ7ID$0HY84Q:GY3LV2LW 2C0IO$571IL+9J2P6%24.8P+5E/HW.CV2L%3L%*8PHN6D7LLK*2HG%89UV-0LZ 2ZJJ %C4IJZJJBY43%8 C1VHLEC78G1TFHM*K2ILS-O:S9UZ4+FJE 4Y3LO78L:P...ecc'}
|
||||||
|
|
||||||
|
The string is the raw value read from a QR code reader app.
|
||||||
|
|
||||||
|
## what does it returns?
|
||||||
|
When the request is complete, the server returns a JSON object with this structure:
|
||||||
|
|
||||||
|
{
|
||||||
|
"signature": {
|
||||||
|
"valid": true,
|
||||||
|
},
|
||||||
|
"valid": {
|
||||||
|
"valid": true,
|
||||||
|
"message": "Certificate is valid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## third party copyright notice
|
||||||
|
This software uses the library [DCC Utils](https://github.com/ministero-salute/dcc-utils) written by ministero-salute
|
@ -5,7 +5,6 @@ import timezone from 'dayjs/plugin/timezone';
|
|||||||
interface checkResult {
|
interface checkResult {
|
||||||
valid: boolean;
|
valid: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
type: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VaccineVerifier {
|
export class VaccineVerifier {
|
||||||
@ -33,7 +32,7 @@ export class VaccineVerifier {
|
|||||||
const vaccineDiff = payload.sd - payload.dn;
|
const vaccineDiff = payload.sd - payload.dn;
|
||||||
const baseRuleIndex = validRulesSet.findIndex((elem:any)=>{ return elem.name == this.vaccineEndDayComplete;});
|
const baseRuleIndex = validRulesSet.findIndex((elem:any)=>{ return elem.name == this.vaccineEndDayComplete;});
|
||||||
if( baseRuleIndex == -1)
|
if( baseRuleIndex == -1)
|
||||||
return {valid:false, message:'Invaild set of rules check with operator', type:'vaccine'};
|
return {valid:false, message:'Invaild set of rules check with operator'};
|
||||||
if(vaccineDiff <= 0){
|
if(vaccineDiff <= 0){
|
||||||
return this.getLogicValidityDays(validRulesSet, this.vaccineStartDayComplete, this.vaccineEndDayComplete,inoculationDate);
|
return this.getLogicValidityDays(validRulesSet, this.vaccineStartDayComplete, this.vaccineEndDayComplete,inoculationDate);
|
||||||
} else {
|
} else {
|
||||||
@ -46,16 +45,16 @@ export class VaccineVerifier {
|
|||||||
const dateFrom = dayjs(payload.df);
|
const dateFrom = dayjs(payload.df);
|
||||||
const dateEnd = dayjs(payload.du);
|
const dateEnd = dayjs(payload.du);
|
||||||
if(now.isAfter(dateFrom) && now.isBefore(dateEnd)){
|
if(now.isAfter(dateFrom) && now.isBefore(dateEnd)){
|
||||||
return{valid:true, message:'Certificate is valid', type:'recovery'};
|
return{valid:true, message:'Certificate is valid'};
|
||||||
}
|
}
|
||||||
return {valid:false, message:'toimplement', type:'recovery'};
|
return {valid:false, message:'toimplement'};
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkTest = (payload:any):checkResult => {
|
private checkTest = (payload:any):checkResult => {
|
||||||
const validRulesSet = this.getRulesSet('GENERIC');
|
const validRulesSet = this.getRulesSet('GENERIC');
|
||||||
const testType = payload.tt;
|
const testType = payload.tt;
|
||||||
if(payload.tr === this.positiveTest)
|
if(payload.tr === this.positiveTest)
|
||||||
return {valid:false, message:'The test detected the virus',type:'test'};
|
return {valid:false, message:'The test detected the virus'};
|
||||||
const collectionDateTime = dayjs.tz(payload.sc,'UTC').tz(dayjs.tz.guess());
|
const collectionDateTime = dayjs.tz(payload.sc,'UTC').tz(dayjs.tz.guess());
|
||||||
if(testType == this.rapidTest){
|
if(testType == this.rapidTest){
|
||||||
return this.getLogicValidityHours(validRulesSet,this.rapidTestStartHour,this.rapidTestEndHour,collectionDateTime);
|
return this.getLogicValidityHours(validRulesSet,this.rapidTestStartHour,this.rapidTestEndHour,collectionDateTime);
|
||||||
@ -63,7 +62,7 @@ export class VaccineVerifier {
|
|||||||
if(testType == this.molecularTest){
|
if(testType == this.molecularTest){
|
||||||
return this.getLogicValidityHours(validRulesSet,this.molecularTestStartHour,this.molecularTestEndHour,collectionDateTime);
|
return this.getLogicValidityHours(validRulesSet,this.molecularTestStartHour,this.molecularTestEndHour,collectionDateTime);
|
||||||
}
|
}
|
||||||
return {valid:false, message:'unknown test type',type:'test'};
|
return {valid:false, message:'unknown test type'};
|
||||||
}
|
}
|
||||||
|
|
||||||
private functionSelector = {
|
private functionSelector = {
|
||||||
@ -110,9 +109,9 @@ export class VaccineVerifier {
|
|||||||
const ruleEnd = validRulesSet.find((elem:any)=>{return elem.name == endKey;});
|
const ruleEnd = validRulesSet.find((elem:any)=>{return elem.name == endKey;});
|
||||||
const startValidity = inoculationDate.add(parseInt(ruleStart['value']),'days');
|
const startValidity = inoculationDate.add(parseInt(ruleStart['value']),'days');
|
||||||
const endValidity = inoculationDate.add(parseInt(ruleEnd['value']),'days');
|
const endValidity = inoculationDate.add(parseInt(ruleEnd['value']),'days');
|
||||||
if(startValidity.isAfter(now)) return {valid:false, message:'Certificate not yet valid', type:'vaccine'};
|
if(startValidity.isAfter(now)) return {valid:false, message:'Certificate not yet valid'};
|
||||||
if(now.isAfter(endValidity)) return {valid:false, message:'Certificate not more valid', type:'vaccine'};
|
if(now.isAfter(endValidity)) return {valid:false, message:'Certificate not more valid'};
|
||||||
return {valid:true, message:'Certificate is valid', type:'vaccine'};
|
return {valid:true, message:'Certificate is valid'};
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLogicValidityHours(validRulesSet:unknown[],startKey:string, endKey:string, inoculationDate: dayjs.Dayjs): checkResult {
|
private getLogicValidityHours(validRulesSet:unknown[],startKey:string, endKey:string, inoculationDate: dayjs.Dayjs): checkResult {
|
||||||
@ -121,9 +120,9 @@ export class VaccineVerifier {
|
|||||||
const ruleEnd = validRulesSet.find((elem:any)=>{return elem.name == endKey;});
|
const ruleEnd = validRulesSet.find((elem:any)=>{return elem.name == endKey;});
|
||||||
const startValidity = inoculationDate.add(parseInt(ruleStart['value']),'hours');
|
const startValidity = inoculationDate.add(parseInt(ruleStart['value']),'hours');
|
||||||
const endValidity = inoculationDate.add(parseInt(ruleEnd['value']),'hours');
|
const endValidity = inoculationDate.add(parseInt(ruleEnd['value']),'hours');
|
||||||
if(startValidity.isAfter(now)) return {valid:false, message:'Certificate not yet valid', type:'test'};
|
if(startValidity.isAfter(now)) return {valid:false, message:'Certificate not yet valid'};
|
||||||
if(now.isAfter(endValidity)) return {valid:false, message:'Certificate not more valid', type:'test'};
|
if(now.isAfter(endValidity)) return {valid:false, message:'Certificate not more valid'};
|
||||||
return {valid:true, message:'Certificate is valid', type:'test'};
|
return {valid:true, message:'Certificate is valid'};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -25,7 +25,7 @@ export default class Verifier {
|
|||||||
async checkCertificate(certificate:string): Promise<unknown>{
|
async checkCertificate(certificate:string): Promise<unknown>{
|
||||||
const dcc = await DCC.fromRaw(certificate);
|
const dcc = await DCC.fromRaw(certificate);
|
||||||
let result:unknown = {};
|
let result:unknown = {};
|
||||||
result = await this.checkKey(dcc);
|
result = await (await this.checkKey(dcc)).valid;
|
||||||
const vaccineVerifier = new VaccineVerifier(await this.ruleDownloader.getRules());
|
const vaccineVerifier = new VaccineVerifier(await this.ruleDownloader.getRules());
|
||||||
result = {signature: result, valid: vaccineVerifier.checkCertifcate(dcc.payload)};
|
result = {signature: result, valid: vaccineVerifier.checkCertifcate(dcc.payload)};
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
Reference in New Issue
Block a user