standardizide the response
This commit is contained in:
parent
d813e08e6e
commit
f551ff3084
14
README.md
14
README.md
@ -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
245
apigreen.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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'};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user