tenneo-auth-plugin 0.1.7 → 0.1.9

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/index.mjs CHANGED
@@ -1,4 +1,3 @@
1
- import { z } from 'zod';
2
1
  import axios from 'axios';
3
2
  import { createContext, useContext, useMemo, useRef, useLayoutEffect, useEffect, useState, useCallback } from 'react';
4
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -67,13 +66,11 @@ function extractTenantKeyFromUrl(url, config, getStorage3, getKey) {
67
66
  if (keyFromHost) return keyFromHost;
68
67
  const clientCode = config.getClientCode();
69
68
  if (clientCode?.trim()) return clientCode.trim();
70
- const tenantId = config.getTenantId();
71
- if (tenantId?.trim()) return tenantId.trim();
72
69
  return config.getClientCode();
73
70
  } catch {
74
71
  const clientCode = config.getClientCode();
75
72
  if (clientCode?.trim()) return clientCode.trim();
76
- return config.getTenantId() || config.getClientCode();
73
+ return config.getClientCode();
77
74
  }
78
75
  }
79
76
  function isCallbackUrlFromUrl(url) {
@@ -804,85 +801,6 @@ function generateState() {
804
801
  return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
805
802
  }
806
803
 
807
- // src/config/env.ts
808
- var ENV_KEYS = {
809
- CLIENT_ID: ["VITE_CLIENT_ID", "CLIENT_ID"],
810
- TENANT_ID: ["VITE_TENANT_ID", "TENANT_ID"],
811
- CLIENTCODE: ["VITE_CLIENTCODE", "CLIENTCODE"]
812
- };
813
- function getEnvValue(keys) {
814
- try {
815
- const g = typeof globalThis !== "undefined" ? globalThis : null;
816
- const env = g?.process && typeof g.process.env === "object" ? g.process.env : null;
817
- if (env) {
818
- for (const key of keys) {
819
- const v = env[key];
820
- if (v != null && String(v).trim()) return String(v).trim();
821
- }
822
- }
823
- } catch {
824
- }
825
- try {
826
- const meta = typeof import.meta !== "undefined" ? import.meta.env : void 0;
827
- if (meta) {
828
- for (const key of keys) {
829
- const v = meta[key];
830
- if (v != null && String(v).trim()) return String(v).trim();
831
- }
832
- }
833
- } catch {
834
- }
835
- return "";
836
- }
837
- var FORBIDDEN_WINDOW_KEYS = ["apiBaseUrl", "apiTenantResolutionBaseUrl", "apiAuthBaseUrl", "authServerUrl", "defaultDomain", "API_BASE_URL", "AUTH_SERVER_URL", "DEFAULT_DOMAIN"];
838
- function getWindowConfigRaw() {
839
- if (typeof window === "undefined") return null;
840
- const w = window;
841
- const raw = w.__AUTH_CONFIG__ ?? w.__APP_CONFIG__;
842
- if (!raw || typeof raw !== "object") return null;
843
- for (const forbidden of FORBIDDEN_WINDOW_KEYS) {
844
- if (forbidden in raw) {
845
- throw new Error("Attempted to override protected internal configuration");
846
- }
847
- }
848
- const out = {};
849
- const map = {
850
- clientId: "CLIENT_ID",
851
- tenantId: "TENANT_ID",
852
- clientcode: "CLIENTCODE"
853
- };
854
- for (const [winKey, sdkKey] of Object.entries(map)) {
855
- const v = raw[winKey];
856
- if (v != null && typeof v === "string" && v.trim()) out[sdkKey] = v.trim();
857
- }
858
- return Object.keys(out).length ? out : null;
859
- }
860
- function loadEnvConfig() {
861
- const partial = {};
862
- for (const [key, envKeys] of Object.entries(ENV_KEYS)) {
863
- const v = getEnvValue(envKeys);
864
- if (v) partial[key] = v;
865
- }
866
- return partial;
867
- }
868
- function loadWindowConfig() {
869
- const raw = getWindowConfigRaw();
870
- if (!raw) return null;
871
- return raw;
872
- }
873
- var schema = z.object({
874
- CLIENT_ID: z.string().min(1, "CLIENT_ID is required"),
875
- TENANT_ID: z.string().min(1, "TENANT_ID is required"),
876
- CLIENTCODE: z.string().min(1, "CLIENTCODE is required")
877
- });
878
- function validateConfig(data) {
879
- return schema.parse(data);
880
- }
881
-
882
- // src/config/types.ts
883
- var INTERNAL_CONFIG_KEYS = ["API_TENANT_RESOLUTION_BASE_URL", "API_AUTH_BASE_URL", "AUTH_SERVER_URL", "DEFAULT_DOMAIN"];
884
- var RUNTIME_CONFIG_KEYS = ["CLIENT_ID", "TENANT_ID", "CLIENTCODE"];
885
-
886
804
  // src/config/constants.ts
887
805
  var OAUTH_CONSTANTS = {
888
806
  SCOPES: "openid profile email",
@@ -910,232 +828,63 @@ var DEFAULT_TOKEN_GRANT_TYPE = OAUTH_CONSTANTS.TOKEN_GRANT_TYPE;
910
828
  var DEFAULT_REFRESH_GRANT_TYPE = OAUTH_CONSTANTS.REFRESH_GRANT_TYPE;
911
829
 
912
830
  // src/config/index.ts
913
- var INTERNAL_DEFAULTS = {
914
- API_TENANT_RESOLUTION_BASE_URL: "https://localhost:5020/api/v1",
915
- API_AUTH_BASE_URL: "https://localhost:5001",
916
- AUTH_SERVER_URL: "https://localhost:5001",
917
- DEFAULT_DOMAIN: "https://localhost:5001"
918
- };
919
- function envOr(key) {
920
- const v = getEnvValue([`VITE_${key}`, key]);
921
- return v && v.trim() ? v.trim() : INTERNAL_DEFAULTS[key];
922
- }
923
- var INTERNAL_CONFIG = Object.freeze({
924
- API_TENANT_RESOLUTION_BASE_URL: envOr("API_TENANT_RESOLUTION_BASE_URL"),
925
- API_AUTH_BASE_URL: envOr("API_AUTH_BASE_URL"),
926
- AUTH_SERVER_URL: envOr("AUTH_SERVER_URL"),
927
- DEFAULT_DOMAIN: envOr("DEFAULT_DOMAIN")
928
- });
929
- var RUNTIME_CONFIG_DEFAULTS = Object.freeze({
930
- CLIENT_ID: "tenneo",
931
- TENANT_ID: "00000000-0000-0000-0000-000000000001",
932
- CLIENTCODE: "productlms"
933
- });
934
- function pickRuntimeConfig(source) {
935
- if (!source) return {};
936
- const picked = {};
937
- for (const key of RUNTIME_CONFIG_KEYS) {
938
- const value = source[key];
939
- if (value != null && typeof value === "string") {
940
- const trimmed = value.trim();
941
- if (trimmed) picked[key] = trimmed;
942
- }
943
- }
944
- return picked;
945
- }
946
- ({
947
- ...INTERNAL_CONFIG,
948
- ...RUNTIME_CONFIG_DEFAULTS
949
- });
950
- var runtimeOverrides = {};
951
- var runtimeConfigOverrides = {};
952
- function mergeRuntime(base, ...sources) {
953
- let out = { ...base };
954
- for (const src of sources) {
955
- if (!src) continue;
956
- for (const key of Object.keys(src)) {
957
- const value = src[key];
958
- if (value != null && String(value).trim() !== "") out[key] = String(value).trim();
959
- }
960
- }
961
- return out;
962
- }
963
- function assertNoInternalOverrides(source) {
964
- if (!source) return;
965
- for (const key of INTERNAL_CONFIG_KEYS) {
966
- if (source[key] !== void 0) throw new Error("Attempted to override protected internal configuration");
967
- }
968
- }
969
- var INTERNAL_KEY_SET = new Set(INTERNAL_CONFIG_KEYS);
970
- var HOST_TO_RUNTIME_KEYS = {
971
- clientId: "CLIENT_ID",
972
- tenantId: "TENANT_ID",
973
- clientcode: "CLIENTCODE"
974
- };
975
- function sanitizeRuntimeOverrides(source) {
976
- if (!source) return void 0;
977
- const filtered = {};
978
- for (const [key, raw] of Object.entries(source)) {
979
- if (raw == null) continue;
980
- if (INTERNAL_KEY_SET.has(key)) continue;
981
- const trimmed = String(raw).trim();
982
- if (!trimmed) continue;
983
- const sdkKey = HOST_TO_RUNTIME_KEYS[key] ?? key;
984
- filtered[sdkKey] = trimmed;
985
- }
986
- const picked = pickRuntimeConfig(filtered);
987
- return Object.keys(picked).length ? picked : void 0;
831
+ var inMemoryConfig = {};
832
+ function readHostConfigFromStorage() {
833
+ try {
834
+ const raw = getStorage(getStorageKey("host_config"));
835
+ if (!raw) return {};
836
+ const parsed = JSON.parse(raw);
837
+ return parsed && typeof parsed === "object" ? parsed : {};
838
+ } catch {
839
+ return {};
840
+ }
841
+ }
842
+ function resolveMerged(overrides) {
843
+ const stored = readHostConfigFromStorage();
844
+ const cfg = { ...stored, ...inMemoryConfig, ...overrides ?? {} };
845
+ const trimmed = (v) => v == null ? "" : String(v).trim();
846
+ return {
847
+ apiBaseUrl: trimmed(cfg.apiBaseUrl),
848
+ authServerUrl: trimmed(cfg.authServerUrl),
849
+ callbackUrl: trimmed(cfg.callbackUrl),
850
+ clientCode: trimmed(cfg.clientCode)
851
+ };
988
852
  }
989
853
  function resolveConfig(overrides) {
990
- assertNoInternalOverrides(runtimeOverrides);
991
- assertNoInternalOverrides(overrides);
992
- const windowCfg = loadWindowConfig();
993
- const envCfg = loadEnvConfig();
994
- const mergedRuntime = mergeRuntime(
995
- RUNTIME_CONFIG_DEFAULTS,
996
- envCfg,
997
- windowCfg ?? void 0,
998
- runtimeOverrides,
999
- sanitizeRuntimeOverrides(overrides)
1000
- );
1001
- const validatedRuntime = validateConfig(mergedRuntime);
1002
- return { ...INTERNAL_CONFIG, ...validatedRuntime };
854
+ return resolveMerged(overrides);
1003
855
  }
1004
856
  function getConfig() {
1005
- return resolveConfig();
857
+ return resolveMerged();
1006
858
  }
1007
859
  function setConfig(overrides) {
1008
- assertNoInternalOverrides(overrides);
1009
- const sanitized = sanitizeRuntimeOverrides(overrides);
1010
- if (sanitized) runtimeOverrides = { ...runtimeOverrides, ...sanitized };
1011
- const { basePath, redirectUri } = overrides;
1012
- if (basePath != null && basePath.trim() !== "") runtimeConfigOverrides = { ...runtimeConfigOverrides, basePath: basePath.trim() };
1013
- if (redirectUri != null && redirectUri.trim() !== "") runtimeConfigOverrides = { ...runtimeConfigOverrides, redirectUri: redirectUri.trim() };
860
+ inMemoryConfig = { ...inMemoryConfig, ...overrides };
1014
861
  }
1015
862
  function clearConfigOverrides() {
1016
- runtimeOverrides = {};
1017
- runtimeConfigOverrides = {};
1018
- }
1019
- function getWindowBasePath() {
1020
- if (typeof window === "undefined") return "";
1021
- const w = window;
1022
- const raw = w.__AUTH_CONFIG__ ?? w.__APP_CONFIG__;
1023
- const bp = raw?.basePath;
1024
- if (bp != null && typeof bp === "string" && bp.trim()) return bp.trim();
1025
- const pathname = window.location.pathname;
1026
- const segments = pathname.split("/").filter(Boolean);
1027
- const commonRoutes = ["dashboards", "callback", "confirmation", "client-confirmed", "client-provisioned", "approval-completed"];
1028
- if (segments.length > 0 && !commonRoutes.includes(segments[0])) {
1029
- let base = "/" + segments[0];
1030
- if (base.endsWith("/")) base = base.slice(0, -1);
1031
- return base;
1032
- }
1033
- return "";
1034
- }
1035
- function getBasePath() {
1036
- if (runtimeConfigOverrides.basePath != null && runtimeConfigOverrides.basePath !== "") return runtimeConfigOverrides.basePath;
1037
- return getWindowBasePath();
863
+ inMemoryConfig = {};
1038
864
  }
1039
865
  function getRedirectUri2() {
1040
- if (typeof window !== "undefined") {
1041
- return `${window.location.origin}/callback`;
1042
- }
1043
- return getEnvValue(["VITE_REDIRECT_URI", "REDIRECT_URI"]) || "http://localhost:5173/callback";
1044
- }
1045
- function hasRuntimeConfig() {
1046
- return loadWindowConfig() !== null || Object.keys(runtimeOverrides).length > 0;
866
+ const cfg = resolveMerged();
867
+ if (cfg.callbackUrl) return cfg.callbackUrl;
868
+ if (typeof window !== "undefined") return `${window.location.origin}/callback`;
869
+ return "";
1047
870
  }
1048
871
  var Config = {
1049
- getApiTenantResolutionBaseUrl() {
1050
- return getConfig().API_TENANT_RESOLUTION_BASE_URL;
1051
- },
1052
- getApiAuthBaseUrl() {
1053
- return getConfig().API_AUTH_BASE_URL;
872
+ getApiBaseUrl() {
873
+ return resolveMerged().apiBaseUrl;
1054
874
  },
1055
875
  getAuthServerUrl() {
1056
- return getConfig().AUTH_SERVER_URL;
1057
- },
1058
- getDefaultDomain() {
1059
- return getConfig().DEFAULT_DOMAIN;
1060
- },
1061
- getClientId() {
1062
- return getConfig().CLIENT_ID;
1063
- },
1064
- getTenantId() {
1065
- return getConfig().TENANT_ID;
876
+ return resolveMerged().authServerUrl;
1066
877
  },
1067
878
  getClientCode() {
1068
- return getConfig().CLIENTCODE;
879
+ return resolveMerged().clientCode;
1069
880
  },
1070
881
  getRedirectUri() {
1071
882
  return getRedirectUri2();
1072
883
  },
1073
- getBasePath() {
1074
- return getBasePath();
1075
- },
1076
- hasRuntimeConfig() {
1077
- return hasRuntimeConfig();
1078
- },
1079
884
  getAll() {
1080
- const c = getConfig();
1081
- return {
1082
- apiTenantResolutionBaseUrl: c.API_TENANT_RESOLUTION_BASE_URL,
1083
- apiAuthBaseUrl: c.API_AUTH_BASE_URL,
1084
- authServerUrl: c.AUTH_SERVER_URL,
1085
- defaultDomain: c.DEFAULT_DOMAIN,
1086
- clientId: c.CLIENT_ID,
1087
- tenantId: c.TENANT_ID,
1088
- clientCode: c.CLIENTCODE,
1089
- redirectUri: getRedirectUri2(),
1090
- basePath: getBasePath()
1091
- };
885
+ return resolveMerged();
1092
886
  }
1093
887
  };
1094
- ({
1095
- AUTH_SERVER_URL: Config.getAuthServerUrl(),
1096
- CLIENT_ID: Config.getClientId(),
1097
- TENANT_ID: Config.getTenantId(),
1098
- CLIENTCODE: Config.getClientCode()
1099
- });
1100
- function getEnvConfig() {
1101
- const authServerUrl = Config.getAuthServerUrl();
1102
- const clientId = Config.getClientId();
1103
- const tenantId = Config.getTenantId();
1104
- const redirectUri = Config.getRedirectUri();
1105
- try {
1106
- new URL(authServerUrl);
1107
- new URL(redirectUri);
1108
- } catch {
1109
- return Promise.resolve(null);
1110
- }
1111
- return Promise.resolve({
1112
- authServerUrl: authServerUrl.trim(),
1113
- clientId: clientId.trim(),
1114
- redirectUri: redirectUri.trim(),
1115
- tenantId: tenantId.trim()
1116
- });
1117
- }
1118
- function getEnvConfigSync() {
1119
- const authServerUrl = Config.getAuthServerUrl();
1120
- const clientId = Config.getClientId();
1121
- const tenantId = Config.getTenantId();
1122
- const redirectUri = Config.getRedirectUri();
1123
- try {
1124
- new URL(authServerUrl);
1125
- new URL(redirectUri);
1126
- } catch {
1127
- return null;
1128
- }
1129
- return {
1130
- authServerUrl: authServerUrl.trim(),
1131
- clientId: clientId.trim(),
1132
- redirectUri: redirectUri.trim(),
1133
- tenantId: tenantId.trim()
1134
- };
1135
- }
1136
- function hasEnvFallback() {
1137
- return getEnvConfigSync() !== null;
1138
- }
1139
888
 
1140
889
  // src/utils/validation.ts
1141
890
  function isValidGuid(guid) {
@@ -1289,7 +1038,8 @@ function storeTenantConfig(config) {
1289
1038
  if (!validation.isValid) {
1290
1039
  logger.warn("Tenant ID validation failed", { tenantId: config.tenantId });
1291
1040
  }
1292
- setStorage(STORAGE_KEYS.authServerUrl, config.authServer);
1041
+ const authServerToStore = Config.getAuthServerUrl() || config.authServer;
1042
+ setStorage(STORAGE_KEYS.authServerUrl, authServerToStore);
1293
1043
  setStorage(STORAGE_KEYS.clientId, config.client.clientId);
1294
1044
  setStorage(STORAGE_KEYS.redirectUri, Config.getRedirectUri());
1295
1045
  setStorage(STORAGE_KEYS.tenantId, config.tenantId);
@@ -1300,6 +1050,22 @@ function storeTenantConfig(config) {
1300
1050
  async function initiateAuthFlow(config) {
1301
1051
  try {
1302
1052
  logger.info("Initiating OAuth authorization flow");
1053
+ const authServerFromProps = Config.getAuthServerUrl();
1054
+ const authServerEffective = (authServerFromProps || config?.authServer || "").replace(/\/+$/, "");
1055
+ const redirectUriEffective = Config.getRedirectUri();
1056
+ const storedTenantId = getStorage(STORAGE_KEYS.tenantId);
1057
+ const storedClientId = getStorage(STORAGE_KEYS.clientId);
1058
+ const tenantIdEffective = storedTenantId || config?.tenantId || "";
1059
+ const clientIdEffective = storedClientId || config?.client?.clientId || "";
1060
+ logger.debug("[initiateAuthFlow] Resolved inputs", {
1061
+ authServerFromProps: authServerFromProps ? "(provided)" : "(empty)",
1062
+ authServerEffective,
1063
+ redirectUriEffective,
1064
+ tenantIdEffective,
1065
+ clientIdEffective,
1066
+ scopes: config?.client?.scopes,
1067
+ hasRuntime: !!getAuthRuntime()
1068
+ });
1303
1069
  const token = getAccessToken();
1304
1070
  if (token && !isAccessTokenExpired()) {
1305
1071
  logger.debug("Valid token already exists, skipping auth flow");
@@ -1321,10 +1087,17 @@ async function initiateAuthFlow(config) {
1321
1087
  }
1322
1088
  }
1323
1089
  setFlowFlags();
1324
- if (!config?.authServer || !config.client?.clientId || !config.client?.redirectUri) {
1090
+ if (!(Config.getAuthServerUrl() || config?.authServer) || !config.client?.clientId || !config.client?.redirectUri) {
1091
+ logger.error("[initiateAuthFlow] Missing required tenant config", {
1092
+ authServerEffective,
1093
+ clientId: config?.client?.clientId,
1094
+ redirectUriFromTenantApi: config?.client?.redirectUri,
1095
+ redirectUriEffective
1096
+ });
1325
1097
  throw new Error("Invalid tenant configuration for auth flow");
1326
1098
  }
1327
1099
  storeTenantConfig(config);
1100
+ logger.debug("[initiateAuthFlow] Stored tenant config, generating PKCE");
1328
1101
  const codeVerifier = generateCodeVerifier();
1329
1102
  const codeChallenge = await generateCodeChallenge(codeVerifier);
1330
1103
  const state = generateState();
@@ -1333,6 +1106,10 @@ async function initiateAuthFlow(config) {
1333
1106
  setStorage(STORAGE_KEYS.codeVerifier, codeVerifier);
1334
1107
  setStorage(STORAGE_KEYS.state, state);
1335
1108
  const authUrl = buildAuthorizationUrl(config, codeChallenge, state);
1109
+ logger.debug("[initiateAuthFlow] Built authorization URL", {
1110
+ authServerEffective,
1111
+ urlPrefix: authUrl?.slice(0, 80)
1112
+ });
1336
1113
  if (!authUrl || !(authUrl.startsWith("http://") || authUrl.startsWith("https://"))) {
1337
1114
  throw new Error("Invalid authorization URL generated");
1338
1115
  }
@@ -1344,8 +1121,15 @@ async function initiateAuthFlow(config) {
1344
1121
  logger.info("Redirecting to authorization server");
1345
1122
  emitAuthEvent(AuthEventNames.LOGIN_STARTED, { tenantKey: config.tenantKey });
1346
1123
  const runtime = getAuthRuntime();
1347
- if (runtime) runtime.urlProvider.redirect(authUrl);
1348
- else if (typeof window !== "undefined") window.location.replace(authUrl);
1124
+ if (runtime) {
1125
+ logger.debug("[initiateAuthFlow] Redirect via runtime.urlProvider.redirect");
1126
+ runtime.urlProvider.redirect(authUrl);
1127
+ } else if (typeof window !== "undefined") {
1128
+ logger.debug("[initiateAuthFlow] Redirect via window.location.replace");
1129
+ window.location.replace(authUrl);
1130
+ } else {
1131
+ logger.error("[initiateAuthFlow] No runtime and no window; cannot redirect", { authUrl });
1132
+ }
1349
1133
  } catch (error) {
1350
1134
  clearFlowFlags();
1351
1135
  logger.error("Failed to initiate auth flow", {
@@ -1355,9 +1139,10 @@ async function initiateAuthFlow(config) {
1355
1139
  }
1356
1140
  }
1357
1141
  function buildAuthorizationUrl(config, codeChallenge, state) {
1142
+ const authServerBase = (Config.getAuthServerUrl() || config.authServer || "").replace(/\/+$/, "");
1358
1143
  if (isLocalhost2()) {
1359
1144
  logger.debug("Building authorization URL", {
1360
- authServer: config.authServer,
1145
+ authServer: authServerBase,
1361
1146
  clientId: config.client.clientId,
1362
1147
  redirectUri: config.client.redirectUri,
1363
1148
  scopes: config.client.scopes
@@ -1378,7 +1163,7 @@ function buildAuthorizationUrl(config, codeChallenge, state) {
1378
1163
  code_challenge: codeChallenge,
1379
1164
  code_challenge_method: DEFAULT_CODE_CHALLENGE_METHOD
1380
1165
  });
1381
- return `${config.authServer}/connect/authorize?${params.toString()}`;
1166
+ return `${authServerBase}/connect/authorize?${params.toString()}`;
1382
1167
  }
1383
1168
 
1384
1169
  // src/strategies/oauth2-pkce/token-exchange.ts
@@ -1408,7 +1193,7 @@ function storeTokens(tokenData) {
1408
1193
  async function exchangeCodeForTokens(params) {
1409
1194
  try {
1410
1195
  const { code, codeVerifier, clientId, redirectUri } = params;
1411
- const apiAuthBaseUrl = Config.getApiAuthBaseUrl();
1196
+ const apiAuthBaseUrl = Config.getAuthServerUrl();
1412
1197
  const tokenUrl = `${apiAuthBaseUrl}/oauth/token`;
1413
1198
  const body = new URLSearchParams({
1414
1199
  grant_type: DEFAULT_TOKEN_GRANT_TYPE,
@@ -1482,7 +1267,7 @@ async function refreshAccessToken() {
1482
1267
  });
1483
1268
  throw new Error("Cannot refresh token: missing required data");
1484
1269
  }
1485
- const apiAuthBaseUrl = Config.getApiAuthBaseUrl();
1270
+ const apiAuthBaseUrl = Config.getApiBaseUrl();
1486
1271
  const tokenUrl = `${apiAuthBaseUrl}/oauth/refresh`;
1487
1272
  const body = new URLSearchParams({
1488
1273
  grant_type: DEFAULT_REFRESH_GRANT_TYPE,
@@ -1879,40 +1664,15 @@ function mergeConfigWithProps(apiEnvConfig, propsConfig, tenantKey) {
1879
1664
  }
1880
1665
  };
1881
1666
  }
1882
- async function buildTenantConfigFromEnv() {
1883
- const envConfig = await getEnvConfig();
1884
- if (!envConfig) return null;
1885
- return {
1886
- tenantId: envConfig.tenantId,
1887
- authServer: envConfig.authServerUrl,
1888
- client: {
1889
- clientId: envConfig.clientId,
1890
- redirectUri: envConfig.redirectUri,
1891
- scopes: "openid profile email"
1892
- }
1893
- };
1894
- }
1895
1667
  async function resolveTenantConfig(tenantKey, tenantResolver) {
1896
1668
  if (!tenantKey) return null;
1897
1669
  const propsConfig = getPropsConfig();
1898
- let apiEnvConfig = null;
1899
- let apiResolved = false;
1900
- apiEnvConfig = await tenantResolver.resolve(tenantKey);
1901
- apiResolved = !!apiEnvConfig;
1902
- if (!apiEnvConfig) {
1903
- apiEnvConfig = await buildTenantConfigFromEnv();
1904
- }
1905
- if (!apiEnvConfig) return null;
1906
- if (!apiResolved && propsConfig) {
1907
- const mergedConfig = mergeConfigWithProps(apiEnvConfig, propsConfig, tenantKey);
1908
- removeStorage(getStorageKey("props_config"));
1909
- logger.info("Merged props config with ENV fallback config");
1910
- return mergedConfig;
1911
- }
1670
+ const resolved = await tenantResolver.resolve(tenantKey);
1671
+ if (!resolved) return null;
1912
1672
  removeStorage(getStorageKey("props_config"));
1913
1673
  return {
1914
- ...apiEnvConfig,
1915
- tenantKey: tenantKey || apiEnvConfig.tenantKey
1674
+ ...propsConfig ? mergeConfigWithProps(resolved, propsConfig, tenantKey) : resolved,
1675
+ tenantKey: tenantKey || resolved.tenantKey
1916
1676
  };
1917
1677
  }
1918
1678
  async function resolveTenantConfigCached(tenantKey, tenantResolver) {
@@ -2106,6 +1866,8 @@ var LoginFlow = class {
2106
1866
  const { runtime } = context;
2107
1867
  const { logger: log } = runtime;
2108
1868
  const getUrl = () => runtime.urlProvider.getCurrentUrl();
1869
+ const url = getUrl();
1870
+ log.debug("[LoginFlow] Start", { url: url.href, pathname: url.pathname, search: url.search });
2109
1871
  const callbackProcessed = getStorage(getStorageKey("callback_processed")) === "true";
2110
1872
  const token = getAccessToken();
2111
1873
  if (callbackProcessed && !token) {
@@ -2115,7 +1877,8 @@ var LoginFlow = class {
2115
1877
  }
2116
1878
  const wasStateMismatch = getStorage(getStorageKey("state_mismatch")) === "true";
2117
1879
  if (wasStateMismatch) removeStorage(getStorageKey("state_mismatch"));
2118
- const tenantKey = getTenantKeyFromRuntime(getUrl(), runtime.configProvider);
1880
+ const tenantKey = getTenantKeyFromRuntime(url, runtime.configProvider);
1881
+ log.debug("[LoginFlow] Tenant key resolved", { tenantKey: tenantKey ?? "(null)" });
2119
1882
  if (!tenantKey) {
2120
1883
  throw new SanitizedError(
2121
1884
  "TENANT_KEY_RESOLUTION_FAILED",
@@ -2123,7 +1886,15 @@ var LoginFlow = class {
2123
1886
  new Error("Tenant key missing")
2124
1887
  );
2125
1888
  }
1889
+ log.debug("[LoginFlow] Resolving tenant config", { tenantKey });
2126
1890
  const tenantConfig = await resolveTenantConfigCached(tenantKey, runtime.tenantResolver);
1891
+ log.debug("[LoginFlow] Tenant config resolved", {
1892
+ ok: !!tenantConfig,
1893
+ tenantId: tenantConfig?.tenantId,
1894
+ authServer: tenantConfig?.authServer ? "(set)" : "(empty)",
1895
+ clientId: tenantConfig?.client?.clientId,
1896
+ redirectUri: tenantConfig?.client?.redirectUri
1897
+ });
2127
1898
  if (!tenantConfig) {
2128
1899
  throw new SanitizedError(
2129
1900
  "TENANT_CONFIG_RESOLUTION_FAILED",
@@ -2133,7 +1904,9 @@ var LoginFlow = class {
2133
1904
  }
2134
1905
  setTenantKey(tenantKey);
2135
1906
  storeTenantConfig(tenantConfig);
1907
+ log.debug("[LoginFlow] Stored tenant config, initiating auth flow");
2136
1908
  await initiateAuthFlow(tenantConfig);
1909
+ log.debug("[LoginFlow] Auth flow initiated (redirect should happen)");
2137
1910
  return { completed: true };
2138
1911
  }
2139
1912
  };
@@ -2482,7 +2255,74 @@ function resetCookieWatcher() {
2482
2255
  authCookies
2483
2256
  });
2484
2257
  }
2258
+
2259
+ // src/infrastructure/watchers/storage-watcher.ts
2260
+ var isWatching2 = false;
2261
+ var lastStorageCheck = null;
2262
+ var storageEventListener = null;
2263
+ function checkStorageCleared() {
2264
+ try {
2265
+ const hasAnyAuthData = Object.values(STORAGE_KEYS).some(
2266
+ (key) => getStorage(key) !== null
2267
+ );
2268
+ if (lastStorageCheck === "had_data" && !hasAnyAuthData) return true;
2269
+ lastStorageCheck = hasAnyAuthData ? "had_data" : "no_data";
2270
+ return false;
2271
+ } catch {
2272
+ return false;
2273
+ }
2274
+ }
2275
+ function handleStorageEvent(event) {
2276
+ if (typeof window !== "undefined" && event.storageArea === window.sessionStorage) {
2277
+ const wasCleared = checkStorageCleared();
2278
+ if (wasCleared) {
2279
+ logger.info("Detected manual sessionStorage clear! Redirecting to login...");
2280
+ const cb = getSessionClearedCallback();
2281
+ if (cb) {
2282
+ Promise.resolve(cb()).catch((error) => {
2283
+ logger.error("Failed to redirect to login after manual clear", {
2284
+ error: error instanceof Error ? error.message : String(error)
2285
+ });
2286
+ });
2287
+ }
2288
+ }
2289
+ }
2290
+ }
2291
+ function startStorageWatcher() {
2292
+ if (isWatching2) return;
2293
+ isWatching2 = true;
2294
+ checkStorageCleared();
2295
+ storageEventListener = handleStorageEvent;
2296
+ window.addEventListener("storage", storageEventListener);
2297
+ const pollInterval = setInterval(() => {
2298
+ const logoutInProgress = typeof window !== "undefined" && window.localStorage.getItem(getStorageKey("logout_in_progress")) === "true";
2299
+ if (logoutInProgress) {
2300
+ logger.debug("Logout detected. Storage watcher will not trigger bootstrap.");
2301
+ return;
2302
+ }
2303
+ const wasCleared = checkStorageCleared();
2304
+ if (wasCleared) {
2305
+ logger.info("Detected manual sessionStorage clear (polling)! Redirecting to login...");
2306
+ clearInterval(pollInterval);
2307
+ const cb = getSessionClearedCallback();
2308
+ if (cb) {
2309
+ Promise.resolve(cb()).catch((error) => {
2310
+ logger.error("Failed to redirect to login after manual clear", {
2311
+ error: error instanceof Error ? error.message : String(error)
2312
+ });
2313
+ if (!isWatching2) startStorageWatcher();
2314
+ });
2315
+ }
2316
+ }
2317
+ }, 1e3);
2318
+ window.__tenneo_auth_storage_watcher_interval = pollInterval;
2319
+ }
2485
2320
  function stopStorageWatcher() {
2321
+ isWatching2 = false;
2322
+ if (storageEventListener) {
2323
+ window.removeEventListener("storage", storageEventListener);
2324
+ storageEventListener = null;
2325
+ }
2486
2326
  const win = window;
2487
2327
  const intervalId = win.__tenneo_auth_storage_watcher_interval;
2488
2328
  if (intervalId) {
@@ -2532,51 +2372,68 @@ function buildUrl(baseUrl, path) {
2532
2372
  url.pathname = url.pathname.endsWith("/") ? `${url.pathname}${normalizedPath.slice(1)}` : `${url.pathname}${normalizedPath}`;
2533
2373
  return url.toString();
2534
2374
  }
2535
- async function callServerLogout(logoutUrl) {
2375
+ function getCsrfToken() {
2536
2376
  try {
2377
+ if (typeof document === "undefined") return null;
2378
+ const meta = document.querySelector('meta[name="csrf-token"]');
2379
+ if (meta?.content) return meta.content;
2380
+ const match = document.cookie.match(/(?:^|;\s*)XSRF-TOKEN=([^;]+)/i);
2381
+ if (match) return decodeURIComponent(match[1]);
2382
+ return null;
2383
+ } catch {
2384
+ return null;
2385
+ }
2386
+ }
2387
+ async function callServerLogout(logoutUrl) {
2388
+ const csrfToken = getCsrfToken();
2389
+ async function doRequest(method) {
2390
+ const isPost = method === "POST";
2391
+ const headers = {
2392
+ "X-Requested-With": "XMLHttpRequest",
2393
+ Accept: "application/json, */*"
2394
+ };
2395
+ if (isPost) {
2396
+ headers["Content-Type"] = "application/x-www-form-urlencoded";
2397
+ }
2398
+ if (csrfToken) {
2399
+ headers["X-CSRF-Token"] = csrfToken;
2400
+ }
2537
2401
  const response = await fetch(logoutUrl, {
2538
- method: "POST",
2539
- headers: {
2540
- "Content-Type": "application/x-www-form-urlencoded",
2541
- "X-Requested-With": "XMLHttpRequest",
2542
- Accept: "application/json"
2543
- },
2402
+ method,
2403
+ mode: "cors",
2404
+ headers,
2544
2405
  credentials: "include"
2545
2406
  });
2407
+ if (!response.ok) {
2408
+ logger.warn("Server logout HTTP error", {
2409
+ method,
2410
+ status: response.status,
2411
+ statusText: response.statusText
2412
+ });
2413
+ return { success: false };
2414
+ }
2546
2415
  const data = await response.json().catch(() => ({}));
2547
- logger.info("Server logout response (POST)", { response: data });
2416
+ logger.info(`Server logout response (${method})`, { response: data });
2548
2417
  if (data && (data.success === true || data.logout === true)) {
2549
2418
  return { success: true, response: data };
2550
2419
  }
2551
- logger.warn("Server logout response invalid (POST)", { response: data });
2420
+ logger.warn("Server logout response invalid payload", {
2421
+ method,
2422
+ response: data
2423
+ });
2552
2424
  return { success: false, response: data };
2425
+ }
2426
+ try {
2427
+ const postResult = await doRequest("POST");
2428
+ if (postResult.success) return postResult;
2429
+ logger.debug("POST logout did not succeed, trying GET");
2430
+ const getResult = await doRequest("GET");
2431
+ return getResult;
2553
2432
  } catch (error) {
2554
- logger.debug("POST logout failed, trying GET", {
2433
+ logger.warn("Server logout failed (both POST and GET)", {
2555
2434
  error: error instanceof Error ? error.message : String(error)
2556
2435
  });
2557
- try {
2558
- const response = await fetch(logoutUrl, {
2559
- method: "GET",
2560
- headers: {
2561
- "X-Requested-With": "XMLHttpRequest",
2562
- Accept: "application/json"
2563
- },
2564
- credentials: "include"
2565
- });
2566
- const data = await response.json().catch(() => ({}));
2567
- logger.info("Server logout response (GET)", { response: data });
2568
- if (data && (data.success === true || data.logout === true)) {
2569
- return { success: true, response: data };
2570
- }
2571
- logger.warn("Server logout response invalid (GET)", { response: data });
2572
- return { success: false, response: data };
2573
- } catch (getError) {
2574
- logger.warn("Server logout failed (both POST and GET)", {
2575
- postError: error instanceof Error ? error.message : String(error),
2576
- getError: getError instanceof Error ? getError.message : String(getError)
2577
- });
2578
- return { success: false };
2579
- }
2436
+ return { success: false };
2580
2437
  }
2581
2438
  }
2582
2439
  function performLocalLogoutCleanup() {
@@ -2589,22 +2446,50 @@ function performLocalLogoutCleanup() {
2589
2446
  });
2590
2447
  }
2591
2448
  clearClientCookies();
2592
- clearAllStorage();
2449
+ try {
2450
+ clearAuthStorage();
2451
+ } catch (error) {
2452
+ logger.warn("clearAuthStorage failed (ignored)", {
2453
+ error: error instanceof Error ? error.message : String(error)
2454
+ });
2455
+ }
2593
2456
  logger.info("Local logout cleanup completed");
2594
2457
  }
2458
+ function acquireLogoutLock() {
2459
+ const LOCK_KEY = getStorageKey("logout_lock");
2460
+ const now = Date.now();
2461
+ const existingLock = getStorage(LOCK_KEY);
2462
+ if (existingLock) {
2463
+ const lockTime = Number(existingLock);
2464
+ if (!Number.isNaN(lockTime) && now - lockTime < 5e3) {
2465
+ logger.debug("Logout lock active \u2013 skipping duplicate logout", {
2466
+ now,
2467
+ lockTime
2468
+ });
2469
+ return false;
2470
+ }
2471
+ }
2472
+ setStorage(LOCK_KEY, String(now));
2473
+ return true;
2474
+ }
2475
+ function releaseLogoutLock() {
2476
+ try {
2477
+ removeStorage(getStorageKey("logout_lock"));
2478
+ } catch {
2479
+ }
2480
+ }
2595
2481
  async function logout(tenantKey) {
2596
- setStorage(getStorageKey("logout_in_progress"), "true");
2597
2482
  setStorage(getStorageKey("force_login"), "true");
2598
- if (tenantKey?.trim()) setStorage(getStorageKey("preserved_tenant_key"), tenantKey.trim());
2599
- if (getStorage(getStorageKey("logout_processing")) === "true") {
2600
- logger.debug("Logout already in progress \u2013 skipping duplicate call");
2483
+ if (tenantKey?.trim()) {
2484
+ setStorage(getStorageKey("preserved_tenant_key"), tenantKey.trim());
2485
+ }
2486
+ if (!acquireLogoutLock()) {
2601
2487
  return { success: true, message: "Logout already in progress." };
2602
2488
  }
2603
- setStorage(getStorageKey("logout_processing"), "true");
2604
2489
  try {
2605
2490
  stopStorageWatcher();
2606
2491
  stopCookieWatcher();
2607
- const apiAuthBaseUrl = Config.getApiAuthBaseUrl();
2492
+ const apiAuthBaseUrl = Config.getAuthServerUrl();
2608
2493
  let serverLogoutSuccess = false;
2609
2494
  let serverResponse;
2610
2495
  if (apiAuthBaseUrl) {
@@ -2613,20 +2498,45 @@ async function logout(tenantKey) {
2613
2498
  const logoutResult = await callServerLogout(logoutUrl);
2614
2499
  serverLogoutSuccess = logoutResult.success;
2615
2500
  serverResponse = logoutResult.response;
2501
+ if (!serverLogoutSuccess) {
2502
+ logger.warn("Server logout failed \u2013 session may still exist", {
2503
+ logoutUrl,
2504
+ serverResponse
2505
+ });
2506
+ }
2507
+ } else {
2508
+ logger.warn("API auth base URL not configured, performing local logout only");
2616
2509
  }
2617
2510
  performLocalLogoutCleanup();
2618
2511
  const preservedTenantKey = getStorage(getStorageKey("preserved_tenant_key"));
2619
2512
  if (preservedTenantKey) {
2620
- setStorage(getStorageKey("props_config"), JSON.stringify({ tenantKey: preservedTenantKey }));
2513
+ const propsKey = getStorageKey("props_config");
2514
+ let existing = {};
2515
+ try {
2516
+ const raw = getStorage(propsKey);
2517
+ if (raw) {
2518
+ existing = JSON.parse(raw);
2519
+ }
2520
+ } catch {
2521
+ existing = {};
2522
+ }
2523
+ const merged = {
2524
+ ...existing,
2525
+ tenantKey: preservedTenantKey
2526
+ };
2527
+ setStorage(propsKey, JSON.stringify(merged));
2621
2528
  removeStorage(getStorageKey("preserved_tenant_key"));
2622
2529
  }
2623
2530
  resetCookieWatcher();
2624
- removeStorage(getStorageKey("logout_processing"));
2531
+ startStorageWatcher();
2532
+ releaseLogoutLock();
2625
2533
  logger.info("Logout completed \u2013 flags set, storage cleared, fresh login required", {
2626
2534
  serverLogoutSuccess,
2627
2535
  serverResponse
2628
2536
  });
2629
2537
  emitAuthEvent(AuthEventNames.LOGOUT_COMPLETED, {
2538
+ serverLogoutSuccess,
2539
+ tenantKey: getStorage(getStorageKey("preserved_tenant_key")) || void 0,
2630
2540
  message: serverLogoutSuccess ? "Server logout success" : "Local logout only"
2631
2541
  });
2632
2542
  return {
@@ -2641,10 +2551,24 @@ async function logout(tenantKey) {
2641
2551
  performLocalLogoutCleanup();
2642
2552
  const preservedTenantKey = getStorage(getStorageKey("preserved_tenant_key"));
2643
2553
  if (preservedTenantKey) {
2644
- setStorage(getStorageKey("props_config"), JSON.stringify({ tenantKey: preservedTenantKey }));
2554
+ const propsKey = getStorageKey("props_config");
2555
+ let existing = {};
2556
+ try {
2557
+ const raw = getStorage(propsKey);
2558
+ if (raw) {
2559
+ existing = JSON.parse(raw);
2560
+ }
2561
+ } catch {
2562
+ existing = {};
2563
+ }
2564
+ const merged = {
2565
+ ...existing,
2566
+ tenantKey: preservedTenantKey
2567
+ };
2568
+ setStorage(propsKey, JSON.stringify(merged));
2645
2569
  removeStorage(getStorageKey("preserved_tenant_key"));
2646
2570
  }
2647
- removeStorage(getStorageKey("logout_processing"));
2571
+ releaseLogoutLock();
2648
2572
  return {
2649
2573
  success: true,
2650
2574
  message: "Logged out locally due to an error. Fresh login required."
@@ -2664,16 +2588,16 @@ function useAuthContext() {
2664
2588
  var ongoingRequests = /* @__PURE__ */ new Map();
2665
2589
  var DEFAULT_SCOPES2 = OAUTH_CONSTANTS.SCOPES;
2666
2590
  function getResolvedTenantBaseUrl() {
2667
- let base = Config.getApiTenantResolutionBaseUrl();
2591
+ let base = Config.getApiBaseUrl();
2668
2592
  if (typeof window !== "undefined" && (!base || base.startsWith("/"))) {
2669
- base = window.location.origin + (base || "/api");
2593
+ base = window.location.origin + (base || "");
2670
2594
  }
2671
2595
  return base;
2672
2596
  }
2673
2597
  var PUBLIC_CODE_PREFIX = "public-";
2674
2598
  function getTenantByCodeUrl(tenantCode) {
2675
2599
  const apiTenantResolutionBaseUrl = getResolvedTenantBaseUrl();
2676
- const base = apiTenantResolutionBaseUrl.replace(/\/api\/v1\/?$/, "") || apiTenantResolutionBaseUrl;
2600
+ const base = (apiTenantResolutionBaseUrl || "").replace(/\/api(?:\/v1)?\/?$/, "") || apiTenantResolutionBaseUrl;
2677
2601
  return `${base}/api/v1/tenant/public/tenants/by-code/${encodeURIComponent(tenantCode)}`;
2678
2602
  }
2679
2603
  async function resolveTenant(tenantKey) {
@@ -2709,7 +2633,9 @@ async function resolveTenant(tenantKey) {
2709
2633
  if (!tenant.id || !tenant.clientCode) return null;
2710
2634
  const authServer = Config.getAuthServerUrl();
2711
2635
  const redirectUri = Config.getRedirectUri();
2712
- if (!authServer || !redirectUri) return null;
2636
+ if (!authServer || !redirectUri) {
2637
+ return null;
2638
+ }
2713
2639
  const clientCodeWithPrefix = tenant.clientCode.startsWith(PUBLIC_CODE_PREFIX) ? tenant.clientCode : `${PUBLIC_CODE_PREFIX}${tenant.clientCode}`;
2714
2640
  const config = {
2715
2641
  tenantId: tenant.id,
@@ -2722,6 +2648,7 @@ async function resolveTenant(tenantKey) {
2722
2648
  scopes: DEFAULT_SCOPES2
2723
2649
  }
2724
2650
  };
2651
+ console.log("config====", config);
2725
2652
  logger.debug("Resolved tenant config", { tenantCode });
2726
2653
  return config;
2727
2654
  } catch (error) {
@@ -2783,13 +2710,10 @@ function createBrowserUrlProvider() {
2783
2710
  }
2784
2711
  function createConfigProvider() {
2785
2712
  return {
2786
- getApiBaseUrl: () => Config.getApiAuthBaseUrl(),
2713
+ getApiBaseUrl: () => Config.getApiBaseUrl(),
2787
2714
  getAuthServerUrl: () => Config.getAuthServerUrl(),
2788
2715
  getRedirectUri: () => Config.getRedirectUri(),
2789
- getClientId: () => Config.getClientId(),
2790
- getTenantId: () => Config.getTenantId(),
2791
- getClientCode: () => Config.getClientCode(),
2792
- getBasePath: () => Config.getBasePath()
2716
+ getClientCode: () => Config.getClientCode()
2793
2717
  };
2794
2718
  }
2795
2719
  function createTenantResolver() {
@@ -2953,6 +2877,9 @@ function AuthProvider({
2953
2877
  children,
2954
2878
  autoInit = true,
2955
2879
  tenantCode,
2880
+ apiBaseUrl,
2881
+ authServerUrl,
2882
+ callbackUrl,
2956
2883
  appId = "",
2957
2884
  storageAdapter
2958
2885
  }) {
@@ -2964,13 +2891,40 @@ function AuthProvider({
2964
2891
  const initRanRef = useRef(false);
2965
2892
  const engineRef = useRef(null);
2966
2893
  useLayoutEffect(() => {
2967
- if (tenantCode) {
2968
- setConfig({ CLIENTCODE: tenantCode });
2894
+ logger.debug("[AuthProvider] Host config props", {
2895
+ tenantCode: tenantCode ?? "(not provided)",
2896
+ apiBaseUrl: apiBaseUrl ? apiBaseUrl : "(empty)",
2897
+ authServerUrl: authServerUrl ? authServerUrl : "(empty)",
2898
+ callbackUrl: callbackUrl ? callbackUrl : "(empty)"
2899
+ });
2900
+ if (!authServerUrl || !authServerUrl.trim()) {
2901
+ logger.warn("[AuthProvider] authServerUrl missing from host props");
2902
+ }
2903
+ if (!callbackUrl || !callbackUrl.trim()) {
2904
+ logger.warn("[AuthProvider] callbackUrl missing from host props");
2969
2905
  }
2906
+ setConfig({
2907
+ ...tenantCode ? { tenantCode } : {},
2908
+ ...apiBaseUrl ? { apiBaseUrl } : {},
2909
+ ...authServerUrl ? { authServerUrl } : {},
2910
+ ...callbackUrl ? { callbackUrl } : {}
2911
+ });
2970
2912
  return () => {
2971
2913
  clearConfigOverrides();
2972
2914
  };
2973
- }, [tenantCode]);
2915
+ }, [tenantCode, apiBaseUrl, authServerUrl, callbackUrl]);
2916
+ useEffect(() => {
2917
+ try {
2918
+ const payload = {
2919
+ tenantCode: tenantCode ?? "",
2920
+ apiBaseUrl: apiBaseUrl ?? "",
2921
+ authServerUrl: authServerUrl ?? "",
2922
+ callbackUrl: callbackUrl ?? ""
2923
+ };
2924
+ setStorage(getStorageKey("host_config"), JSON.stringify(payload));
2925
+ } catch {
2926
+ }
2927
+ }, [tenantCode, apiBaseUrl, authServerUrl, callbackUrl]);
2974
2928
  useLayoutEffect(() => {
2975
2929
  setStorageKeyPrefix(resolvedTenantKey ?? "");
2976
2930
  const adapter = storageAdapter !== void 0 && storageAdapter !== null ? storageAdapter : createSecureSessionStorageAdapter(namespace);
@@ -3431,6 +3385,6 @@ function useAuthInit() {
3431
3385
  );
3432
3386
  }
3433
3387
 
3434
- export { AuthCallback, AuthEventNames, AuthProvider, Config, OAUTH_CONSTANTS, ProtectedRoute, STORAGE_KEYS2 as STORAGE_KEYS, STORAGE_KEY_PREFIX, SanitizedError, bootstrap, buildStorageKey, createAuthEngine, createCookieStorageAdapter, createMemoryStorageAdapter, createOAuth2PkceStrategy, createSecureSessionStorageAdapter, emitAuthEvent, enforceHttps, ensureValidAccessToken, extractTenantKey, getAccessToken2 as getAccessToken, getAuthRuntime, getConfig, getEnvConfig, getStorageAdapter, getStorageNamespace, getAccessToken as getStoredAccessToken, hasEnvFallback, isAccessTokenExpired, isCallbackUrl, logout, refreshAccessToken, resetCookieWatcher, resolveConfig, resolveTenant, sanitizeErrorMessage, setAuthRuntime, setConfig, setStorageContext, startCookieWatcher, stopCookieWatcher, subscribeAuthEvent, useAuth, useAuthContext, useAuthInit };
3388
+ export { AuthCallback, AuthEventNames, AuthProvider, Config, OAUTH_CONSTANTS, ProtectedRoute, STORAGE_KEYS2 as STORAGE_KEYS, STORAGE_KEY_PREFIX, SanitizedError, bootstrap, buildStorageKey, createAuthEngine, createCookieStorageAdapter, createMemoryStorageAdapter, createOAuth2PkceStrategy, createSecureSessionStorageAdapter, emitAuthEvent, enforceHttps, ensureValidAccessToken, extractTenantKey, getAccessToken2 as getAccessToken, getAuthRuntime, getConfig, getStorageAdapter, getStorageNamespace, getAccessToken as getStoredAccessToken, isAccessTokenExpired, isCallbackUrl, logout, refreshAccessToken, resetCookieWatcher, resolveConfig, resolveTenant, sanitizeErrorMessage, setAuthRuntime, setConfig, setStorageContext, startCookieWatcher, stopCookieWatcher, subscribeAuthEvent, useAuth, useAuthContext, useAuthInit };
3435
3389
  //# sourceMappingURL=index.mjs.map
3436
3390
  //# sourceMappingURL=index.mjs.map