From 00a68c19ee6c6be536f3a8b9bb7e8998799a2c5a Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 30 Aug 2021 15:11:38 +0200 Subject: [PATCH] Finished MUPSaobracajnaAPI class + addded example --- index.ts | 127 ++++++++++++++++++++++++++++++++++---------- models/api/api.ts | 26 +++++---- models/api/types.ts | 49 +++++++++++++++++ 3 files changed, 164 insertions(+), 38 deletions(-) diff --git a/index.ts b/index.ts index bd53c76..10c3a17 100644 --- a/index.ts +++ b/index.ts @@ -1,9 +1,82 @@ import SaobracajnaApi, { SaobracajnaApiResponseStatus } from "./models/api/api"; +import { RegistrationIndex } from "./models/api/types"; class MUPSaobracajnaApi { - -} + private api: SaobracajnaApi; + device: string = ""; + constructor( + device = "", + private cacheEnabled = false, + private isInit = false + ) { + this.api = new SaobracajnaApi(); + this.start(); + if (device) this.selectReaderSync(device); + } + + private start() { + const status = this.api.startup().status; + if (status !== SaobracajnaApiResponseStatus.OK) throw new Error(status); + this.isInit = true; + } + private selectReaderSync(device: string) { + const status = this.api.selectReader(device).status; + if (status !== SaobracajnaApiResponseStatus.OK) throw new Error(status); + } + async processNewCard() { + const status = this.api.processNewCard().status; + if (status !== SaobracajnaApiResponseStatus.OK) throw new Error(status); + } + async readAllData() { + if (!this.cacheEnabled) { + await this.processNewCard(); + } + const res = await Promise.all([ + this.readDocumentData(false), + this.readPersonalData(false), + this.readVehicleData(false), + ]); + return { ...res[0], ...res[1], ...res[2] }; + } + async readDocumentData(forceRead = !this.cacheEnabled) { + if (forceRead) await this.processNewCard(); + const res = this.api.readDocumentData(); + if (res.status !== SaobracajnaApiResponseStatus.OK) + throw new Error(res.status); + return res.data!; + } + async readVehicleData(forceRead = !this.cacheEnabled) { + if (forceRead) await this.processNewCard(); + const res = this.api.readVehicleData(); + if (res.status !== SaobracajnaApiResponseStatus.OK) + throw new Error(res.status); + return res.data!; + } + async readPersonalData(forceRead = !this.cacheEnabled) { + if (forceRead) await this.processNewCard(); + const res = this.api.readPersonalData(); + if (res.status !== SaobracajnaApiResponseStatus.OK) + throw new Error(res.status); + return res.data!; + } + async readRegistration( + regInd: RegistrationIndex, + forceRead = !this.cacheEnabled + ) { + if (forceRead) await this.processNewCard(); + const res = this.api.readRegistration(regInd); + if (res.status !== SaobracajnaApiResponseStatus.OK) + throw new Error(res.status); + return res.data!; + } + async end() { + if (!this.isInit) return; + const status = this.api.cleanup().status; + if (status !== SaobracajnaApiResponseStatus.OK) throw new Error(status); + this.isInit = false; + } +} /* EXAMPLE */ const smartcard = require("smartcard"); @@ -12,32 +85,28 @@ const devices = new smartcard.Devices(); devices.on("device-activated", (e: any) => { console.log("---Device:", e.device.name); console.log("Waiting for card..."); - const api = new SaobracajnaApi(); - let status; - if (api.startup().status === SaobracajnaApiResponseStatus.OK) { - console.log("Started."); - status = api.selectReader(e.device.name).status; - if (status === SaobracajnaApiResponseStatus.OK) { - e.device.on("card-inserted", (e: any) => { - console.log("---Card:", e.card.getAtr()); - - status = api.processNewCard().status; - if (status === SaobracajnaApiResponseStatus.OK) { - const res = api.readDocumentData(); - if (res.status === SaobracajnaApiResponseStatus.OK) { - console.log(res.data); - } else { - console.log(res.status); - } - } else { - console.log(status); - } - }); - } else { - console.log(status); - } - } else { - console.log("ERROR"); - } + + e.device.on("card-inserted", (e: any) => { + console.log("---Card:", e.card.getAtr()); + + _test(e.device.name); + }); }); console.log("Waiting for device..."); + +const _test = async (device: string) => { + console.log("---START---"); + const celik = new MUPSaobracajnaApi(device); + try { + const data = await celik.readAllData(); + console.log(data); + // const reg = await celik.readRegistration(RegistrationIndex.EF_Registration_A); + // console.log(reg); + } catch (e: any) { + console.log(e.message ?? new Error(e)); + } finally { + await celik.end(); + console.log("---END---"); + process.exit(); + } +}; diff --git a/models/api/api.ts b/models/api/api.ts index 50d4494..4724072 100644 --- a/models/api/api.ts +++ b/models/api/api.ts @@ -5,7 +5,13 @@ import { SaobracajnaApiResponseStatus, } from "./responses"; import API_TYPES from "../saobracajna/types"; -import { RegistrationIndex } from "./types"; +import { + RegistrationIndex, + sdDocumentData, + sdPersonalData, + sdRegistrationData, + sdVehicleData, +} from "./types"; import { convertStruct } from "../converter"; class SaobracajnaApi { @@ -27,25 +33,27 @@ class SaobracajnaApi { processNewCard(): SaobracajnaApiResponse { return getResponse(this.saobracajnaApiLib.sdProcessNewCard()); } - readDocumentData(): SaobracajnaApiResponse { + readDocumentData(): SaobracajnaApiResponse { const pData = new API_TYPES.SD_DOCUMENT_DATA(); const res = this.saobracajnaApiLib.sdReadDocumentData(pData.ref()); - return getResponse(res, convertStruct(pData)); + return getResponse(res, convertStruct(pData) as sdDocumentData); } - readVehicleData(): SaobracajnaApiResponse { + readVehicleData(): SaobracajnaApiResponse { const pData = new API_TYPES.SD_VEHICLE_DATA(); const res = this.saobracajnaApiLib.sdReadVehicleData(pData.ref()); - return getResponse(res, convertStruct(pData)); + return getResponse(res, convertStruct(pData) as sdVehicleData); } - readPersonalData(): SaobracajnaApiResponse { + readPersonalData(): SaobracajnaApiResponse { const pData = new API_TYPES.SD_PERSONAL_DATA(); const res = this.saobracajnaApiLib.sdReadPersonalData(pData.ref()); - return getResponse(res, convertStruct(pData)); + return getResponse(res, convertStruct(pData) as sdPersonalData); } - readRegistration(index: RegistrationIndex): SaobracajnaApiResponse { + readRegistration( + index: RegistrationIndex + ): SaobracajnaApiResponse { const pData = new API_TYPES.SD_REGISTRATION_DATA(); const res = this.saobracajnaApiLib.sdReadRegistration(pData.ref(), index); - return getResponse(res, convertStruct(pData)); + return getResponse(res, convertStruct(pData) as sdRegistrationData); } } diff --git a/models/api/types.ts b/models/api/types.ts index dbedb4c..e9da436 100644 --- a/models/api/types.ts +++ b/models/api/types.ts @@ -1,3 +1,52 @@ +export type sdDocumentData = { + stateIssuing: string; + competentAuthority: string; + authorityIssuing: string; + unambiguousNumber: string; + issuingDate: string; + expiryDate: string; + serialNumber: string; +}; +export type sdPersonalData = { + ownersPersonalNo: string; + ownersSurnameOrBusinessName: string; + ownerName: string; + ownerAddress: string; + usersPersonalNo: string; + usersSurnameOrBusinessName: string; + usersName: string; + usersAddress: string; +}; +export type sdVehicleData = { + dateOfFirstRegistration: string; + yearOfProduction: string; + vehicleMake: string; + vehicleType: string; + commercialDescription: string; + vehicleIDNumber: string; + registrationNumberOfVehicle: string; + maximumNetPower: string; + engineCapacity: string; + typeOfFuel: string; + powerWeightRatio: string; + vehicleMass: string; + maximumPermissibleLadenMass: string; + typeApprovalNumber: string; + numberOfSeats: string; + numberOfStandingPlaces: string; + engineIDNumber: string; + numberOfAxles: string; + vehicleCategory: string; + colourOfVehicle: string; + restrictionToChangeOwner: string; + vehicleLoad: string; +}; +export type sdRegistrationData = { + registrationData: string; + signatureData: string; + issuingAuthority: string; +}; + export enum RegistrationIndex { EF_Registration_A = 1, EF_Registration_B = 2,