@tern-secure/auth 1.1.0-canary.v20251020170039 → 1.1.0-canary.v20251024005655
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/cjs/index.js +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/instance/TernAuth.js +78 -136
- package/dist/cjs/instance/TernAuth.js.map +1 -1
- package/dist/cjs/resources/SignIn.js +78 -36
- package/dist/cjs/resources/SignIn.js.map +1 -1
- package/dist/cjs/utils/construct.js +91 -4
- package/dist/cjs/utils/construct.js.map +1 -1
- package/dist/cjs/utils/index.js +5 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/redirectUrls.js +156 -0
- package/dist/cjs/utils/redirectUrls.js.map +1 -0
- package/dist/cjs/utils/windowNavigate.js +45 -0
- package/dist/cjs/utils/windowNavigate.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/instance/TernAuth.js +79 -136
- package/dist/esm/instance/TernAuth.js.map +1 -1
- package/dist/esm/resources/SignIn.js +78 -36
- package/dist/esm/resources/SignIn.js.map +1 -1
- package/dist/esm/utils/construct.js +84 -4
- package/dist/esm/utils/construct.js.map +1 -1
- package/dist/esm/utils/index.js +2 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/redirectUrls.js +132 -0
- package/dist/esm/utils/redirectUrls.js.map +1 -0
- package/dist/esm/utils/windowNavigate.js +19 -0
- package/dist/esm/utils/windowNavigate.js.map +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/instance/TernAuth.d.ts +10 -10
- package/dist/types/instance/TernAuth.d.ts.map +1 -1
- package/dist/types/resources/SignIn.d.ts +26 -5
- package/dist/types/resources/SignIn.d.ts.map +1 -1
- package/dist/types/utils/construct.d.ts +31 -0
- package/dist/types/utils/construct.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/redirectUrls.d.ts +23 -0
- package/dist/types/utils/redirectUrls.d.ts.map +1 -0
- package/dist/types/utils/windowNavigate.d.ts +12 -0
- package/dist/types/utils/windowNavigate.d.ts.map +1 -0
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var index_exports = {};
|
|
20
20
|
__export(index_exports, {
|
|
21
21
|
CoreApiClient: () => import_coreApiClient.CoreApiClient,
|
|
22
|
+
RedirectUrls: () => import_redirectUrls.RedirectUrls,
|
|
22
23
|
SignIn: () => import_internal.SignIn,
|
|
23
24
|
TernSecureAuth: () => import_TernAuth.TernSecureAuth,
|
|
24
25
|
TernSecureBase: () => import_internal.TernSecureBase,
|
|
@@ -31,9 +32,11 @@ var import_TernAuth = require("./instance/TernAuth");
|
|
|
31
32
|
var import_TernAuthServer = require("./instance/TernAuthServer");
|
|
32
33
|
var import_coreApiClient = require("./instance/coreApiClient");
|
|
33
34
|
var import_internal = require("./resources/internal");
|
|
35
|
+
var import_redirectUrls = require("./utils/redirectUrls");
|
|
34
36
|
// Annotate the CommonJS export names for ESM import in node:
|
|
35
37
|
0 && (module.exports = {
|
|
36
38
|
CoreApiClient,
|
|
39
|
+
RedirectUrls,
|
|
37
40
|
SignIn,
|
|
38
41
|
TernSecureAuth,
|
|
39
42
|
TernSecureBase,
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export { TernSecureAuth } from './instance/TernAuth';\nexport type { TernAuth } from './instance/TernAuth';\nexport { TernServerAuth } from './instance/TernAuthServer';\nexport type { TernServerAuthOptions, AuthenticatedApp } from './instance/TernAuthServer';\n\nexport { CoreApiClient, coreApiClient } from './instance/coreApiClient';\nexport type { \n ApiResponse, \n ApiResponseJSON, \n RequestOptions,\n BeforeRequestHook,\n AfterResponseHook\n} from './instance/coreApiClient';\n\nexport { SignIn, TernSecureBase, buildURL } from './resources/internal';\n\nexport type {\n AuthErrorTree,\n TernSecureConfig,\n SignInFormValues,\n SignInProps,\n SignUpProps,\n SignInResponse,\n
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export { TernSecureAuth } from './instance/TernAuth';\nexport type { TernAuth } from './instance/TernAuth';\nexport { TernServerAuth } from './instance/TernAuthServer';\nexport type { TernServerAuthOptions, AuthenticatedApp } from './instance/TernAuthServer';\n\nexport { CoreApiClient, coreApiClient } from './instance/coreApiClient';\nexport type { \n ApiResponse, \n ApiResponseJSON, \n RequestOptions,\n BeforeRequestHook,\n AfterResponseHook\n} from './instance/coreApiClient';\n\nexport { SignIn, TernSecureBase, buildURL } from './resources/internal';\n\nexport type {\n AuthErrorTree,\n TernSecureConfig,\n SignInFormValues,\n SignInProps,\n SignUpProps,\n SignInResponse,\n SignInForceRedirectUrl,\n SignUpForceRedirectUrl,\n SignInFallbackRedirectUrl,\n ResendEmailVerification,\n TernSecureUser,\n TernSecureState\n} from '@tern-secure/types';\n\nexport { RedirectUrls } from './utils/redirectUrls';"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA+B;AAE/B,4BAA+B;AAG/B,2BAA6C;AAS7C,sBAAiD;AAiBjD,0BAA6B;","names":[]}
|
|
@@ -31,7 +31,8 @@ var import_auth = require("firebase/auth");
|
|
|
31
31
|
var import_installations = require("firebase/installations");
|
|
32
32
|
var import_request = require("../auth/request");
|
|
33
33
|
var import_internal = require("../resources/internal");
|
|
34
|
-
var
|
|
34
|
+
var import_utils2 = require("../utils/");
|
|
35
|
+
var import_redirectUrls = require("../utils/redirectUrls");
|
|
35
36
|
var import_c_coreApiClient = require("./c_coreApiClient");
|
|
36
37
|
var import_events = require("./events");
|
|
37
38
|
var import_jwtClient = require("./jwtClient");
|
|
@@ -39,10 +40,10 @@ function inBrowser() {
|
|
|
39
40
|
return typeof window !== "undefined";
|
|
40
41
|
}
|
|
41
42
|
class TernSecureAuth {
|
|
42
|
-
static version = "1.1.0-canary.
|
|
43
|
+
static version = "1.1.0-canary.v20251024005655";
|
|
43
44
|
static sdkMetadata = {
|
|
44
45
|
name: "@tern-secure/auth",
|
|
45
|
-
version: "1.1.0-canary.
|
|
46
|
+
version: "1.1.0-canary.v20251024005655",
|
|
46
47
|
environment: process.env.NODE_ENV || "production"
|
|
47
48
|
};
|
|
48
49
|
static instance = null;
|
|
@@ -140,7 +141,7 @@ class TernSecureAuth {
|
|
|
140
141
|
_internal_getAllOptions() {
|
|
141
142
|
return Object.freeze({ ...this.#options });
|
|
142
143
|
}
|
|
143
|
-
static
|
|
144
|
+
static getOrCreateInstance(options) {
|
|
144
145
|
if (!this.instance) {
|
|
145
146
|
this.instance = new TernSecureAuth(options);
|
|
146
147
|
}
|
|
@@ -156,10 +157,18 @@ class TernSecureAuth {
|
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
static initialize(options) {
|
|
159
|
-
const instance = this.
|
|
160
|
+
const instance = this.getOrCreateInstance(options);
|
|
160
161
|
instance.#initialize(options);
|
|
161
162
|
return instance;
|
|
162
163
|
}
|
|
164
|
+
initialize = async (options) => {
|
|
165
|
+
void this.#initialize(options || {});
|
|
166
|
+
};
|
|
167
|
+
static create(options) {
|
|
168
|
+
const instance = this.getOrCreateInstance();
|
|
169
|
+
void instance.initialize(options);
|
|
170
|
+
return instance;
|
|
171
|
+
}
|
|
163
172
|
#initialize = (options) => {
|
|
164
173
|
this.#options = this.#initOptions(options);
|
|
165
174
|
try {
|
|
@@ -185,7 +194,6 @@ class TernSecureAuth {
|
|
|
185
194
|
});
|
|
186
195
|
this.#setStatus("ready");
|
|
187
196
|
this.#publicEventBus.emit(import_ternStatusEvent.ternEvents.Status, "ready");
|
|
188
|
-
return this;
|
|
189
197
|
} catch (error) {
|
|
190
198
|
this.error = error;
|
|
191
199
|
this.#setStatus("error");
|
|
@@ -198,7 +206,8 @@ class TernSecureAuth {
|
|
|
198
206
|
this.firebaseClientApp = (0, import_app.getApps)().length === 0 ? (0, import_app.initializeApp)(config, appName) : (0, import_app.getApps)()[0];
|
|
199
207
|
const persistence = this.#setPersistence();
|
|
200
208
|
const auth = (0, import_auth.initializeAuth)(this.firebaseClientApp, {
|
|
201
|
-
persistence
|
|
209
|
+
persistence,
|
|
210
|
+
popupRedirectResolver: import_auth.browserPopupRedirectResolver
|
|
202
211
|
});
|
|
203
212
|
this.auth = auth;
|
|
204
213
|
if (config.tenantId) {
|
|
@@ -228,10 +237,7 @@ class TernSecureAuth {
|
|
|
228
237
|
this.user = jwtClient;
|
|
229
238
|
this.#emit();
|
|
230
239
|
}).catch((error) => {
|
|
231
|
-
console.error(
|
|
232
|
-
"[ternauth] Error during client auth request initialization:",
|
|
233
|
-
error
|
|
234
|
-
);
|
|
240
|
+
console.error("[ternauth] Error during client auth request initialization:", error);
|
|
235
241
|
this.user = null;
|
|
236
242
|
this.#emit();
|
|
237
243
|
});
|
|
@@ -245,9 +251,7 @@ class TernSecureAuth {
|
|
|
245
251
|
if (options == null ? void 0 : options.onAfterSignOut) {
|
|
246
252
|
await options.onAfterSignOut();
|
|
247
253
|
}
|
|
248
|
-
|
|
249
|
-
window.location.href = redirectUrl;
|
|
250
|
-
}
|
|
254
|
+
await this.navigate(redirectUrl);
|
|
251
255
|
import_events.eventBus.emit(import_events.events.UserSignOut, null);
|
|
252
256
|
import_events.eventBus.emit(import_events.events.TokenUpdate, { token: null });
|
|
253
257
|
this.#emit();
|
|
@@ -320,7 +324,7 @@ class TernSecureAuth {
|
|
|
320
324
|
this.signedInSession = null;
|
|
321
325
|
}
|
|
322
326
|
}
|
|
323
|
-
async
|
|
327
|
+
checkRedirectResult = async () => {
|
|
324
328
|
try {
|
|
325
329
|
const result = await (0, import_auth.getRedirectResult)(this.auth);
|
|
326
330
|
if (result) {
|
|
@@ -338,9 +342,9 @@ class TernSecureAuth {
|
|
|
338
342
|
error: authError.code
|
|
339
343
|
};
|
|
340
344
|
}
|
|
341
|
-
}
|
|
345
|
+
};
|
|
342
346
|
getRedirectResult = async () => {
|
|
343
|
-
|
|
347
|
+
return this.checkRedirectResult();
|
|
344
348
|
};
|
|
345
349
|
addListener = (listener) => {
|
|
346
350
|
this.#listeners.push(listener);
|
|
@@ -372,39 +376,41 @@ class TernSecureAuth {
|
|
|
372
376
|
const sessionResult = await session.getIdTokenResult();
|
|
373
377
|
const sessionData = new import_internal.Session(sessionResult);
|
|
374
378
|
await sessionData.create(this.csrfToken || "");
|
|
375
|
-
|
|
379
|
+
if (redirectUrl) {
|
|
380
|
+
await this.navigate(this.constructUrlWithAuthRedirect(redirectUrl));
|
|
381
|
+
}
|
|
376
382
|
this.#setCreatedActiveSession(session);
|
|
377
383
|
this.#emit();
|
|
378
384
|
} catch (error) {
|
|
379
385
|
console.error("[TernSecureAuth] Error creating active session:", error);
|
|
380
386
|
}
|
|
381
387
|
};
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
this.#options = this.#initOptions(options);
|
|
393
|
-
try {
|
|
394
|
-
if (!this.#options.ternSecureConfig) {
|
|
395
|
-
throw new Error("TernSecureConfig is required to initialize TernSecureAuth");
|
|
396
|
-
}
|
|
397
|
-
this.initializeFirebaseApp(this.#options.ternSecureConfig);
|
|
398
|
-
this.signIn = new import_internal.SignIn(this.auth, this.csrfToken);
|
|
399
|
-
this.signUp = new import_internal.SignUp(this.auth);
|
|
400
|
-
this.#setStatus("ready");
|
|
401
|
-
} catch (error) {
|
|
402
|
-
this.error = error;
|
|
403
|
-
this.#setStatus("error");
|
|
404
|
-
throw error;
|
|
388
|
+
navigate = async (to, options) => {
|
|
389
|
+
if (!to || !inBrowser()) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
let toURL = new URL(to, window.location.href);
|
|
393
|
+
if (!this.#allowedRedirectProtocols.includes(toURL.protocol)) {
|
|
394
|
+
console.warn(
|
|
395
|
+
`TernSecureAuth: "${toURL.protocol}" is not a valid protocol. Redirecting to "/" instead. If you think this is a mistake, please open an issue.`
|
|
396
|
+
);
|
|
397
|
+
toURL = new URL("/", window.location.href);
|
|
405
398
|
}
|
|
399
|
+
const customNavigate = (options == null ? void 0 : options.replace) && this.#options.routerReplace ? this.#options.routerReplace : this.#options.routerPush;
|
|
400
|
+
if (toURL.origin !== "null" && toURL.origin !== window.location.origin || !customNavigate) {
|
|
401
|
+
(0, import_utils2.windowNavigate)(toURL);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
const metadata = {
|
|
405
|
+
...(options == null ? void 0 : options.metadata) ? { __internal_metadata: options == null ? void 0 : options.metadata } : {},
|
|
406
|
+
windowNavigate: import_utils2.windowNavigate
|
|
407
|
+
};
|
|
408
|
+
return await customNavigate((0, import_utils2.stripOrigin)(toURL), metadata);
|
|
406
409
|
};
|
|
407
410
|
constructUrlWithAuthRedirect = (to) => {
|
|
411
|
+
if (this.#instanceType === "production") {
|
|
412
|
+
return to;
|
|
413
|
+
}
|
|
408
414
|
const baseUrl = window.location.origin;
|
|
409
415
|
const url = new URL(to, baseUrl);
|
|
410
416
|
if (url.origin === window.location.origin) {
|
|
@@ -413,102 +419,27 @@ class TernSecureAuth {
|
|
|
413
419
|
return url.toString();
|
|
414
420
|
};
|
|
415
421
|
#buildUrl = (key, options) => {
|
|
416
|
-
var _a, _b;
|
|
417
422
|
if (!key || !this.isReady) {
|
|
418
423
|
return "";
|
|
419
424
|
}
|
|
420
425
|
const baseUrlConfig = key === "signInUrl" ? this.#options.signInUrl : this.#options.signUpUrl;
|
|
421
426
|
const defaultPagePath = key === "signInUrl" ? "/sign-in" : "/sign-up";
|
|
422
427
|
const base = baseUrlConfig || defaultPagePath;
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if (existingRedirectParam) {
|
|
433
|
-
effectiveRedirectUrl = existingRedirectParam;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
if (!effectiveRedirectUrl && inBrowser()) {
|
|
437
|
-
effectiveRedirectUrl = window.location.pathname + window.location.search + window.location.hash;
|
|
438
|
-
}
|
|
439
|
-
if (effectiveRedirectUrl && inBrowser()) {
|
|
440
|
-
let signInPagePath;
|
|
441
|
-
try {
|
|
442
|
-
signInPagePath = this.#options.signInUrl ? new URL(this.#options.signInUrl, window.location.origin).pathname : defaultPagePath;
|
|
443
|
-
} catch {
|
|
444
|
-
signInPagePath = defaultPagePath;
|
|
445
|
-
}
|
|
446
|
-
let signUpPagePath;
|
|
447
|
-
try {
|
|
448
|
-
signUpPagePath = this.#options.signUpUrl ? new URL(this.#options.signUpUrl, window.location.origin).pathname : key === "signUpUrl" ? defaultPagePath : "/sign-in";
|
|
449
|
-
} catch {
|
|
450
|
-
signUpPagePath = key === "signUpUrl" ? defaultPagePath : "/sign-in";
|
|
451
|
-
}
|
|
452
|
-
const redirectTargetObj = new URL(effectiveRedirectUrl, window.location.origin);
|
|
453
|
-
if (redirectTargetObj.pathname === signInPagePath || redirectTargetObj.pathname === signUpPagePath) {
|
|
454
|
-
effectiveRedirectUrl = "/";
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
const paramsForBuildUrl = {
|
|
458
|
-
base,
|
|
459
|
-
searchParams: new URLSearchParams()
|
|
460
|
-
};
|
|
461
|
-
if (effectiveRedirectUrl) {
|
|
462
|
-
if (inBrowser()) {
|
|
463
|
-
const absoluteRedirectUrl = new URL(effectiveRedirectUrl, window.location.origin).href;
|
|
464
|
-
(_a = paramsForBuildUrl.searchParams) == null ? void 0 : _a.set("redirect_url", absoluteRedirectUrl);
|
|
465
|
-
} else {
|
|
466
|
-
(_b = paramsForBuildUrl.searchParams) == null ? void 0 : _b.set("redirect_url", effectiveRedirectUrl);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
const constructedUrl = (0, import_construct.buildURL)(paramsForBuildUrl, {
|
|
470
|
-
stringify: true,
|
|
471
|
-
skipOrigin: false
|
|
472
|
-
});
|
|
473
|
-
if (typeof constructedUrl !== "string") {
|
|
474
|
-
console.error(
|
|
475
|
-
"[TernSecure] Error: buildURL did not return a string as expected. Falling back to base URL."
|
|
476
|
-
);
|
|
477
|
-
if (inBrowser()) {
|
|
478
|
-
try {
|
|
479
|
-
return new URL(base, window.location.origin).href;
|
|
480
|
-
} catch {
|
|
481
|
-
return base;
|
|
482
|
-
}
|
|
428
|
+
const redirectUrls = new import_redirectUrls.RedirectUrls(this.#options, options).toSearchParams();
|
|
429
|
+
const constructedUrl = (0, import_utils2.buildURL)(
|
|
430
|
+
{
|
|
431
|
+
base,
|
|
432
|
+
hashSearchParams: [redirectUrls]
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
stringify: true,
|
|
436
|
+
skipOrigin: false
|
|
483
437
|
}
|
|
484
|
-
|
|
485
|
-
}
|
|
438
|
+
);
|
|
486
439
|
return this.constructUrlWithAuthRedirect(constructedUrl);
|
|
487
440
|
};
|
|
488
441
|
#constructAfterSignInUrl = () => {
|
|
489
|
-
|
|
490
|
-
return "/";
|
|
491
|
-
}
|
|
492
|
-
let redirectPath = void 0;
|
|
493
|
-
const defaultRedirectPath = "/";
|
|
494
|
-
if (this.#options.signInForceRedirectUrl) {
|
|
495
|
-
redirectPath = this.#options.signInForceRedirectUrl;
|
|
496
|
-
}
|
|
497
|
-
if (!redirectPath) {
|
|
498
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
499
|
-
const redirectPathFromParams = urlParams.get("redirect_url");
|
|
500
|
-
if (redirectPathFromParams) {
|
|
501
|
-
redirectPath = redirectPathFromParams;
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
if (!redirectPath) {
|
|
505
|
-
redirectPath = defaultRedirectPath;
|
|
506
|
-
}
|
|
507
|
-
const currentPath = window.location.pathname;
|
|
508
|
-
if ((0, import_construct.hasRedirectLoop)(currentPath, redirectPath)) {
|
|
509
|
-
return defaultRedirectPath;
|
|
510
|
-
}
|
|
511
|
-
return this.constructUrlWithAuthRedirect(redirectPath);
|
|
442
|
+
return this.constructUrlWithAuthRedirect(new import_redirectUrls.RedirectUrls(this.#options).getAfterSignInUrl());
|
|
512
443
|
};
|
|
513
444
|
#constructAfterSignOutUrl = () => {
|
|
514
445
|
if (!this.#options.afterSignOutUrl) {
|
|
@@ -518,33 +449,44 @@ class TernSecureAuth {
|
|
|
518
449
|
};
|
|
519
450
|
redirectToSignIn = async (options) => {
|
|
520
451
|
if (inBrowser()) {
|
|
521
|
-
|
|
522
|
-
window.location.href = url;
|
|
452
|
+
return this.navigate(this.constructSignInUrl(options));
|
|
523
453
|
}
|
|
524
454
|
return;
|
|
525
455
|
};
|
|
526
456
|
redirectToSignUp = async (options) => {
|
|
527
457
|
if (inBrowser()) {
|
|
528
|
-
|
|
529
|
-
window.location.href = redirectUrl;
|
|
458
|
+
return this.navigate(this.constructSignUpUrl());
|
|
530
459
|
}
|
|
531
460
|
return;
|
|
532
461
|
};
|
|
533
462
|
redirectAfterSignIn = async () => {
|
|
534
463
|
if (inBrowser()) {
|
|
535
|
-
|
|
536
|
-
window.location.href = destinationUrl;
|
|
464
|
+
return this.navigate(this.#constructAfterSignInUrl());
|
|
537
465
|
}
|
|
466
|
+
return;
|
|
538
467
|
};
|
|
539
468
|
redirectAfterSignUp = () => {
|
|
540
469
|
throw new Error("redirectAfterSignUp is not implemented yet");
|
|
541
470
|
};
|
|
542
471
|
constructSignInUrl = (options) => {
|
|
543
|
-
return this.#buildUrl("signInUrl", {
|
|
472
|
+
return this.#buildUrl("signInUrl", {
|
|
473
|
+
...options,
|
|
474
|
+
signInForceRedirectUrl: (options == null ? void 0 : options.signInForceRedirectUrl) || window.location.href
|
|
475
|
+
});
|
|
544
476
|
};
|
|
545
477
|
constructSignUpUrl = (options) => {
|
|
546
|
-
return this.#buildUrl("signUpUrl", {
|
|
478
|
+
return this.#buildUrl("signUpUrl", {
|
|
479
|
+
...options,
|
|
480
|
+
signUpForceRedirectUrl: (options == null ? void 0 : options.signUpForceRedirectUrl) || window.location.href
|
|
481
|
+
});
|
|
547
482
|
};
|
|
483
|
+
get #allowedRedirectProtocols() {
|
|
484
|
+
let allowedProtocols = import_utils2.ALLOWED_PROTOCOLS;
|
|
485
|
+
if (this.#options.allowedRedirectProtocols) {
|
|
486
|
+
allowedProtocols = allowedProtocols.concat(this.#options.allowedRedirectProtocols);
|
|
487
|
+
}
|
|
488
|
+
return allowedProtocols;
|
|
489
|
+
}
|
|
548
490
|
__internal_setCountry = (country) => {
|
|
549
491
|
if (!this.__internal_country) {
|
|
550
492
|
this.__internal_country = country;
|
|
@@ -602,7 +544,7 @@ class TernSecureAuth {
|
|
|
602
544
|
}
|
|
603
545
|
const emulatorUrl = host.startsWith("http") ? host : `http://${host}`;
|
|
604
546
|
try {
|
|
605
|
-
(0, import_auth.connectAuthEmulator)(this.auth, emulatorUrl, { disableWarnings:
|
|
547
|
+
(0, import_auth.connectAuthEmulator)(this.auth, emulatorUrl, { disableWarnings: false });
|
|
606
548
|
console.warn(`[TernSecure] Firebase Auth Emulator connected at ${emulatorUrl}`);
|
|
607
549
|
} catch (error) {
|
|
608
550
|
console.error("[TernSecure] Error connecting to Firebase Auth Emulator:", error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/instance/TernAuth.ts"],"sourcesContent":["import { handleFirebaseAuthError } from '@tern-secure/shared/errors';\nimport { createTernAuthEventBus, ternEvents } from '@tern-secure/shared/ternStatusEvent';\nimport { stripScheme } from '@tern-secure/shared/url';\nimport { handleValueOrFn } from '@tern-secure/shared/utils';\nimport type {\n CreateActiveSession,\n DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n RedirectOptions,\n SessionResource,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponse,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernAuthSDK,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureUser,\n TernSecureUserData,\n UnsubscribeCallback,\n} from '@tern-secure/types';\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApps, initializeApp } from 'firebase/app';\nimport type { Auth, Auth as TernAuth } from 'firebase/auth';\nimport {\n browserLocalPersistence,\n browserSessionPersistence,\n connectAuthEmulator,\n getIdToken,\n getRedirectResult,\n initializeAuth,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n} from 'firebase/auth';\nimport { getInstallations } from 'firebase/installations';\n\nimport { type ClientAuthRequest, createClientAuthRequest } from '../auth/request';\nimport { AuthCookieManager, Session, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { buildURL, hasRedirectLoop } from '../utils/construct';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\nimport { createClientFromJwt } from './jwtClient';\n\nexport function inBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport { TernAuth };\n\n/**\n * Firebase implementation of the TernSecureAuth interface\n */\nexport class TernSecureAuth implements TernSecureAuthInterface {\n public static version: string = PACKAGE_VERSION;\n public static sdkMetadata: TernAuthSDK = {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV || 'production',\n };\n private static instance: TernSecureAuth | null = null;\n private _currentUser: TernSecureUser | null = null;\n private signedInSession: SignedInSession | null = null;\n private firebaseClientApp: FirebaseApp | undefined;\n private authStateUnsubscribe: (() => void) | null = null;\n private auth!: Auth;\n private csrfToken: string | undefined;\n public isLoading = false;\n public error: Error | null = null;\n public user: TernSecureUser | null | undefined = null;\n public __internal_country?: string | null;\n #domain: DomainOrProxyUrl['domain'];\n #apiClient: ApiClient;\n #apiUrl: string;\n #instanceType?: InstanceType;\n #status: TernSecureAuthInterface['status'] = 'loading';\n #listeners: Array<(emission: TernSecureResources) => void> = [];\n #options: TernSecureAuthOptions = {};\n #authCookieManager?: AuthCookieManager;\n #clientAuthRequest?: ClientAuthRequest;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource;\n signUp!: SignUpResource;\n session!: SessionResource;\n\n get isReady(): boolean {\n return this.status === 'ready';\n }\n\n get status(): TernSecureAuthInterface['status'] {\n return this.#status;\n }\n\n get version(): string {\n return TernSecureAuth.version;\n }\n\n set sdkMetadata(metadata: TernAuthSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernAuthSDK {\n return TernSecureAuth.sdkMetadata;\n }\n\n get requiresVerification(): boolean {\n return this.#options.requiresVerification ?? true;\n }\n\n get apiUrl(): string {\n return this.#apiUrl;\n }\n\n get domain(): string {\n if (inBrowser()) {\n const strippedDomainString = stripScheme(\n handleValueOrFn(this.#domain, new URL(window.location.href)),\n );\n if (this.#instanceType === 'production') {\n return strippedDomainString;\n }\n return strippedDomainString;\n }\n return '';\n }\n\n get instanceType() {\n return this.#instanceType;\n }\n\n public constructor(options?: TernSecureAuthOptions) {\n this.#domain = options?.ternSecureConfig?.authDomain;\n this.#apiUrl = options?.apiUrl || '';\n this.#instanceType = (process.env.NODE_ENV as InstanceType) || 'production';\n\n this.#apiClient = createCoreApiClient({\n domain: this.#domain,\n apiUrl: options?.apiUrl,\n instanceType: this.instanceType as InstanceType,\n });\n\n this.#publicEventBus.emit(ternEvents.Status, 'loading');\n TernSecureBase.ternsecure = this;\n }\n\n public getApiClient = (): ApiClient => this.#apiClient;\n\n /**\n * Get user data for the provided ID token via backend API\n */\n public async getUserData(): Promise<TernSecureUserData | null> {\n if (!this.#clientAuthRequest) {\n throw new Error('Client auth request not initialized');\n }\n\n return this.#clientAuthRequest.getUserData();\n }\n\n public setLoading(isLoading: boolean): void {\n this.isLoading = isLoading;\n }\n\n public authCookieManager(): AuthCookieManager | undefined {\n return this.#authCookieManager;\n }\n\n public _internal_getOption<K extends keyof TernSecureAuthOptions>(\n key: K,\n ): TernSecureAuthOptions[K] {\n return this.#options[key];\n }\n\n public _internal_getAllOptions(): Readonly<TernSecureAuthOptions> {\n return Object.freeze({ ...this.#options });\n }\n\n static getorCreateInstance(options?: TernSecureAuthOptions): TernSecureAuth {\n if (!this.instance) {\n this.instance = new TernSecureAuth(options);\n }\n return this.instance;\n }\n\n static clearInstance() {\n if (TernSecureAuth.instance) {\n if (TernSecureAuth.instance.authStateUnsubscribe) {\n TernSecureAuth.instance.authStateUnsubscribe();\n TernSecureAuth.instance.authStateUnsubscribe = null;\n }\n TernSecureAuth.instance = null;\n }\n }\n\n public static initialize(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getorCreateInstance(options);\n instance.#initialize(options);\n return instance;\n }\n\n #initialize = (options: TernSecureAuthOptions): TernSecureAuth => {\n this.#options = this.#initOptions(options);\n\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n if (!this.#options.apiUrl) {\n throw new Error('apiUrl is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n const isBrowserCookiePersistence = this.#options.persistence === 'browserCookie';\n\n if (!isBrowserCookiePersistence) {\n this.authStateUnsubscribe = this.initAuthStateListener();\n }\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.#clientAuthRequest = createClientAuthRequest();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n eventBus.on(events.SessionChanged, () => {\n this.#setCreatedActiveSession(this.user || null);\n this.#emit();\n });\n\n this.#setStatus('ready');\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n\n return this;\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n this.#publicEventBus.emit(ternEvents.Status, 'error');\n throw error;\n }\n };\n\n private initializeFirebaseApp(config: TernSecureConfig) {\n const appName = config.appName || '[DEFAULT]';\n this.firebaseClientApp = getApps().length === 0 ? initializeApp(config, appName) : getApps()[0];\n\n const persistence = this.#setPersistence();\n const auth = initializeAuth(this.firebaseClientApp, {\n persistence,\n });\n\n this.auth = auth;\n\n if (config.tenantId) {\n this.auth.tenantId = config.tenantId;\n }\n\n this.#configureEmulator();\n\n getInstallations(this.firebaseClientApp);\n }\n\n\n /**\n * use when cookie are not httpOnly\n */\n initClient = () => {\n const idTokenInCookie = this.#authCookieManager?.getIdTokenCookie();\n const jwtClient = createClientFromJwt(idTokenInCookie || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n };\n\n\n /**\n * @deprecated will be removed in future releases.\n */\n initClientAuthRequest = () => {\n this.#clientAuthRequest\n ?.getIdTokenFromCookie()\n .then(idTokenInCookie => {\n const { token } = idTokenInCookie;\n const jwtClient = createClientFromJwt(token || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n })\n .catch(error => {\n console.error(\n '[ternauth] Error during client auth request initialization:',\n error\n );\n this.user = null;\n this.#emit();\n });\n };\n\n public signOut: SignOut = async (options?: SignOutOptions) => {\n const redirectUrl = options?.redirectUrl || this.#constructAfterSignOutUrl();\n if (options?.onBeforeSignOut) {\n await options.onBeforeSignOut();\n }\n\n await this.auth.signOut();\n\n if (options?.onAfterSignOut) {\n await options.onAfterSignOut();\n }\n if (inBrowser()) {\n window.location.href = redirectUrl;\n }\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenUpdate, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\n }\n\n private initAuthListener(): () => void {\n (async () => {\n await this.auth.authStateReady();\n const user = this.auth.currentUser as TernSecureUser | null;\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n this.#emit();\n })();\n\n // Return a no-op unsubscribe function since we're not setting up a listener\n return () => {\n // No-op: nothing to unsubscribe from\n };\n }\n\n private initAuthStateListener(): () => void {\n return onAuthStateChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private _onIdTokenChanged(): () => void {\n return onIdTokenChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private async getIdToken(): Promise<string | null> {\n await this.auth.authStateReady();\n if (!this.auth.currentUser) {\n return null;\n }\n return getIdToken(this.auth.currentUser);\n }\n\n public onAuthStateChanged(callback: (cb: any) => void): () => void {\n return onAuthStateChanged(this.auth, callback);\n }\n\n public onIdTokenChanged(callback: (cb: any) => void): () => void {\n return onIdTokenChanged(this.auth, callback);\n }\n\n private async updateCurrentSession(): Promise<void> {\n if (!this._currentUser) {\n this.signedInSession = null;\n return;\n }\n\n try {\n const res = await this._currentUser.getIdTokenResult();\n this.signedInSession = {\n status: 'active',\n token: res.token,\n claims: res.claims,\n issuedAtTime: res.issuedAtTime,\n expirationTime: res.expirationTime,\n authTime: res.authTime,\n signInProvider: res.signInProvider || 'unknown',\n signInSecondFactor: res.signInSecondFactor,\n };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n public async checkRedirectResult(): Promise<SignInResponse | null> {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n status: 'success',\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n }\n\n public getRedirectResult = async (): Promise<any> => {\n throw new Error('getRedirectResult not implemented');\n };\n\n public addListener = (listener: ListenerCallback): UnsubscribeCallback => {\n this.#listeners.push(listener);\n if (this._currentUser) {\n listener({\n user: this._currentUser,\n session: this.signedInSession,\n });\n }\n\n const unsubscribe = () => {\n this.#listeners = this.#listeners.filter(l => l !== listener);\n };\n return unsubscribe;\n };\n\n public on: TernSecureAuthInterface['on'] = (...args) => {\n this.#publicEventBus.on(...args);\n };\n\n public off: TernSecureAuthInterface['off'] = (...args) => {\n this.#publicEventBus.off(...args);\n };\n\n public createActiveSession: CreateActiveSession = async ({\n session,\n redirectUrl,\n }): Promise<void> => {\n try {\n if (!session) {\n throw new Error('No session provided to createActiveSession');\n }\n const sessionResult = await session.getIdTokenResult();\n const sessionData = new Session(sessionResult);\n await sessionData.create(this.csrfToken || '');\n await this.redirectAfterSignIn();\n this.#setCreatedActiveSession(session);\n this.#emit();\n } catch (error) {\n console.error('[TernSecureAuth] Error creating active session:', error);\n }\n };\n\n public initialize(options: TernSecureAuthOptions): Promise<void> {\n this._initialize(options);\n return Promise.resolve();\n }\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getorCreateInstance();\n instance.initialize(options);\n return instance;\n }\n\n _initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n this.#setStatus('ready');\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n throw error;\n }\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\n const baseUrl = window.location.origin;\n const url = new URL(to, baseUrl);\n\n if (url.origin === window.location.origin) {\n return url.href;\n }\n\n return url.toString();\n };\n\n #buildUrl = (key: 'signInUrl' | 'signUpUrl', options: RedirectOptions): string => {\n if (!key || !this.isReady) {\n return '';\n }\n\n const baseUrlConfig = key === 'signInUrl' ? this.#options.signInUrl : this.#options.signUpUrl;\n const defaultPagePath = key === 'signInUrl' ? '/sign-in' : '/sign-up';\n const base = baseUrlConfig || defaultPagePath;\n\n let effectiveRedirectUrl: string | null | undefined;\n\n // Priority 1: Get redirect URL from options (signInForceRedirectUrl or signUpForceRedirectUrl)\n if (key === 'signInUrl' && 'signInForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signInForceRedirectUrl;\n } else if (key === 'signUpUrl' && 'signUpForceRedirectUrl' in options) {\n effectiveRedirectUrl = options.signUpForceRedirectUrl;\n }\n\n // Priority 2: If no force redirect from options, check 'redirect' param in current URL (only in browser)\n if (!effectiveRedirectUrl && inBrowser()) {\n const currentUrlParams = new URLSearchParams(window.location.search);\n const existingRedirectParam = currentUrlParams.get('redirect_url');\n if (existingRedirectParam) {\n effectiveRedirectUrl = existingRedirectParam;\n }\n }\n\n // Priority 3: If still no redirect URL, fallback to current page's full path (only in browser)\n // This ensures that if the call originates from a page, it attempts to redirect back there by default.\n if (!effectiveRedirectUrl && inBrowser()) {\n effectiveRedirectUrl =\n window.location.pathname + window.location.search + window.location.hash;\n }\n\n if (effectiveRedirectUrl && inBrowser()) {\n let signInPagePath: string | undefined;\n try {\n signInPagePath = this.#options.signInUrl\n ? new URL(this.#options.signInUrl, window.location.origin).pathname\n : defaultPagePath;\n } catch {\n signInPagePath = defaultPagePath;\n }\n\n let signUpPagePath: string | undefined;\n try {\n signUpPagePath = this.#options.signUpUrl\n ? new URL(this.#options.signUpUrl, window.location.origin).pathname\n : key === 'signUpUrl'\n ? defaultPagePath\n : '/sign-in';\n } catch {\n signUpPagePath = key === 'signUpUrl' ? defaultPagePath : '/sign-in';\n }\n\n const redirectTargetObj = new URL(effectiveRedirectUrl, window.location.origin);\n\n if (\n redirectTargetObj.pathname === signInPagePath ||\n redirectTargetObj.pathname === signUpPagePath\n ) {\n // If the intended redirect path is the sign-in or sign-up page itself,\n // change the redirect target to the application root ('/').\n effectiveRedirectUrl = '/';\n }\n }\n\n const paramsForBuildUrl: Parameters<typeof buildURL>[0] = {\n base,\n searchParams: new URLSearchParams(),\n };\n\n if (effectiveRedirectUrl) {\n // Check if a redirect URL was determined\n if (inBrowser()) {\n const absoluteRedirectUrl = new URL(effectiveRedirectUrl, window.location.origin).href;\n paramsForBuildUrl.searchParams?.set('redirect_url', absoluteRedirectUrl);\n } else {\n // If not in browser, use the effectiveRedirectUrl as is.\n // This assumes it's either absolute or a path the server can interpret.\n paramsForBuildUrl.searchParams?.set('redirect_url', effectiveRedirectUrl);\n }\n }\n\n const constructedUrl = buildURL(paramsForBuildUrl, {\n stringify: true,\n skipOrigin: false,\n });\n\n if (typeof constructedUrl !== 'string') {\n console.error(\n '[TernSecure] Error: buildURL did not return a string as expected. Falling back to base URL.',\n );\n if (inBrowser()) {\n try {\n return new URL(base, window.location.origin).href;\n } catch {\n return base;\n }\n }\n return base;\n }\n\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignInUrl = (): string => {\n if (!inBrowser()) {\n return '/';\n }\n\n let redirectPath: string | null | undefined = undefined;\n const defaultRedirectPath = '/';\n\n // Priority 1: Check for signInForceRedirectUrl from instance options\n if (this.#options.signInForceRedirectUrl) {\n redirectPath = this.#options.signInForceRedirectUrl;\n }\n\n // Priority 2: If no force redirect, check 'redirect' param in current URL\n if (!redirectPath) {\n const urlParams = new URLSearchParams(window.location.search);\n const redirectPathFromParams = urlParams.get('redirect_url');\n if (redirectPathFromParams) {\n redirectPath = redirectPathFromParams;\n }\n }\n\n // Priority 3: Fallback to default path\n if (!redirectPath) {\n redirectPath = defaultRedirectPath;\n }\n\n const currentPath = window.location.pathname;\n\n if (hasRedirectLoop(currentPath, redirectPath)) {\n //console.warn('[TernSecure] Redirect loop detected. Redirecting to default path.');\n return defaultRedirectPath;\n }\n\n return this.constructUrlWithAuthRedirect(redirectPath);\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public redirectToSignIn = async (options?: SignInRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n const url = this.constructSignInUrl(options);\n window.location.href = url;\n }\n return;\n };\n\n public redirectToSignUp = async (options?: SignUpRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n const redirectUrl = this.constructSignUpUrl();\n window.location.href = redirectUrl;\n }\n return;\n };\n\n redirectAfterSignIn = async (): Promise<void> => {\n if (inBrowser()) {\n const destinationUrl = this.#constructAfterSignInUrl();\n window.location.href = destinationUrl;\n }\n };\n\n redirectAfterSignUp = (): void => {\n throw new Error('redirectAfterSignUp is not implemented yet');\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', { ...options });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', { ...options });\n };\n\n __internal_setCountry = (country: string | null) => {\n if (!this.__internal_country) {\n this.__internal_country = country;\n }\n };\n\n #initOptions = (options: TernSecureAuthOptions): TernSecureAuthOptions => {\n return {\n ...options,\n };\n };\n\n #emit = (): void => {\n for (const listener of this.#listeners) {\n listener({\n user: this.user,\n session: this.signedInSession,\n });\n }\n };\n\n #setStatus(newStatus: TernSecureAuthStatus): void {\n if (this.#status !== newStatus) {\n this.#status = newStatus;\n this.#publicEventBus.emit(ternEvents.Status, this.#status);\n\n if (newStatus === 'ready') {\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n }\n }\n }\n\n #setCreatedActiveSession = (session: TernSecureUser | null) => {\n this.user = session;\n };\n\n #setPersistence = () => {\n const persistenceType = this.#options.persistence;\n\n switch (persistenceType) {\n case 'browserCookie':\n return inMemoryPersistence;\n case 'session':\n return browserSessionPersistence;\n case 'local':\n return browserLocalPersistence;\n case 'none':\n default:\n return inMemoryPersistence;\n }\n };\n\n #emulatorHost = (): string | undefined => {\n if (typeof process === 'undefined') return undefined;\n return process.env.FIREBASE_AUTH_EMULATOR_HOST;\n };\n\n #configureEmulator = (): void => {\n const host = this.#emulatorHost();\n const isDev = this.#instanceType === 'development';\n const shouldUseEmulator = isDev && !!host;\n if (!shouldUseEmulator || !host) {\n return;\n }\n\n const emulatorUrl = host.startsWith('http') ? host : `http://${host}`;\n\n try {\n //(this.auth as unknown as any)._canInitEmulator = true;\n connectAuthEmulator(this.auth, emulatorUrl, { disableWarnings: true });\n console.warn(`[TernSecure] Firebase Auth Emulator connected at ${emulatorUrl}`);\n } catch (error) {\n console.error('[TernSecure] Error connecting to Firebase Auth Emulator:', error);\n }\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/instance/TernAuth.ts"],"sourcesContent":["import { handleFirebaseAuthError } from '@tern-secure/shared/errors';\nimport { createTernAuthEventBus, ternEvents } from '@tern-secure/shared/ternStatusEvent';\nimport { stripScheme } from '@tern-secure/shared/url';\nimport { handleValueOrFn } from '@tern-secure/shared/utils';\nimport type {\n CreateActiveSession,\n DomainOrProxyUrl,\n InstanceType,\n ListenerCallback,\n NavigateOptions,\n RedirectOptions,\n SessionResource,\n SignedInSession,\n SignInRedirectOptions,\n SignInResource,\n SignInResponse,\n SignOut,\n SignOutOptions,\n SignUpRedirectOptions,\n SignUpResource,\n TernAuthSDK,\n TernSecureAuth as TernSecureAuthInterface,\n TernSecureAuthOptions,\n TernSecureAuthStatus,\n TernSecureConfig,\n TernSecureResources,\n TernSecureUser,\n TernSecureUserData,\n UnsubscribeCallback,\n} from '@tern-secure/types';\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApps, initializeApp } from 'firebase/app';\nimport type { Auth, Auth as TernAuth } from 'firebase/auth';\nimport {\n browserLocalPersistence,\n browserPopupRedirectResolver,\n browserSessionPersistence,\n connectAuthEmulator,\n getIdToken,\n getRedirectResult,\n initializeAuth,\n inMemoryPersistence,\n onAuthStateChanged,\n onIdTokenChanged,\n} from 'firebase/auth';\nimport { getInstallations } from 'firebase/installations';\n\nimport { type ClientAuthRequest, createClientAuthRequest } from '../auth/request';\nimport { AuthCookieManager, Session, SignIn, SignUp, TernSecureBase } from '../resources/internal';\nimport { ALLOWED_PROTOCOLS, buildURL, stripOrigin, windowNavigate } from '../utils/';\nimport { RedirectUrls } from '../utils/redirectUrls';\nimport { type ApiClient, createCoreApiClient } from './c_coreApiClient';\nimport { eventBus, events } from './events';\nimport { createClientFromJwt } from './jwtClient';\n\nexport function inBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport { TernAuth };\n\n/**\n * Firebase implementation of the TernSecureAuth interface\n */\nexport class TernSecureAuth implements TernSecureAuthInterface {\n public static version: string = PACKAGE_VERSION;\n public static sdkMetadata: TernAuthSDK = {\n name: PACKAGE_NAME,\n version: PACKAGE_VERSION,\n environment: process.env.NODE_ENV || 'production',\n };\n private static instance: TernSecureAuth | null = null;\n private _currentUser: TernSecureUser | null = null;\n private signedInSession: SignedInSession | null = null;\n private firebaseClientApp: FirebaseApp | undefined;\n private authStateUnsubscribe: (() => void) | null = null;\n private auth!: Auth;\n private csrfToken: string | undefined;\n public isLoading = false;\n public error: Error | null = null;\n public user: TernSecureUser | null | undefined = null;\n public __internal_country?: string | null;\n #domain: DomainOrProxyUrl['domain'];\n #apiClient: ApiClient;\n #apiUrl: string;\n #instanceType?: InstanceType;\n #status: TernSecureAuthInterface['status'] = 'loading';\n #listeners: Array<(emission: TernSecureResources) => void> = [];\n #options: TernSecureAuthOptions = {};\n #authCookieManager?: AuthCookieManager;\n #clientAuthRequest?: ClientAuthRequest;\n #publicEventBus = createTernAuthEventBus();\n\n signIn!: SignInResource | null | undefined;\n signUp!: SignUpResource | null | undefined;\n session!: SessionResource | null | undefined;\n\n get isReady(): boolean {\n return this.status === 'ready';\n }\n\n get status(): TernSecureAuthInterface['status'] {\n return this.#status;\n }\n\n get version(): string {\n return TernSecureAuth.version;\n }\n\n set sdkMetadata(metadata: TernAuthSDK) {\n TernSecureAuth.sdkMetadata = metadata;\n }\n\n get sdkMetadata(): TernAuthSDK {\n return TernSecureAuth.sdkMetadata;\n }\n\n get requiresVerification(): boolean {\n return this.#options.requiresVerification ?? true;\n }\n\n get apiUrl(): string {\n return this.#apiUrl;\n }\n\n get domain(): string {\n if (inBrowser()) {\n const strippedDomainString = stripScheme(\n handleValueOrFn(this.#domain, new URL(window.location.href)),\n );\n if (this.#instanceType === 'production') {\n return strippedDomainString;\n }\n return strippedDomainString;\n }\n return '';\n }\n\n get instanceType() {\n return this.#instanceType;\n }\n\n public constructor(options?: TernSecureAuthOptions) {\n this.#domain = options?.ternSecureConfig?.authDomain;\n this.#apiUrl = options?.apiUrl || '';\n this.#instanceType = (process.env.NODE_ENV as InstanceType) || 'production';\n\n this.#apiClient = createCoreApiClient({\n domain: this.#domain,\n apiUrl: options?.apiUrl,\n instanceType: this.instanceType as InstanceType,\n });\n\n this.#publicEventBus.emit(ternEvents.Status, 'loading');\n TernSecureBase.ternsecure = this;\n }\n\n public getApiClient = (): ApiClient => this.#apiClient;\n\n /**\n * Get user data for the provided ID token via backend API\n */\n public async getUserData(): Promise<TernSecureUserData | null> {\n if (!this.#clientAuthRequest) {\n throw new Error('Client auth request not initialized');\n }\n\n return this.#clientAuthRequest.getUserData();\n }\n\n public setLoading(isLoading: boolean): void {\n this.isLoading = isLoading;\n }\n\n public authCookieManager(): AuthCookieManager | undefined {\n return this.#authCookieManager;\n }\n\n public _internal_getOption<K extends keyof TernSecureAuthOptions>(\n key: K,\n ): TernSecureAuthOptions[K] {\n return this.#options[key];\n }\n\n public _internal_getAllOptions(): Readonly<TernSecureAuthOptions> {\n return Object.freeze({ ...this.#options });\n }\n\n static getOrCreateInstance(options?: TernSecureAuthOptions): TernSecureAuth {\n if (!this.instance) {\n this.instance = new TernSecureAuth(options);\n }\n return this.instance;\n }\n\n static clearInstance() {\n if (TernSecureAuth.instance) {\n if (TernSecureAuth.instance.authStateUnsubscribe) {\n TernSecureAuth.instance.authStateUnsubscribe();\n TernSecureAuth.instance.authStateUnsubscribe = null;\n }\n TernSecureAuth.instance = null;\n }\n }\n\n public static initialize(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getOrCreateInstance(options);\n instance.#initialize(options);\n return instance;\n }\n\n initialize = async (options?: TernSecureAuthOptions): Promise<void> => {\n void this.#initialize(options || {});\n };\n\n public static create(options: TernSecureAuthOptions): TernSecureAuth {\n const instance = this.getOrCreateInstance();\n void instance.initialize(options);\n return instance;\n }\n\n #initialize = (options: TernSecureAuthOptions): void => {\n this.#options = this.#initOptions(options);\n\n try {\n if (!this.#options.ternSecureConfig) {\n throw new Error('TernSecureConfig is required to initialize TernSecureAuth');\n }\n\n if (!this.#options.apiUrl) {\n throw new Error('apiUrl is required to initialize TernSecureAuth');\n }\n\n this.initializeFirebaseApp(this.#options.ternSecureConfig);\n\n const isBrowserCookiePersistence = this.#options.persistence === 'browserCookie';\n\n if (!isBrowserCookiePersistence) {\n this.authStateUnsubscribe = this.initAuthStateListener();\n }\n\n this.#authCookieManager = new AuthCookieManager();\n this.csrfToken = this.#authCookieManager.getCSRFToken();\n\n this.#clientAuthRequest = createClientAuthRequest();\n\n this.signIn = new SignIn(this.auth, this.csrfToken);\n this.signUp = new SignUp(this.auth);\n\n eventBus.on(events.SessionChanged, () => {\n this.#setCreatedActiveSession(this.user || null);\n this.#emit();\n });\n\n this.#setStatus('ready');\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n\n //return this;\n } catch (error) {\n this.error = error as Error;\n this.#setStatus('error');\n this.#publicEventBus.emit(ternEvents.Status, 'error');\n throw error;\n }\n };\n\n private initializeFirebaseApp(config: TernSecureConfig) {\n const appName = config.appName || '[DEFAULT]';\n this.firebaseClientApp = getApps().length === 0 ? initializeApp(config, appName) : getApps()[0];\n\n const persistence = this.#setPersistence();\n const auth = initializeAuth(this.firebaseClientApp, {\n persistence,\n popupRedirectResolver: browserPopupRedirectResolver,\n });\n\n this.auth = auth;\n\n if (config.tenantId) {\n this.auth.tenantId = config.tenantId;\n }\n\n this.#configureEmulator();\n\n getInstallations(this.firebaseClientApp);\n }\n\n /**\n * use when cookie are not httpOnly\n */\n initClient = () => {\n const idTokenInCookie = this.#authCookieManager?.getIdTokenCookie();\n const jwtClient = createClientFromJwt(idTokenInCookie || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n };\n\n /**\n * @deprecated will be removed in future releases.\n */\n initClientAuthRequest = () => {\n this.#clientAuthRequest\n ?.getIdTokenFromCookie()\n .then(idTokenInCookie => {\n const { token } = idTokenInCookie;\n const jwtClient = createClientFromJwt(token || null);\n this.user = jwtClient as TernSecureUser | null;\n this.#emit();\n })\n .catch(error => {\n console.error('[ternauth] Error during client auth request initialization:', error);\n this.user = null;\n this.#emit();\n });\n };\n\n public signOut: SignOut = async (options?: SignOutOptions) => {\n const redirectUrl = options?.redirectUrl || this.#constructAfterSignOutUrl();\n if (options?.onBeforeSignOut) {\n await options.onBeforeSignOut();\n }\n\n await this.auth.signOut();\n\n if (options?.onAfterSignOut) {\n await options.onAfterSignOut();\n }\n\n await this.navigate(redirectUrl);\n\n eventBus.emit(events.UserSignOut, null);\n eventBus.emit(events.TokenUpdate, { token: null });\n this.#emit();\n };\n\n get currentSession(): SignedInSession | null {\n return this.signedInSession;\n }\n\n private initAuthListener(): () => void {\n (async () => {\n await this.auth.authStateReady();\n const user = this.auth.currentUser as TernSecureUser | null;\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n this.#emit();\n })();\n\n // Return a no-op unsubscribe function since we're not setting up a listener\n return () => {\n // No-op: nothing to unsubscribe from\n };\n }\n\n private initAuthStateListener(): () => void {\n return onAuthStateChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private _onIdTokenChanged(): () => void {\n return onIdTokenChanged(this.auth, async (user: TernSecureUser | null) => {\n await this.auth.authStateReady();\n this._currentUser = user;\n this.user = user;\n await this.updateCurrentSession();\n\n this.#emit();\n });\n }\n\n private async getIdToken(): Promise<string | null> {\n await this.auth.authStateReady();\n if (!this.auth.currentUser) {\n return null;\n }\n return getIdToken(this.auth.currentUser);\n }\n\n public onAuthStateChanged(callback: (cb: any) => void): () => void {\n return onAuthStateChanged(this.auth, callback);\n }\n\n public onIdTokenChanged(callback: (cb: any) => void): () => void {\n return onIdTokenChanged(this.auth, callback);\n }\n\n private async updateCurrentSession(): Promise<void> {\n if (!this._currentUser) {\n this.signedInSession = null;\n return;\n }\n\n try {\n const res = await this._currentUser.getIdTokenResult();\n this.signedInSession = {\n status: 'active',\n token: res.token,\n claims: res.claims,\n issuedAtTime: res.issuedAtTime,\n expirationTime: res.expirationTime,\n authTime: res.authTime,\n signInProvider: res.signInProvider || 'unknown',\n signInSecondFactor: res.signInSecondFactor,\n };\n } catch (error) {\n console.error('[TernSecureAuth] Error updating session:', error);\n this.signedInSession = null;\n }\n }\n\n private checkRedirectResult = async (): Promise<SignInResponse | null> => {\n try {\n const result = await getRedirectResult(this.auth);\n if (result) {\n return {\n status: 'success',\n user: result.user as TernSecureUser,\n };\n }\n return null;\n } catch (error) {\n const authError = handleFirebaseAuthError(error);\n return {\n status: 'error',\n message: authError.message,\n error: authError.code,\n };\n }\n };\n\n public getRedirectResult = async (): Promise<any> => {\n return this.checkRedirectResult();\n };\n\n public addListener = (listener: ListenerCallback): UnsubscribeCallback => {\n this.#listeners.push(listener);\n if (this._currentUser) {\n listener({\n user: this._currentUser,\n session: this.signedInSession,\n });\n }\n\n const unsubscribe = () => {\n this.#listeners = this.#listeners.filter(l => l !== listener);\n };\n return unsubscribe;\n };\n\n public on: TernSecureAuthInterface['on'] = (...args) => {\n this.#publicEventBus.on(...args);\n };\n\n public off: TernSecureAuthInterface['off'] = (...args) => {\n this.#publicEventBus.off(...args);\n };\n\n public createActiveSession: CreateActiveSession = async ({\n session,\n redirectUrl,\n }): Promise<void> => {\n try {\n if (!session) {\n throw new Error('No session provided to createActiveSession');\n }\n const sessionResult = await session.getIdTokenResult();\n const sessionData = new Session(sessionResult);\n await sessionData.create(this.csrfToken || '');\n\n if (redirectUrl) {\n await this.navigate(this.constructUrlWithAuthRedirect(redirectUrl));\n }\n\n this.#setCreatedActiveSession(session);\n this.#emit();\n } catch (error) {\n console.error('[TernSecureAuth] Error creating active session:', error);\n }\n };\n\n public navigate = async (to: string | undefined, options?: NavigateOptions): Promise<unknown> => {\n if (!to || !inBrowser()) {\n return;\n }\n\n let toURL = new URL(to, window.location.href);\n\n if (!this.#allowedRedirectProtocols.includes(toURL.protocol)) {\n console.warn(\n `TernSecureAuth: \"${toURL.protocol}\" is not a valid protocol. Redirecting to \"/\" instead. If you think this is a mistake, please open an issue.`,\n );\n toURL = new URL('/', window.location.href);\n }\n\n const customNavigate =\n options?.replace && this.#options.routerReplace\n ? this.#options.routerReplace\n : this.#options.routerPush;\n\n if ((toURL.origin !== 'null' && toURL.origin !== window.location.origin) || !customNavigate) {\n windowNavigate(toURL);\n return;\n }\n\n const metadata = {\n ...(options?.metadata ? { __internal_metadata: options?.metadata } : {}),\n windowNavigate,\n };\n\n // React router only wants the path, search or hash portion.\n return await customNavigate(stripOrigin(toURL), metadata);\n };\n\n public constructUrlWithAuthRedirect = (to: string): string => {\n if (this.#instanceType === 'production') {\n return to;\n }\n const baseUrl = window.location.origin;\n const url = new URL(to, baseUrl);\n\n if (url.origin === window.location.origin) {\n return url.href;\n }\n\n return url.toString();\n };\n\n #buildUrl = (key: 'signInUrl' | 'signUpUrl', options: RedirectOptions): string => {\n if (!key || !this.isReady) {\n return '';\n }\n\n const baseUrlConfig = key === 'signInUrl' ? this.#options.signInUrl : this.#options.signUpUrl;\n const defaultPagePath = key === 'signInUrl' ? '/sign-in' : '/sign-up';\n const base = baseUrlConfig || defaultPagePath;\n\n const redirectUrls = new RedirectUrls(this.#options, options).toSearchParams();\n const constructedUrl = buildURL(\n {\n base,\n hashSearchParams: [redirectUrls],\n },\n {\n stringify: true,\n skipOrigin: false,\n },\n );\n return this.constructUrlWithAuthRedirect(constructedUrl);\n };\n\n #constructAfterSignInUrl = (): string => {\n return this.constructUrlWithAuthRedirect(new RedirectUrls(this.#options).getAfterSignInUrl());\n };\n\n #constructAfterSignOutUrl = (): string => {\n if (!this.#options.afterSignOutUrl) {\n return '/';\n }\n return this.constructUrlWithAuthRedirect(this.#options.afterSignOutUrl);\n };\n\n public redirectToSignIn = async (options?: SignInRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.constructSignInUrl(options));\n }\n return;\n };\n\n public redirectToSignUp = async (options?: SignUpRedirectOptions): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.constructSignUpUrl());\n }\n return;\n };\n\n public redirectAfterSignIn = async (): Promise<unknown> => {\n if (inBrowser()) {\n return this.navigate(this.#constructAfterSignInUrl());\n }\n return;\n };\n\n redirectAfterSignUp = (): void => {\n throw new Error('redirectAfterSignUp is not implemented yet');\n };\n\n public constructSignInUrl = (options?: SignInRedirectOptions): string => {\n return this.#buildUrl('signInUrl', {\n ...options,\n signInForceRedirectUrl: options?.signInForceRedirectUrl || window.location.href,\n });\n };\n\n public constructSignUpUrl = (options?: SignUpRedirectOptions): string => {\n return this.#buildUrl('signUpUrl', {\n ...options,\n signUpForceRedirectUrl: options?.signUpForceRedirectUrl || window.location.href,\n });\n };\n\n get #allowedRedirectProtocols() {\n let allowedProtocols = ALLOWED_PROTOCOLS;\n\n if (this.#options.allowedRedirectProtocols) {\n allowedProtocols = allowedProtocols.concat(this.#options.allowedRedirectProtocols);\n }\n\n return allowedProtocols;\n }\n\n __internal_setCountry = (country: string | null) => {\n if (!this.__internal_country) {\n this.__internal_country = country;\n }\n };\n\n #initOptions = (options: TernSecureAuthOptions): TernSecureAuthOptions => {\n return {\n ...options,\n };\n };\n\n #emit = (): void => {\n for (const listener of this.#listeners) {\n listener({\n user: this.user,\n session: this.signedInSession,\n });\n }\n };\n\n #setStatus(newStatus: TernSecureAuthStatus): void {\n if (this.#status !== newStatus) {\n this.#status = newStatus;\n this.#publicEventBus.emit(ternEvents.Status, this.#status);\n\n if (newStatus === 'ready') {\n this.#publicEventBus.emit(ternEvents.Status, 'ready');\n }\n }\n }\n\n #setCreatedActiveSession = (session: TernSecureUser | null) => {\n this.user = session;\n };\n\n #setPersistence = () => {\n const persistenceType = this.#options.persistence;\n\n switch (persistenceType) {\n case 'browserCookie':\n return inMemoryPersistence;\n case 'session':\n return browserSessionPersistence;\n case 'local':\n return browserLocalPersistence;\n case 'none':\n default:\n return inMemoryPersistence;\n }\n };\n\n #emulatorHost = (): string | undefined => {\n if (typeof process === 'undefined') return undefined;\n return process.env.FIREBASE_AUTH_EMULATOR_HOST;\n };\n\n #configureEmulator = (): void => {\n const host = this.#emulatorHost();\n const isDev = this.#instanceType === 'development';\n const shouldUseEmulator = isDev && !!host;\n if (!shouldUseEmulator || !host) {\n return;\n }\n\n const emulatorUrl = host.startsWith('http') ? host : `http://${host}`;\n\n try {\n //(this.auth as unknown as any)._canInitEmulator = true;\n connectAuthEmulator(this.auth, emulatorUrl, { disableWarnings: false });\n console.warn(`[TernSecure] Firebase Auth Emulator connected at ${emulatorUrl}`);\n } catch (error) {\n console.error('[TernSecure] Error connecting to Firebase Auth Emulator:', error);\n }\n };\n}\n"],"mappings":"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","names":["import_utils"]}
|