UNPKG

@truschery/eimzo

Version:

A lightweight Node.js package for seamless integration with Eimzo, providing easy-to-use functionality for creating digital signatures and managing API keys.

14 lines (13 loc) 9.55 kB
var t={1001:"Incorrect password entered",1002:"Password entry canceled"};class e{static NotFoundClass(t){return{success:!1,message:`Failed to find [${t}] class`}}static ErrorInMethod(t){return{success:!1,message:`Error in [${t}] method`}}static ErrorCode(e){return{success:!1,message:t[e],code:e}}static Error(t){return{success:!1,message:t}}static ThrowError(t){throw new Error(t)}}class s{constructor(){this.socket=null,this.connect()}connect(){if(!window?.WebSocket)throw new Error("Failed to find [WebSocket] class");try{const t=this.getUrl();this.socket=new WebSocket(t),this.socket.onclose=t=>{if(1e3!==t.code)throw new Error(`Failed connect to WebSocket. Error Code: ${t.code}`)}}catch(t){throw new Error(t.reason)}}send(t){return new Promise((e,s)=>{if(this.socket.addEventListener("message",t=>{const s=JSON.parse(t.data);e(s)}),this.socket.readyState===WebSocket.OPEN)return this.socket.send(JSON.stringify(t));this.socket.onopen=()=>{this.socket.send(JSON.stringify(t))}})}async pkcs7(t,s,r){const i=await this.api({plugin:"pkcs7",name:"create_pkcs7",arguments:[t,s,r]});return i.success?i:i.hasOwnProperty("reason")&&-1!==i.reason.indexOf("javax.crypto.BadPaddingException")?Promise.reject(e.ErrorCode(1001)):i.success||-1===i.reason.indexOf("Ввод пароля отменен")?void 0:Promise.reject(e.ErrorCode(1002))}api(t){return this.send(t)}version(){return this.send({name:"version"})}apidoc(){return this.send({name:"apidoc"})}apikey(t){return this.send({name:"apikey",arguments:t})}getUrl(){return("https:"===window.location.protocol.toLowerCase()?"wss://127.0.0.1:64443":"ws://127.0.0.1:64646")+"/service/cryptapi"}}function r(t,e){const s=this,r=[];if(t)r.push(s);else{ // Substitution of matched string function i(t){const e="0"===t[0]?"1":"0";let s="";for(let r=0;r<t.length;r++)s+=e;return s}const n=[]; // Getting mached value and its index s[t instanceof RegExp?"replace":"replaceAll"](t,function(t,e,s){return n.push({value:t,index:e}),i(t)}); // Finds split substrings let a=0;for(let o=0;o<n.length;o++){const c=n[o],h=1==e?c.index:c.index+c.value.length;if(h!==a){const l=s.substring(a,h);r.push(l),a=h}}if(a<s.length){const u=s.substring(a,s.length);r.push(u)}}return r}function i(t,e){String.prototype.splitKeep=r;const s=t.splitKeep(/,[A-Z]+=/g,!0);for(let t in s){const r=s[t].search((t>0?",":"")+e+"=");if(-1!==r)return s[t].slice(r+e.length+1+(t>0?1:0))}return""}function n(t,e){const s=[0,2,1][t.length%3],r=t.charCodeAt(0)<<16|(t.length>1?t.charCodeAt(1):0)<<8|(t.length>2?t.charCodeAt(2):0);return[e.charAt(r>>>18),e.charAt(r>>>12&63),s>=2?"=":e.charAt(r>>>6&63),s>=1?"=":e.charAt(63&r)].join("")}function a(t){const e=String.fromCharCode;if(t.length<2){const s=t.charCodeAt(0);return s<128?t:s<2048?e(192|s>>>6)+e(128|63&s):e(224|s>>>12&15)+e(128|s>>>6&63)+e(128|63&s)}{const s=65536+1024*(t.charCodeAt(0)-55296)+(t.charCodeAt(1)-56320);return e(240|s>>>18&7)+e(128|s>>>12&63)+e(128|s>>>6&63)+e(128|63&s)}}function o(t){return t.replace(/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g,a)}const c=new RegExp(["[À-ß][€-¿]","[à-ï][€-¿]{2}","[ð-÷][€-¿]{3}"].join("|"),"g"),h=function(t){const e=String.fromCharCode;switch(t.length){case 4:const s=((7&t.charCodeAt(0))<<18|(63&t.charCodeAt(1))<<12|(63&t.charCodeAt(2))<<6|63&t.charCodeAt(3))-65536;return e((s>>>10)+55296)+e(56320+(1023&s));case 3:return e((15&t.charCodeAt(0))<<12|(63&t.charCodeAt(1))<<6|63&t.charCodeAt(2));default:return e((31&t.charCodeAt(0))<<6|63&t.charCodeAt(1))}};function l(t){return t.replace(c,h)}var u=btoa||(t=>t.replace(/[\s\S]{1,3}/g,n));class d{b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";constructor(){if(this.b64tab=function(t){for(var e={},s=0,r=t.length;s<r;s++)e[t.charAt(s)]=s;return e}(this.b64chars),this.atob=atob||this.localAtob,this.Base64={VERSION:"2.1.4",atob:this.atob,btoa:this.btoa,fromBase64:this.decode,toBase64:this.encode,utob:o,encode:this.encode,encodeURI:this.encodeURI,btou:l,decode:this.decode,noConflict:this.noConflict},"function"==typeof Object.defineProperty){const t=function(t){return{value:t,enumerable:!1,writable:!0,configurable:!0}};this.Base64.extendString=()=>{Object.defineProperty(String.prototype,"fromBase64",t(()=>this.decode(this))),Object.defineProperty(String.prototype,"toBase64",t(t=>this.encode(this,t))),Object.defineProperty(String.prototype,"toBase64URI",t(()=>this.encode(this,!0)))}}}encode(t,e){const s=t=>u(o(t));return e?s(t).replace(/[+\/]/g,function(t){return"+"==t?"-":"_"}).replace(/=/g,""):s(t)}decode(t){return(()=>l(this.atob(t)))(t.replace(/[-_]/g,function(t){return"-"==t?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))}noConflict(){return this.Base64}encodeURI(t){return this.encode(t,!0)}localAtob(t){return t.replace(/[\s\S]{1,4}/g,this.localDecode)}localDecode(t){const e=String.fromCharCode,s=t.length,r=s%4,i=(s>0?this.b64tab[t.charAt(0)]<<18:0)|(s>1?this.b64tab[t.charAt(1)]<<12:0)|(s>2?this.b64tab[t.charAt(2)]<<6:0)|(s>3?this.b64tab[t.charAt(3)]:0),n=[e(i>>>16),e(i>>>8&255),e(255&i)];return n.length-=[0,0,2,1][r],n.join("")}}class p{alias=null;serialNumber=null;validFrom=null;validTo=null;CN=null;TIN=null;UID=null;PINFL=null;O=null;T=null;type=null;constructor(t){this.certificate=t,this.disk=this.certificate.disk,this.path=this.certificate.path,this.name=this.certificate.name,this.type="pfx",this.defaultAlias=this.certificate.alias,this.parse()}parse(){let t=this.certificate.alias.toUpperCase();t=t.replace("1.2.860.3.16.1.1=","INN="),// Замена на ИНН t=t.replace("1.2.860.3.16.1.2=","PINFL="),// Замена на ПИНФЛ this.alias=t,this.aliasSplitted=t.split(","),this.install()}install(){this.serialNumber=this.getFromAlias("SERIALNUMBER").value,this.CN=this.getFromAlias("CN").value,this.TIN=this.getFromAlias("TIN").value,this.UID=this.getFromAlias("UID").value,this.PINFL=this.getFromAlias("PINFL").value,this.O=this.getFromAlias("O").value,this.T=this.getFromAlias("T").value,this.validFrom=new Date(this.getFromAlias("VALIDFROM").value),this.validTo=new Date(this.getFromAlias("VALIDTO").value)}getKey(){return{disk:this.disk,path:this.path,name:this.name,alias:this.defaultAlias,serialNumber:this.serialNumber,validFrom:this.validFrom,validTo:this.validTo,CN:this.CN,TIN:this.TIN,UID:this.UID,PINFL:this.PINFL,O:this.O,T:this.O,type:this.type}}getFromAlias(t){const e=this.aliasSplitted.find(e=>-1!==e.indexOf(t)); // console.log(this.aliasSplitted) if(!e)return!1;const[s,r]=e.split("=");return{property:s,value:r}}}class f extends s{constructor(t){if(super(),!t||!t.length)return!1;this.NEW_API=!1,this.NEW_API2=!1,this.API_KEYS=t,this.cryptography=new d}checkVersion(){return new Promise(async(t,e)=>{try{const s=await super.version();if(!s.success)return e(s?.reason);if(!s.major||!s.minor)return e("undefined E-IMZO version");const r=100*parseInt(s.major)+parseInt(s.minor);return this.NEW_API=r>=336,this.NEW_API2=r>=412,t({major:s.major,minor:s.minor})}catch(t){return e(t?.reason)}})}installApiKeys(){return super.apikey(this.API_KEYS)}getPfxCertificates(){return new Promise(async(t,e)=>{t(await this._findPfxs2())})}getFtjcCertificates(){return new Promise(async(t,e)=>{if(!this.NEW_API)return e("Please install new version of E-IMZO");const s=await this._findPfxs2(),r=await this._findTokens2();t({firstKey:s.firstKey??r.firstKey,keys:s.keys})})}loadPfxKey(t,e){return new Promise(async(s,r)=>{t&&t.hasOwnProperty("disk")&&t.hasOwnProperty("path")&&t.hasOwnProperty("name")&&t.hasOwnProperty("alias")||r("Certificate is invalid");try{const r=await super.api({plugin:"pfx",name:"load_key",arguments:[t.disk,t.path,t.name,t.alias]});e&&s(await super.api({name:"verify_password",plugin:"pfx",arguments:[r]})),s(r)}catch(t){r(t.reason)}})}createPkcs7(t,e,s,r){return new Promise(async(i,n)=>{let a=function(t){try{return btoa(atob(t))===t}catch(t){return!1}}(e)?e:this.cryptography.encode(e),o=r?"yes":"no";const c=await super.pkcs7(a,t,o).catch(t=>n(t));if(!s)return i(c);const h=c.signer_serial_number;s(c.signature_hex,async t=>{const e=await super.api({plugin:"pkcs7",name:"attach_timestamp_token_pkcs7",arguments:[c,h,t]}).catch(t=>n(t.reason));i(e)})})}async _findPfxs2(){const t=await super.api({plugin:"pfx",name:"list_all_certificates"});let e=[];for(let s in t.certificates){const r=t.certificates[s],i=new p(r).getKey();(i.TIN||i.PINFL)&&e.push(i)}return e}async _findTokens2(t,e){const s=await super.api({plugin:"ftjc",name:"list_all_keys",arguments:[""]});let r,n=[];for(let t in s.tokens){const e=s.tokens[t];let a=e.info.toUpperCase();a=a.replace("1.2.860.3.16.1.1=","INN="),a=a.replace("1.2.860.3.16.1.2=","PINFL="); // TODO: Сделать отдельный класс для этого функционала const o={cardUID:e.cardUID,statusInfo:e.statusInfo,ownerName:e.ownerName,info:e.info,serialNumber:i(a,"SERIALNUMBER"),validFrom:new Date(i(a,"VALIDFROM")),validTo:new Date(i(a,"VALIDTO")),CN:i(a,"CN"),TIN:i(a,"INN")?i(a,"INN"):i(a,"UID"),UID:i(a,"UID"),PINFL:i(a,"PINFL"),O:i(a,"O"),T:i(a,"T"),type:"ftjc"};(o.TIN||o.PINFL)&&(r="itm-"+o.serialNumber+"-"+t,n.push(o))}return{firstKey:r,keys:n}}}class g extends f{constructor(t){super(t),this.certificates=[]}async install(){await super.checkVersion(),await super.installApiKeys(),this.certificates=await super.getPfxCertificates()}sign(t,e,s){return new Promise(async(r,i)=>{try{const n=this.certificates.find(e=>e.serialNumber===t);if(!n)return!1;const a=await super.loadPfxKey(n);r((await super.createPkcs7(a.keyId,e,s).catch(t=>i(t))).pkcs7_64)}catch(t){i(t)}})}}export{f as EClient,g as default};