standardizide the response

This commit is contained in:
Gianmarco Pettinato 2021-09-26 20:00:33 +02:00
parent d813e08e6e
commit f551ff3084
4 changed files with 291 additions and 28 deletions

View File

@ -24,18 +24,18 @@ When the request is complete, the server returns a JSON object with this structu
{ {
"signature": { "signature": {
"valid": true, "valid": true
}, },
"valid": { "valid": {
"valid": true, "valid": true,
"message": "Certificate is valid" "message": "Certificate is valid"
}, },
"info": { "info": {
"identity": { "identity": {
"fnt": "ROSSI", "fnt": "ROSSI",
"fn": "ROSSI", "fn": "ROSSI",
"gnt": "MARIO", "gnt": "MARIO",
"gn": "MARIO" "gn": "MARIO"
}, },
"dob": "1973-06-22" "dob": "1973-06-22"
} }

245
apigreen.json Normal file
View File

@ -0,0 +1,245 @@
{
"openapi": "3.0.0",
"info": {
"contact": {
"name": "Gianmarco Pettianto",
"email": "gianmarco@pettinato.eu",
"url": "jatus.tech"
},
"description": "Endpoint for DGC server",
"title": "green",
"version": "1.0"
},
"servers": [
{
"url": "http://localhost:3000"
}
],
"paths": {
"/api/green": {
"post": {
"tags": [],
"summary": "Sends a request of testing",
"operationId": "post-certificate",
"description": "Checks the greenpass raw data",
"parameters": [],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Valid-response"
},
"examples": {
"Valid certificate response": {
"value": {
"signature": {
"valid": true
},
"valid": {
"valid": true,
"message": "Certificate is valid"
},
"info": {
"identity": {
"fnt": "ROSSI",
"fn": "ROSSI",
"gnt": "MARIO",
"gn": "MARIO"
},
"dob": "1973-06-22"
}
}
},
"expired certificate": {
"value": {
"signature": {
"valid": true
},
"valid": {
"valid": false,
"message": "Certificate is not valid"
},
"info": {
"identity": {
"fnt": "ROSSI",
"fn": "ROSSI",
"gnt": "MARIO",
"gn": "MARIO"
},
"dob": "1973-06-22"
}
}
},
"Certificate not yet valid": {
"value": {
"signature": {
"valid": true
},
"valid": {
"valid": false,
"message": "Certificate is not valid yet"
},
"info": {
"identity": {
"fnt": "ROSSI",
"fn": "ROSSI",
"gnt": "MARIO",
"gn": "MARIO"
},
"dob": "1973-06-22"
}
}
},
"Invalid signature": {
"value": {
"signature": {
"valid": false
},
"valid": {
"valid": false,
"message": "Certificate is not valid yet"
},
"info": {
"identity": {
"fnt": "ROSSI",
"fn": "ROSSI",
"gnt": "MARIO",
"gn": "MARIO"
},
"dob": "1973-06-22"
}
}
},
"Invalid certificate": {
"value": {
"signature": {
"valid": false
},
"valid": {
"valid": false,
"message": ""
},
"info": {
"identity": {
"fnt": "",
"fn": "",
"gnt": "",
"gn": ""
},
"dob": ""
}
}
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Valid-response": {
"description": "",
"type": "object",
"x-examples": {
"example-1": {
"signature": {
"valid": true
},
"valid": {
"valid": true,
"message": "Certificate is valid"
},
"info": {
"identity": {
"fnt": "ROSSI",
"fn": "ROSSI",
"gnt": "MARIO",
"gn": "MARIO"
},
"dob": "1973-06-22"
}
}
},
"properties": {
"signature": {
"type": "object",
"required": [
"valid"
],
"properties": {
"valid": {
"type": "boolean"
}
}
},
"valid": {
"type": "object",
"required": [
"valid",
"message"
],
"properties": {
"valid": {
"type": "boolean"
},
"message": {
"type": "string",
"minLength": 1
}
}
},
"info": {
"type": "object",
"required": [
"identity",
"dob"
],
"properties": {
"identity": {
"type": "object",
"required": [
"fnt",
"fn",
"gnt",
"gn"
],
"properties": {
"fnt": {
"type": "string",
"minLength": 1
},
"fn": {
"type": "string",
"minLength": 1
},
"gnt": {
"type": "string",
"minLength": 1
},
"gn": {
"type": "string",
"minLength": 1
}
}
},
"dob": {
"type": "string",
"minLength": 1
}
}
}
},
"required": [
"signature",
"valid",
"info"
]
}
}
}
}

View File

@ -2,7 +2,7 @@ import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc'; import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone'; import timezone from 'dayjs/plugin/timezone';
interface checkResult { export interface CheckResult {
valid: boolean; valid: boolean;
message: string; message: string;
} }
@ -26,7 +26,7 @@ export class VaccineVerifier {
settings=[]; settings=[];
certTypes=['r','v','t',] certTypes=['r','v','t',]
private checkVaccine = (payload:any):checkResult => { private checkVaccine = (payload:any):CheckResult => {
const inoculationDate = dayjs(payload.dt); const inoculationDate = dayjs(payload.dt);
const validRulesSet = this.getRulesSet(payload.mp); const validRulesSet = this.getRulesSet(payload.mp);
const vaccineDiff = payload.sd - payload.dn; const vaccineDiff = payload.sd - payload.dn;
@ -40,17 +40,17 @@ export class VaccineVerifier {
} }
} }
private checkRecovery = (payload:any):checkResult => { private checkRecovery = (payload:any):CheckResult => {
const now = dayjs(); const now = dayjs();
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'}; return{valid:true, message:'Certificate is valid'};
} }
return {valid:false, message:'toimplement'}; return {valid:false, message:'Certificate is not valid'};
} }
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)
@ -77,10 +77,9 @@ export class VaccineVerifier {
this.settings = settings; this.settings = settings;
} }
public checkCertifcate(pass:unknown):checkResult { public checkCertifcate(pass:unknown):CheckResult {
console.log(pass);
const certificateDataAndType = this.getCertificateData(pass); const certificateDataAndType = this.getCertificateData(pass);
const result: checkResult = this.functionSelector[certificateDataAndType.key](certificateDataAndType.certificateData); const result: CheckResult = this.functionSelector[certificateDataAndType.key](certificateDataAndType.certificateData);
return result; return result;
} }
@ -103,25 +102,25 @@ export class VaccineVerifier {
}); });
} }
private getLogicValidityDays(validRulesSet:unknown[],startKey:string, endKey:string, inoculationDate: dayjs.Dayjs): checkResult { private getLogicValidityDays(validRulesSet:unknown[],startKey:string, endKey:string, inoculationDate: dayjs.Dayjs): CheckResult {
const now = dayjs(); const now = dayjs();
const ruleStart = validRulesSet.find((elem:any)=>{return elem.name == startKey;}); const ruleStart = validRulesSet.find((elem:any)=>{return elem.name == startKey;});
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'}; if(startValidity.isAfter(now)) return {valid:false, message:'Certificate is not valid yet'};
if(now.isAfter(endValidity)) return {valid:false, message:'Certificate not more valid'}; if(now.isAfter(endValidity)) return {valid:false, message:'Certificate is not valid'};
return {valid:true, message:'Certificate is valid'}; 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 {
const now = dayjs(); const now = dayjs();
const ruleStart = validRulesSet.find((elem:any)=>{return elem.name == startKey;}); const ruleStart = validRulesSet.find((elem:any)=>{return elem.name == startKey;});
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'}; if(startValidity.isAfter(now)) return {valid:false, message:'Certificate is not valid yet'};
if(now.isAfter(endValidity)) return {valid:false, message:'Certificate not more valid'}; if(now.isAfter(endValidity)) return {valid:false, message:'Certificate is not valid'};
return {valid:true, message:'Certificate is valid'}; return {valid:true, message:'Certificate is valid'};
} }

View File

@ -1,8 +1,23 @@
import { CertificateDownloader } from '../SettingsDownloader/CertificateDownloader'; import { CertificateDownloader } from '../SettingsDownloader/CertificateDownloader';
import { RuleDownloader } from '../SettingsDownloader/RuleDownloader'; import { RuleDownloader } from '../SettingsDownloader/RuleDownloader';
import { VaccineVerifier } from './VaccineVerifier'; import { CheckResult, VaccineVerifier } from './VaccineVerifier';
import {DCC} from 'dcc-utils'; import {DCC} from 'dcc-utils';
import jsrsasign from 'jsrsasign'; import jsrsasign from 'jsrsasign';
interface certificateResponse {
signature:{
valid: boolean
},
valid:CheckResult,
info:{
identity:{
fnt:string,
fn:string,
gnt:string,
gn:string
},
dob:string
}
}
export default class Verifier { export default class Verifier {
static instance: Verifier|undefined = undefined; static instance: Verifier|undefined = undefined;
private certDownloader: CertificateDownloader; private certDownloader: CertificateDownloader;
@ -22,12 +37,16 @@ export default class Verifier {
return Verifier.instance; return Verifier.instance;
} }
async checkCertificate(certificate:string): Promise<unknown>{ async checkCertificate(certificate:string): Promise<certificateResponse>{
const dcc = await DCC.fromRaw(certificate); let result:certificateResponse = {signature:{valid: false}, valid:{valid:false, message:''}, info:{identity:{fnt:'',fn:'',gnt:'',gn:''},dob:''}};
let result:unknown = {}; try {
result = await (await this.checkKey(dcc)).valid; const dcc = await DCC.fromRaw(certificate);
const vaccineVerifier = new VaccineVerifier(await this.ruleDownloader.getRules()); const signatureValidity = (await this.checkKey(dcc)).valid;
result = {signature: result, valid: vaccineVerifier.checkCertifcate(dcc.payload), info:{identity:dcc.payload.nam,dob:dcc.payload.dob}}; const vaccineVerifier = new VaccineVerifier(await this.ruleDownloader.getRules());
result = {signature:{valid: signatureValidity}, valid: vaccineVerifier.checkCertifcate(dcc.payload), info:{identity:dcc.payload.nam,dob:dcc.payload.dob}};
} catch (error) {
console.log(error);
}
return result; return result;
} }