first commit

This commit is contained in:
Gianmarco Pettinato 2021-09-23 15:38:13 +02:00
commit b2cd5d7c5c
15 changed files with 6389 additions and 0 deletions

36
.eslintrc.json Normal file
View File

@ -0,0 +1,36 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

5663
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

24
package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "greenserver",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"typescript": "^4.4.3"
},
"devDependencies": {
"@types/node": "^16.9.6",
"@typescript-eslint/eslint-plugin": "^4.31.2",
"@typescript-eslint/parser": "^4.31.2",
"eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.24.2"
}
}

12
src/app.ts Normal file
View File

@ -0,0 +1,12 @@
import express from 'express';
import bodyParser from 'body-parser';
const app = express();
app.set('port', process.env.PORT || 3000);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
import './api';
export default app;

View File

@ -0,0 +1,5 @@
import { Request, Response } from 'express';
export const get = (req: Request, res: Response):void => {
res.status(200).send({});
};

View File

@ -0,0 +1,16 @@
import { Router } from 'express';
import * as exampleMW from './middleware';
import * as exampleCtrl from './controller';
import { API } from '../index';
export default class GreenApi implements API {
private router: Router;
constructor(router: Router) {
this.router = router;
}
setupApi():void {
this.router.get('/example',exampleMW.canGet,exampleCtrl.get);
}
}

View File

@ -0,0 +1,6 @@
import { Request, Response, NextFunction } from 'express';
export const canGet = (req: Request, res: Response, next: NextFunction):void => {
return next();
};

15
src/routes/api/index.ts Normal file
View File

@ -0,0 +1,15 @@
import GreenApi from './green';
import { Router, Express } from 'express';
export const setupApis = (application: Express):void => {
const router = Router();
const exampleApi = new GreenApi(router);
exampleApi.setupApi();
application.use('/api', router);
};
export interface API {
setupApi(): void; //virtual method
}

14
src/server.ts Normal file
View File

@ -0,0 +1,14 @@
import app from './app';
const server = app.listen(app.get('port'), () => {
console.log(
'App is running at http://localhost:%d in %s mode',
app.get('port'),
app.get('env')
);
console.log('Press CTRL-C to stop\n');
});
export default server;

View File

@ -0,0 +1,45 @@
// import crypto from 'crypto';
export class CertificateDownloader{
static instance: CertificateDownloader;
// private readonly baseUrl = 'https://get.dgc.gov.it';
private readonly keyStorage = 'cerificate_collection';
private readonly timeSpan = 86400000;
// private readonly timeSpan = 1000;
private cerficateCollection = {}
// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor(){}
public getCertificates(): unknown {
const savedData = JSON.parse(localStorage.getItem(this.keyStorage) || '{}');
if(savedData.lastupdateDate == null || Date.now() - savedData?.lastupdateDate > this.timeSpan){
this.getAllCertificate()
.then(() => { console.log('could not read the certificates from the local file'); return this.cerficateCollection })
.catch(console.error);
}
console.log('cerficates collection is valid loading from local source');
// console.log(dataRead.certificates);
this.cerficateCollection = savedData.certificates;
return this.cerficateCollection;
}
public static getCertificateDownloader():CertificateDownloader{
if(CertificateDownloader.instance == undefined){
CertificateDownloader.instance = new CertificateDownloader();
}
return CertificateDownloader.instance;
}
async getAllCertificate(): Promise<void> {
this.cerficateCollection = {};
const response = (await fetch('https://raw.githubusercontent.com/lovasoa/sanipasse/master/src/assets/Digital_Green_Certificate_Signing_Keys.json'));
if(response.ok){
this.cerficateCollection = await response.json();
console.log(response);
const lastupdateDate = Date.now();
localStorage.setItem(this.keyStorage, JSON.stringify({'certificates':this.cerficateCollection, lastupdateDate}))
// fs.writeFile('./cerificate_collection.json', JSON.stringify({'certificates':this.cerficateCollection, lastupdateDate}),'utf8',console.error);
}else{
throw new Error(response.statusText);
}
}
}

View File

@ -0,0 +1,41 @@
export class RuleDownloader {
static instance: RuleDownloader;
private readonly baseUrl = 'https://get.dgc.gov.it';
private readonly timeSpan = 86400000;
private readonly keyStorage = 'rules'
// private readonly timeSpan = 1000;
public rules:unknown = {}
// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor(){
this.getRules();
}
public getRules(): unknown {
const savedData = JSON.parse(localStorage.getItem(this.keyStorage) || '{}');
if(savedData.lastupdateDate == null || Date.now() - savedData?.lastupdateDate > this.timeSpan){
this.getSettings()
.then(() => { console.log('could not read the certificates from the local file'); return this.rules })
.catch(console.error);
}
console.log('cerficates collection is valid loading from local source');
// console.log(dataRead.certificates);
this.rules = savedData.certificates;
return this.rules;
}
static getRuleDownloader(): RuleDownloader{
if(this.instance == undefined){
RuleDownloader.instance = new RuleDownloader();
}
return RuleDownloader.instance;
}
private async getSettings(): Promise<unknown>{
const response = await fetch(`${this.baseUrl}/v1/dgc/settings`);
const jsonData = await response.json();
// this.rules = Rule.fromJSON(jsonData,{valueSets, validationClock:new Date().toISOString(),})
this.rules = jsonData;
localStorage.setItem(this.keyStorage, JSON.stringify({rules:this.rules,lastupdateDate:Date.now()}));
return jsonData;
}
}

View File

@ -0,0 +1,22 @@
import { CertificateDownloader } from './CertificateDownloader';
import { RuleDownloader } from './RuleDownloader';
import {DCC} from 'dcc-utils';
import fs from 'fs';
export default class Verifier {
static certDownloader: CertificateDownloader;
static ruleDownloader: RuleDownloader;
static certificateList: any;
static async setup():Promise<void> {
Verifier.certDownloader = CertificateDownloader.getCertificateDownloader();
Verifier.ruleDownloader = RuleDownloader.getRuleDownloader();
Verifier.certificateList = await Verifier.certDownloader.getCertificates()
}
static async checkCertificate(certificate:string): Promise<unknown>{
const dcc = await DCC.fromRaw(certificate);
const certCheck = await dcc.checkSignatureWithKeysList(Verifier.certificateList);
return certCheck;
}
}

View File

@ -0,0 +1,389 @@
{
"country-2-codes": [
"AD",
"AE",
"AF",
"AG",
"AI",
"AL",
"AM",
"AO",
"AQ",
"AR",
"AS",
"AT",
"AU",
"AW",
"AX",
"AZ",
"BA",
"BB",
"BD",
"BE",
"BF",
"BG",
"BH",
"BI",
"BJ",
"BL",
"BM",
"BN",
"BO",
"BQ",
"BR",
"BS",
"BT",
"BV",
"BW",
"BY",
"BZ",
"CA",
"CC",
"CD",
"CF",
"CG",
"CH",
"CI",
"CK",
"CL",
"CM",
"CN",
"CO",
"CR",
"CU",
"CV",
"CW",
"CX",
"CY",
"CZ",
"DE",
"DJ",
"DK",
"DM",
"DO",
"DZ",
"EC",
"EE",
"EG",
"EH",
"ER",
"ES",
"ET",
"FI",
"FJ",
"FK",
"FM",
"FO",
"FR",
"GA",
"GB",
"GD",
"GE",
"GF",
"GG",
"GH",
"GI",
"GL",
"GM",
"GN",
"GP",
"GQ",
"GR",
"GS",
"GT",
"GU",
"GW",
"GY",
"HK",
"HM",
"HN",
"HR",
"HT",
"HU",
"ID",
"IE",
"IL",
"IM",
"IN",
"IO",
"IQ",
"IR",
"IS",
"IT",
"JE",
"JM",
"JO",
"JP",
"KE",
"KG",
"KH",
"KI",
"KM",
"KN",
"KP",
"KR",
"KW",
"KY",
"KZ",
"LA",
"LB",
"LC",
"LI",
"LK",
"LR",
"LS",
"LT",
"LU",
"LV",
"LY",
"MA",
"MC",
"MD",
"ME",
"MF",
"MG",
"MH",
"MK",
"ML",
"MM",
"MN",
"MO",
"MP",
"MQ",
"MR",
"MS",
"MT",
"MU",
"MV",
"MW",
"MX",
"MY",
"MZ",
"NA",
"NC",
"NE",
"NF",
"NG",
"NI",
"NL",
"NO",
"NP",
"NR",
"NU",
"NZ",
"OM",
"PA",
"PE",
"PF",
"PG",
"PH",
"PK",
"PL",
"PM",
"PN",
"PR",
"PS",
"PT",
"PW",
"PY",
"QA",
"RE",
"RO",
"RS",
"RU",
"RW",
"SA",
"SB",
"SC",
"SD",
"SE",
"SG",
"SH",
"SI",
"SJ",
"SK",
"SL",
"SM",
"SN",
"SO",
"SR",
"SS",
"ST",
"SV",
"SX",
"SY",
"SZ",
"TC",
"TD",
"TF",
"TG",
"TH",
"TJ",
"TK",
"TL",
"TM",
"TN",
"TO",
"TR",
"TT",
"TV",
"TW",
"TZ",
"UA",
"UG",
"UM",
"US",
"UY",
"UZ",
"VA",
"VC",
"VE",
"VG",
"VI",
"VN",
"VU",
"WF",
"WS",
"YE",
"YT",
"ZA",
"ZM",
"ZW"
],
"disease-agent-targeted": [
"840539006"
],
"covid-19-lab-test-manufacturer-and-name": [
"1065",
"1097",
"1114",
"1144",
"1162",
"1173",
"1180",
"1190",
"1199",
"1201",
"1215",
"1218",
"1223",
"1225",
"1232",
"1236",
"1242",
"1244",
"1253",
"1257",
"1263",
"1266",
"1267",
"1268",
"1271",
"1278",
"1295",
"1296",
"1304",
"1319",
"1331",
"1333",
"1341",
"1343",
"1360",
"1363",
"1365",
"1375",
"1392",
"1420",
"1437",
"1443",
"1456",
"1466",
"1468",
"1481",
"1484",
"1489",
"1490",
"1501",
"1574",
"1604",
"1606",
"1654",
"1736",
"1747",
"1763",
"1764",
"1767",
"1769",
"1815",
"1822",
"1833",
"1844",
"1870",
"1884",
"1906",
"1919",
"1934",
"2010",
"2017",
"2029",
"2074",
"2098",
"2101",
"2103",
"2104",
"2108",
"2109",
"2116",
"2128",
"2130",
"2139",
"2183",
"308",
"344",
"345",
"768"
],
"covid-19-lab-result": [
"260373001",
"260415000"
],
"covid-19-lab-test-type": [
"LP217198-3",
"LP6464-4"
],
"vaccines-covid-19-auth-holders": [
"Bharat-Biotech",
"Gamaleya-Research-Institute",
"ORG-100001417",
"ORG-100001699",
"ORG-100006270",
"ORG-100010771",
"ORG-100013793",
"ORG-100020693",
"ORG-100024420",
"ORG-100030215",
"ORG-100031184",
"ORG-100032020",
"Sinovac-Biotech",
"Vector-Institute"
],
"vaccines-covid-19-names": [
"BBIBP-CorV",
"CVnCoV",
"Convidecia",
"CoronaVac",
"Covaxin",
"EU/1/20/1507",
"EU/1/20/1525",
"EU/1/20/1528",
"EU/1/21/1529",
"EpiVacCorona",
"Inactivated-SARS-CoV-2-Vero-Cell",
"Sputnik-V"
],
"sct-vaccines-covid-19": [
"1119305005",
"1119349007",
"J07BX03"
]
}

100
tsconfig.json Normal file
View File

@ -0,0 +1,100 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Projects */
// "incremental": true, /* Enable incremental compilation */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "resolveJsonModule": true, /* Enable importing .json files */
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}