semplified the validity check process
This commit is contained in:
parent
71d7c0531d
commit
e7cf6a1c2d
@ -1,7 +1,65 @@
|
|||||||
describe('CertificateDownloader',()=>{
|
|
||||||
|
import { CertificateDownloader } from './CertificateDownloader';
|
||||||
|
import mock from 'mock-fs';
|
||||||
|
import axios, { AxiosResponse } from 'axios';
|
||||||
|
jest.mock('axios');
|
||||||
|
|
||||||
|
const certifcateDownloader = new CertificateDownloader();
|
||||||
|
const testCetificate = 'MIICyzCCAnGgAwIBAgIBATAKBggqhkjOPQQDAjCBqTELMAkGA1UEBhMCREsxKTAnBgNVBAoMIFRoZSBEYW5pc2ggSGVhbHRoIERhdGEgQXV0aG9yaXR5MSkwJwYDVQQLDCBUaGUgRGFuaXNoIEhlYWx0aCBEYXRhIEF1dGhvcml0eTEcMBoGA1UEAwwTUFJPRF9DU0NBX0RHQ19ES18wMTEmMCQGCSqGSIb3DQEJARYXa29udGFrdEBzdW5kaGVkc2RhdGEuZGswHhcNMjEwNTE5MDk0NzI1WhcNMjMwNTIwMDk0NzI1WjCBqDELMAkGA1UEBhMCREsxKTAnBgNVBAoMIFRoZSBEYW5pc2ggSGVhbHRoIERhdGEgQXV0aG9yaXR5MSkwJwYDVQQLDCBUaGUgRGFuaXNoIEhlYWx0aCBEYXRhIEF1dGhvcml0eTEbMBkGA1UEAwwSUFJPRF9EU0NfREdDX0RLXzAxMSYwJAYJKoZIhvcNAQkBFhdrb250YWt0QHN1bmRoZWRzZGF0YS5kazBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAZnYGP1TkbHnF8WP9MTTTs6CTUWlZzDJh7OY4l6xr2gzstY8w1Dsr0fvicYH9PmLhsqef1AGNECIe';
|
||||||
|
const kidHeader = 'NAyCKly+hCg=';
|
||||||
|
const testCollecion = [{kid:kidHeader,certificate:testCetificate}];
|
||||||
|
let resumeToken = 2;
|
||||||
|
const allKids = ['NAyCKly+hCg=', '25QCxBrBJvA=', 'ODqaG8mnbro=', 'e4lH6I4iMIM='];
|
||||||
|
const validKid = ['NAyCKly+hCg='];
|
||||||
|
let responseCounter = 0;
|
||||||
|
|
||||||
|
const mockedAxios = axios as jest.Mocked<typeof axios>;
|
||||||
|
const axiosResponseCertificates = (data: any): AxiosResponse => {
|
||||||
|
console.log('axios mock ', data);
|
||||||
|
const status = (responseCounter < allKids.length -1)? 200 : 204;
|
||||||
|
return {
|
||||||
|
data: testCetificate,
|
||||||
|
status,
|
||||||
|
statusText: 'OK',
|
||||||
|
headers:{
|
||||||
|
'x-kid':allKids[responseCounter++],
|
||||||
|
'x-resume-token':resumeToken++,
|
||||||
|
},
|
||||||
|
config:{}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const axioResponseValidKids: AxiosResponse = {
|
||||||
|
data: validKid,
|
||||||
|
status: 200,
|
||||||
|
statusText: 'OK',
|
||||||
|
headers:{},
|
||||||
|
config:{}
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('CertificateDownloader', ()=>{
|
||||||
describe('getCertificates()',()=>{
|
describe('getCertificates()',()=>{
|
||||||
it('placeholder',()=>{
|
test('Testing getCertificates basic outcome: file loaded from local source and is still valid',async ()=>{
|
||||||
expect(false).toBe(false);
|
mock({
|
||||||
|
'./cerificate_collection.json': Buffer.from(JSON.stringify({certificates:testCollecion,lastupdateDate:Date.now()}))
|
||||||
|
});
|
||||||
|
const collection = await certifcateDownloader.getCertificates();
|
||||||
|
mock.restore();
|
||||||
|
expect(JSON.stringify(collection)).toBe(JSON.stringify(testCollecion));
|
||||||
});
|
});
|
||||||
|
// test('Testing getRules basic outcome: file loaded from local source and is expired',async ()=>{
|
||||||
|
// mockedAxios.get.mockResolvedValueOnce(axioResponseValidKids);
|
||||||
|
// mockedAxios.get.mockResolvedValueOnce(axiosResponseCertificates);
|
||||||
|
|
||||||
|
// const date = Date.now() - 86400010;
|
||||||
|
// mock({
|
||||||
|
// './cerificate_collection.json': Buffer.from(JSON.stringify({certificates:testCollecion,lastupdateDate:date}))
|
||||||
|
// });
|
||||||
|
// expect(axios.get).not.toHaveBeenCalled();
|
||||||
|
// const collection = await certifcateDownloader.getCertificates();
|
||||||
|
// expect(axios.get).toHaveBeenCalled();
|
||||||
|
// mock.restore();
|
||||||
|
// expect(JSON.stringify(collection)).toBe(JSON.stringify(testCollecion));
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,7 @@ export class CertificateDownloader{
|
|||||||
private readonly baseUrl = 'https://get.dgc.gov.it';
|
private readonly baseUrl = 'https://get.dgc.gov.it';
|
||||||
private readonly updateApi = '/v1/dgc/signercertificate/update'
|
private readonly updateApi = '/v1/dgc/signercertificate/update'
|
||||||
private readonly statusApi = '/v1/dgc/signercertificate/status'
|
private readonly statusApi = '/v1/dgc/signercertificate/status'
|
||||||
private readonly keyStorage = './cerificate_collection.json';
|
private readonly keyStorage = './certificate_collection.json';
|
||||||
private readonly timeSpan = 86400000;
|
private readonly timeSpan = 86400000;
|
||||||
// private readonly timeSpan = 1;
|
// private readonly timeSpan = 1;
|
||||||
private certificatesCollection:{kid:string,certificate:string}[] = [];
|
private certificatesCollection:{kid:string,certificate:string}[] = [];
|
||||||
@ -27,7 +27,8 @@ export class CertificateDownloader{
|
|||||||
}
|
}
|
||||||
return this.certificatesCollection;
|
return this.certificatesCollection;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if(error.message == 'ENOENT: no such file or directory, open \'rules.json\''){
|
console.log(error.message);
|
||||||
|
if(error.message == 'ENOENT: no such file or directory, open \'./certificate_collection.json\''){
|
||||||
await fs.writeFile(this.keyStorage,'{}');
|
await fs.writeFile(this.keyStorage,'{}');
|
||||||
return this.getCertificates();
|
return this.getCertificates();
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ describe('RuleDownloader', ()=>{
|
|||||||
mock.restore();
|
mock.restore();
|
||||||
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
||||||
});
|
});
|
||||||
test('Testing getRules basic outcome: file loaded from local source and is still valid',async ()=>{
|
test('Testing getRules basic outcome: file loaded from local source is expired download a new one',async ()=>{
|
||||||
mockedAxios.get.mockResolvedValue(successResposnse);
|
mockedAxios.get.mockResolvedValueOnce(successResposnse);
|
||||||
const date = Date.now() - 86400010;
|
const date = Date.now() - 86400010;
|
||||||
mock({
|
mock({
|
||||||
'./rules.json': Buffer.from(JSON.stringify({rules:mockRules,lastupdateDate:date}))
|
'./rules.json': Buffer.from(JSON.stringify({rules:mockRules,lastupdateDate:date}))
|
||||||
@ -42,17 +42,11 @@ describe('RuleDownloader', ()=>{
|
|||||||
mock.restore();
|
mock.restore();
|
||||||
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
||||||
});
|
});
|
||||||
test('Testing getRules basic outcome: file loaded from local source and is still valid',async ()=>{
|
// test('Testing getRules basic outcome: file loaded from local source and is still valid',async ()=>{
|
||||||
mock({});
|
// mockedAxios.get.mockResolvedValueOnce(successResposnse);
|
||||||
try {
|
// expect(axios.get).not.toHaveBeenCalled();
|
||||||
mockedAxios.get.mockResolvedValue(successResposnse);
|
// const rules = await ruleDownloader.getRules();
|
||||||
const rules = await ruleDownloader.getRules();
|
// expect(axios.get).toHaveBeenCalled();
|
||||||
mock.restore();
|
// });
|
||||||
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -32,9 +32,7 @@ export class RuleDownloader {
|
|||||||
private async getSettings(): Promise<unknown[]>{
|
private async getSettings(): Promise<unknown[]>{
|
||||||
const response:AxiosResponse<unknown[]> = await axios.get(`${this.baseUrl}/v1/dgc/settings`);
|
const response:AxiosResponse<unknown[]> = await axios.get(`${this.baseUrl}/v1/dgc/settings`);
|
||||||
const jsonData = response.data;
|
const jsonData = response.data;
|
||||||
// this.rules = Rule.fromJSON(jsonData,{valueSets, validationClock:new Date().toISOString(),})
|
|
||||||
this.rules = jsonData;
|
this.rules = jsonData;
|
||||||
// localStorage.setItem(this.keyStorage, JSON.stringify({rules:this.rules,lastupdateDate:Date.now()}));
|
|
||||||
const file = await fs.open(this.keyStorage,'w');
|
const file = await fs.open(this.keyStorage,'w');
|
||||||
await file.writeFile(JSON.stringify({rules:this.rules,lastupdateDate:Date.now()}));
|
await file.writeFile(JSON.stringify({rules:this.rules,lastupdateDate:Date.now()}));
|
||||||
await file.close();
|
await file.close();
|
||||||
|
25
src/Services/dgcVerifier/VaccineVerifier.spec.ts
Normal file
25
src/Services/dgcVerifier/VaccineVerifier.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
describe('VaccineVerifier',()=>{
|
||||||
|
describe('checkCertifcate',()=>{
|
||||||
|
it('Valid vaccine',()=>{
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
it('Expired vaccine',()=>{
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
it('Yet to be valid vaccine',()=>{
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
it('Test vaccine',()=>{
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
it('Expired Test',()=>{
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
it('Yet to be valid Test',()=>{
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
it('Positive Test',()=>{
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,4 +1,3 @@
|
|||||||
import {DCC} from 'dcc-utils';
|
|
||||||
import dayjs from 'dayjs';
|
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';
|
||||||
@ -38,7 +37,6 @@ export class VaccineVerifier {
|
|||||||
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 {
|
||||||
console.log('single dose');
|
|
||||||
return this.getLogicValidityDays(validRulesSet, this.vaccineStartDayNotComplete, this.vaccineEndDayNotComplete,inoculationDate);
|
return this.getLogicValidityDays(validRulesSet, this.vaccineStartDayNotComplete, this.vaccineEndDayNotComplete,inoculationDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,20 +78,20 @@ export class VaccineVerifier {
|
|||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkCertifcate(pass:DCC):checkResult {
|
public checkCertifcate(pass:unknown):checkResult {
|
||||||
console.log(pass.payload);
|
console.log(pass);
|
||||||
const payloadAndType = this.getPayloadAndType(pass);
|
const certificateDataAndType = this.getCertificateData(pass);
|
||||||
const result: checkResult = this.functionSelector[payloadAndType.key](payloadAndType.payload);
|
const result: checkResult = this.functionSelector[certificateDataAndType.key](certificateDataAndType.certificateData);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPayloadAndType(pass:DCC): {key:string,payload:unknown}{
|
private getCertificateData(pass:unknown): {key:string,certificateData:unknown}{
|
||||||
const result:{key:string,payload:unknown} = {key:'',payload:[]};
|
const result:{key:string,certificateData:unknown} = {key:'',certificateData:[]};
|
||||||
this.certTypes.forEach((key:string) => {
|
this.certTypes.forEach((key:string) => {
|
||||||
if(pass.payload[key] != undefined){
|
if(pass[key] != undefined){
|
||||||
if((pass.payload[key] as unknown[]).length != 0){
|
if((pass[key] as unknown[]).length != 0){
|
||||||
result.key =(key);
|
result.key =(key);
|
||||||
result.payload = (pass.payload[key][pass.payload[key].length -1]);
|
result.certificateData = (pass[key][pass[key].length -1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -108,7 +106,6 @@ 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();
|
||||||
console.log(validRulesSet);
|
|
||||||
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');
|
||||||
|
@ -23,14 +23,11 @@ export default class Verifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async checkCertificate(certificate:string): Promise<unknown>{
|
async checkCertificate(certificate:string): Promise<unknown>{
|
||||||
console.log(certificate);
|
|
||||||
const dcc = await DCC.fromRaw(certificate);
|
const dcc = await DCC.fromRaw(certificate);
|
||||||
console.log(dcc.payload);
|
|
||||||
let result:unknown = {};
|
let result:unknown = {};
|
||||||
result = await this.checkKey(dcc);
|
result = await this.checkKey(dcc);
|
||||||
const vaccineVerifier = new VaccineVerifier(await this.ruleDownloader.getRules());
|
const vaccineVerifier = new VaccineVerifier(await this.ruleDownloader.getRules());
|
||||||
result = {signature: result, valid: vaccineVerifier.checkCertifcate(dcc)};
|
result = {signature: result, valid: vaccineVerifier.checkCertifcate(dcc.payload)};
|
||||||
console.log(result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user