@tern-secure/shared 1.1.0 → 1.1.1
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/cookie.d.mts +12 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.js +54 -0
- package/dist/cookie.js.map +1 -0
- package/dist/cookie.mjs +19 -0
- package/dist/cookie.mjs.map +1 -0
- package/dist/derivedAuthState.js +0 -3
- package/dist/derivedAuthState.js.map +1 -1
- package/dist/derivedAuthState.mjs +0 -3
- package/dist/derivedAuthState.mjs.map +1 -1
- package/dist/loadTernUIScript.d.mts +0 -1
- package/dist/loadTernUIScript.d.ts +0 -1
- package/dist/loadTernUIScript.js +1 -1
- package/dist/loadTernUIScript.js.map +1 -1
- package/dist/loadTernUIScript.mjs +1 -1
- package/dist/loadTernUIScript.mjs.map +1 -1
- package/dist/serviceWorker.d.mts +13 -0
- package/dist/serviceWorker.d.ts +13 -0
- package/dist/serviceWorker.js +93 -0
- package/dist/serviceWorker.js.map +1 -0
- package/dist/serviceWorker.mjs +66 -0
- package/dist/serviceWorker.mjs.map +1 -0
- package/dist/types/cookie.d.ts +12 -0
- package/dist/types/cookie.d.ts.map +1 -0
- package/dist/types/derivedAuthState.d.ts.map +1 -1
- package/dist/types/loadTernUIScript.d.ts +0 -1
- package/dist/types/loadTernUIScript.d.ts.map +1 -1
- package/dist/types/serviceWorker.d.ts +12 -0
- package/dist/types/serviceWorker.d.ts.map +1 -0
- package/package.json +7 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type removeCookieParams = {
|
|
2
|
+
path?: string;
|
|
3
|
+
domain?: string;
|
|
4
|
+
};
|
|
5
|
+
declare function cookieHandler(cookieNanme: string): {
|
|
6
|
+
set(value: string, options?: Cookies.CookieAttributes): void;
|
|
7
|
+
get(): string | undefined;
|
|
8
|
+
remove(removeCookieParams?: removeCookieParams): void;
|
|
9
|
+
};
|
|
10
|
+
type CookieAttributes = Cookies.CookieAttributes;
|
|
11
|
+
|
|
12
|
+
export { type CookieAttributes, cookieHandler };
|
package/dist/cookie.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type removeCookieParams = {
|
|
2
|
+
path?: string;
|
|
3
|
+
domain?: string;
|
|
4
|
+
};
|
|
5
|
+
declare function cookieHandler(cookieNanme: string): {
|
|
6
|
+
set(value: string, options?: Cookies.CookieAttributes): void;
|
|
7
|
+
get(): string | undefined;
|
|
8
|
+
remove(removeCookieParams?: removeCookieParams): void;
|
|
9
|
+
};
|
|
10
|
+
type CookieAttributes = Cookies.CookieAttributes;
|
|
11
|
+
|
|
12
|
+
export { type CookieAttributes, cookieHandler };
|
package/dist/cookie.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/cookie.ts
|
|
31
|
+
var cookie_exports = {};
|
|
32
|
+
__export(cookie_exports, {
|
|
33
|
+
cookieHandler: () => cookieHandler
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(cookie_exports);
|
|
36
|
+
var import_js_cookie = __toESM(require("js-cookie"));
|
|
37
|
+
function cookieHandler(cookieNanme) {
|
|
38
|
+
return {
|
|
39
|
+
set(value, options = {}) {
|
|
40
|
+
import_js_cookie.default.set(cookieNanme, value, options);
|
|
41
|
+
},
|
|
42
|
+
get() {
|
|
43
|
+
return import_js_cookie.default.get(cookieNanme);
|
|
44
|
+
},
|
|
45
|
+
remove(removeCookieParams) {
|
|
46
|
+
import_js_cookie.default.remove(cookieNanme, removeCookieParams);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
51
|
+
0 && (module.exports = {
|
|
52
|
+
cookieHandler
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=cookie.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cookie.ts"],"sourcesContent":["import Cookies from 'js-cookie';\n\ntype removeCookieParams = {\n path?: string;\n domain?: string;\n}\n\nexport function cookieHandler(cookieNanme: string) {\n return {\n set(value: string, options: Cookies.CookieAttributes = {}): void {\n Cookies.set(cookieNanme, value, options);\n },\n get() {\n return Cookies.get(cookieNanme);\n },\n remove(removeCookieParams?: removeCookieParams) {\n Cookies.remove(cookieNanme, removeCookieParams)\n }\n }\n}\n\nexport type CookieAttributes = Cookies.CookieAttributes;"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAoB;AAOb,SAAS,cAAc,aAAqB;AAC/C,SAAO;AAAA,IACH,IAAI,OAAe,UAAoC,CAAC,GAAS;AAC7D,uBAAAA,QAAQ,IAAI,aAAa,OAAO,OAAO;AAAA,IAC3C;AAAA,IACA,MAAM;AACF,aAAO,iBAAAA,QAAQ,IAAI,WAAW;AAAA,IAClC;AAAA,IACA,OAAO,oBAAyC;AAC5C,uBAAAA,QAAQ,OAAO,aAAa,kBAAkB;AAAA,IAClD;AAAA,EACJ;AACJ;","names":["Cookies"]}
|
package/dist/cookie.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/cookie.ts
|
|
2
|
+
import Cookies from "js-cookie";
|
|
3
|
+
function cookieHandler(cookieNanme) {
|
|
4
|
+
return {
|
|
5
|
+
set(value, options = {}) {
|
|
6
|
+
Cookies.set(cookieNanme, value, options);
|
|
7
|
+
},
|
|
8
|
+
get() {
|
|
9
|
+
return Cookies.get(cookieNanme);
|
|
10
|
+
},
|
|
11
|
+
remove(removeCookieParams) {
|
|
12
|
+
Cookies.remove(cookieNanme, removeCookieParams);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
cookieHandler
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=cookie.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cookie.ts"],"sourcesContent":["import Cookies from 'js-cookie';\n\ntype removeCookieParams = {\n path?: string;\n domain?: string;\n}\n\nexport function cookieHandler(cookieNanme: string) {\n return {\n set(value: string, options: Cookies.CookieAttributes = {}): void {\n Cookies.set(cookieNanme, value, options);\n },\n get() {\n return Cookies.get(cookieNanme);\n },\n remove(removeCookieParams?: removeCookieParams) {\n Cookies.remove(cookieNanme, removeCookieParams)\n }\n }\n}\n\nexport type CookieAttributes = Cookies.CookieAttributes;"],"mappings":";AAAA,OAAO,aAAa;AAOb,SAAS,cAAc,aAAqB;AAC/C,SAAO;AAAA,IACH,IAAI,OAAe,UAAoC,CAAC,GAAS;AAC7D,cAAQ,IAAI,aAAa,OAAO,OAAO;AAAA,IAC3C;AAAA,IACA,MAAM;AACF,aAAO,QAAQ,IAAI,WAAW;AAAA,IAClC;AAAA,IACA,OAAO,oBAAyC;AAC5C,cAAQ,OAAO,aAAa,kBAAkB;AAAA,IAClD;AAAA,EACJ;AACJ;","names":[]}
|
package/dist/derivedAuthState.js
CHANGED
|
@@ -34,7 +34,6 @@ var DEFAULT_TERN_SECURE_STATE = {
|
|
|
34
34
|
token: null,
|
|
35
35
|
email: null,
|
|
36
36
|
status: "loading",
|
|
37
|
-
requiresVerification: false,
|
|
38
37
|
user: null
|
|
39
38
|
};
|
|
40
39
|
var deriveAuthState = (internalState) => {
|
|
@@ -51,7 +50,6 @@ var deriveAuthState = (internalState) => {
|
|
|
51
50
|
const email = internalState.email || null;
|
|
52
51
|
const error = internalState.error || null;
|
|
53
52
|
const status = internalState.status || "loading";
|
|
54
|
-
const requiresVerification = internalState.requiresVerification || false;
|
|
55
53
|
const user = internalState.user || null;
|
|
56
54
|
return {
|
|
57
55
|
userId,
|
|
@@ -63,7 +61,6 @@ var deriveAuthState = (internalState) => {
|
|
|
63
61
|
email,
|
|
64
62
|
error,
|
|
65
63
|
status,
|
|
66
|
-
requiresVerification,
|
|
67
64
|
user
|
|
68
65
|
};
|
|
69
66
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/derivedAuthState.ts"],"sourcesContent":["import { \n TernSecureState,\n TernSecureUser\n //DEFAULT_TERN_SECURE_STATE\n} from \"@tern-secure/types\";\n\n\n/**\n * Default state for derived auth state\n */\n//export const DEFAULT_DERIVED_AUTH_STATE = DEFAULT_TERN_SECURE_STATE\n\nexport const DEFAULT_TERN_SECURE_STATE: TernSecureState = {\n userId: null,\n isLoaded: false,\n error: null,\n isValid: false,\n isVerified: false,\n isAuthenticated: false,\n token: null,\n email: null,\n status: \"loading\",\n
|
|
1
|
+
{"version":3,"sources":["../src/derivedAuthState.ts"],"sourcesContent":["import { \n TernSecureState,\n TernSecureUser\n //DEFAULT_TERN_SECURE_STATE\n} from \"@tern-secure/types\";\n\n\n/**\n * Default state for derived auth state\n */\n//export const DEFAULT_DERIVED_AUTH_STATE = DEFAULT_TERN_SECURE_STATE\n\nexport const DEFAULT_TERN_SECURE_STATE: TernSecureState = {\n userId: null,\n isLoaded: false,\n error: null,\n isValid: false,\n isVerified: false,\n isAuthenticated: false,\n token: null,\n email: null,\n status: \"loading\",\n user: null\n};\n\n\nexport const deriveAuthState = (internalState: TernSecureState | undefined ): TernSecureState => {\n \n if (!internalState) {\n console.warn('[deriveAuthState] internalState is undefined or null. Returning default state.');\n return DEFAULT_TERN_SECURE_STATE\n }\n\n const userId = internalState.userId || null;\n const isLoaded = internalState.isLoaded || false;\n const isValid = internalState.isValid || false;\n const isVerified = internalState.isVerified || false;\n const isAuthenticated = internalState.isAuthenticated || false;\n const token = internalState.token || null;\n const email = internalState.email || null;\n const error = internalState.error || null;\n const status = internalState.status || \"loading\";\n const user = internalState.user || null;\n\n return {\n userId,\n isLoaded,\n isValid,\n isVerified,\n isAuthenticated,\n token,\n email,\n error,\n status,\n user\n }\n};"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYO,IAAM,4BAA6C;AAAA,EACxD,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AAGO,IAAM,kBAAkB,CAAC,kBAAiE;AAE/F,MAAI,CAAC,eAAe;AAClB,YAAQ,KAAK,gFAAgF;AAC7F,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,cAAc,UAAU;AACvC,QAAM,WAAW,cAAc,YAAY;AAC3C,QAAM,UAAU,cAAc,WAAW;AACzC,QAAM,aAAa,cAAc,cAAc;AAC/C,QAAM,kBAAkB,cAAc,mBAAmB;AACzD,QAAM,QAAQ,cAAc,SAAS;AACrC,QAAM,QAAQ,cAAc,SAAS;AACrC,QAAM,QAAQ,cAAc,SAAS;AACrC,QAAM,SAAS,cAAc,UAAU;AACvC,QAAM,OAAO,cAAc,QAAQ;AAEnC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -9,7 +9,6 @@ var DEFAULT_TERN_SECURE_STATE = {
|
|
|
9
9
|
token: null,
|
|
10
10
|
email: null,
|
|
11
11
|
status: "loading",
|
|
12
|
-
requiresVerification: false,
|
|
13
12
|
user: null
|
|
14
13
|
};
|
|
15
14
|
var deriveAuthState = (internalState) => {
|
|
@@ -26,7 +25,6 @@ var deriveAuthState = (internalState) => {
|
|
|
26
25
|
const email = internalState.email || null;
|
|
27
26
|
const error = internalState.error || null;
|
|
28
27
|
const status = internalState.status || "loading";
|
|
29
|
-
const requiresVerification = internalState.requiresVerification || false;
|
|
30
28
|
const user = internalState.user || null;
|
|
31
29
|
return {
|
|
32
30
|
userId,
|
|
@@ -38,7 +36,6 @@ var deriveAuthState = (internalState) => {
|
|
|
38
36
|
email,
|
|
39
37
|
error,
|
|
40
38
|
status,
|
|
41
|
-
requiresVerification,
|
|
42
39
|
user
|
|
43
40
|
};
|
|
44
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/derivedAuthState.ts"],"sourcesContent":["import { \n TernSecureState,\n TernSecureUser\n //DEFAULT_TERN_SECURE_STATE\n} from \"@tern-secure/types\";\n\n\n/**\n * Default state for derived auth state\n */\n//export const DEFAULT_DERIVED_AUTH_STATE = DEFAULT_TERN_SECURE_STATE\n\nexport const DEFAULT_TERN_SECURE_STATE: TernSecureState = {\n userId: null,\n isLoaded: false,\n error: null,\n isValid: false,\n isVerified: false,\n isAuthenticated: false,\n token: null,\n email: null,\n status: \"loading\",\n
|
|
1
|
+
{"version":3,"sources":["../src/derivedAuthState.ts"],"sourcesContent":["import { \n TernSecureState,\n TernSecureUser\n //DEFAULT_TERN_SECURE_STATE\n} from \"@tern-secure/types\";\n\n\n/**\n * Default state for derived auth state\n */\n//export const DEFAULT_DERIVED_AUTH_STATE = DEFAULT_TERN_SECURE_STATE\n\nexport const DEFAULT_TERN_SECURE_STATE: TernSecureState = {\n userId: null,\n isLoaded: false,\n error: null,\n isValid: false,\n isVerified: false,\n isAuthenticated: false,\n token: null,\n email: null,\n status: \"loading\",\n user: null\n};\n\n\nexport const deriveAuthState = (internalState: TernSecureState | undefined ): TernSecureState => {\n \n if (!internalState) {\n console.warn('[deriveAuthState] internalState is undefined or null. Returning default state.');\n return DEFAULT_TERN_SECURE_STATE\n }\n\n const userId = internalState.userId || null;\n const isLoaded = internalState.isLoaded || false;\n const isValid = internalState.isValid || false;\n const isVerified = internalState.isVerified || false;\n const isAuthenticated = internalState.isAuthenticated || false;\n const token = internalState.token || null;\n const email = internalState.email || null;\n const error = internalState.error || null;\n const status = internalState.status || \"loading\";\n const user = internalState.user || null;\n\n return {\n userId,\n isLoaded,\n isValid,\n isVerified,\n isAuthenticated,\n token,\n email,\n error,\n status,\n user\n }\n};"],"mappings":";AAYO,IAAM,4BAA6C;AAAA,EACxD,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AAGO,IAAM,kBAAkB,CAAC,kBAAiE;AAE/F,MAAI,CAAC,eAAe;AAClB,YAAQ,KAAK,gFAAgF;AAC7F,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,cAAc,UAAU;AACvC,QAAM,WAAW,cAAc,YAAY;AAC3C,QAAM,UAAU,cAAc,WAAW;AACzC,QAAM,aAAa,cAAc,cAAc;AAC/C,QAAM,kBAAkB,cAAc,mBAAmB;AACzD,QAAM,QAAQ,cAAc,SAAS;AACrC,QAAM,QAAQ,cAAc,SAAS;AACrC,QAAM,QAAQ,cAAc,SAAS;AACrC,QAAM,SAAS,cAAc,UAAU;AACvC,QAAM,OAAO,cAAc,QAAQ;AAEnC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
package/dist/loadTernUIScript.js
CHANGED
|
@@ -105,7 +105,7 @@ var loadTernUIScript = async (options) => {
|
|
|
105
105
|
});
|
|
106
106
|
};
|
|
107
107
|
var ternUIgetScriptUrl = (options) => {
|
|
108
|
-
const isTernSecureDev =
|
|
108
|
+
const isTernSecureDev = options == null ? void 0 : options.isTernSecureDev;
|
|
109
109
|
const version = (options == null ? void 0 : options.version) || process.env.TERN_UI_VERSION || "latest";
|
|
110
110
|
if (isTernSecureDev) {
|
|
111
111
|
const localHost = process.env.TERN_UI_HOST || "localhost";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/loadTernUIScript.ts","../src/loadScript.ts"],"sourcesContent":["import type { TernSecureInstanceTreeOptions } from \"@tern-secure/types\";\nimport { loadScript } from \"./loadScript\";\n\n\nexport type LoadTernUISCriptOptions = TernSecureInstanceTreeOptions & {\n apiKey?: string;\n customDomain?: string;\n proxyUrl?: string;\n version?: string;\n
|
|
1
|
+
{"version":3,"sources":["../src/loadTernUIScript.ts","../src/loadScript.ts"],"sourcesContent":["import type { TernSecureInstanceTreeOptions } from \"@tern-secure/types\";\nimport { loadScript } from \"./loadScript\";\n\n\nexport type LoadTernUISCriptOptions = TernSecureInstanceTreeOptions & {\n apiKey?: string;\n customDomain?: string;\n proxyUrl?: string;\n version?: string;\n scriptHost?: string;\n localPort?: string;\n nonce?: string;\n}\n\n\nexport const loadTernUIScript = async (options?: LoadTernUISCriptOptions) => {\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-ternui-script]');\n console.log('[TernSecure-shared] Existing script:', existingScript);\n\n if (existingScript) {\n return new Promise((resolve, reject) => {\n existingScript.addEventListener('load', () => {\n resolve(existingScript);\n });\n\n existingScript.addEventListener('error', (error) => {\n reject(error);\n });\n });\n }\n\n if (!options?.customDomain) {\n throw new Error('TernUI script requires a custom domain or proxy URL to be specified in options.');\n }\n \n return loadScript(ternUIgetScriptUrl(options), {\n async: true,\n //crossOrigin: undefined,\n beforeLoad: beforeLoadWithOptions(options)\n }).catch((error) => {\n console.error('[TernSecure] Failed to load TernUI script:', error);\n throw new Error('Failed to load TernUI script');\n });\n }\n\nexport const ternUIgetScriptUrl = (options?: LoadTernUISCriptOptions) => {\n const isTernSecureDev = options?.isTernSecureDev\n const version = options?.version || process.env.TERN_UI_VERSION || 'latest';\n\n if ( isTernSecureDev) {\n const localHost = process.env.TERN_UI_HOST || 'localhost';\n const localPort = options?.localPort || process.env.TERN_UI_PORT || '4000';\n return `http://${localHost}:${localPort}/ternsecure.browser.js`;\n //return `http://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n }\n return `https://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n\n //const ternsecureCDN = options?.customDomain || \n //(options?.proxyUrl && new URL(options.proxyUrl).host) || 'cdn.tern-secure.com';\n //return `${ternsecureCDN}/ternsecure.browser.js`;\n //return `https://${ternsecureCDN}/npm/@ternsecure/tern-ui@${version}/dist/ternsecure.browser.js`;\n\n}\n\n \nconst beforeLoadWithOptions = (options?: LoadTernUISCriptOptions) => (script: HTMLScriptElement) => {\n const attributes = constructScriptAttributes(options);\n Object.entries(attributes).forEach(([key, value]) => {\n if (value) script.setAttribute(key, String(value));\n });\n console.log('[TernSecure-shared] Script attributes set:', attributes);\n};\n\nexport const constructScriptAttributes = (options?: LoadTernUISCriptOptions) => {\n return {\n 'data-domain': options?.customDomain || '',\n 'data-apikey': options?.apiKey || '',\n 'data-environment': process.env.NODE_ENV || 'development',\n 'data-proxyUrl': options?.proxyUrl || '',\n 'data-version': options?.version || process.env.TERN_UI_VERSION || 'latest',\n ...(options?.nonce ? { nonce: options.nonce } : {})\n };\n};"," import { retry } from './retry'\n\n type LoadScriptOptions = {\n async?: boolean;\n defer?: boolean;\n crossOrigin?: 'anonymous' | 'use-credentials';\n nonce?: string;\n beforeLoad?: (script: HTMLScriptElement) => void;\n };\n\n export async function loadScript(src ='', options: LoadScriptOptions): Promise<HTMLScriptElement> {\n const { async, defer, crossOrigin, nonce, beforeLoad } = options;\n\n const load = () => {\n return new Promise<HTMLScriptElement>((resolve, reject) => {\n if (!src) {\n reject(new Error('Script src is required'));\n }\n\n if (!document || !document.body) {\n reject(new Error('Document body is not available'));\n }\n\n const script = document.createElement('script');\n\n if (crossOrigin) script.setAttribute('crossorigin', crossOrigin);\n script.async = async || false;\n script.defer = defer || false;\n\n let resolved = false;\n let timeoutId: NodeJS.Timeout | null = null;\n\n const cleanup = () => {\n script.removeEventListener('load', handleLoad);\n script.removeEventListener('error', handleError);\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n \n const handleLoad = () => {\n if (resolved) return;\n console.log(`[loadScript] Script loaded successfully: ${src}`);\n\n resolved = true;\n cleanup();\n resolve(script);\n };\n \n const handleError = (error: ErrorEvent) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n script.remove();\n console.error(`[loadScript] Failed to load script: ${src}`, error);\n reject(new Error(`Failed to load script: ${src}, Error: ${error.message || error}`));\n };\n \n script.addEventListener('load', handleLoad);\n script.addEventListener('error', handleError);\n\n script.src = src;\n script.nonce = nonce;\n beforeLoad?.(script);\n\n console.log(`[loadScript] Appending script to document body: ${src}`);\n document.body.appendChild(script)\n });\n };\n\n return load()\n\n //return retry(load, { shouldRetry: (_, iterations) => iterations <=5 });\n }"],"mappings":"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","names":[]}
|
|
@@ -29,7 +29,7 @@ var loadTernUIScript = async (options) => {
|
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
31
|
var ternUIgetScriptUrl = (options) => {
|
|
32
|
-
const isTernSecureDev =
|
|
32
|
+
const isTernSecureDev = options == null ? void 0 : options.isTernSecureDev;
|
|
33
33
|
const version = (options == null ? void 0 : options.version) || process.env.TERN_UI_VERSION || "latest";
|
|
34
34
|
if (isTernSecureDev) {
|
|
35
35
|
const localHost = process.env.TERN_UI_HOST || "localhost";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/loadTernUIScript.ts"],"sourcesContent":["import type { TernSecureInstanceTreeOptions } from \"@tern-secure/types\";\nimport { loadScript } from \"./loadScript\";\n\n\nexport type LoadTernUISCriptOptions = TernSecureInstanceTreeOptions & {\n apiKey?: string;\n customDomain?: string;\n proxyUrl?: string;\n version?: string;\n
|
|
1
|
+
{"version":3,"sources":["../src/loadTernUIScript.ts"],"sourcesContent":["import type { TernSecureInstanceTreeOptions } from \"@tern-secure/types\";\nimport { loadScript } from \"./loadScript\";\n\n\nexport type LoadTernUISCriptOptions = TernSecureInstanceTreeOptions & {\n apiKey?: string;\n customDomain?: string;\n proxyUrl?: string;\n version?: string;\n scriptHost?: string;\n localPort?: string;\n nonce?: string;\n}\n\n\nexport const loadTernUIScript = async (options?: LoadTernUISCriptOptions) => {\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-ternui-script]');\n console.log('[TernSecure-shared] Existing script:', existingScript);\n\n if (existingScript) {\n return new Promise((resolve, reject) => {\n existingScript.addEventListener('load', () => {\n resolve(existingScript);\n });\n\n existingScript.addEventListener('error', (error) => {\n reject(error);\n });\n });\n }\n\n if (!options?.customDomain) {\n throw new Error('TernUI script requires a custom domain or proxy URL to be specified in options.');\n }\n \n return loadScript(ternUIgetScriptUrl(options), {\n async: true,\n //crossOrigin: undefined,\n beforeLoad: beforeLoadWithOptions(options)\n }).catch((error) => {\n console.error('[TernSecure] Failed to load TernUI script:', error);\n throw new Error('Failed to load TernUI script');\n });\n }\n\nexport const ternUIgetScriptUrl = (options?: LoadTernUISCriptOptions) => {\n const isTernSecureDev = options?.isTernSecureDev\n const version = options?.version || process.env.TERN_UI_VERSION || 'latest';\n\n if ( isTernSecureDev) {\n const localHost = process.env.TERN_UI_HOST || 'localhost';\n const localPort = options?.localPort || process.env.TERN_UI_PORT || '4000';\n return `http://${localHost}:${localPort}/ternsecure.browser.js`;\n //return `http://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n }\n return `https://cdn.lifesprintcare.ca/dist/ternsecure.browser.js`\n\n //const ternsecureCDN = options?.customDomain || \n //(options?.proxyUrl && new URL(options.proxyUrl).host) || 'cdn.tern-secure.com';\n //return `${ternsecureCDN}/ternsecure.browser.js`;\n //return `https://${ternsecureCDN}/npm/@ternsecure/tern-ui@${version}/dist/ternsecure.browser.js`;\n\n}\n\n \nconst beforeLoadWithOptions = (options?: LoadTernUISCriptOptions) => (script: HTMLScriptElement) => {\n const attributes = constructScriptAttributes(options);\n Object.entries(attributes).forEach(([key, value]) => {\n if (value) script.setAttribute(key, String(value));\n });\n console.log('[TernSecure-shared] Script attributes set:', attributes);\n};\n\nexport const constructScriptAttributes = (options?: LoadTernUISCriptOptions) => {\n return {\n 'data-domain': options?.customDomain || '',\n 'data-apikey': options?.apiKey || '',\n 'data-environment': process.env.NODE_ENV || 'development',\n 'data-proxyUrl': options?.proxyUrl || '',\n 'data-version': options?.version || process.env.TERN_UI_VERSION || 'latest',\n ...(options?.nonce ? { nonce: options.nonce } : {})\n };\n};"],"mappings":";;;;;AAeO,IAAM,mBAAmB,OAAO,YAAsC;AAC3E,QAAM,iBAAkB,SAAS,cAAiC,4BAA4B;AAC9F,UAAQ,IAAI,wCAAwC,cAAc;AAElE,MAAI,gBAAgB;AAClB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,qBAAe,iBAAiB,QAAQ,MAAM;AAC5C,gBAAQ,cAAc;AAAA,MACxB,CAAC;AAED,qBAAe,iBAAiB,SAAS,CAAC,UAAU;AAClD,eAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,MAAI,EAAC,mCAAS,eAAc;AAC1B,UAAM,IAAI,MAAM,iFAAiF;AAAA,EACnG;AAEA,SAAO,WAAW,mBAAmB,OAAO,GAAG;AAAA,IAC7C,OAAO;AAAA;AAAA,IAEN,YAAY,sBAAsB,OAAO;AAAA,EAC1C,CAAC,EAAE,MAAM,CAAC,UAAU;AAClB,YAAQ,MAAM,8CAA8C,KAAK;AACjE,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD,CAAC;AACH;AAEK,IAAM,qBAAqB,CAAC,YAAsC;AACrE,QAAM,kBAAkB,mCAAS;AACjC,QAAM,WAAU,mCAAS,YAAW,QAAQ,IAAI,mBAAmB;AAEnE,MAAK,iBAAiB;AAClB,UAAM,YAAY,QAAQ,IAAI,gBAAgB;AAC9C,UAAM,aAAY,mCAAS,cAAa,QAAQ,IAAI,gBAAgB;AACpE,WAAO,UAAU,SAAS,IAAI,SAAS;AAAA,EAE3C;AACA,SAAO;AAOX;AAGA,IAAM,wBAAwB,CAAC,YAAsC,CAAC,WAA8B;AAClG,QAAM,aAAa,0BAA0B,OAAO;AACpD,SAAO,QAAQ,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACnD,QAAI,MAAO,QAAO,aAAa,KAAK,OAAO,KAAK,CAAC;AAAA,EACnD,CAAC;AACD,UAAQ,IAAI,8CAA8C,UAAU;AACtE;AAEO,IAAM,4BAA4B,CAAC,YAAsC;AAC9E,SAAO;AAAA,IACL,gBAAe,mCAAS,iBAAgB;AAAA,IACxC,gBAAe,mCAAS,WAAU;AAAA,IAClC,oBAAoB,QAAQ,IAAI,YAAY;AAAA,IAC5C,kBAAiB,mCAAS,aAAY;AAAA,IACtC,iBAAgB,mCAAS,YAAW,QAAQ,IAAI,mBAAmB;AAAA,IACnE,IAAI,mCAAS,SAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,EACnD;AACF;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type ServiceWorkerOptions = {
|
|
2
|
+
firebaseConfig: Record<string, any>;
|
|
3
|
+
scope?: string;
|
|
4
|
+
updateViaCache?: 'imports' | 'all' | 'none';
|
|
5
|
+
domain?: string;
|
|
6
|
+
isTernSecureDev?: boolean;
|
|
7
|
+
localPort?: string;
|
|
8
|
+
};
|
|
9
|
+
declare const reg: (opt: ServiceWorkerOptions) => void;
|
|
10
|
+
declare const registerServiceWorker: (options: ServiceWorkerOptions) => Promise<ServiceWorkerRegistration | null>;
|
|
11
|
+
declare const unregisterServiceWorker: () => Promise<boolean>;
|
|
12
|
+
|
|
13
|
+
export { type ServiceWorkerOptions, reg, registerServiceWorker, unregisterServiceWorker };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type ServiceWorkerOptions = {
|
|
2
|
+
firebaseConfig: Record<string, any>;
|
|
3
|
+
scope?: string;
|
|
4
|
+
updateViaCache?: 'imports' | 'all' | 'none';
|
|
5
|
+
domain?: string;
|
|
6
|
+
isTernSecureDev?: boolean;
|
|
7
|
+
localPort?: string;
|
|
8
|
+
};
|
|
9
|
+
declare const reg: (opt: ServiceWorkerOptions) => void;
|
|
10
|
+
declare const registerServiceWorker: (options: ServiceWorkerOptions) => Promise<ServiceWorkerRegistration | null>;
|
|
11
|
+
declare const unregisterServiceWorker: () => Promise<boolean>;
|
|
12
|
+
|
|
13
|
+
export { type ServiceWorkerOptions, reg, registerServiceWorker, unregisterServiceWorker };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/serviceWorker.ts
|
|
21
|
+
var serviceWorker_exports = {};
|
|
22
|
+
__export(serviceWorker_exports, {
|
|
23
|
+
reg: () => reg,
|
|
24
|
+
registerServiceWorker: () => registerServiceWorker,
|
|
25
|
+
unregisterServiceWorker: () => unregisterServiceWorker
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(serviceWorker_exports);
|
|
28
|
+
var getUrlEndpoint = () => {
|
|
29
|
+
const isLocalhost = window.location.hostname === "localhost";
|
|
30
|
+
return isLocalhost ? "http://localhost:3000" : `${window.location.origin}`;
|
|
31
|
+
};
|
|
32
|
+
var getServiceWorkerUrl = (options) => {
|
|
33
|
+
const { firebaseConfig, domain, isTernSecureDev, localPort } = options;
|
|
34
|
+
const serializedConfig = encodeURIComponent(JSON.stringify(firebaseConfig));
|
|
35
|
+
let baseUrl;
|
|
36
|
+
if (isTernSecureDev) {
|
|
37
|
+
const localHost = process.env.TERN_UI_HOST || "localhost";
|
|
38
|
+
const port = localPort || process.env.TERN_UI_PORT || "3000";
|
|
39
|
+
baseUrl = `http://${localHost}:${port}`;
|
|
40
|
+
} else {
|
|
41
|
+
baseUrl = domain || getUrlEndpoint();
|
|
42
|
+
}
|
|
43
|
+
return `${baseUrl}/service-worker.js?firebaseConfig=${serializedConfig}`;
|
|
44
|
+
};
|
|
45
|
+
var reg = (opt) => {
|
|
46
|
+
const { firebaseConfig } = opt;
|
|
47
|
+
if ("serviceWorker" in navigator) {
|
|
48
|
+
const serializedFirebaseConfig = encodeURIComponent(JSON.stringify(firebaseConfig));
|
|
49
|
+
const serviceWorkerUrl = getServiceWorkerUrl(opt);
|
|
50
|
+
navigator.serviceWorker.register(serviceWorkerUrl).then((registration) => console.log("scope is: ", registration.scope));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var registerServiceWorker = async (options) => {
|
|
54
|
+
if (!("serviceWorker" in navigator)) {
|
|
55
|
+
console.warn("[ServiceWorker] Service workers are not supported");
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const { scope = "/", updateViaCache = "imports" } = options;
|
|
59
|
+
try {
|
|
60
|
+
const serviceWorkerUrl = getServiceWorkerUrl(options);
|
|
61
|
+
const registration = await navigator.serviceWorker.register(serviceWorkerUrl, {
|
|
62
|
+
scope,
|
|
63
|
+
updateViaCache
|
|
64
|
+
});
|
|
65
|
+
console.log("[ServiceWorker] Registration successful:", registration);
|
|
66
|
+
return registration;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error("[ServiceWorker] Registration failed:", error);
|
|
69
|
+
throw new Error(`Failed to register service worker: ${error}`);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var unregisterServiceWorker = async () => {
|
|
73
|
+
if (!("serviceWorker" in navigator)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const registrations = await navigator.serviceWorker.getRegistrations();
|
|
78
|
+
const unregisterPromises = registrations.map((registration) => registration.unregister());
|
|
79
|
+
await Promise.all(unregisterPromises);
|
|
80
|
+
console.log("[ServiceWorker] All service workers unregistered");
|
|
81
|
+
return true;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error("[ServiceWorker] Failed to unregister service workers:", error);
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
88
|
+
0 && (module.exports = {
|
|
89
|
+
reg,
|
|
90
|
+
registerServiceWorker,
|
|
91
|
+
unregisterServiceWorker
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=serviceWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/serviceWorker.ts"],"sourcesContent":["export type ServiceWorkerOptions = {\n firebaseConfig: Record<string, any>;\n scope?: string;\n updateViaCache?: 'imports' | 'all' | 'none';\n domain?: string;\n isTernSecureDev?: boolean;\n localPort?: string;\n};\n\nconst getUrlEndpoint = (): string => {\n const isLocalhost = window.location.hostname === 'localhost';\n return isLocalhost ? 'http://localhost:3000' : `${window.location.origin}`;\n }\n\nconst getServiceWorkerUrl = (options: ServiceWorkerOptions): string => {\n const { firebaseConfig, domain, isTernSecureDev, localPort } = options;\n const serializedConfig = encodeURIComponent(JSON.stringify(firebaseConfig));\n \n let baseUrl: string;\n \n if (isTernSecureDev) {\n const localHost = process.env.TERN_UI_HOST || 'localhost';\n const port = localPort || process.env.TERN_UI_PORT || '3000';\n baseUrl = `http://${localHost}:${port}`;\n } else {\n baseUrl = domain || getUrlEndpoint();\n }\n \n return `${baseUrl}/service-worker.js?firebaseConfig=${serializedConfig}`;\n};\n\nexport const reg = (opt: ServiceWorkerOptions) => {\n const { firebaseConfig } = opt;\n if (\"serviceWorker\" in navigator) {\n const serializedFirebaseConfig = encodeURIComponent(JSON.stringify(firebaseConfig));\n const serviceWorkerUrl = getServiceWorkerUrl(opt);\n \n navigator.serviceWorker\n .register(serviceWorkerUrl)\n .then((registration) => console.log(\"scope is: \", registration.scope));\n }\n}\n\nexport const registerServiceWorker = async (options: ServiceWorkerOptions): Promise<ServiceWorkerRegistration | null> => {\n if (!('serviceWorker' in navigator)) {\n console.warn('[ServiceWorker] Service workers are not supported');\n return null;\n }\n\n const { scope = '/', updateViaCache = 'imports' } = options;\n\n try {\n const serviceWorkerUrl = getServiceWorkerUrl(options);\n \n const registration = await navigator.serviceWorker.register(serviceWorkerUrl, {\n scope,\n updateViaCache,\n });\n\n console.log('[ServiceWorker] Registration successful:', registration);\n return registration;\n } catch (error) {\n console.error('[ServiceWorker] Registration failed:', error);\n throw new Error(`Failed to register service worker: ${error}`);\n }\n};\n\nexport const unregisterServiceWorker = async (): Promise<boolean> => {\n if (!('serviceWorker' in navigator)) {\n return false;\n }\n\n try {\n const registrations = await navigator.serviceWorker.getRegistrations();\n const unregisterPromises = registrations.map(registration => registration.unregister());\n \n await Promise.all(unregisterPromises);\n console.log('[ServiceWorker] All service workers unregistered');\n return true;\n } catch (error) {\n console.error('[ServiceWorker] Failed to unregister service workers:', error);\n return false;\n }\n};"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,IAAM,iBAAiB,MAAc;AACjC,QAAM,cAAc,OAAO,SAAS,aAAa;AACjD,SAAO,cAAc,0BAA0B,GAAG,OAAO,SAAS,MAAM;AAC1E;AAEF,IAAM,sBAAsB,CAAC,YAA0C;AACrE,QAAM,EAAE,gBAAgB,QAAQ,iBAAiB,UAAU,IAAI;AAC/D,QAAM,mBAAmB,mBAAmB,KAAK,UAAU,cAAc,CAAC;AAE1E,MAAI;AAEJ,MAAI,iBAAiB;AACnB,UAAM,YAAY,QAAQ,IAAI,gBAAgB;AAC9C,UAAM,OAAO,aAAa,QAAQ,IAAI,gBAAgB;AACtD,cAAU,UAAU,SAAS,IAAI,IAAI;AAAA,EACvC,OAAO;AACL,cAAU,UAAU,eAAe;AAAA,EACrC;AAEA,SAAO,GAAG,OAAO,qCAAqC,gBAAgB;AACxE;AAEO,IAAM,MAAM,CAAC,QAA8B;AAC9C,QAAM,EAAE,eAAe,IAAI;AAC3B,MAAI,mBAAmB,WAAW;AAC9B,UAAM,2BAA2B,mBAAmB,KAAK,UAAU,cAAc,CAAC;AAClF,UAAM,mBAAmB,oBAAoB,GAAG;AAEhD,cAAU,cACP,SAAS,gBAAgB,EACzB,KAAK,CAAC,iBAAiB,QAAQ,IAAI,cAAc,aAAa,KAAK,CAAC;AAAA,EACvE;AACR;AAEO,IAAM,wBAAwB,OAAO,YAA6E;AACvH,MAAI,EAAE,mBAAmB,YAAY;AACnC,YAAQ,KAAK,mDAAmD;AAChE,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,QAAQ,KAAK,iBAAiB,UAAU,IAAI;AAEpD,MAAI;AACF,UAAM,mBAAmB,oBAAoB,OAAO;AAEpD,UAAM,eAAe,MAAM,UAAU,cAAc,SAAS,kBAAkB;AAAA,MAC5E;AAAA,MACA;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,4CAA4C,YAAY;AACpE,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,wCAAwC,KAAK;AAC3D,UAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAAA,EAC/D;AACF;AAEO,IAAM,0BAA0B,YAA8B;AACnE,MAAI,EAAE,mBAAmB,YAAY;AACnC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,UAAU,cAAc,iBAAiB;AACrE,UAAM,qBAAqB,cAAc,IAAI,kBAAgB,aAAa,WAAW,CAAC;AAEtF,UAAM,QAAQ,IAAI,kBAAkB;AACpC,YAAQ,IAAI,kDAAkD;AAC9D,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,yDAAyD,KAAK;AAC5E,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// src/serviceWorker.ts
|
|
2
|
+
var getUrlEndpoint = () => {
|
|
3
|
+
const isLocalhost = window.location.hostname === "localhost";
|
|
4
|
+
return isLocalhost ? "http://localhost:3000" : `${window.location.origin}`;
|
|
5
|
+
};
|
|
6
|
+
var getServiceWorkerUrl = (options) => {
|
|
7
|
+
const { firebaseConfig, domain, isTernSecureDev, localPort } = options;
|
|
8
|
+
const serializedConfig = encodeURIComponent(JSON.stringify(firebaseConfig));
|
|
9
|
+
let baseUrl;
|
|
10
|
+
if (isTernSecureDev) {
|
|
11
|
+
const localHost = process.env.TERN_UI_HOST || "localhost";
|
|
12
|
+
const port = localPort || process.env.TERN_UI_PORT || "3000";
|
|
13
|
+
baseUrl = `http://${localHost}:${port}`;
|
|
14
|
+
} else {
|
|
15
|
+
baseUrl = domain || getUrlEndpoint();
|
|
16
|
+
}
|
|
17
|
+
return `${baseUrl}/service-worker.js?firebaseConfig=${serializedConfig}`;
|
|
18
|
+
};
|
|
19
|
+
var reg = (opt) => {
|
|
20
|
+
const { firebaseConfig } = opt;
|
|
21
|
+
if ("serviceWorker" in navigator) {
|
|
22
|
+
const serializedFirebaseConfig = encodeURIComponent(JSON.stringify(firebaseConfig));
|
|
23
|
+
const serviceWorkerUrl = getServiceWorkerUrl(opt);
|
|
24
|
+
navigator.serviceWorker.register(serviceWorkerUrl).then((registration) => console.log("scope is: ", registration.scope));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var registerServiceWorker = async (options) => {
|
|
28
|
+
if (!("serviceWorker" in navigator)) {
|
|
29
|
+
console.warn("[ServiceWorker] Service workers are not supported");
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const { scope = "/", updateViaCache = "imports" } = options;
|
|
33
|
+
try {
|
|
34
|
+
const serviceWorkerUrl = getServiceWorkerUrl(options);
|
|
35
|
+
const registration = await navigator.serviceWorker.register(serviceWorkerUrl, {
|
|
36
|
+
scope,
|
|
37
|
+
updateViaCache
|
|
38
|
+
});
|
|
39
|
+
console.log("[ServiceWorker] Registration successful:", registration);
|
|
40
|
+
return registration;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error("[ServiceWorker] Registration failed:", error);
|
|
43
|
+
throw new Error(`Failed to register service worker: ${error}`);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var unregisterServiceWorker = async () => {
|
|
47
|
+
if (!("serviceWorker" in navigator)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const registrations = await navigator.serviceWorker.getRegistrations();
|
|
52
|
+
const unregisterPromises = registrations.map((registration) => registration.unregister());
|
|
53
|
+
await Promise.all(unregisterPromises);
|
|
54
|
+
console.log("[ServiceWorker] All service workers unregistered");
|
|
55
|
+
return true;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("[ServiceWorker] Failed to unregister service workers:", error);
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
export {
|
|
62
|
+
reg,
|
|
63
|
+
registerServiceWorker,
|
|
64
|
+
unregisterServiceWorker
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=serviceWorker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/serviceWorker.ts"],"sourcesContent":["export type ServiceWorkerOptions = {\n firebaseConfig: Record<string, any>;\n scope?: string;\n updateViaCache?: 'imports' | 'all' | 'none';\n domain?: string;\n isTernSecureDev?: boolean;\n localPort?: string;\n};\n\nconst getUrlEndpoint = (): string => {\n const isLocalhost = window.location.hostname === 'localhost';\n return isLocalhost ? 'http://localhost:3000' : `${window.location.origin}`;\n }\n\nconst getServiceWorkerUrl = (options: ServiceWorkerOptions): string => {\n const { firebaseConfig, domain, isTernSecureDev, localPort } = options;\n const serializedConfig = encodeURIComponent(JSON.stringify(firebaseConfig));\n \n let baseUrl: string;\n \n if (isTernSecureDev) {\n const localHost = process.env.TERN_UI_HOST || 'localhost';\n const port = localPort || process.env.TERN_UI_PORT || '3000';\n baseUrl = `http://${localHost}:${port}`;\n } else {\n baseUrl = domain || getUrlEndpoint();\n }\n \n return `${baseUrl}/service-worker.js?firebaseConfig=${serializedConfig}`;\n};\n\nexport const reg = (opt: ServiceWorkerOptions) => {\n const { firebaseConfig } = opt;\n if (\"serviceWorker\" in navigator) {\n const serializedFirebaseConfig = encodeURIComponent(JSON.stringify(firebaseConfig));\n const serviceWorkerUrl = getServiceWorkerUrl(opt);\n \n navigator.serviceWorker\n .register(serviceWorkerUrl)\n .then((registration) => console.log(\"scope is: \", registration.scope));\n }\n}\n\nexport const registerServiceWorker = async (options: ServiceWorkerOptions): Promise<ServiceWorkerRegistration | null> => {\n if (!('serviceWorker' in navigator)) {\n console.warn('[ServiceWorker] Service workers are not supported');\n return null;\n }\n\n const { scope = '/', updateViaCache = 'imports' } = options;\n\n try {\n const serviceWorkerUrl = getServiceWorkerUrl(options);\n \n const registration = await navigator.serviceWorker.register(serviceWorkerUrl, {\n scope,\n updateViaCache,\n });\n\n console.log('[ServiceWorker] Registration successful:', registration);\n return registration;\n } catch (error) {\n console.error('[ServiceWorker] Registration failed:', error);\n throw new Error(`Failed to register service worker: ${error}`);\n }\n};\n\nexport const unregisterServiceWorker = async (): Promise<boolean> => {\n if (!('serviceWorker' in navigator)) {\n return false;\n }\n\n try {\n const registrations = await navigator.serviceWorker.getRegistrations();\n const unregisterPromises = registrations.map(registration => registration.unregister());\n \n await Promise.all(unregisterPromises);\n console.log('[ServiceWorker] All service workers unregistered');\n return true;\n } catch (error) {\n console.error('[ServiceWorker] Failed to unregister service workers:', error);\n return false;\n }\n};"],"mappings":";AASA,IAAM,iBAAiB,MAAc;AACjC,QAAM,cAAc,OAAO,SAAS,aAAa;AACjD,SAAO,cAAc,0BAA0B,GAAG,OAAO,SAAS,MAAM;AAC1E;AAEF,IAAM,sBAAsB,CAAC,YAA0C;AACrE,QAAM,EAAE,gBAAgB,QAAQ,iBAAiB,UAAU,IAAI;AAC/D,QAAM,mBAAmB,mBAAmB,KAAK,UAAU,cAAc,CAAC;AAE1E,MAAI;AAEJ,MAAI,iBAAiB;AACnB,UAAM,YAAY,QAAQ,IAAI,gBAAgB;AAC9C,UAAM,OAAO,aAAa,QAAQ,IAAI,gBAAgB;AACtD,cAAU,UAAU,SAAS,IAAI,IAAI;AAAA,EACvC,OAAO;AACL,cAAU,UAAU,eAAe;AAAA,EACrC;AAEA,SAAO,GAAG,OAAO,qCAAqC,gBAAgB;AACxE;AAEO,IAAM,MAAM,CAAC,QAA8B;AAC9C,QAAM,EAAE,eAAe,IAAI;AAC3B,MAAI,mBAAmB,WAAW;AAC9B,UAAM,2BAA2B,mBAAmB,KAAK,UAAU,cAAc,CAAC;AAClF,UAAM,mBAAmB,oBAAoB,GAAG;AAEhD,cAAU,cACP,SAAS,gBAAgB,EACzB,KAAK,CAAC,iBAAiB,QAAQ,IAAI,cAAc,aAAa,KAAK,CAAC;AAAA,EACvE;AACR;AAEO,IAAM,wBAAwB,OAAO,YAA6E;AACvH,MAAI,EAAE,mBAAmB,YAAY;AACnC,YAAQ,KAAK,mDAAmD;AAChE,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,QAAQ,KAAK,iBAAiB,UAAU,IAAI;AAEpD,MAAI;AACF,UAAM,mBAAmB,oBAAoB,OAAO;AAEpD,UAAM,eAAe,MAAM,UAAU,cAAc,SAAS,kBAAkB;AAAA,MAC5E;AAAA,MACA;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,4CAA4C,YAAY;AACpE,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,wCAAwC,KAAK;AAC3D,UAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAAA,EAC/D;AACF;AAEO,IAAM,0BAA0B,YAA8B;AACnE,MAAI,EAAE,mBAAmB,YAAY;AACnC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,UAAU,cAAc,iBAAiB;AACrE,UAAM,qBAAqB,cAAc,IAAI,kBAAgB,aAAa,WAAW,CAAC;AAEtF,UAAM,QAAQ,IAAI,kBAAkB;AACpC,YAAQ,IAAI,kDAAkD;AAC9D,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,yDAAyD,KAAK;AAC5E,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type removeCookieParams = {
|
|
2
|
+
path?: string;
|
|
3
|
+
domain?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function cookieHandler(cookieNanme: string): {
|
|
6
|
+
set(value: string, options?: Cookies.CookieAttributes): void;
|
|
7
|
+
get(): string | undefined;
|
|
8
|
+
remove(removeCookieParams?: removeCookieParams): void;
|
|
9
|
+
};
|
|
10
|
+
export type CookieAttributes = Cookies.CookieAttributes;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=cookie.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../../src/cookie.ts"],"names":[],"mappings":"AAEA,KAAK,kBAAkB,GAAG;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM;eAE9B,MAAM,YAAW,OAAO,CAAC,gBAAgB,GAAQ,IAAI;;gCAMpC,kBAAkB;EAIrD;AAED,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derivedAuthState.d.ts","sourceRoot":"","sources":["../../src/derivedAuthState.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,eAAe,EAGlB,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AAGH,eAAO,MAAM,yBAAyB,EAAE,
|
|
1
|
+
{"version":3,"file":"derivedAuthState.d.ts","sourceRoot":"","sources":["../../src/derivedAuthState.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,eAAe,EAGlB,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AAGH,eAAO,MAAM,yBAAyB,EAAE,eAWvC,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,eAAe,eAAe,GAAG,SAAS,KAAI,eA8B7E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadTernUIScript.d.ts","sourceRoot":"","sources":["../../src/loadTernUIScript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAIxE,MAAM,MAAM,uBAAuB,GAAG,6BAA6B,GAAG;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"loadTernUIScript.d.ts","sourceRoot":"","sources":["../../src/loadTernUIScript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAIxE,MAAM,MAAM,uBAAuB,GAAG,6BAA6B,GAAG;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAA;AAGD,eAAO,MAAM,gBAAgB,GAAU,UAAU,uBAAuB,qBA4BrE,CAAA;AAEH,eAAO,MAAM,kBAAkB,GAAI,UAAU,uBAAuB,WAiBnE,CAAA;AAWD,eAAO,MAAM,yBAAyB,GAAI,UAAU,uBAAuB;;;;;;;CAS1E,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ServiceWorkerOptions = {
|
|
2
|
+
firebaseConfig: Record<string, any>;
|
|
3
|
+
scope?: string;
|
|
4
|
+
updateViaCache?: 'imports' | 'all' | 'none';
|
|
5
|
+
domain?: string;
|
|
6
|
+
isTernSecureDev?: boolean;
|
|
7
|
+
localPort?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const reg: (opt: ServiceWorkerOptions) => void;
|
|
10
|
+
export declare const registerServiceWorker: (options: ServiceWorkerOptions) => Promise<ServiceWorkerRegistration | null>;
|
|
11
|
+
export declare const unregisterServiceWorker: () => Promise<boolean>;
|
|
12
|
+
//# sourceMappingURL=serviceWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceWorker.d.ts","sourceRoot":"","sources":["../../src/serviceWorker.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAwBF,eAAO,MAAM,GAAG,GAAI,KAAK,oBAAoB,SAU5C,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAU,SAAS,oBAAoB,KAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAsBnH,CAAC;AAEF,eAAO,MAAM,uBAAuB,QAAa,OAAO,CAAC,OAAO,CAgB/D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tern-secure/shared",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/TernSecure/typescript.git",
|
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
"description": "Shared types and utilities for TernSecure projects",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
+
"cookie",
|
|
17
18
|
"derivedAuthState",
|
|
18
19
|
"eventBus",
|
|
19
20
|
"loadScript",
|
|
20
21
|
"loadTernUIScript",
|
|
22
|
+
"react",
|
|
21
23
|
"retry"
|
|
22
24
|
],
|
|
23
25
|
"exports": {
|
|
26
|
+
"./package.json": "./package.json",
|
|
24
27
|
".": {
|
|
25
28
|
"import": {
|
|
26
29
|
"types": "./dist/index.d.mts",
|
|
@@ -54,14 +57,16 @@
|
|
|
54
57
|
},
|
|
55
58
|
"main": "./dist/index.js",
|
|
56
59
|
"devDependencies": {
|
|
60
|
+
"@types/js-cookie": "^3.0.6",
|
|
57
61
|
"prettier": "^3.3.3",
|
|
58
62
|
"rimraf": "^6.0.1",
|
|
59
63
|
"tsup": "^8.3.5",
|
|
60
64
|
"typescript": "^5.7.2"
|
|
61
65
|
},
|
|
62
66
|
"dependencies": {
|
|
67
|
+
"js-cookie": "^3.0.5",
|
|
63
68
|
"tslib": "2.4.1",
|
|
64
|
-
"@tern-secure/types": "1.0.
|
|
69
|
+
"@tern-secure/types": "1.0.2"
|
|
65
70
|
},
|
|
66
71
|
"peerDependencies": {
|
|
67
72
|
"react": "^19",
|