dome-embedded-app-sdk 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dome-sdk.d.ts +61 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/dome-sdk.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ export declare enum ViewerMessageType {
|
|
|
6
6
|
REQUEST_INITIAL_DATA = "REQUEST_INITIAL_DATA",// Request to load initial data from the parent
|
|
7
7
|
SET_DIRTY = "SET_DIRTY",// Indicates the app has unsaved changes
|
|
8
8
|
SEND_CLOSE = "SEND_CLOSE",// Signals the app is ready to close
|
|
9
|
-
SEND_EXCEPTION = "SEND_EXCEPTION"
|
|
9
|
+
SEND_EXCEPTION = "SEND_EXCEPTION",// Sends an exception event to parent
|
|
10
|
+
OPEN_DEEPLINK = "OPEN_DEEPLINK"
|
|
10
11
|
}
|
|
11
12
|
declare enum ClientMessageType {
|
|
12
13
|
CONNECT = "CONNECT",
|
|
@@ -15,6 +16,9 @@ declare enum ClientMessageType {
|
|
|
15
16
|
SAVE_ERROR = "SAVE_ERROR",// Sends status of the save event
|
|
16
17
|
SAVE_SUCCESS = "SAVE_SUCCESS",// Sends status of the save event
|
|
17
18
|
DATA_CHANGE = "DATA_CHANGE",
|
|
19
|
+
FILE_DATA = "FILE_DATA",
|
|
20
|
+
WRITE_FILE_ACK = "WRITE_FILE_ACK",
|
|
21
|
+
READ_FILE_ACK = "READ_FILE_ACK",
|
|
18
22
|
INIT_ACK = "INIT_ACK",
|
|
19
23
|
ERROR = "ERROR",
|
|
20
24
|
REFRESH = "REFRESH"
|
|
@@ -55,12 +59,23 @@ declare class DomeEmbeddedAppSdk {
|
|
|
55
59
|
private readonly targetOrigin;
|
|
56
60
|
protected isAppReady: boolean;
|
|
57
61
|
protected port2: MessagePort | null;
|
|
58
|
-
|
|
62
|
+
protected platform: "android" | "ios" | "web" | "unknown";
|
|
63
|
+
private readonly handleDeepLinkClick;
|
|
59
64
|
constructor();
|
|
60
65
|
/**
|
|
61
66
|
* Detects the platform (iOS, Android, or Web) and saves it.
|
|
62
67
|
*/
|
|
63
68
|
private detectPlatform;
|
|
69
|
+
/**
|
|
70
|
+
* Listens for deep link anchor clicks on web to forward them to the parent app.
|
|
71
|
+
*/
|
|
72
|
+
private setupDeepLinkInterception;
|
|
73
|
+
/**
|
|
74
|
+
* Sends an OPEN_DEEPLINK message when the href uses an allowed protocol.
|
|
75
|
+
* @returns true if the message was dispatched, false otherwise.
|
|
76
|
+
*/
|
|
77
|
+
protected emitDeepLink(href: string): boolean;
|
|
78
|
+
getPlatform(): "android" | "ios" | "web" | "unknown";
|
|
64
79
|
/**
|
|
65
80
|
* Method to send messages to the parent application.
|
|
66
81
|
* Ensures the parent window exists and sends a structured message with type and data.
|
|
@@ -157,7 +172,10 @@ export declare class ViewerSdk extends DomeEmbeddedAppSdk {
|
|
|
157
172
|
}
|
|
158
173
|
export declare enum CardMessageType {
|
|
159
174
|
APP_READY = "APP_READY",// Indicates the app is ready to be interacted with
|
|
160
|
-
INIT = "INIT"
|
|
175
|
+
INIT = "INIT",// Event to send the init key to the viewer
|
|
176
|
+
READ_FILE = "READ_FILE",
|
|
177
|
+
WRITE_FILE = "WRITE_FILE",
|
|
178
|
+
FILE_DIRTY = "FILE_DIRTY"
|
|
161
179
|
}
|
|
162
180
|
export interface CardEventHandler {
|
|
163
181
|
onInit: (data: any) => void;
|
|
@@ -166,6 +184,21 @@ export interface CardEventHandler {
|
|
|
166
184
|
message: string;
|
|
167
185
|
data: any;
|
|
168
186
|
}) => void;
|
|
187
|
+
onFileChange: (data: {
|
|
188
|
+
iuid: string;
|
|
189
|
+
data: {
|
|
190
|
+
data: {
|
|
191
|
+
type: string;
|
|
192
|
+
value: any;
|
|
193
|
+
};
|
|
194
|
+
link: {
|
|
195
|
+
url: string;
|
|
196
|
+
};
|
|
197
|
+
meta: any;
|
|
198
|
+
perms: any;
|
|
199
|
+
from_cache: boolean;
|
|
200
|
+
};
|
|
201
|
+
}) => void;
|
|
169
202
|
onRefreshRequest: (data: any) => void;
|
|
170
203
|
}
|
|
171
204
|
/**
|
|
@@ -176,6 +209,14 @@ export declare class CardSdk extends DomeEmbeddedAppSdk {
|
|
|
176
209
|
private handler;
|
|
177
210
|
private cryptoA01;
|
|
178
211
|
dataStore: any;
|
|
212
|
+
private accessToken;
|
|
213
|
+
cardFS: {
|
|
214
|
+
readFile: (card_iuid: string, name: string) => Promise<any>;
|
|
215
|
+
writeFile: (card_iuid: string, name: string, data: any) => Promise<void>;
|
|
216
|
+
};
|
|
217
|
+
private fileReadResolvers;
|
|
218
|
+
private fileWriteResolvers;
|
|
219
|
+
private pendingAcks;
|
|
179
220
|
private constructor();
|
|
180
221
|
/**
|
|
181
222
|
* Static initialization method to get or create the singleton instance of CardSdk.
|
|
@@ -191,9 +232,16 @@ export declare class CardSdk extends DomeEmbeddedAppSdk {
|
|
|
191
232
|
* @param handler - Custom handler for different message types
|
|
192
233
|
*/
|
|
193
234
|
setHandler(handler: CardEventHandler): void;
|
|
235
|
+
/**
|
|
236
|
+
* Sends a deep link request to the parent directly from the card.
|
|
237
|
+
*/
|
|
238
|
+
openDeepLink(href: string): void;
|
|
194
239
|
private initializeCardSdk;
|
|
195
240
|
private sendInit;
|
|
241
|
+
private sendMessageWithAck;
|
|
196
242
|
protected handleMessage: (type: ClientMessageType, data: any) => void;
|
|
243
|
+
private _readFile;
|
|
244
|
+
private _writeFile;
|
|
197
245
|
/**
|
|
198
246
|
* Converts a JavaScript object to a JSON file.
|
|
199
247
|
*/
|
|
@@ -205,12 +253,19 @@ export declare class CardSdk extends DomeEmbeddedAppSdk {
|
|
|
205
253
|
/**
|
|
206
254
|
* Get document associated with the current card
|
|
207
255
|
*/
|
|
208
|
-
|
|
256
|
+
getDocumentAttachedToCard(card_iuid: string, document_name?: string, ts_m?: number): Promise<any>;
|
|
209
257
|
/**
|
|
210
|
-
*
|
|
258
|
+
* Save document attached to current card
|
|
211
259
|
*/
|
|
212
|
-
|
|
260
|
+
postDocumentAttachedToCard(card_iuid: string, document: any): Promise<any>;
|
|
261
|
+
getAllDocumentsAttachedToCard(card_iuid: string): Promise<Response>;
|
|
262
|
+
postUploadFile(name: string, fileObj: any): Promise<any>;
|
|
263
|
+
shareDocumentWithCard(card_iuid: string, documents: any): Promise<any>;
|
|
213
264
|
private sendEventError;
|
|
265
|
+
setFileDirty(data: {
|
|
266
|
+
iuid: string;
|
|
267
|
+
ts_m: number;
|
|
268
|
+
}): void;
|
|
214
269
|
getUsername(userObj: any): string;
|
|
215
270
|
}
|
|
216
271
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.domeSdk=t():e.domeSdk=t()}(this,(()=>(()=>{"use strict";var e={d:(t,n)=>{for(var s in n)e.o(n,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:n[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{CardSdk:()=>c,CryptoA01:()=>s,ViewerSdk:()=>d});const n="0.1.3";class s{constructor(){if(this.subtleCrypto=window.crypto?.subtle,!this.subtleCrypto)throw new Error("SubtleCrypto API is not available in this environment.")}async decrypt(e,t,n){try{if(!e)throw new Error("Invalid token");const s=this.base64UrlDecode(e);if(128!==s[0])throw new Error("Invalid version");s.slice(1,9);const r=s.slice(9,25),o=s.slice(25,-32),i=s.slice(-32),a=await this.deriveKey(t,n),{hmacKey:d,aesKey:c}=await this.splitKey(a),l=s.slice(0,-32);if(!new Uint8Array(await this.subtleCrypto.sign("HMAC",d,l)).every(((e,t)=>e===i[t])))throw new Error("Invalid HMAC. Token has been tampered with!");const h=await this.subtleCrypto.decrypt({name:"AES-CBC",iv:r},c,o);return(new TextDecoder).decode(h)}catch(e){throw console.log("Error in decrypt:",e),e}}async deriveKey(e,t,n=1e4){const s=new TextEncoder,r=await this.subtleCrypto.importKey("raw",s.encode(e),"PBKDF2",!1,["deriveKey"]);return this.subtleCrypto.deriveKey({name:"PBKDF2",hash:"SHA-256",salt:s.encode(t),iterations:n},r,{name:"AES-CBC",length:256},!0,["encrypt","decrypt"])}async splitKey(e){const t=new Uint8Array(await this.subtleCrypto.exportKey("raw",e));return{hmacKey:await this.subtleCrypto.importKey("raw",t.slice(0,16),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"]),aesKey:await this.subtleCrypto.importKey("raw",t.slice(16),{name:"AES-CBC"},!1,["encrypt","decrypt"])}}base64UrlDecode(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=atob(t);return new Uint8Array([...n].map((e=>e.charCodeAt(0))))}}var r,o,i;!function(e){e.CONNECTION_SUCCESS="CONNECTION_SUCCESS",e.INIT="INIT",e.REQUEST_SAVE="REQUEST_SAVE",e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_INITIAL_DATA="REQUEST_INITIAL_DATA",e.SET_DIRTY="SET_DIRTY",e.SEND_CLOSE="SEND_CLOSE",e.SEND_EXCEPTION="SEND_EXCEPTION"}(r||(r={})),function(e){e.CONNECT="CONNECT",e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_SAVE="REQUEST_SAVE",e.SAVE_ERROR="SAVE_ERROR",e.SAVE_SUCCESS="SAVE_SUCCESS",e.DATA_CHANGE="DATA_CHANGE",e.INIT_ACK="INIT_ACK",e.ERROR="ERROR",e.REFRESH="REFRESH"}(o||(o={})),new Set("undefined"==typeof window?[]:[window.location.origin,"https://dome.so","https://spaces.intouchapp.com/","http://localhost:4200","http://localhost:4201","null"]);class a{constructor(){this.targetOrigin="*",this.isAppReady=!1,this.port2=null,this.platform="unknown",this.detectPlatform()}detectPlatform(){void 0!==window.AndroidBridge?this.platform="android":void 0!==window.webkit?this.platform="ios":this.platform="web",console.debug(`Detected platform: ${this.platform}`)}sendMessage(e,t){const n={type:e,data:t??null};switch(this.platform){case"android":window.AndroidBridge?.sendMessage(JSON.stringify(n));break;case"ios":window?.webkit?.messageHandlers?window.webkit?.messageHandlers.appHandler.postMessage(JSON.stringify(n)):console.error("webkit.messageHandlers not found");break;case"web":this.port2?this.port2.postMessage(n):console.error("Web connection is not established.");break;default:console.error("Unsupported platform, cannot send message.")}console.debug(`Sent message to ${this.platform}:`,n)}sendAppInit(){this.isAppReady||(this.isAppReady=!0,this.sendMessage(r.INIT,{sdk:{ver:n}}))}safeInvoke(e,t,n){const s=t[e];"function"==typeof s?s(n):console.warn(`Handler for '${String(e)}' is not defined.`)}setupParentConnection(){return new Promise(((e,t)=>{switch(this.platform){case"android":window.receiveFromAndroid=e=>{console.debug("Message received from Android:",e),this.handleMessage(e.type,e.data)},e();break;case"ios":window.receiveFromIOS=e=>{console.debug("Message received from iOS:",e),this.handleMessage(e.type,e.data)},e();break;case"web":this.port2&&(console.warn("Connection already established. Skipping reinitialization."),e());const n=t=>{const{type:s}=t.data||{};s===o.CONNECT&&t.ports&&t.ports.length>0&&(this.port2=t.ports[0],this.port2.onmessage=e=>this.handlePortMessage(e),window.removeEventListener("message",n),this.notifyConnectionSuccess(),e())};window.addEventListener("message",n);break;default:console.error("Unknown platform."),t("Unknown platform")}}))}notifyConnectionSuccess(){this.sendMessage(r.CONNECTION_SUCCESS)}handlePortMessage(e){const{type:t,data:n}=e.data||{};t&&this.handleMessage(t,n)}handleMessage(e,t){throw new Error("Subclasses must implement handleMessage.")}}class d extends a{constructor(){super(),this.handler=null,this.pendingRequests=new Map,this.pendingInitAck=null}static init(e){return console.debug("init called",e&&"with handler"),d.initialized?(console.warn("ViewerSdk is already initialized. Skipping initialization."),d.instance):(d.instance||(d.instance=new d,d.instance.setupParentConnection().then((()=>{try{d.instance.initializeViewerSdk()}catch(e){console.error("Error in initializeViewerSdk:",e)}})).catch((e=>{console.error("init: Error setting up parent connection!",e),console.trace("called from:")}))),e&&d.instance.setHandler(e),d.initialized=!0,d.instance)}setHandler(e){this.handler=e,this.pendingInitAck&&(console.debug("Processing pending INIT_ACK message after handler is set."),this.safeInvoke("onInitialData",this.handler,this.pendingInitAck),this.pendingInitAck=null)}canRead(e){return!!e?.includes("r")}canWrite(e){return!!e?.includes("w")||!!e?.includes("*")}initializeViewerSdk(){console.debug("initializing viewer sdk"),this.sendAppInit()}requestInitialData(){this.sendMessage(r.REQUEST_INITIAL_DATA)}requestSave(e,t){const n=function(){if("undefined"!=typeof window&&window.crypto&&window.crypto.randomUUID)return window.crypto.randomUUID();if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();throw new Error("UUID generation is not supported in this environment")}();return this.sendMessage(r.REQUEST_SAVE,{doc:e,isDataDirty:t,requestId:n}),new Promise(((e,t)=>{this.pendingRequests.set(n,e),this.pendingRequests.set(n+"_reject",t),setTimeout((()=>{this.pendingRequests.has(n)&&(this.pendingRequests.delete(n),this.pendingRequests.delete(n+"_reject"))}),3e4)}))}handleOnSave(e){const{requestId:t,status:n,message:s}=e,r=this.pendingRequests.get(t),o=this.pendingRequests.get(t+"_reject");r&&("error"===n?o?.({status:n,message:s}):r({status:n,message:s}),this.pendingRequests.delete(t),this.pendingRequests.delete(t+"_reject"))}setDirty(e){this.sendMessage(r.SET_DIRTY,e)}sendClose(e,t){this.sendMessage(r.SEND_CLOSE,{doc:e,isDataDirty:t})}sendException(e){this.sendMessage(r.SEND_EXCEPTION,e)}handleMessage(e,t){if(console.debug("handleMessage called for:",e,"with data:",t),this.handler)switch(e){case o.INIT_ACK:this.safeInvoke("onInitialData",this.handler,t);break;case o.DATA_CHANGE:this.safeInvoke("onDataChange",this.handler,t);break;case o.REQUEST_CLOSE:this.safeInvoke("onCloseRequest",this.handler);break;case o.REQUEST_SAVE:this.safeInvoke("onSaveRequest",this.handler);break;case o.SAVE_SUCCESS:case o.SAVE_ERROR:this.handleOnSave(t);break;default:console.warn(`No handler found for message type: ${e}`)}else e===o.INIT_ACK?(console.warn("Handler not set. Storing INIT_ACK message for later processing."),this.pendingInitAck=t):console.error("Message handler not found for type:",e)}}d.initialized=!1,function(e){e.APP_READY="APP_READY",e.INIT="INIT"}(i||(i={}));class c extends a{constructor(){super(),this.handler=null,this.handleMessage=(e,t)=>{if(!this.handler)throw new Error("Message handler not found!");switch(e){case o.INIT_ACK:console.debug("CardSdk: INIT_ACK received"),this.dataStore.kw1=t.key_wa1,this.dataStore.iuid=t.iuid;try{this.cryptoA01.decrypt(this.dataStore.denc,t.key_wa1+this.dataStore.kw2,t.iuid).then((e=>{console.debug("CardSdk: INIT_ACK: decrypted data ",e);const n=JSON.parse(e);this.handler&&this.safeInvoke("onInit",this.handler,{...n,ui:t.ui}),delete this.dataStore.denc})).catch((e=>{throw console.error("Final decrypt error",e),e}))}catch(e){console.error("Decryption failed!",e),this.sendEventError("dec2_failed",e.message)}break;case o.ERROR:this.safeInvoke("onError",this.handler,t);break;case o.REFRESH:this.safeInvoke("onRefreshRequest",this.handler,t);break;default:console.warn(`No handler found for message type: ${e}`)}},this.cryptoA01=new s,console.debug("CardSdk::constructor: done")}static async init(e,t,n){try{return console.debug("CardSdk::init"),c.instance||(c.instance=new c,c.instance.setupParentConnection().then((()=>{c.instance.initializeCardSdk(e)})).catch((e=>{console.error(e)})),t&&c.instance.setHandler(t)),c.instance}catch(e){throw console.error("CardSdk: Unrecoverable error in init",e),e}}setHandler(e){this.handler=e}async initializeCardSdk(e){let t="CardSdk::initializeCardSdk:";try{if(console.debug(t,"enter"),!e)throw new Error("Invalid secret");const n=window.IT_DATA_AF1;if(!n)throw console.error(t,"No data"),new Error("No data");const s=window.location.href;console.debug(t,"url:",s);const r=new URL(s).pathname.split("/").filter((e=>e));let o;if(r.length>1)o=r[r.length-2];else{if(1!=r.length)throw new Error("Invalid URL");o=r[0]}const i=o.split("").reverse().join("").substring(4,25);if(console.debug(t,"ss:",i),!i)throw new Error("Cannot decrypt (1)");const a=await this.cryptoA01.decrypt(n,e,i);try{const e=JSON.parse(a);if(console.debug("CardSdk: dataFromServer:",e),!e.ite)throw new Error("Invalid data");this.dataStore={denc:e.d,kw2:e.kw2},c.instance.sendInit(e.ite)}catch(e){throw console.error("Initial Decryption failed (2):",e),e}}catch(e){console.error(t,"Init failed:",e),this.sendEventError("init_failed",e.message)}}async sendInit(e){this.sendMessage(i.INIT,{token:e,sdk:{ver:n}})}async convertToJsonFile(e,t="json",n="file.json"){const s=JSON.stringify(e,null,2),r="application/json",o=new Blob([s],{type:r});return new File([o],n,{type:r})}async convertToFile(e,t,n="json",s){if("json"===n)return this.convertToJsonFile(e,"json",t);{const n=new Blob([e],s?{type:s}:void 0);return new File([n],t,{type:n.type})}}async getCardDocument(e,t){const n=`/api/v1/${e}/`,s=`/api/v1/documents/create_for/${t}`,r=async e=>{const t=e.headers.get("Content-Type")||"";if(t.includes("application/json"))return e.json();if(t.includes("text/"))return e.text();throw new Error(`Unsupported response type: ${t}`)};try{const e=await fetch(n,{method:"GET"});if(e.ok)return r(e);if(404===e.status){const e=await fetch(s,{method:"POST"});if(!e.ok)throw new Error(`Failed to create document: ${e.status}`);return r(e)}throw new Error(`Failed to fetch document: ${e.status}`)}catch(e){throw console.error("Error handling document:",e),e}}async saveDocument(e,t){const{name:n,type:s}=e,r=await this.convertToFile(e,n,s),o=`/api/v1/${t}/`,i=new FormData;return i.append("file",r),fetch(o,{method:"PUT",body:i})}sendEventError(e,t,n=void 0){let s={message:t,error_code:e,data:n};this.handler&&this.safeInvoke("onError",this.handler,s)}getUsername(e){const t=e?.name;return t&&Object.values(t).some((e=>e))?function(e){const{prefix:t="",given:n="",middle:s="",family:r="",suffix:o=""}=e||{};return[t,n,s,r,o].filter((e=>e)).join(" ").trim()}(t):""}}return t})()));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.domeSdk=t():e.domeSdk=t()}(this,(()=>(()=>{"use strict";var e={d:(t,s)=>{for(var n in s)e.o(s,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:s[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{CardSdk:()=>l,CryptoA01:()=>n,ViewerSdk:()=>d});const s="0.1.5";class n{constructor(){if(this.subtleCrypto=window.crypto?.subtle,!this.subtleCrypto)throw new Error("SubtleCrypto API is not available in this environment.")}async decrypt(e,t,s){try{if(!e)throw new Error("Invalid token");const n=this.base64UrlDecode(e);if(128!==n[0])throw new Error("Invalid version");n.slice(1,9);const i=n.slice(9,25),r=n.slice(25,-32),o=n.slice(-32),a=await this.deriveKey(t,s),{hmacKey:d,aesKey:c}=await this.splitKey(a),l=n.slice(0,-32);if(!new Uint8Array(await this.subtleCrypto.sign("HMAC",d,l)).every(((e,t)=>e===o[t])))throw new Error("Invalid HMAC. Token has been tampered with!");const h=await this.subtleCrypto.decrypt({name:"AES-CBC",iv:i},c,r);return(new TextDecoder).decode(h)}catch(e){throw console.log("Error in decrypt:",e),e}}async deriveKey(e,t,s=1e4){const n=new TextEncoder,i=await this.subtleCrypto.importKey("raw",n.encode(e),"PBKDF2",!1,["deriveKey"]);return this.subtleCrypto.deriveKey({name:"PBKDF2",hash:"SHA-256",salt:n.encode(t),iterations:s},i,{name:"AES-CBC",length:256},!0,["encrypt","decrypt"])}async splitKey(e){const t=new Uint8Array(await this.subtleCrypto.exportKey("raw",e));return{hmacKey:await this.subtleCrypto.importKey("raw",t.slice(0,16),{name:"HMAC",hash:"SHA-256"},!1,["sign","verify"]),aesKey:await this.subtleCrypto.importKey("raw",t.slice(16),{name:"AES-CBC"},!1,["encrypt","decrypt"])}}base64UrlDecode(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),s=atob(t);return new Uint8Array([...s].map((e=>e.charCodeAt(0))))}}var i,r;!function(e){e.CONNECTION_SUCCESS="CONNECTION_SUCCESS",e.INIT="INIT",e.REQUEST_SAVE="REQUEST_SAVE",e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_INITIAL_DATA="REQUEST_INITIAL_DATA",e.SET_DIRTY="SET_DIRTY",e.SEND_CLOSE="SEND_CLOSE",e.SEND_EXCEPTION="SEND_EXCEPTION",e.OPEN_DEEPLINK="OPEN_DEEPLINK"}(i||(i={})),function(e){e.CONNECT="CONNECT",e.REQUEST_CLOSE="REQUEST_CLOSE",e.REQUEST_SAVE="REQUEST_SAVE",e.SAVE_ERROR="SAVE_ERROR",e.SAVE_SUCCESS="SAVE_SUCCESS",e.DATA_CHANGE="DATA_CHANGE",e.FILE_DATA="FILE_DATA",e.WRITE_FILE_ACK="WRITE_FILE_ACK",e.READ_FILE_ACK="READ_FILE_ACK",e.INIT_ACK="INIT_ACK",e.ERROR="ERROR",e.REFRESH="REFRESH"}(r||(r={}));new Set("undefined"==typeof window?[]:[window.location.origin,"https://dome.so","https://spaces.intouchapp.com/","http://localhost:4200","http://localhost:4201","null"]);const o=new Set(["dome","intouchapp"]);class a{constructor(){this.targetOrigin="*",this.isAppReady=!1,this.port2=null,this.platform="unknown",this.handleDeepLinkClick=e=>{if("web"!==this.platform)return;if(!(e.target instanceof Element))return;const t=e.target.closest("a[href]");if(!t)return;const s=t.getAttribute("href")??"";this.emitDeepLink(s)&&e.preventDefault()},this.detectPlatform(),this.setupDeepLinkInterception()}detectPlatform(){void 0!==window.AndroidBridge?this.platform="android":void 0!==window.webkit?this.platform="ios":this.platform="web",this.platform}setupDeepLinkInterception(){"web"===this.platform&&"undefined"!=typeof document&&document.addEventListener("click",this.handleDeepLinkClick,!0)}emitDeepLink(e){if("string"!=typeof e||""===e.trim())return console.warn("emitDeepLink called without a valid href"),!1;const t=e.split(":")[0]?.toLowerCase();return!(!t||!o.has(t))&&(this.sendMessage(i.OPEN_DEEPLINK,e),!0)}getPlatform(){return this.platform}sendMessage(e,t){const s={type:e,data:t??null};switch(this.platform){case"android":window.AndroidBridge?.sendMessage(JSON.stringify(s));break;case"ios":window?.webkit?.messageHandlers?window.webkit?.messageHandlers.appHandler.postMessage(JSON.stringify(s)):console.error("webkit.messageHandlers not found");break;case"web":this.port2?this.port2.postMessage(s):console.error("Web connection is not established.");break;default:console.error("Unsupported platform, cannot send message.")}this.platform}sendAppInit(){this.isAppReady||(this.isAppReady=!0,this.sendMessage(i.INIT,{sdk:{ver:s}}))}safeInvoke(e,t,s){const n=t[e];"function"==typeof n?n(s):console.warn(`Handler for '${String(e)}' is not defined.`)}setupParentConnection(){return new Promise(((e,t)=>{switch(this.platform){case"android":window.receiveFromAndroid=e=>{this.handleMessage(e.type,e.data)},e();break;case"ios":window.receiveFromIOS=e=>{this.handleMessage(e.type,e.data)},e();break;case"web":this.port2&&(console.warn("Connection already established. Skipping reinitialization."),e());const s=t=>{const{type:n}=t.data||{};n===r.CONNECT&&t.ports&&t.ports.length>0&&(this.port2=t.ports[0],this.port2.onmessage=e=>this.handlePortMessage(e),window.removeEventListener("message",s),this.notifyConnectionSuccess(),e())};window.addEventListener("message",s);break;default:console.error("Unknown platform."),t("Unknown platform")}}))}notifyConnectionSuccess(){this.sendMessage(i.CONNECTION_SUCCESS)}handlePortMessage(e){const{type:t,data:s}=e.data||{};t&&this.handleMessage(t,s)}handleMessage(e,t){throw new Error("Subclasses must implement handleMessage.")}}class d extends a{constructor(){super(),this.handler=null,this.pendingRequests=new Map,this.pendingInitAck=null}static init(e){return d.initialized?(console.warn("ViewerSdk is already initialized. Skipping initialization."),d.instance):(d.instance||(d.instance=new d,d.instance.setupParentConnection().then((()=>{try{d.instance.initializeViewerSdk()}catch(e){console.error("Error in initializeViewerSdk:",e)}})).catch((e=>{console.error("init: Error setting up parent connection!",e),console.trace("called from:")}))),e&&d.instance.setHandler(e),d.initialized=!0,d.instance)}setHandler(e){this.handler=e,this.pendingInitAck&&(this.safeInvoke("onInitialData",this.handler,this.pendingInitAck),this.pendingInitAck=null)}canRead(e){return!!e?.includes("r")}canWrite(e){return!!e?.includes("w")||!!e?.includes("*")}initializeViewerSdk(){this.sendAppInit()}requestInitialData(){this.sendMessage(i.REQUEST_INITIAL_DATA)}requestSave(e,t){const s=function(){if("undefined"!=typeof window&&window.crypto&&window.crypto.randomUUID)return window.crypto.randomUUID();if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();throw new Error("UUID generation is not supported in this environment")}();return this.sendMessage(i.REQUEST_SAVE,{doc:e,isDataDirty:t,requestId:s}),new Promise(((e,t)=>{this.pendingRequests.set(s,e),this.pendingRequests.set(s+"_reject",t),setTimeout((()=>{this.pendingRequests.has(s)&&(this.pendingRequests.delete(s),this.pendingRequests.delete(s+"_reject"))}),3e4)}))}handleOnSave(e){const{requestId:t,status:s,message:n}=e,i=this.pendingRequests.get(t),r=this.pendingRequests.get(t+"_reject");i&&("error"===s?r?.({status:s,message:n}):i({status:s,message:n}),this.pendingRequests.delete(t),this.pendingRequests.delete(t+"_reject"))}setDirty(e){this.sendMessage(i.SET_DIRTY,e)}sendClose(e,t){this.sendMessage(i.SEND_CLOSE,{doc:e,isDataDirty:t})}sendException(e){this.sendMessage(i.SEND_EXCEPTION,e)}handleMessage(e,t){if(this.handler)switch(e){case r.INIT_ACK:this.safeInvoke("onInitialData",this.handler,t);break;case r.DATA_CHANGE:this.safeInvoke("onDataChange",this.handler,t);break;case r.REQUEST_CLOSE:this.safeInvoke("onCloseRequest",this.handler);break;case r.REQUEST_SAVE:this.safeInvoke("onSaveRequest",this.handler);break;case r.SAVE_SUCCESS:case r.SAVE_ERROR:this.handleOnSave(t);break;default:console.warn(`No handler found for message type: ${e}`)}else e===r.INIT_ACK?(console.warn("Handler not set. Storing INIT_ACK message for later processing."),this.pendingInitAck=t):console.error("Message handler not found for type:",e)}}var c;d.initialized=!1,function(e){e.APP_READY="APP_READY",e.INIT="INIT",e.READ_FILE="READ_FILE",e.WRITE_FILE="WRITE_FILE",e.FILE_DIRTY="FILE_DIRTY"}(c||(c={}));class l extends a{constructor(){super(),this.handler=null,this.accessToken="",this.cardFS={readFile:this._readFile.bind(this),writeFile:this._writeFile.bind(this)},this.fileReadResolvers=new Map,this.fileWriteResolvers=new Map,this.pendingAcks=new Map,this.handleMessage=(e,t)=>{if(!this.handler)throw new Error("Message handler not found!");const s=t?.messageId;if(s&&this.pendingAcks.has(s)){const{resolve:e,timeout:n}=this.pendingAcks.get(s);return clearTimeout(n),this.pendingAcks.delete(s),void e(t)}switch(e){case r.INIT_ACK:this.dataStore.kw1=t.key_wa1,this.dataStore.iuid=t.iuid;try{this.cryptoA01.decrypt(this.dataStore.denc,t.key_wa1+this.dataStore.kw2,t.iuid).then((e=>{const s=JSON.parse(e);this.handler&&this.safeInvoke("onInit",this.handler,{...s,ui:t.ui}),delete this.dataStore.denc})).catch((e=>{throw console.error("Final decrypt error",e),e}))}catch(e){console.error("Decryption failed!",e),this.sendEventError("dec2_failed",e.message)}break;case r.FILE_DATA:const s=t?.name;if(s&&this.fileReadResolvers.has(s)){const e=this.fileReadResolvers.get(s);this.fileReadResolvers.delete(s),e(t)}else console.warn("CardSdk: FILE_DATA received but no resolver found for",s);break;case r.DATA_CHANGE:this.safeInvoke("onFileChange",this.handler,t);case r.SAVE_SUCCESS:const n=t?.name;if(n&&this.fileWriteResolvers.has(n)){const{resolve:e}=this.fileWriteResolvers.get(n);this.fileWriteResolvers.delete(n),e()}else console.warn("CardSdk: SAVE_SUCCESS received but no resolver found for",n);break;case r.SAVE_ERROR:const i=t?.name;if(i&&this.fileWriteResolvers.has(i)){const{reject:e}=this.fileWriteResolvers.get(i);this.fileWriteResolvers.delete(i),e(new Error(t?.message||"Unknown write error"))}else console.warn("CardSdk: SAVE_ERROR received but no resolver found for",i);break;case r.ERROR:this.safeInvoke("onError",this.handler,t);break;case r.REFRESH:this.safeInvoke("onRefreshRequest",this.handler,t);break;default:console.warn(`No handler found for message type: ${e}`)}},this.cryptoA01=new n}static async init(e,t,s){try{return l.instance||(l.instance=new l,l.instance.setupParentConnection().then((()=>{l.instance.initializeCardSdk(e)})).catch((e=>{console.error(e)})),t&&l.instance.setHandler(t)),l.instance}catch(e){throw console.error("CardSdk: Unrecoverable error in init",e),e}}setHandler(e){this.handler=e}openDeepLink(e){this.emitDeepLink(e)||console.warn("openDeepLink ignored; provide a dome:// or intouchapp:// href")}async initializeCardSdk(e){let t="CardSdk::initializeCardSdk:";try{if(!e)throw new Error("Invalid secret");const s=window.IT_DATA_AF1;if(!s)throw console.error(t,"No data"),new Error("No data");const n=window.location.href;const i=new URL(n).pathname.split("/wa/").filter(Boolean)[1].split("/")[0].split("").reverse().join("").substring(4,25);if(!i)throw new Error("Cannot decrypt (1)");const r=await this.cryptoA01.decrypt(s,e,i);try{const e=JSON.parse(r);if(!e.ite)throw new Error("Invalid data");this.dataStore={denc:e.d,kw2:e.kw2},this.accessToken=e.ite,l.instance.sendInit(e.ite)}catch(e){throw console.error("Initial Decryption failed (2):",e),e}}catch(e){console.error(t,"Init failed:",e),this.sendEventError("init_failed",e.message)}}async sendInit(e){this.sendMessage(c.INIT,{token:e,sdk:{ver:s}})}sendMessageWithAck(e,t,s,n=15e3){const i=crypto.randomUUID();return new Promise(((r,o)=>{const a=setTimeout((()=>{this.pendingAcks.delete(i),o(new Error(`${s} not received in time`))}),n);this.pendingAcks.set(i,{resolve:r,reject:o,timeout:a}),this.sendMessage(e,{...t,messageId:i})}))}_readFile(e,t){return new Promise(((s,n)=>{if(this.fileReadResolvers.has(t))return void n(new Error(`A read request is already pending for file: ${t}`));const i=setTimeout((()=>{this.fileReadResolvers.delete(t),n(new Error(`Timed out waiting for file: ${t}`))}),15e3);this.fileReadResolvers.set(t,(e=>{clearTimeout(i),s(e)})),this.sendMessageWithAck(c.READ_FILE,{card_iuid:e,name:t},r.READ_FILE_ACK).catch((()=>{clearTimeout(i),this.fileReadResolvers.delete(t),this.getDocumentAttachedToCard(e,t).then(s).catch(n)}))}))}_writeFile(e,t,s){return new Promise(((n,i)=>{if(this.fileWriteResolvers.has(t))return void i(new Error(`A write request is already pending for file: ${t}`));const o=setTimeout((()=>{this.fileWriteResolvers.delete(t),i(new Error(`Write timed out for file: ${t}`))}),15e3);this.fileWriteResolvers.set(t,{resolve:()=>{clearTimeout(o),this.fileWriteResolvers.delete(t),n()},reject:e=>{clearTimeout(o),this.fileWriteResolvers.delete(t),i(e)}}),this.sendMessageWithAck(c.WRITE_FILE,{name:t,data:s},r.WRITE_FILE_ACK).then((()=>{clearTimeout(o),this.fileWriteResolvers.delete(t),n()})).catch((s=>{clearTimeout(o),this.fileWriteResolvers.delete(t),this.postDocumentAttachedToCard(e,document).then((()=>n())).catch(i)}))}))}async convertToJsonFile(e,t="json",s="file.json"){const n=JSON.stringify(e,null,2),i="application/json",r=new Blob([n],{type:i});return new File([r],s,{type:i})}async convertToFile(e,t,s="json",n){if("json"===s)return this.convertToJsonFile(e,"json",t);{const s=new Blob([e],n?{type:n}:void 0);return new File([s],t,{type:s.type})}}async getDocumentAttachedToCard(e,t="default",s){const n=new URL(`/api/v1/documents/attached_to/${e}/`);n.searchParams.set("name",t),s&&n.searchParams.set("ts_m",s.toString());const i=await fetch(n.toString(),{method:"GET",headers:{Authorization:`Bearer ${this.accessToken||""}`,"Content-Type":"application/json"}});if(!i.ok){const e=await i.text();throw new Error(`Fetch failed: ${e}`)}return i.json()}async postDocumentAttachedToCard(e,t){const s=await fetch(`/api/v1/documents/attached_to/${e}/`,{method:"POST",headers:{Authorization:`Bearer ${this.accessToken||""}`,"Content-Type":"application/json"},body:JSON.stringify(t)});if(!s.ok){const e=await s.text();throw new Error(`Post failed: ${e}`)}return s.json()}async getAllDocumentsAttachedToCard(e){const t=await fetch(`/api/v1/documents/with_card/${e}/`,{method:"GET",headers:{Authorization:`Bearer ${this.accessToken||""}`,"Content-Type":"application/json"}});return await t.json()}async postUploadFile(e,t){const{type:s}=t,n=await this.convertToFile(t,e,s),i=new FormData;i.append("file",n);const r=await fetch("/api/v1/documents/",{method:"POST",headers:{Authorization:`Bearer ${this.accessToken||""}`},body:i});if(!r.ok){const e=await r.text();throw new Error(`Upload failed: ${e}`)}return r.json()}async shareDocumentWithCard(e,t){const s=await fetch(`/api/v1/documents/with_card/${e}/`,{method:"POST",headers:{Authorization:`Bearer ${this.accessToken||""}`,"Content-Type":"application/json"},body:JSON.stringify(t)});if(!s.ok){const e=await s.text();throw new Error(`Share failed: ${e}`)}return s.json()}sendEventError(e,t,s=void 0){let n={message:t,error_code:e,data:s};this.handler&&this.safeInvoke("onError",this.handler,n)}setFileDirty(e){this.sendMessage(c.FILE_DIRTY,e)}getUsername(e){const t=e?.name;return t&&Object.values(t).some((e=>e))?function(e){const{prefix:t="",given:s="",middle:n="",family:i="",suffix:r=""}=e||{};return[t,s,n,i,r].filter((e=>e)).join(" ").trim()}(t):""}}return t})()));
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://domeSdk/webpack/universalModuleDefinition","webpack://domeSdk/webpack/bootstrap","webpack://domeSdk/webpack/runtime/define property getters","webpack://domeSdk/webpack/runtime/hasOwnProperty shorthand","webpack://domeSdk/webpack/runtime/make namespace object","webpack://domeSdk/./src/crypto.ts","webpack://domeSdk/./src/dome-sdk.ts","webpack://domeSdk/./src/utils.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"domeSdk\"] = factory();\n\telse\n\t\troot[\"domeSdk\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// Provide enc / dec using Algorithm01\nexport class CryptoA01 {\n constructor() {\n // Initialize subtleCrypto once\n this.subtleCrypto = window.crypto?.subtle;\n if (!this.subtleCrypto) {\n throw new Error('SubtleCrypto API is not available in this environment.');\n }\n }\n /**\n * Perform decryption using AES based V1 algorithm.\n *\n * string: the encrypted string (base64 encoded)\n * password: the password used for encryption\n * salt: the base64 encoded salt used\n */\n async decrypt(token, password, salt) {\n try {\n if (!token) {\n throw new Error(\"Invalid token\");\n }\n const tokenBytes = this.base64UrlDecode(token);\n // Extract token components\n const version = tokenBytes[0];\n if (version !== 0x80) {\n // console.log(\"Incorrect Version: \", version);\n throw new Error('Invalid version');\n }\n const timestamp = tokenBytes.slice(1, 9);\n const iv = tokenBytes.slice(9, 25);\n const ciphertext = tokenBytes.slice(25, -32);\n const hmacFromToken = tokenBytes.slice(-32);\n // Derive the key and split it into HMAC and AES keys\n const fullKey = await this.deriveKey(password, salt);\n const { hmacKey, aesKey } = await this.splitKey(fullKey);\n // Compute HMAC over version + timestamp + IV + ciphertext\n const hmacInput = tokenBytes.slice(0, -32);\n const computedHmac = new Uint8Array(await this.subtleCrypto.sign('HMAC', hmacKey, hmacInput));\n // Validate HMAC\n if (!computedHmac.every((byte, i) => byte === hmacFromToken[i])) {\n throw new Error('Invalid HMAC. Token has been tampered with!');\n }\n // Decrypt the ciphertext\n const decrypted = await this.subtleCrypto.decrypt({\n name: 'AES-CBC',\n iv: iv,\n }, aesKey, ciphertext);\n // Convert decrypted data to UTF-8 string\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n }\n catch (err) {\n console.log(\"Error in decrypt:\", err);\n throw err;\n }\n }\n async deriveKey(password, salt, iterations = 10000) {\n const encoder = new TextEncoder();\n const keyMaterial = await this.subtleCrypto.importKey(\"raw\", encoder.encode(password), \"PBKDF2\", false, [\"deriveKey\"]);\n return this.subtleCrypto.deriveKey({\n name: \"PBKDF2\",\n hash: \"SHA-256\",\n salt: encoder.encode(salt),\n iterations: iterations,\n }, keyMaterial, { name: \"AES-CBC\", length: 256 }, true, // Allow export of the derived key (req for splitting)\n [\"encrypt\", \"decrypt\"]);\n }\n // Split the full key into HMAC and AES keys\n async splitKey(fullKey) {\n const rawKey = new Uint8Array(await this.subtleCrypto.exportKey('raw', fullKey));\n // Split the key into HMAC (first 16 bytes) and AES (last 16 bytes)\n const hmacKey = await this.subtleCrypto.importKey('raw', rawKey.slice(0, 16), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);\n const aesKey = await this.subtleCrypto.importKey('raw', rawKey.slice(16), { name: 'AES-CBC' }, false, ['encrypt', 'decrypt']);\n return { hmacKey, aesKey };\n }\n // Decode Base64 URL-safe strings\n base64UrlDecode(base64) {\n // assumes URL safe encoding that has + in place of - and _ in place of /\n const base64String = base64.replace(/-/g, '+').replace(/_/g, '/');\n const decodedString = atob(base64String);\n return new Uint8Array([...decodedString].map(c => c.charCodeAt(0)));\n }\n}\n","import pkg from \"../package.json\";\nimport { generateUUID, getNameString } from './utils';\nimport { CryptoA01 } from './crypto';\n// Enum defining message types sent from the viewer to the parent application\nexport var ViewerMessageType;\n(function (ViewerMessageType) {\n ViewerMessageType[\"CONNECTION_SUCCESS\"] = \"CONNECTION_SUCCESS\";\n ViewerMessageType[\"INIT\"] = \"INIT\";\n ViewerMessageType[\"REQUEST_SAVE\"] = \"REQUEST_SAVE\";\n ViewerMessageType[\"REQUEST_CLOSE\"] = \"REQUEST_CLOSE\";\n ViewerMessageType[\"REQUEST_INITIAL_DATA\"] = \"REQUEST_INITIAL_DATA\";\n ViewerMessageType[\"SET_DIRTY\"] = \"SET_DIRTY\";\n ViewerMessageType[\"SEND_CLOSE\"] = \"SEND_CLOSE\";\n ViewerMessageType[\"SEND_EXCEPTION\"] = \"SEND_EXCEPTION\"; // Sends an exception event to parent\n})(ViewerMessageType || (ViewerMessageType = {}));\n// Enum defining message types sent from the parent application to the embedded app\nvar ClientMessageType;\n(function (ClientMessageType) {\n ClientMessageType[\"CONNECT\"] = \"CONNECT\";\n ClientMessageType[\"REQUEST_CLOSE\"] = \"REQUEST_CLOSE\";\n ClientMessageType[\"REQUEST_SAVE\"] = \"REQUEST_SAVE\";\n ClientMessageType[\"SAVE_ERROR\"] = \"SAVE_ERROR\";\n ClientMessageType[\"SAVE_SUCCESS\"] = \"SAVE_SUCCESS\";\n ClientMessageType[\"DATA_CHANGE\"] = \"DATA_CHANGE\";\n ClientMessageType[\"INIT_ACK\"] = \"INIT_ACK\";\n ClientMessageType[\"ERROR\"] = \"ERROR\";\n ClientMessageType[\"REFRESH\"] = \"REFRESH\";\n})(ClientMessageType || (ClientMessageType = {}));\n;\nconst ALLOWED_ORIGINS = new Set(getAllowedOrigins());\nfunction getAllowedOrigins() {\n if (typeof window === 'undefined')\n return [];\n return [\n window.location.origin,\n 'https://dome.so',\n 'https://spaces.intouchapp.com/',\n 'http://localhost:4200',\n 'http://localhost:4201',\n 'null',\n ];\n}\n/**\n * DomeEmbeddedAppSdk:\n * Base SDK class providing methods to send messages to the parent application.\n */\nclass DomeEmbeddedAppSdk {\n constructor() {\n this.targetOrigin = \"*\";\n this.isAppReady = false;\n this.port2 = null;\n this.platform = \"unknown\"; // Store detected platform\n this.detectPlatform();\n }\n /**\n * Detects the platform (iOS, Android, or Web) and saves it.\n */\n detectPlatform() {\n if (typeof window.AndroidBridge !== \"undefined\") {\n this.platform = \"android\";\n }\n else if (typeof window.webkit !== \"undefined\") {\n this.platform = \"ios\";\n }\n else {\n this.platform = \"web\";\n }\n console.debug(`Detected platform: ${this.platform}`);\n }\n /**\n * Method to send messages to the parent application.\n * Ensures the parent window exists and sends a structured message with type and data.\n * @param type - The type of message being sent\n * @param data - (Optional) payload data for the message\n */\n sendMessage(type, data) {\n const message = { type, data: data ?? null };\n switch (this.platform) {\n case \"android\":\n window.AndroidBridge?.sendMessage(JSON.stringify(message));\n break;\n case \"ios\":\n if (window?.webkit?.messageHandlers) {\n window.webkit?.messageHandlers.appHandler.postMessage(JSON.stringify(message));\n }\n else {\n console.error(\"webkit.messageHandlers not found\");\n }\n break;\n case \"web\":\n if (this.port2) {\n this.port2.postMessage(message);\n }\n else {\n console.error(\"Web connection is not established.\");\n }\n break;\n default:\n console.error(\"Unsupported platform, cannot send message.\");\n break;\n }\n console.debug(`Sent message to ${this.platform}:`, message);\n }\n /**\n * Notifies the parent application that the app is ready, if it hasn’t already.\n */\n sendAppInit() {\n if (!this.isAppReady) {\n this.isAppReady = true;\n this.sendMessage(ViewerMessageType.INIT, { sdk: { ver: pkg.version } });\n }\n }\n /**\n * Safely invokes a function from the handler object if it exists.\n * and logs a warning if the handler is not provided for the given message type.\n *\n * @param eventName - Name of the event method to be invoked from the handler.\n * @param handlerObj - The handler object that contains the message handling methods.\n * @param data - (Optional) The data to be passed to the handler function if invoked.\n */\n safeInvoke(eventName, handlerObj, data) {\n const handler = handlerObj[eventName];\n if (typeof handler === 'function') {\n handler(data);\n }\n else {\n console.warn(`Handler for '${String(eventName)}' is not defined.`);\n }\n }\n // Sets up connection with iframe parent using message channel\n // Call this once only in the lifetime. Should be called\n // _before_ iFrame's onLoad is called (otherwise messaging will\n // not be setup)\n setupParentConnection() {\n return new Promise((resolve, reject) => {\n switch (this.platform) {\n case \"android\":\n window.receiveFromAndroid = (message) => {\n console.debug(\"Message received from Android:\", message);\n this.handleMessage(message.type, message.data);\n };\n resolve();\n break;\n case \"ios\":\n window.receiveFromIOS = (message) => {\n console.debug(\"Message received from iOS:\", message);\n this.handleMessage(message.type, message.data);\n };\n resolve();\n break;\n case \"web\":\n if (this.port2) {\n console.warn(\"Connection already established. Skipping reinitialization.\");\n resolve();\n }\n const handleMessage = (event) => {\n const { type } = event.data || {};\n if (type !== ClientMessageType.CONNECT)\n return;\n if (event.ports && event.ports.length > 0) {\n this.port2 = event.ports[0];\n this.port2.onmessage = (e) => this.handlePortMessage(e);\n window.removeEventListener(\"message\", handleMessage); // Cleanup\n this.notifyConnectionSuccess();\n resolve();\n }\n };\n // Listen for browser-based `message` events\n window.addEventListener(\"message\", handleMessage);\n break;\n default:\n console.error(\"Unknown platform.\");\n reject(\"Unknown platform\");\n }\n });\n }\n // Send CONNECTION_SUCCESS message to parent\n notifyConnectionSuccess() {\n this.sendMessage(ViewerMessageType.CONNECTION_SUCCESS);\n }\n // Handle messages coming over message channel port\n handlePortMessage(event) {\n const { type, data } = event.data || {};\n if (!type)\n return;\n // Delegate to subclass-specific message handler\n this.handleMessage(type, data);\n }\n // Common method for handling messages to be implemented by sub-classes\n handleMessage(type, data) {\n throw new Error(\"Subclasses must implement handleMessage.\");\n }\n}\n/**\n * ViewerSdk:\n * A subclass of DomeEmbeddedAppSdk specifically for document viewer applications.\n * It includes additional methods and properties to manage app interactions.\n */\nexport class ViewerSdk extends DomeEmbeddedAppSdk {\n constructor() {\n super();\n this.handler = null; // Handler instance for client messages\n this.pendingRequests = new Map();\n this.pendingInitAck = null;\n }\n /**\n * Static initialization method to get or create the singleton instance of ViewerSdk.\n * Allows setting the handler during initialization.\n * @param handler - (Optional) Custom handler for different message types\n * @returns The singleton ViewerSdk instance\n */\n static init(handler) {\n console.debug(\"init called\", handler && \"with handler\");\n // Prevent reinitialization if already initialized\n if (ViewerSdk.initialized) {\n console.warn(\"ViewerSdk is already initialized. Skipping initialization.\");\n return ViewerSdk.instance;\n }\n if (!ViewerSdk.instance) {\n ViewerSdk.instance = new ViewerSdk();\n // Initialize parent communication - REQUIRED!\n ViewerSdk.instance.setupParentConnection()\n .then(() => {\n try {\n // Connection established with parent\n ViewerSdk.instance.initializeViewerSdk();\n }\n catch (err) {\n console.error(\"Error in initializeViewerSdk:\", err);\n }\n })\n .catch((err) => {\n console.error(\"init: Error setting up parent connection!\", err);\n console.trace(\"called from:\");\n });\n }\n if (handler) {\n ViewerSdk.instance.setHandler(handler); // Set handler if provided during initialization\n }\n // Mark as initialized\n ViewerSdk.initialized = true;\n return ViewerSdk.instance;\n }\n /**\n * Method to set or update the handler object.\n * @param handler - Custom handler for different message types\n */\n setHandler(handler) {\n this.handler = handler;\n // If INIT_ACK message was received and stored, process it now\n if (this.pendingInitAck) {\n console.debug(\"Processing pending INIT_ACK message after handler is set.\");\n this.safeInvoke(\"onInitialData\", this.handler, this.pendingInitAck);\n this.pendingInitAck = null; // Clear the stored message\n }\n }\n /**\n * Checks if the given permissions string allows reading.\n * @param perms - The permissions string.\n * @returns - True if the permission string includes read access.\n */\n canRead(perms) {\n return !!perms?.includes('r');\n }\n /**\n * Checks if the given permissions string allows writing.\n * @param perms - The permissions string.\n * @returns - True if the permission string includes write access.\n */\n canWrite(perms) {\n return !!perms?.includes('w') || !!perms?.includes('*');\n }\n // Initializes the viewer SDK, setting up the message listener and sending an initial \"ready\" message.\n initializeViewerSdk() {\n console.debug(\"initializing viewer sdk\");\n this.sendAppInit();\n }\n /**\n * Sends a request to the parent application to retrieve initial data.\n */\n requestInitialData() {\n this.sendMessage(ViewerMessageType.REQUEST_INITIAL_DATA);\n }\n /**\n * Sends a request to the parent application to save data.\n * @param doc - payload data to be saved\n * @param isDataDirty - Boolean indicating indicating modified data\n */\n requestSave(doc, isDataDirty) {\n const requestId = generateUUID();\n // Send save request with the generated requestId\n this.sendMessage(ViewerMessageType.REQUEST_SAVE, { doc, isDataDirty, requestId });\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(requestId, resolve);\n this.pendingRequests.set(requestId + '_reject', reject);\n // Timeout if the parent fails to respond in time\n setTimeout(() => {\n if (this.pendingRequests.has(requestId)) {\n this.pendingRequests.delete(requestId);\n this.pendingRequests.delete(requestId + '_reject');\n }\n }, 30000);\n });\n }\n handleOnSave(data) {\n const { requestId, status, message } = data;\n // Check if we have a pending request for this requestId\n const resolve = this.pendingRequests.get(requestId);\n const reject = this.pendingRequests.get(requestId + '_reject');\n if (resolve) {\n // If status is \"error\", reject the promise, otherwise resolve it\n if (status === \"error\") {\n reject?.({ status, message });\n }\n else {\n resolve({ status, message });\n }\n // Clean up\n this.pendingRequests.delete(requestId);\n this.pendingRequests.delete(requestId + '_reject');\n }\n }\n /**\n * Sets the viewer's \"dirty\" state, indicating modified data.\n * @param isDirty - Boolean indicating whether the viewer has modified data\n */\n setDirty(isDirty) {\n this.sendMessage(ViewerMessageType.SET_DIRTY, isDirty);\n }\n /**\n * Sends a close request to the parent, with information on whether the data is dirty.\n * @param doc - Latest document data\n * @param isDataDirty - Boolean indicating indicating modified data\n */\n sendClose(doc, isDataDirty) {\n this.sendMessage(ViewerMessageType.SEND_CLOSE, { doc, isDataDirty });\n }\n /**\n * Sends an exception to parent.\n * @param error - An error object with name and message or an error string\n */\n sendException(error) {\n this.sendMessage(ViewerMessageType.SEND_EXCEPTION, error);\n }\n // Sets up the message listener for viewer to receive messages from the parent.\n handleMessage(type, data) {\n console.debug(\"handleMessage called for:\", type, \"with data:\", data);\n if (!this.handler) {\n if (type === ClientMessageType.INIT_ACK) {\n console.warn(\"Handler not set. Storing INIT_ACK message for later processing.\");\n this.pendingInitAck = data; // Save INIT_ACK message\n }\n else {\n console.error(\"Message handler not found for type:\", type);\n }\n return;\n }\n switch (type) {\n case ClientMessageType.INIT_ACK:\n this.safeInvoke(\"onInitialData\", this.handler, data);\n break;\n case ClientMessageType.DATA_CHANGE:\n this.safeInvoke(\"onDataChange\", this.handler, data);\n break;\n case ClientMessageType.REQUEST_CLOSE:\n this.safeInvoke(\"onCloseRequest\", this.handler);\n break;\n case ClientMessageType.REQUEST_SAVE:\n this.safeInvoke(\"onSaveRequest\", this.handler);\n break;\n case ClientMessageType.SAVE_SUCCESS:\n this.handleOnSave(data);\n break;\n case ClientMessageType.SAVE_ERROR:\n this.handleOnSave(data);\n break;\n default:\n console.warn(`No handler found for message type: ${type}`);\n }\n }\n}\nViewerSdk.initialized = false;\n// Card SDK\n// Enum defining message types sent from the card to the parent application\nexport var CardMessageType;\n(function (CardMessageType) {\n CardMessageType[\"APP_READY\"] = \"APP_READY\";\n CardMessageType[\"INIT\"] = \"INIT\"; // Event to send the init key to the viewer\n})(CardMessageType || (CardMessageType = {}));\n;\n/**\n * Use CardSdk to create webapp cards\n */\nexport class CardSdk extends DomeEmbeddedAppSdk {\n constructor() {\n super();\n this.handler = null; // Handler instance for client messages\n // Sets up the message listener for cards to receive messages from the parent.\n this.handleMessage = (type, data) => {\n if (!this.handler) {\n throw new Error(\"Message handler not found!\");\n }\n switch (type) {\n case ClientMessageType.INIT_ACK:\n // Parent sent INIT_ACK\n console.debug(\"CardSdk: INIT_ACK received\");\n this.dataStore.kw1 = data.key_wa1;\n this.dataStore.iuid = data.iuid;\n try {\n this.cryptoA01.decrypt(this.dataStore.denc, data.key_wa1 + this.dataStore.kw2, data.iuid)\n .then((decData) => {\n console.debug(\"CardSdk: INIT_ACK: decrypted data \", decData);\n const decryptedData = JSON.parse(decData);\n if (this.handler)\n this.safeInvoke(\"onInit\", this.handler, { ...decryptedData, ui: data.ui });\n // no need for orig enc data.. free to delete it\n delete this.dataStore.denc;\n })\n .catch((err) => {\n console.error(\"Final decrypt error\", err);\n throw err;\n });\n }\n catch (err) {\n console.error(\"Decryption failed!\", err);\n this.sendEventError('dec2_failed', err.message);\n }\n break;\n case ClientMessageType.ERROR:\n // Parent sent an ERROR\n this.safeInvoke(\"onError\", this.handler, data);\n break;\n case ClientMessageType.REFRESH:\n // Asking for UI refresh\n this.safeInvoke(\"onRefreshRequest\", this.handler, data);\n break;\n default:\n console.warn(`No handler found for message type: ${type}`);\n }\n };\n this.cryptoA01 = new CryptoA01();\n console.debug(\"CardSdk::constructor: done\");\n }\n /**\n * Static initialization method to get or create the singleton instance of CardSdk.\n * @param secret - The card developer secret key\n * @param handler - (Optional) Handler for different events emitted by the SDK\n * @returns The singleton CardSdk instance\n */\n static async init(secret, handler, options) {\n try {\n console.debug(\"CardSdk::init\");\n if (!CardSdk.instance) {\n CardSdk.instance = new CardSdk();\n // Initialize parent communication - REQUIRED!\n CardSdk.instance.setupParentConnection()\n .then(() => {\n // Connection established with parents..\n // Initialize SDK in async\n CardSdk.instance.initializeCardSdk(secret);\n })\n .catch((err) => {\n console.error(err);\n });\n }\n else {\n return CardSdk.instance;\n }\n // Setup handlers\n if (handler) {\n CardSdk.instance.setHandler(handler); // Set handler if provided during initialization\n }\n return CardSdk.instance;\n }\n catch (err) {\n console.error(\"CardSdk: Unrecoverable error in init\", err);\n throw err;\n }\n }\n /**\n * Method to set or update the handler object.\n * @param handler - Custom handler for different message types\n */\n setHandler(handler) {\n this.handler = handler;\n }\n // Function to initialize SDK after instance is created\n async initializeCardSdk(secret) {\n let TAG = \"CardSdk::initializeCardSdk:\";\n try {\n console.debug(TAG, \"enter\");\n if (!secret) {\n throw new Error(\"Invalid secret\");\n }\n // Get data from HTML\n const data_af1 = window.IT_DATA_AF1;\n if (!data_af1) {\n console.error(TAG, \"No data\");\n throw new Error('No data');\n }\n const url = window.location.href;\n console.debug(TAG, \"url:\", url);\n const urlObject = new URL(url);\n const segments = urlObject.pathname.split('/').filter(segment => segment);\n let url_part;\n if (segments.length > 1) {\n url_part = segments[segments.length - 2];\n }\n else if (segments.length == 1) {\n url_part = segments[0];\n }\n else {\n throw new Error('Invalid URL');\n }\n const ss = url_part.split('').reverse().join('').substring(4, 25);\n console.debug(TAG, \"ss:\", ss);\n if (!ss) {\n throw new Error('Cannot decrypt (1)');\n }\n const decData = await this.cryptoA01.decrypt(data_af1, secret, ss);\n try {\n const dataFromServer = JSON.parse(decData);\n console.debug(\"CardSdk: dataFromServer:\", dataFromServer);\n if (!dataFromServer.ite) {\n throw new Error(\"Invalid data\");\n }\n this.dataStore = {\n 'denc': dataFromServer.d,\n 'kw2': dataFromServer.kw2\n };\n CardSdk.instance.sendInit(dataFromServer.ite);\n }\n catch (err) {\n console.error(\"Initial Decryption failed (2):\", err);\n throw err;\n }\n }\n catch (err) {\n console.error(TAG, \"Init failed:\", err);\n this.sendEventError('init_failed', err.message);\n }\n }\n async sendInit(token) {\n this.sendMessage(CardMessageType.INIT, { 'token': token, sdk: { ver: pkg.version } });\n }\n /**\n * Converts a JavaScript object to a JSON file.\n */\n async convertToJsonFile(object, type = 'json', fileName = 'file.json') {\n const jsonString = JSON.stringify(object, null, 2);\n const jsonFileType = 'application/json';\n const blob = new Blob([jsonString], { type: jsonFileType });\n return new File([blob], fileName, { type: jsonFileType });\n }\n /**\n * Converts data to a file.\n */\n async convertToFile(data, fileName, fileType = 'json', fileMimeType) {\n if (fileType === 'json') {\n return this.convertToJsonFile(data, 'json', fileName);\n }\n else {\n const blob = new Blob([data], fileMimeType ? { type: fileMimeType } : undefined);\n return new File([blob], fileName, { type: blob.type });\n }\n }\n /**\n * Get document associated with the current card\n */\n async getCardDocument(documentIuid, cardIuid) {\n const fetchUrl = `/api/v1/${documentIuid}/`;\n const createUrl = `/api/v1/documents/create_for/${cardIuid}`;\n // Helper to handle response content\n const parseResponse = async (response) => {\n const contentType = response.headers.get('Content-Type') || '';\n if (contentType.includes('application/json'))\n return response.json();\n if (contentType.includes('text/'))\n return response.text();\n throw new Error(`Unsupported response type: ${contentType}`);\n };\n try {\n // Try to fetch the document\n const fetchResponse = await fetch(fetchUrl, { method: 'GET' });\n if (fetchResponse.ok)\n return parseResponse(fetchResponse);\n if (fetchResponse.status === 404) {\n // Create the document if not found\n const createResponse = await fetch(createUrl, { method: 'POST' });\n if (!createResponse.ok)\n throw new Error(`Failed to create document: ${createResponse.status}`);\n return parseResponse(createResponse);\n }\n throw new Error(`Failed to fetch document: ${fetchResponse.status}`);\n }\n catch (error) {\n console.error('Error handling document:', error);\n throw error;\n }\n }\n /**\n * Uploads a file to the specified document IUID endpoint.\n */\n async saveDocument(fileObj, documentIuid) {\n // Convert the fileObj to a File\n const { name, type } = fileObj;\n const file = await this.convertToFile(fileObj, name, type);\n // Construct the full URL\n const apiUrl = `/api/v1/${documentIuid}/`;\n // Create FormData and append the file\n const formData = new FormData();\n formData.append('file', file);\n // Make the POST request\n return fetch(apiUrl, {\n method: 'PUT',\n body: formData,\n });\n }\n // Send event on error (clients will get \"onError\" event)\n sendEventError(error_code, message, data = undefined) {\n let data_to_send = {\n 'message': message,\n 'error_code': error_code,\n 'data': data\n };\n if (this.handler)\n this.safeInvoke(\"onError\", this.handler, data_to_send);\n }\n // Get username string from user object received from parent\n getUsername(userObj) {\n const nameObj = userObj?.name;\n if (nameObj && Object.values(nameObj).some(value => value)) {\n return getNameString(nameObj);\n }\n return '';\n }\n}\n","/**\n * Helper function to generate a unique requestId (UUID).\n * This uses the browser's crypto API for random UUID generation.\n */\nexport function generateUUID() {\n // If in a browser environment with crypto support (modern browsers)\n if (typeof window !== 'undefined' && window.crypto && window.crypto.randomUUID) {\n return window.crypto.randomUUID();\n }\n // Fallback for non-browser environments (e.g., Node.js)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto support\n throw new Error('UUID generation is not supported in this environment');\n}\n/**\n * Helper function to get username from user object\n * @param nameObj the user object\n */\nexport function getNameString(nameObj) {\n const { prefix = '', given = '', middle = '', family = '', suffix = '' } = nameObj || {};\n const fullname = [prefix, given, middle, family, suffix].filter(namePart => namePart).join(' ');\n return fullname.trim();\n}\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","CryptoA01","constructor","subtleCrypto","window","crypto","subtle","Error","decrypt","token","password","salt","tokenBytes","base64UrlDecode","slice","iv","ciphertext","hmacFromToken","fullKey","deriveKey","hmacKey","aesKey","splitKey","hmacInput","Uint8Array","sign","every","byte","i","decrypted","name","TextDecoder","decode","err","console","log","iterations","encoder","TextEncoder","keyMaterial","importKey","encode","hash","length","rawKey","exportKey","base64","base64String","replace","decodedString","atob","map","c","charCodeAt","ViewerMessageType","ClientMessageType","CardMessageType","Set","location","origin","DomeEmbeddedAppSdk","targetOrigin","isAppReady","port2","platform","detectPlatform","AndroidBridge","webkit","debug","sendMessage","type","data","message","JSON","stringify","messageHandlers","appHandler","postMessage","error","sendAppInit","INIT","sdk","ver","safeInvoke","eventName","handlerObj","handler","warn","String","setupParentConnection","Promise","resolve","reject","receiveFromAndroid","handleMessage","receiveFromIOS","event","CONNECT","ports","onmessage","e","handlePortMessage","removeEventListener","notifyConnectionSuccess","addEventListener","CONNECTION_SUCCESS","ViewerSdk","super","pendingRequests","Map","pendingInitAck","init","initialized","instance","then","initializeViewerSdk","catch","trace","setHandler","canRead","perms","includes","canWrite","requestInitialData","REQUEST_INITIAL_DATA","requestSave","doc","isDataDirty","requestId","randomUUID","generateUUID","REQUEST_SAVE","set","setTimeout","has","delete","handleOnSave","status","setDirty","isDirty","SET_DIRTY","sendClose","SEND_CLOSE","sendException","SEND_EXCEPTION","INIT_ACK","DATA_CHANGE","REQUEST_CLOSE","SAVE_SUCCESS","SAVE_ERROR","CardSdk","dataStore","kw1","key_wa1","iuid","cryptoA01","denc","kw2","decData","decryptedData","parse","ui","sendEventError","ERROR","REFRESH","secret","options","initializeCardSdk","TAG","data_af1","IT_DATA_AF1","url","href","segments","URL","pathname","split","filter","segment","url_part","ss","reverse","join","substring","dataFromServer","ite","d","sendInit","convertToJsonFile","object","fileName","jsonString","jsonFileType","blob","Blob","File","convertToFile","fileType","fileMimeType","undefined","getCardDocument","documentIuid","cardIuid","fetchUrl","createUrl","parseResponse","async","response","contentType","headers","json","text","fetchResponse","fetch","method","ok","createResponse","saveDocument","fileObj","file","apiUrl","formData","FormData","append","body","error_code","data_to_send","getUsername","userObj","nameObj","values","some","prefix","given","middle","family","suffix","namePart","trim","getNameString"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"index.js","mappings":"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","sources":["webpack://domeSdk/webpack/universalModuleDefinition","webpack://domeSdk/webpack/bootstrap","webpack://domeSdk/webpack/runtime/define property getters","webpack://domeSdk/webpack/runtime/hasOwnProperty shorthand","webpack://domeSdk/webpack/runtime/make namespace object","webpack://domeSdk/./src/crypto.ts","webpack://domeSdk/./src/dome-sdk.ts","webpack://domeSdk/./src/utils.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"domeSdk\"] = factory();\n\telse\n\t\troot[\"domeSdk\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// Provide enc / dec using Algorithm01\nexport class CryptoA01 {\n constructor() {\n // Initialize subtleCrypto once\n this.subtleCrypto = window.crypto?.subtle;\n if (!this.subtleCrypto) {\n throw new Error('SubtleCrypto API is not available in this environment.');\n }\n }\n /**\n * Perform decryption using AES based V1 algorithm.\n *\n * string: the encrypted string (base64 encoded)\n * password: the password used for encryption\n * salt: the base64 encoded salt used\n */\n async decrypt(token, password, salt) {\n try {\n if (!token) {\n throw new Error(\"Invalid token\");\n }\n const tokenBytes = this.base64UrlDecode(token);\n // Extract token components\n const version = tokenBytes[0];\n if (version !== 0x80) {\n // console.log(\"Incorrect Version: \", version);\n throw new Error('Invalid version');\n }\n const timestamp = tokenBytes.slice(1, 9);\n const iv = tokenBytes.slice(9, 25);\n const ciphertext = tokenBytes.slice(25, -32);\n const hmacFromToken = tokenBytes.slice(-32);\n // Derive the key and split it into HMAC and AES keys\n const fullKey = await this.deriveKey(password, salt);\n const { hmacKey, aesKey } = await this.splitKey(fullKey);\n // Compute HMAC over version + timestamp + IV + ciphertext\n const hmacInput = tokenBytes.slice(0, -32);\n const computedHmac = new Uint8Array(await this.subtleCrypto.sign('HMAC', hmacKey, hmacInput));\n // Validate HMAC\n if (!computedHmac.every((byte, i) => byte === hmacFromToken[i])) {\n throw new Error('Invalid HMAC. Token has been tampered with!');\n }\n // Decrypt the ciphertext\n const decrypted = await this.subtleCrypto.decrypt({\n name: 'AES-CBC',\n iv: iv,\n }, aesKey, ciphertext);\n // Convert decrypted data to UTF-8 string\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n }\n catch (err) {\n console.log(\"Error in decrypt:\", err);\n throw err;\n }\n }\n async deriveKey(password, salt, iterations = 10000) {\n const encoder = new TextEncoder();\n const keyMaterial = await this.subtleCrypto.importKey(\"raw\", encoder.encode(password), \"PBKDF2\", false, [\"deriveKey\"]);\n return this.subtleCrypto.deriveKey({\n name: \"PBKDF2\",\n hash: \"SHA-256\",\n salt: encoder.encode(salt),\n iterations: iterations,\n }, keyMaterial, { name: \"AES-CBC\", length: 256 }, true, // Allow export of the derived key (req for splitting)\n [\"encrypt\", \"decrypt\"]);\n }\n // Split the full key into HMAC and AES keys\n async splitKey(fullKey) {\n const rawKey = new Uint8Array(await this.subtleCrypto.exportKey('raw', fullKey));\n // Split the key into HMAC (first 16 bytes) and AES (last 16 bytes)\n const hmacKey = await this.subtleCrypto.importKey('raw', rawKey.slice(0, 16), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);\n const aesKey = await this.subtleCrypto.importKey('raw', rawKey.slice(16), { name: 'AES-CBC' }, false, ['encrypt', 'decrypt']);\n return { hmacKey, aesKey };\n }\n // Decode Base64 URL-safe strings\n base64UrlDecode(base64) {\n // assumes URL safe encoding that has + in place of - and _ in place of /\n const base64String = base64.replace(/-/g, '+').replace(/_/g, '/');\n const decodedString = atob(base64String);\n return new Uint8Array([...decodedString].map(c => c.charCodeAt(0)));\n }\n}\n","import pkg from \"../package.json\";\nimport { generateUUID, getNameString } from './utils';\nimport { CryptoA01 } from './crypto';\n// Enum defining message types sent from the viewer to the parent application\nexport var ViewerMessageType;\n(function (ViewerMessageType) {\n ViewerMessageType[\"CONNECTION_SUCCESS\"] = \"CONNECTION_SUCCESS\";\n ViewerMessageType[\"INIT\"] = \"INIT\";\n ViewerMessageType[\"REQUEST_SAVE\"] = \"REQUEST_SAVE\";\n ViewerMessageType[\"REQUEST_CLOSE\"] = \"REQUEST_CLOSE\";\n ViewerMessageType[\"REQUEST_INITIAL_DATA\"] = \"REQUEST_INITIAL_DATA\";\n ViewerMessageType[\"SET_DIRTY\"] = \"SET_DIRTY\";\n ViewerMessageType[\"SEND_CLOSE\"] = \"SEND_CLOSE\";\n ViewerMessageType[\"SEND_EXCEPTION\"] = \"SEND_EXCEPTION\";\n ViewerMessageType[\"OPEN_DEEPLINK\"] = \"OPEN_DEEPLINK\";\n})(ViewerMessageType || (ViewerMessageType = {}));\n// Enum defining message types sent from the parent application to the embedded app\nvar ClientMessageType;\n(function (ClientMessageType) {\n ClientMessageType[\"CONNECT\"] = \"CONNECT\";\n ClientMessageType[\"REQUEST_CLOSE\"] = \"REQUEST_CLOSE\";\n ClientMessageType[\"REQUEST_SAVE\"] = \"REQUEST_SAVE\";\n ClientMessageType[\"SAVE_ERROR\"] = \"SAVE_ERROR\";\n ClientMessageType[\"SAVE_SUCCESS\"] = \"SAVE_SUCCESS\";\n ClientMessageType[\"DATA_CHANGE\"] = \"DATA_CHANGE\";\n ClientMessageType[\"FILE_DATA\"] = \"FILE_DATA\";\n ClientMessageType[\"WRITE_FILE_ACK\"] = \"WRITE_FILE_ACK\";\n ClientMessageType[\"READ_FILE_ACK\"] = \"READ_FILE_ACK\";\n ClientMessageType[\"INIT_ACK\"] = \"INIT_ACK\";\n ClientMessageType[\"ERROR\"] = \"ERROR\";\n ClientMessageType[\"REFRESH\"] = \"REFRESH\";\n})(ClientMessageType || (ClientMessageType = {}));\n;\nconst ALLOWED_ORIGINS = new Set(getAllowedOrigins());\nconst ALLOWED_DEEP_LINK_PROTOCOLS = new Set([\"dome\", \"intouchapp\"]);\nfunction getAllowedOrigins() {\n if (typeof window === 'undefined')\n return [];\n return [\n window.location.origin,\n 'https://dome.so',\n 'https://spaces.intouchapp.com/',\n 'http://localhost:4200',\n 'http://localhost:4201',\n 'null',\n ];\n}\n/**\n * DomeEmbeddedAppSdk:\n * Base SDK class providing methods to send messages to the parent application.\n */\nclass DomeEmbeddedAppSdk {\n constructor() {\n this.targetOrigin = \"*\";\n this.isAppReady = false;\n this.port2 = null;\n this.platform = \"unknown\"; // Store detected platform\n this.handleDeepLinkClick = (event) => {\n if (this.platform !== \"web\")\n return;\n if (!(event.target instanceof Element))\n return;\n const anchor = event.target.closest(\"a[href]\");\n if (!anchor)\n return;\n const href = anchor.getAttribute(\"href\") ?? \"\";\n if (this.emitDeepLink(href)) {\n event.preventDefault();\n }\n };\n this.detectPlatform();\n this.setupDeepLinkInterception();\n }\n /**\n * Detects the platform (iOS, Android, or Web) and saves it.\n */\n detectPlatform() {\n if (typeof window.AndroidBridge !== \"undefined\") {\n this.platform = \"android\";\n }\n else if (typeof window.webkit !== \"undefined\") {\n this.platform = \"ios\";\n }\n else {\n this.platform = \"web\";\n }\n console.debug(`Detected platform: ${this.platform}`);\n }\n /**\n * Listens for deep link anchor clicks on web to forward them to the parent app.\n */\n setupDeepLinkInterception() {\n if (this.platform !== \"web\")\n return;\n if (typeof document === \"undefined\")\n return;\n document.addEventListener(\"click\", this.handleDeepLinkClick, true);\n }\n /**\n * Sends an OPEN_DEEPLINK message when the href uses an allowed protocol.\n * @returns true if the message was dispatched, false otherwise.\n */\n emitDeepLink(href) {\n if (typeof href !== \"string\" || href.trim() === \"\") {\n console.warn(\"emitDeepLink called without a valid href\");\n return false;\n }\n const protocol = href.split(\":\")[0]?.toLowerCase();\n if (!protocol || !ALLOWED_DEEP_LINK_PROTOCOLS.has(protocol)) {\n return false;\n }\n this.sendMessage(ViewerMessageType.OPEN_DEEPLINK, href);\n return true;\n }\n getPlatform() {\n return this.platform;\n }\n /**\n * Method to send messages to the parent application.\n * Ensures the parent window exists and sends a structured message with type and data.\n * @param type - The type of message being sent\n * @param data - (Optional) payload data for the message\n */\n sendMessage(type, data) {\n const message = { type, data: data ?? null };\n switch (this.platform) {\n case \"android\":\n window.AndroidBridge?.sendMessage(JSON.stringify(message));\n break;\n case \"ios\":\n if (window?.webkit?.messageHandlers) {\n window.webkit?.messageHandlers.appHandler.postMessage(JSON.stringify(message));\n }\n else {\n console.error(\"webkit.messageHandlers not found\");\n }\n break;\n case \"web\":\n if (this.port2) {\n this.port2.postMessage(message);\n }\n else {\n console.error(\"Web connection is not established.\");\n }\n break;\n default:\n console.error(\"Unsupported platform, cannot send message.\");\n break;\n }\n console.debug(`Sent message to ${this.platform}:`, message);\n }\n /**\n * Notifies the parent application that the app is ready, if it hasn’t already.\n */\n sendAppInit() {\n if (!this.isAppReady) {\n this.isAppReady = true;\n this.sendMessage(ViewerMessageType.INIT, { sdk: { ver: pkg.version } });\n }\n }\n /**\n * Safely invokes a function from the handler object if it exists.\n * and logs a warning if the handler is not provided for the given message type.\n *\n * @param eventName - Name of the event method to be invoked from the handler.\n * @param handlerObj - The handler object that contains the message handling methods.\n * @param data - (Optional) The data to be passed to the handler function if invoked.\n */\n safeInvoke(eventName, handlerObj, data) {\n const handler = handlerObj[eventName];\n if (typeof handler === 'function') {\n handler(data);\n }\n else {\n console.warn(`Handler for '${String(eventName)}' is not defined.`);\n }\n }\n // Sets up connection with iframe parent using message channel\n // Call this once only in the lifetime. Should be called\n // _before_ iFrame's onLoad is called (otherwise messaging will\n // not be setup)\n setupParentConnection() {\n return new Promise((resolve, reject) => {\n switch (this.platform) {\n case \"android\":\n window.receiveFromAndroid = (message) => {\n console.debug(\"Message received from Android:\", message);\n this.handleMessage(message.type, message.data);\n };\n resolve();\n break;\n case \"ios\":\n window.receiveFromIOS = (message) => {\n console.debug(\"Message received from iOS:\", message);\n this.handleMessage(message.type, message.data);\n };\n resolve();\n break;\n case \"web\":\n if (this.port2) {\n console.warn(\"Connection already established. Skipping reinitialization.\");\n resolve();\n }\n const handleMessage = (event) => {\n const { type } = event.data || {};\n if (type !== ClientMessageType.CONNECT)\n return;\n if (event.ports && event.ports.length > 0) {\n this.port2 = event.ports[0];\n this.port2.onmessage = (e) => this.handlePortMessage(e);\n window.removeEventListener(\"message\", handleMessage); // Cleanup\n this.notifyConnectionSuccess();\n resolve();\n }\n };\n // Listen for browser-based `message` events\n window.addEventListener(\"message\", handleMessage);\n break;\n default:\n console.error(\"Unknown platform.\");\n reject(\"Unknown platform\");\n }\n });\n }\n // Send CONNECTION_SUCCESS message to parent\n notifyConnectionSuccess() {\n this.sendMessage(ViewerMessageType.CONNECTION_SUCCESS);\n }\n // Handle messages coming over message channel port\n handlePortMessage(event) {\n const { type, data } = event.data || {};\n if (!type)\n return;\n // Delegate to subclass-specific message handler\n this.handleMessage(type, data);\n }\n // Common method for handling messages to be implemented by sub-classes\n handleMessage(type, data) {\n throw new Error(\"Subclasses must implement handleMessage.\");\n }\n}\n/**\n * ViewerSdk:\n * A subclass of DomeEmbeddedAppSdk specifically for document viewer applications.\n * It includes additional methods and properties to manage app interactions.\n */\nexport class ViewerSdk extends DomeEmbeddedAppSdk {\n constructor() {\n super();\n this.handler = null; // Handler instance for client messages\n this.pendingRequests = new Map();\n this.pendingInitAck = null;\n }\n /**\n * Static initialization method to get or create the singleton instance of ViewerSdk.\n * Allows setting the handler during initialization.\n * @param handler - (Optional) Custom handler for different message types\n * @returns The singleton ViewerSdk instance\n */\n static init(handler) {\n console.debug(\"init called\", handler && \"with handler\");\n // Prevent reinitialization if already initialized\n if (ViewerSdk.initialized) {\n console.warn(\"ViewerSdk is already initialized. Skipping initialization.\");\n return ViewerSdk.instance;\n }\n if (!ViewerSdk.instance) {\n ViewerSdk.instance = new ViewerSdk();\n // Initialize parent communication - REQUIRED!\n ViewerSdk.instance.setupParentConnection()\n .then(() => {\n try {\n // Connection established with parent\n ViewerSdk.instance.initializeViewerSdk();\n }\n catch (err) {\n console.error(\"Error in initializeViewerSdk:\", err);\n }\n })\n .catch((err) => {\n console.error(\"init: Error setting up parent connection!\", err);\n console.trace(\"called from:\");\n });\n }\n if (handler) {\n ViewerSdk.instance.setHandler(handler); // Set handler if provided during initialization\n }\n // Mark as initialized\n ViewerSdk.initialized = true;\n return ViewerSdk.instance;\n }\n /**\n * Method to set or update the handler object.\n * @param handler - Custom handler for different message types\n */\n setHandler(handler) {\n this.handler = handler;\n // If INIT_ACK message was received and stored, process it now\n if (this.pendingInitAck) {\n console.debug(\"Processing pending INIT_ACK message after handler is set.\");\n this.safeInvoke(\"onInitialData\", this.handler, this.pendingInitAck);\n this.pendingInitAck = null; // Clear the stored message\n }\n }\n /**\n * Checks if the given permissions string allows reading.\n * @param perms - The permissions string.\n * @returns - True if the permission string includes read access.\n */\n canRead(perms) {\n return !!perms?.includes('r');\n }\n /**\n * Checks if the given permissions string allows writing.\n * @param perms - The permissions string.\n * @returns - True if the permission string includes write access.\n */\n canWrite(perms) {\n return !!perms?.includes('w') || !!perms?.includes('*');\n }\n // Initializes the viewer SDK, setting up the message listener and sending an initial \"ready\" message.\n initializeViewerSdk() {\n console.debug(\"initializing viewer sdk\");\n this.sendAppInit();\n }\n /**\n * Sends a request to the parent application to retrieve initial data.\n */\n requestInitialData() {\n this.sendMessage(ViewerMessageType.REQUEST_INITIAL_DATA);\n }\n /**\n * Sends a request to the parent application to save data.\n * @param doc - payload data to be saved\n * @param isDataDirty - Boolean indicating indicating modified data\n */\n requestSave(doc, isDataDirty) {\n const requestId = generateUUID();\n // Send save request with the generated requestId\n this.sendMessage(ViewerMessageType.REQUEST_SAVE, { doc, isDataDirty, requestId });\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(requestId, resolve);\n this.pendingRequests.set(requestId + '_reject', reject);\n // Timeout if the parent fails to respond in time\n setTimeout(() => {\n if (this.pendingRequests.has(requestId)) {\n this.pendingRequests.delete(requestId);\n this.pendingRequests.delete(requestId + '_reject');\n }\n }, 30000);\n });\n }\n handleOnSave(data) {\n const { requestId, status, message } = data;\n // Check if we have a pending request for this requestId\n const resolve = this.pendingRequests.get(requestId);\n const reject = this.pendingRequests.get(requestId + '_reject');\n if (resolve) {\n // If status is \"error\", reject the promise, otherwise resolve it\n if (status === \"error\") {\n reject?.({ status, message });\n }\n else {\n resolve({ status, message });\n }\n // Clean up\n this.pendingRequests.delete(requestId);\n this.pendingRequests.delete(requestId + '_reject');\n }\n }\n /**\n * Sets the viewer's \"dirty\" state, indicating modified data.\n * @param isDirty - Boolean indicating whether the viewer has modified data\n */\n setDirty(isDirty) {\n this.sendMessage(ViewerMessageType.SET_DIRTY, isDirty);\n }\n /**\n * Sends a close request to the parent, with information on whether the data is dirty.\n * @param doc - Latest document data\n * @param isDataDirty - Boolean indicating indicating modified data\n */\n sendClose(doc, isDataDirty) {\n this.sendMessage(ViewerMessageType.SEND_CLOSE, { doc, isDataDirty });\n }\n /**\n * Sends an exception to parent.\n * @param error - An error object with name and message or an error string\n */\n sendException(error) {\n this.sendMessage(ViewerMessageType.SEND_EXCEPTION, error);\n }\n // Sets up the message listener for viewer to receive messages from the parent.\n handleMessage(type, data) {\n console.debug(\"handleMessage called for:\", type, \"with data:\", data);\n if (!this.handler) {\n if (type === ClientMessageType.INIT_ACK) {\n console.warn(\"Handler not set. Storing INIT_ACK message for later processing.\");\n this.pendingInitAck = data; // Save INIT_ACK message\n }\n else {\n console.error(\"Message handler not found for type:\", type);\n }\n return;\n }\n switch (type) {\n case ClientMessageType.INIT_ACK:\n this.safeInvoke(\"onInitialData\", this.handler, data);\n break;\n case ClientMessageType.DATA_CHANGE:\n this.safeInvoke(\"onDataChange\", this.handler, data);\n break;\n case ClientMessageType.REQUEST_CLOSE:\n this.safeInvoke(\"onCloseRequest\", this.handler);\n break;\n case ClientMessageType.REQUEST_SAVE:\n this.safeInvoke(\"onSaveRequest\", this.handler);\n break;\n case ClientMessageType.SAVE_SUCCESS:\n this.handleOnSave(data);\n break;\n case ClientMessageType.SAVE_ERROR:\n this.handleOnSave(data);\n break;\n default:\n console.warn(`No handler found for message type: ${type}`);\n }\n }\n}\nViewerSdk.initialized = false;\n// Card SDK\n// Enum defining message types sent from the card to the parent application\nexport var CardMessageType;\n(function (CardMessageType) {\n CardMessageType[\"APP_READY\"] = \"APP_READY\";\n CardMessageType[\"INIT\"] = \"INIT\";\n CardMessageType[\"READ_FILE\"] = \"READ_FILE\";\n CardMessageType[\"WRITE_FILE\"] = \"WRITE_FILE\";\n CardMessageType[\"FILE_DIRTY\"] = \"FILE_DIRTY\";\n})(CardMessageType || (CardMessageType = {}));\n;\n/**\n * Use CardSdk to create webapp cards\n */\nexport class CardSdk extends DomeEmbeddedAppSdk {\n constructor() {\n super();\n this.handler = null; // Handler instance for client messages\n this.accessToken = '';\n this.cardFS = {\n readFile: this._readFile.bind(this),\n writeFile: this._writeFile.bind(this),\n };\n this.fileReadResolvers = new Map();\n this.fileWriteResolvers = new Map();\n this.pendingAcks = new Map();\n // Sets up the message listener for cards to receive messages from the parent.\n this.handleMessage = (type, data) => {\n if (!this.handler) {\n throw new Error(\"Message handler not found!\");\n }\n // Check for ACK response with messageId\n const messageId = data?.messageId;\n if (messageId && this.pendingAcks.has(messageId)) {\n const { resolve, timeout } = this.pendingAcks.get(messageId);\n clearTimeout(timeout);\n this.pendingAcks.delete(messageId);\n resolve(data);\n return;\n }\n switch (type) {\n case ClientMessageType.INIT_ACK:\n // Parent sent INIT_ACK\n console.debug(\"CardSdk: INIT_ACK received\");\n this.dataStore.kw1 = data.key_wa1;\n this.dataStore.iuid = data.iuid;\n try {\n this.cryptoA01.decrypt(this.dataStore.denc, data.key_wa1 + this.dataStore.kw2, data.iuid)\n .then((decData) => {\n console.debug(\"CardSdk: INIT_ACK: decrypted data \", decData);\n const decryptedData = JSON.parse(decData);\n if (this.handler)\n this.safeInvoke(\"onInit\", this.handler, { ...decryptedData, ui: data.ui });\n // no need for orig enc data.. free to delete it\n delete this.dataStore.denc;\n })\n .catch((err) => {\n console.error(\"Final decrypt error\", err);\n throw err;\n });\n }\n catch (err) {\n console.error(\"Decryption failed!\", err);\n this.sendEventError('dec2_failed', err.message);\n }\n break;\n case ClientMessageType.FILE_DATA:\n const fileName = data?.name;\n if (fileName && this.fileReadResolvers.has(fileName)) {\n const resolver = this.fileReadResolvers.get(fileName);\n this.fileReadResolvers.delete(fileName);\n resolver(data);\n }\n else {\n console.warn(\"CardSdk: FILE_DATA received but no resolver found for\", fileName);\n }\n break;\n case ClientMessageType.DATA_CHANGE:\n this.safeInvoke(\"onFileChange\", this.handler, data);\n case ClientMessageType.SAVE_SUCCESS:\n const savedName = data?.name;\n if (savedName && this.fileWriteResolvers.has(savedName)) {\n const { resolve } = this.fileWriteResolvers.get(savedName);\n this.fileWriteResolvers.delete(savedName);\n resolve();\n }\n else {\n console.warn(\"CardSdk: SAVE_SUCCESS received but no resolver found for\", savedName);\n }\n break;\n case ClientMessageType.SAVE_ERROR:\n const failedName = data?.name;\n if (failedName && this.fileWriteResolvers.has(failedName)) {\n const { reject } = this.fileWriteResolvers.get(failedName);\n this.fileWriteResolvers.delete(failedName);\n reject(new Error(data?.message || 'Unknown write error'));\n }\n else {\n console.warn(\"CardSdk: SAVE_ERROR received but no resolver found for\", failedName);\n }\n break;\n case ClientMessageType.ERROR:\n // Parent sent an ERROR\n this.safeInvoke(\"onError\", this.handler, data);\n break;\n case ClientMessageType.REFRESH:\n // Asking for UI refresh\n this.safeInvoke(\"onRefreshRequest\", this.handler, data);\n break;\n default:\n console.warn(`No handler found for message type: ${type}`);\n }\n };\n this.cryptoA01 = new CryptoA01();\n console.debug(\"CardSdk::constructor: done\");\n }\n /**\n * Static initialization method to get or create the singleton instance of CardSdk.\n * @param secret - The card developer secret key\n * @param handler - (Optional) Handler for different events emitted by the SDK\n * @returns The singleton CardSdk instance\n */\n static async init(secret, handler, options) {\n try {\n console.debug(\"CardSdk::init\");\n if (!CardSdk.instance) {\n CardSdk.instance = new CardSdk();\n // Initialize parent communication - REQUIRED!\n CardSdk.instance.setupParentConnection()\n .then(() => {\n // Connection established with parents..\n // Initialize SDK in async\n CardSdk.instance.initializeCardSdk(secret);\n })\n .catch((err) => {\n console.error(err);\n });\n }\n else {\n return CardSdk.instance;\n }\n // Setup handlers\n if (handler) {\n CardSdk.instance.setHandler(handler); // Set handler if provided during initialization\n }\n return CardSdk.instance;\n }\n catch (err) {\n console.error(\"CardSdk: Unrecoverable error in init\", err);\n throw err;\n }\n }\n /**\n * Method to set or update the handler object.\n * @param handler - Custom handler for different message types\n */\n setHandler(handler) {\n this.handler = handler;\n }\n /**\n * Sends a deep link request to the parent directly from the card.\n */\n openDeepLink(href) {\n if (!this.emitDeepLink(href)) {\n console.warn(\"openDeepLink ignored; provide a dome:// or intouchapp:// href\");\n }\n }\n // Function to initialize SDK after instance is created\n async initializeCardSdk(secret) {\n let TAG = \"CardSdk::initializeCardSdk:\";\n try {\n console.debug(TAG, \"enter\");\n if (!secret) {\n throw new Error(\"Invalid secret\");\n }\n // Get data from HTML\n const data_af1 = window.IT_DATA_AF1;\n if (!data_af1) {\n console.error(TAG, \"No data\");\n throw new Error('No data');\n }\n const url = window.location.href;\n console.debug(TAG, \"url:\", url);\n const urlObject = new URL(url);\n // Take the string between /wa/ and / \n let url_part = urlObject.pathname.split(\"/wa/\").filter(Boolean)[1].split(\"/\")[0];\n const ss = url_part.split('').reverse().join('').substring(4, 25);\n console.debug(TAG, \"ss:\", ss);\n if (!ss) {\n throw new Error('Cannot decrypt (1)');\n }\n const decData = await this.cryptoA01.decrypt(data_af1, secret, ss);\n try {\n const dataFromServer = JSON.parse(decData);\n console.debug(\"CardSdk: dataFromServer:\", dataFromServer);\n if (!dataFromServer.ite) {\n throw new Error(\"Invalid data\");\n }\n this.dataStore = {\n 'denc': dataFromServer.d,\n 'kw2': dataFromServer.kw2\n };\n this.accessToken = dataFromServer.ite;\n CardSdk.instance.sendInit(dataFromServer.ite);\n }\n catch (err) {\n console.error(\"Initial Decryption failed (2):\", err);\n throw err;\n }\n }\n catch (err) {\n console.error(TAG, \"Init failed:\", err);\n this.sendEventError('init_failed', err.message);\n }\n }\n async sendInit(token) {\n this.sendMessage(CardMessageType.INIT, { 'token': token, sdk: { ver: pkg.version } });\n }\n sendMessageWithAck(type, data, ackType, timeoutMs = 15000) {\n const messageId = crypto.randomUUID();\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingAcks.delete(messageId);\n reject(new Error(`${ackType} not received in time`));\n }, timeoutMs);\n this.pendingAcks.set(messageId, { resolve, reject, timeout });\n this.sendMessage(type, { ...data, messageId });\n });\n }\n _readFile(card_iuid, name) {\n return new Promise((resolve, reject) => {\n if (this.fileReadResolvers.has(name)) {\n reject(new Error(`A read request is already pending for file: ${name}`));\n return;\n }\n const timeoutId = setTimeout(() => {\n this.fileReadResolvers.delete(name);\n reject(new Error(`Timed out waiting for file: ${name}`));\n }, 15000);\n // Resolver for when FILE_DATA arrives\n this.fileReadResolvers.set(name, (data) => {\n clearTimeout(timeoutId);\n resolve(data);\n });\n // Try to read via parent\n this.sendMessageWithAck(CardMessageType.READ_FILE, { card_iuid, name }, ClientMessageType.READ_FILE_ACK)\n .catch(() => {\n // No ACK — fallback to direct API call\n clearTimeout(timeoutId);\n this.fileReadResolvers.delete(name);\n this.getDocumentAttachedToCard(card_iuid, name)\n .then(resolve)\n .catch(reject);\n });\n });\n }\n _writeFile(card_iuid, name, data) {\n return new Promise((resolve, reject) => {\n if (this.fileWriteResolvers.has(name)) {\n reject(new Error(`A write request is already pending for file: ${name}`));\n return;\n }\n const timeoutId = setTimeout(() => {\n this.fileWriteResolvers.delete(name);\n reject(new Error(`Write timed out for file: ${name}`));\n }, 15000);\n this.fileWriteResolvers.set(name, {\n resolve: () => {\n clearTimeout(timeoutId);\n this.fileWriteResolvers.delete(name);\n resolve();\n },\n reject: (err) => {\n clearTimeout(timeoutId);\n this.fileWriteResolvers.delete(name);\n reject(err);\n },\n });\n this.sendMessageWithAck(CardMessageType.WRITE_FILE, { name, data }, ClientMessageType.WRITE_FILE_ACK)\n .then(() => {\n clearTimeout(timeoutId);\n this.fileWriteResolvers.delete(name);\n resolve();\n })\n .catch(err => {\n clearTimeout(timeoutId);\n this.fileWriteResolvers.delete(name);\n this.postDocumentAttachedToCard(card_iuid, document)\n .then(() => resolve())\n .catch(reject);\n });\n });\n }\n /**\n * Converts a JavaScript object to a JSON file.\n */\n async convertToJsonFile(object, type = 'json', fileName = 'file.json') {\n const jsonString = JSON.stringify(object, null, 2);\n const jsonFileType = 'application/json';\n const blob = new Blob([jsonString], { type: jsonFileType });\n return new File([blob], fileName, { type: jsonFileType });\n }\n /**\n * Converts data to a file.\n */\n async convertToFile(data, fileName, fileType = 'json', fileMimeType) {\n if (fileType === 'json') {\n return this.convertToJsonFile(data, 'json', fileName);\n }\n else {\n const blob = new Blob([data], fileMimeType ? { type: fileMimeType } : undefined);\n return new File([blob], fileName, { type: blob.type });\n }\n }\n /**\n * Get document associated with the current card\n */\n async getDocumentAttachedToCard(card_iuid, document_name = 'default', ts_m) {\n const url = new URL(`/api/v1/documents/attached_to/${card_iuid}/`);\n url.searchParams.set('name', document_name);\n if (ts_m) {\n url.searchParams.set('ts_m', ts_m.toString());\n }\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.accessToken || ''}`,\n 'Content-Type': 'application/json'\n }\n });\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Fetch failed: ${error}`);\n }\n return response.json();\n }\n /**\n * Save document attached to current card\n */\n async postDocumentAttachedToCard(card_iuid, document) {\n const response = await fetch(`/api/v1/documents/attached_to/${card_iuid}/`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.accessToken || ''}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(document)\n });\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Post failed: ${error}`);\n }\n return response.json();\n }\n async getAllDocumentsAttachedToCard(card_iuid) {\n const response = await fetch(`/api/v1/documents/with_card/${card_iuid}/`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.accessToken || ''}`,\n 'Content-Type': 'application/json',\n },\n });\n const data = await response.json();\n return data;\n }\n async postUploadFile(name, fileObj) {\n const { type } = fileObj;\n const file = await this.convertToFile(fileObj, name, type);\n const formData = new FormData();\n formData.append('file', file);\n const response = await fetch(`/api/v1/documents/`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.accessToken || ''}`\n },\n body: formData\n });\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Upload failed: ${error}`);\n }\n return response.json();\n }\n async shareDocumentWithCard(card_iuid, documents) {\n const response = await fetch(`/api/v1/documents/with_card/${card_iuid}/`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.accessToken || ''}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(documents)\n });\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Share failed: ${error}`);\n }\n return response.json();\n }\n // Send event on error (clients will get \"onError\" event)\n sendEventError(error_code, message, data = undefined) {\n let data_to_send = {\n 'message': message,\n 'error_code': error_code,\n 'data': data\n };\n if (this.handler)\n this.safeInvoke(\"onError\", this.handler, data_to_send);\n }\n setFileDirty(data) {\n this.sendMessage(CardMessageType.FILE_DIRTY, data);\n }\n // Get username string from user object received from parent\n getUsername(userObj) {\n const nameObj = userObj?.name;\n if (nameObj && Object.values(nameObj).some(value => value)) {\n return getNameString(nameObj);\n }\n return '';\n }\n}\n","/**\n * Helper function to generate a unique requestId (UUID).\n * This uses the browser's crypto API for random UUID generation.\n */\nexport function generateUUID() {\n // If in a browser environment with crypto support (modern browsers)\n if (typeof window !== 'undefined' && window.crypto && window.crypto.randomUUID) {\n return window.crypto.randomUUID();\n }\n // Fallback for non-browser environments (e.g., Node.js)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto support\n throw new Error('UUID generation is not supported in this environment');\n}\n/**\n * Helper function to get username from user object\n * @param nameObj the user object\n */\nexport function getNameString(nameObj) {\n const { prefix = '', given = '', middle = '', family = '', suffix = '' } = nameObj || {};\n const fullname = [prefix, given, middle, family, suffix].filter(namePart => namePart).join(' ');\n return fullname.trim();\n}\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","CryptoA01","constructor","subtleCrypto","window","crypto","subtle","Error","decrypt","token","password","salt","tokenBytes","base64UrlDecode","slice","iv","ciphertext","hmacFromToken","fullKey","deriveKey","hmacKey","aesKey","splitKey","hmacInput","Uint8Array","sign","every","byte","i","decrypted","name","TextDecoder","decode","err","console","log","iterations","encoder","TextEncoder","keyMaterial","importKey","encode","hash","length","rawKey","exportKey","base64","base64String","replace","decodedString","atob","map","c","charCodeAt","ViewerMessageType","ClientMessageType","Set","location","origin","ALLOWED_DEEP_LINK_PROTOCOLS","DomeEmbeddedAppSdk","targetOrigin","isAppReady","port2","platform","handleDeepLinkClick","event","target","Element","anchor","closest","href","getAttribute","emitDeepLink","preventDefault","detectPlatform","setupDeepLinkInterception","AndroidBridge","webkit","document","addEventListener","trim","warn","protocol","split","toLowerCase","has","sendMessage","OPEN_DEEPLINK","getPlatform","type","data","message","JSON","stringify","messageHandlers","appHandler","postMessage","error","sendAppInit","INIT","sdk","ver","safeInvoke","eventName","handlerObj","handler","String","setupParentConnection","Promise","resolve","reject","receiveFromAndroid","handleMessage","receiveFromIOS","CONNECT","ports","onmessage","e","handlePortMessage","removeEventListener","notifyConnectionSuccess","CONNECTION_SUCCESS","ViewerSdk","super","pendingRequests","Map","pendingInitAck","init","initialized","instance","then","initializeViewerSdk","catch","trace","setHandler","canRead","perms","includes","canWrite","requestInitialData","REQUEST_INITIAL_DATA","requestSave","doc","isDataDirty","requestId","randomUUID","generateUUID","REQUEST_SAVE","set","setTimeout","delete","handleOnSave","status","setDirty","isDirty","SET_DIRTY","sendClose","SEND_CLOSE","sendException","SEND_EXCEPTION","INIT_ACK","DATA_CHANGE","REQUEST_CLOSE","SAVE_SUCCESS","SAVE_ERROR","CardMessageType","CardSdk","accessToken","cardFS","readFile","_readFile","bind","writeFile","_writeFile","fileReadResolvers","fileWriteResolvers","pendingAcks","messageId","timeout","clearTimeout","dataStore","kw1","key_wa1","iuid","cryptoA01","denc","kw2","decData","decryptedData","parse","ui","sendEventError","FILE_DATA","fileName","resolver","savedName","failedName","ERROR","REFRESH","secret","options","initializeCardSdk","openDeepLink","TAG","data_af1","IT_DATA_AF1","url","ss","URL","pathname","filter","Boolean","reverse","join","substring","dataFromServer","ite","d","sendInit","sendMessageWithAck","ackType","timeoutMs","card_iuid","timeoutId","READ_FILE","READ_FILE_ACK","getDocumentAttachedToCard","WRITE_FILE","WRITE_FILE_ACK","postDocumentAttachedToCard","convertToJsonFile","object","jsonString","jsonFileType","blob","Blob","File","convertToFile","fileType","fileMimeType","undefined","document_name","ts_m","searchParams","toString","response","fetch","method","headers","ok","text","json","body","getAllDocumentsAttachedToCard","postUploadFile","fileObj","file","formData","FormData","append","shareDocumentWithCard","documents","error_code","data_to_send","setFileDirty","FILE_DIRTY","getUsername","userObj","nameObj","values","some","prefix","given","middle","family","suffix","namePart","getNameString"],"sourceRoot":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dome-embedded-app-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"build:webpack": "webpack --config webpack.config.ts",
|
|
19
19
|
"build": "npm run build:tsc && npm run build:webpack",
|
|
20
20
|
"release": "npm run build && npm publish",
|
|
21
|
+
"version:patch": "npm version patch && git push && git push --tags && npm run release",
|
|
22
|
+
"version:minor": "npm version minor && git push && git push --tags && npm run release",
|
|
23
|
+
"version:major": "npm version major && git push && git push --tags && npm run release",
|
|
24
|
+
"test-pack": "npm pack --dry-run",
|
|
21
25
|
"watch": "webpack --watch"
|
|
22
26
|
},
|
|
23
27
|
"publishConfig": {
|