autogram-sdk
Version:
SDK for Autogram signer
4 lines • 7.18 kB
JavaScript
import{a as u,b as c,d as o}from"./chunk-EHCYI2EK.mjs";import{SignJWT as h}from"jose";import n from"zod";import{Base64 as m}from"js-base64";var p=class{constructor(t){this.keyPair=null;this.integrationGuid=null;this._subtleCrypto=null;this.apiClient=new l,this.db=t}get subtleCrypto(){if(!this._subtleCrypto)throw new Error("SubtleCrypto not available");return this._subtleCrypto}loadOrRegister(){return o(this,null,function*(){this.loadSubtleCrypto(),this.keyPair=yield this.getKeyPairFromDb(),this.integrationGuid=yield this.getIntegrationGuidFromDb(),console.log(this.keyPair),(!this.keyPair||!this.integrationGuid)&&(yield this.register()),console.log("keys init",{public:yield this.getPublicKeyStr(),guid:this.integrationGuid})})}getQrCodeUrl(t,e=!1){return o(this,null,function*(){if(!this.integrationGuid)throw new Error("Integration guid missing");if(!t.guid||!t.encryptionKey)throw console.log(t),new Error("Document guid or key missing");let r={};if(e){let i=yield this.getIntegrationBearerToken(!0);console.log("Integration JWT",i),r={integration:i}}return this.apiClient.qrCodeUrl(u({guid:t.guid,key:t.encryptionKey},r))})}register(){return o(this,null,function*(){if(this.keyPair&&this.integrationGuid)throw new Error("Already registered.");yield this.generateKeys();let t=yield this.getPublicKeyStr();console.log("Registering integration",t);let e=yield this.apiClient.registerIntegration({platform:"extension",displayName:"Autogram Extension",publicKey:`-----BEGIN PUBLIC KEY-----
`+t+`
-----END PUBLIC KEY-----`});this.integrationGuid=e.guid,yield this.saveIntegrationGuid(e.guid),console.log("Integration registered",e)})}addDocument(t){return o(this,null,function*(){let e=yield this.initDocumentKey();console.log("Sending document",t);let r=yield this.apiClient.postDocuments(t,yield this.getIntegrationBearerToken(),e);return{guid:r.guid,encryptionKey:e,lastModified:r.lastModified}})}waitForSignature(t,e){return o(this,null,function*(){if(!t.guid||!t.encryptionKey||!t.lastModified)throw console.log(t),new Error("Document guid, key or last-modified missing");for(this.apiClient.signRequest({documentGuid:t.guid,documentEncryptionKey:t.encryptionKey},yield this.getIntegrationBearerToken());!e.signal.aborted;){let r=yield this.apiClient.getDocument({guid:t.guid},t.encryptionKey,t.lastModified);if(console.log(r),r.status==="signed")return r.document;r.status,yield I(1e3)}throw new Error("Aborted")})}loadSubtleCrypto(){return o(this,null,function*(){if(!this._subtleCrypto){let t=globalThis.crypto.subtle;if(t){this._subtleCrypto=t;return}try{let e=yield import("crypto");this._subtleCrypto=e.webcrypto.subtle;return}catch(e){throw new Error("SubtleCrypto not available")}}})}getIntegrationBearerToken(t=!1){return o(this,null,function*(){if(!this.keyPair)throw new Error("Key pair missing");if(!this.integrationGuid)throw new Error("Integration guid missing");let e=new h({}).setProtectedHeader({alg:"ES256"}).setJti(D()).setSubject(this.integrationGuid);return t&&(e=e.setAudience("device")),e=e.setExpirationTime("5min"),e.sign(this.keyPair.privateKey)})}exportRawBase64(t){return this.subtleCrypto.exportKey("raw",t).then(d)}generateKeys(){return o(this,null,function*(){console.log("Generating keys");let t=yield this.subtleCrypto.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]);console.log("Key pair generated",t),yield this.saveKeyPair(t),this.keyPair=t,console.log("Keys generated",this.keyPair)})}saveKeyPair(t){return o(this,null,function*(){return this.db.set("keyPair",t)})}getKeyPairFromDb(){return o(this,null,function*(){return this.db.get("keyPair").then(t=>t||null)})}saveIntegrationGuid(t){return o(this,null,function*(){return this.db.set("integrationGuid",t)})}getIntegrationGuidFromDb(){return o(this,null,function*(){return this.db.get("integrationGuid").then(t=>t||null)})}getPublicKeyStr(){return o(this,null,function*(){if(!this.keyPair)throw new Error("Key pair missing");return this.subtleCrypto.exportKey("spki",this.keyPair.publicKey).then(d)})}initDocumentKey(){return o(this,null,function*(){let t=yield this.subtleCrypto.generateKey({name:"AES-GCM",length:256},!0,["encrypt","decrypt"]);return yield this.exportRawBase64(t)})}},l=class{constructor(){this._registerIntegration="/integrations";this._getIntegrationDevices="/integration-devices";this._documents="/documents";this._getDocument="/documents/{guid}";this._signRequest="/sign-request";this._getQrCodeUrl="/qr-code";this.baseUrl="https://autogram.slovensko.digital/api/v1"}registerIntegration(t){let e=JSON.stringify(t),r=this.baseUrl+this._registerIntegration;return console.log("Registering integration",{url:r,requestBody:e}),fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:e}).then(i=>o(this,null,function*(){let s=yield i.text();return console.log("Integration registration response",{text:s,status:i.status,statusText:i.statusText}),JSON.parse(s)})).catch(i=>{throw console.error("Integration registration failed",i),i}).then(i=>b.parse(i))}getIntegrationDevices(){return fetch(this.baseUrl+this._getIntegrationDevices,{method:"GET"}).then(t=>f.parse(t.json()))}postDocuments(t,e,r){return o(this,null,function*(){if(!r)throw new Error("Document encryption key missing");if(!e)throw new Error("Bearer token missing");let i=yield fetch(this.baseUrl+this._documents,{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+e,"X-Encryption-Key":r},body:JSON.stringify(t)});if(i.status!==200){console.log("API Error",i.status,i.statusText);let g=yield i.json();throw new Error(JSON.stringify(y.parse(g)))}let s=yield i.json();return c(u({},w.parse(s)),{lastModified:i.headers.get("Last-Modified")})})}getDocument(t,e,r){return o(this,null,function*(){if(!e)throw new Error("Document encryption key missing");let i=yield fetch(this.baseUrl+this._getDocument.replace("{guid}",t.guid),{method:"GET",headers:u({"Content-Type":"application/json",Accept:"application/json","X-Encryption-Key":e},r?{"If-Modified-Since":r}:null)});if(i.status==304)return{status:"pending"};if(i.status!=200){let g=y.parse(yield i.json());throw console.error("API Error",g),new Error(JSON.stringify(g))}let s=yield i.json();return{status:"signed",document:P.parse(s)}})}signRequest(t,e){return fetch(this.baseUrl+this._signRequest,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(t)}).then(r=>r.json())}qrCodeUrl(t){return this.baseUrl+this._getQrCodeUrl+"?"+new URLSearchParams(t).toString()}},b=n.object({guid:n.string()}),f=n.array(n.object({deviceId:n.string(),platform:n.string(),displayName:n.string()})),w=n.object({guid:n.string()}),y=n.object({code:n.string(),message:n.string(),details:n.string().optional()}),P=n.object({filename:n.string(),mimeType:n.string(),content:n.string(),signers:n.array(n.object({signedBy:n.string().optional(),issuedBy:n.string().optional()})).optional()});function d(a){return m.fromUint8Array(new Uint8Array(a))}function D(){return globalThis.crypto.randomUUID()}function I(a){return o(this,null,function*(){return new Promise(t=>setTimeout(t,a))})}export{p as a,P as b,D as c};
//# sourceMappingURL=chunk-JFEJ4PVF.mjs.map