tenneo-auth-plugin 0.1.8 → 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: "http://localhost:5021/api/v1",
915
- API_AUTH_BASE_URL: "http://localhost:5000",
916
- AUTH_SERVER_URL: "http://localhost:5000",
917
- DEFAULT_DOMAIN: "http://localhost:5000"
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
  };
@@ -2716,7 +2489,7 @@ async function logout(tenantKey) {
2716
2489
  try {
2717
2490
  stopStorageWatcher();
2718
2491
  stopCookieWatcher();
2719
- const apiAuthBaseUrl = Config.getApiAuthBaseUrl();
2492
+ const apiAuthBaseUrl = Config.getAuthServerUrl();
2720
2493
  let serverLogoutSuccess = false;
2721
2494
  let serverResponse;
2722
2495
  if (apiAuthBaseUrl) {
@@ -2815,16 +2588,16 @@ function useAuthContext() {
2815
2588
  var ongoingRequests = /* @__PURE__ */ new Map();
2816
2589
  var DEFAULT_SCOPES2 = OAUTH_CONSTANTS.SCOPES;
2817
2590
  function getResolvedTenantBaseUrl() {
2818
- let base = Config.getApiTenantResolutionBaseUrl();
2591
+ let base = Config.getApiBaseUrl();
2819
2592
  if (typeof window !== "undefined" && (!base || base.startsWith("/"))) {
2820
- base = window.location.origin + (base || "/api");
2593
+ base = window.location.origin + (base || "");
2821
2594
  }
2822
2595
  return base;
2823
2596
  }
2824
2597
  var PUBLIC_CODE_PREFIX = "public-";
2825
2598
  function getTenantByCodeUrl(tenantCode) {
2826
2599
  const apiTenantResolutionBaseUrl = getResolvedTenantBaseUrl();
2827
- const base = apiTenantResolutionBaseUrl.replace(/\/api\/v1\/?$/, "") || apiTenantResolutionBaseUrl;
2600
+ const base = (apiTenantResolutionBaseUrl || "").replace(/\/api(?:\/v1)?\/?$/, "") || apiTenantResolutionBaseUrl;
2828
2601
  return `${base}/api/v1/tenant/public/tenants/by-code/${encodeURIComponent(tenantCode)}`;
2829
2602
  }
2830
2603
  async function resolveTenant(tenantKey) {
@@ -2860,7 +2633,9 @@ async function resolveTenant(tenantKey) {
2860
2633
  if (!tenant.id || !tenant.clientCode) return null;
2861
2634
  const authServer = Config.getAuthServerUrl();
2862
2635
  const redirectUri = Config.getRedirectUri();
2863
- if (!authServer || !redirectUri) return null;
2636
+ if (!authServer || !redirectUri) {
2637
+ return null;
2638
+ }
2864
2639
  const clientCodeWithPrefix = tenant.clientCode.startsWith(PUBLIC_CODE_PREFIX) ? tenant.clientCode : `${PUBLIC_CODE_PREFIX}${tenant.clientCode}`;
2865
2640
  const config = {
2866
2641
  tenantId: tenant.id,
@@ -2873,6 +2648,7 @@ async function resolveTenant(tenantKey) {
2873
2648
  scopes: DEFAULT_SCOPES2
2874
2649
  }
2875
2650
  };
2651
+ console.log("config====", config);
2876
2652
  logger.debug("Resolved tenant config", { tenantCode });
2877
2653
  return config;
2878
2654
  } catch (error) {
@@ -2934,13 +2710,10 @@ function createBrowserUrlProvider() {
2934
2710
  }
2935
2711
  function createConfigProvider() {
2936
2712
  return {
2937
- getApiBaseUrl: () => Config.getApiAuthBaseUrl(),
2713
+ getApiBaseUrl: () => Config.getApiBaseUrl(),
2938
2714
  getAuthServerUrl: () => Config.getAuthServerUrl(),
2939
2715
  getRedirectUri: () => Config.getRedirectUri(),
2940
- getClientId: () => Config.getClientId(),
2941
- getTenantId: () => Config.getTenantId(),
2942
- getClientCode: () => Config.getClientCode(),
2943
- getBasePath: () => Config.getBasePath()
2716
+ getClientCode: () => Config.getClientCode()
2944
2717
  };
2945
2718
  }
2946
2719
  function createTenantResolver() {
@@ -3104,6 +2877,9 @@ function AuthProvider({
3104
2877
  children,
3105
2878
  autoInit = true,
3106
2879
  tenantCode,
2880
+ apiBaseUrl,
2881
+ authServerUrl,
2882
+ callbackUrl,
3107
2883
  appId = "",
3108
2884
  storageAdapter
3109
2885
  }) {
@@ -3115,13 +2891,40 @@ function AuthProvider({
3115
2891
  const initRanRef = useRef(false);
3116
2892
  const engineRef = useRef(null);
3117
2893
  useLayoutEffect(() => {
3118
- if (tenantCode) {
3119
- 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");
3120
2905
  }
2906
+ setConfig({
2907
+ ...tenantCode ? { tenantCode } : {},
2908
+ ...apiBaseUrl ? { apiBaseUrl } : {},
2909
+ ...authServerUrl ? { authServerUrl } : {},
2910
+ ...callbackUrl ? { callbackUrl } : {}
2911
+ });
3121
2912
  return () => {
3122
2913
  clearConfigOverrides();
3123
2914
  };
3124
- }, [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]);
3125
2928
  useLayoutEffect(() => {
3126
2929
  setStorageKeyPrefix(resolvedTenantKey ?? "");
3127
2930
  const adapter = storageAdapter !== void 0 && storageAdapter !== null ? storageAdapter : createSecureSessionStorageAdapter(namespace);
@@ -3582,6 +3385,6 @@ function useAuthInit() {
3582
3385
  );
3583
3386
  }
3584
3387
 
3585
- 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 };
3586
3389
  //# sourceMappingURL=index.mjs.map
3587
3390
  //# sourceMappingURL=index.mjs.map