tenneo-auth-plugin 0.1.8 → 0.1.10
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/README.md +23 -45
- package/dist/index.d.mts +84 -110
- package/dist/index.d.ts +84 -110
- package/dist/index.js +146 -341
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +147 -339
- package/dist/index.mjs.map +1 -1
- package/package.json +53 -53
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.
|
|
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
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
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
|
-
|
|
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
|
|
857
|
+
return resolveMerged();
|
|
1006
858
|
}
|
|
1007
859
|
function setConfig(overrides) {
|
|
1008
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
return
|
|
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
|
-
|
|
1050
|
-
return
|
|
1051
|
-
},
|
|
1052
|
-
getApiAuthBaseUrl() {
|
|
1053
|
-
return getConfig().API_AUTH_BASE_URL;
|
|
872
|
+
getApiBaseUrl() {
|
|
873
|
+
return resolveMerged().apiBaseUrl;
|
|
1054
874
|
},
|
|
1055
875
|
getAuthServerUrl() {
|
|
1056
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
1348
|
-
|
|
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:
|
|
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 `${
|
|
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.
|
|
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.
|
|
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
|
-
|
|
1899
|
-
|
|
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
|
-
...
|
|
1915
|
-
tenantKey: 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(
|
|
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.
|
|
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.
|
|
2591
|
+
let base = Config.getApiBaseUrl();
|
|
2819
2592
|
if (typeof window !== "undefined" && (!base || base.startsWith("/"))) {
|
|
2820
|
-
base = window.location.origin + (base || "
|
|
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
|
|
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)
|
|
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.
|
|
2713
|
+
getApiBaseUrl: () => Config.getApiBaseUrl(),
|
|
2938
2714
|
getAuthServerUrl: () => Config.getAuthServerUrl(),
|
|
2939
2715
|
getRedirectUri: () => Config.getRedirectUri(),
|
|
2940
|
-
|
|
2941
|
-
getTenantId: () => Config.getTenantId(),
|
|
2942
|
-
getClientCode: () => Config.getClientCode(),
|
|
2943
|
-
getBasePath: () => Config.getBasePath()
|
|
2716
|
+
getClientCode: () => Config.getClientCode()
|
|
2944
2717
|
};
|
|
2945
2718
|
}
|
|
2946
2719
|
function createTenantResolver() {
|
|
@@ -3103,11 +2876,19 @@ function createAuthEngine(config) {
|
|
|
3103
2876
|
function AuthProvider({
|
|
3104
2877
|
children,
|
|
3105
2878
|
autoInit = true,
|
|
2879
|
+
config,
|
|
3106
2880
|
tenantCode,
|
|
2881
|
+
apiBaseUrl,
|
|
2882
|
+
authServerUrl,
|
|
2883
|
+
callbackUrl,
|
|
3107
2884
|
appId = "",
|
|
3108
2885
|
storageAdapter
|
|
3109
2886
|
}) {
|
|
3110
|
-
const
|
|
2887
|
+
const mergedTenantCode = tenantCode ?? config?.tenantCode;
|
|
2888
|
+
const mergedApiBaseUrl = apiBaseUrl ?? config?.apiBaseUrl;
|
|
2889
|
+
const mergedAuthServerUrl = authServerUrl ?? config?.authServerUrl;
|
|
2890
|
+
const mergedCallbackUrl = callbackUrl ?? config?.callbackUrl;
|
|
2891
|
+
const resolvedTenantKey = mergedTenantCode ?? Config.getClientCode();
|
|
3111
2892
|
const namespace = useMemo(
|
|
3112
2893
|
() => ({ tenantId: resolvedTenantKey ?? "", appId: appId ?? "" }),
|
|
3113
2894
|
[resolvedTenantKey, appId]
|
|
@@ -3115,13 +2896,40 @@ function AuthProvider({
|
|
|
3115
2896
|
const initRanRef = useRef(false);
|
|
3116
2897
|
const engineRef = useRef(null);
|
|
3117
2898
|
useLayoutEffect(() => {
|
|
3118
|
-
|
|
3119
|
-
|
|
2899
|
+
logger.debug("[AuthProvider] Host config props", {
|
|
2900
|
+
tenantCode: mergedTenantCode ?? "(not provided)",
|
|
2901
|
+
apiBaseUrl: mergedApiBaseUrl ? mergedApiBaseUrl : "(empty)",
|
|
2902
|
+
authServerUrl: mergedAuthServerUrl ? mergedAuthServerUrl : "(empty)",
|
|
2903
|
+
callbackUrl: mergedCallbackUrl ? mergedCallbackUrl : "(empty)"
|
|
2904
|
+
});
|
|
2905
|
+
if (!mergedAuthServerUrl || !mergedAuthServerUrl.trim()) {
|
|
2906
|
+
logger.warn("[AuthProvider] authServerUrl missing from host props");
|
|
2907
|
+
}
|
|
2908
|
+
if (!mergedCallbackUrl || !mergedCallbackUrl.trim()) {
|
|
2909
|
+
logger.warn("[AuthProvider] callbackUrl missing from host props");
|
|
3120
2910
|
}
|
|
2911
|
+
setConfig({
|
|
2912
|
+
...mergedTenantCode ? { tenantCode: mergedTenantCode } : {},
|
|
2913
|
+
...mergedApiBaseUrl ? { apiBaseUrl: mergedApiBaseUrl } : {},
|
|
2914
|
+
...mergedAuthServerUrl ? { authServerUrl: mergedAuthServerUrl } : {},
|
|
2915
|
+
...mergedCallbackUrl ? { callbackUrl: mergedCallbackUrl } : {}
|
|
2916
|
+
});
|
|
3121
2917
|
return () => {
|
|
3122
2918
|
clearConfigOverrides();
|
|
3123
2919
|
};
|
|
3124
|
-
}, [
|
|
2920
|
+
}, [mergedTenantCode, mergedApiBaseUrl, mergedAuthServerUrl, mergedCallbackUrl]);
|
|
2921
|
+
useEffect(() => {
|
|
2922
|
+
try {
|
|
2923
|
+
const payload = {
|
|
2924
|
+
tenantCode: mergedTenantCode ?? "",
|
|
2925
|
+
apiBaseUrl: mergedApiBaseUrl ?? "",
|
|
2926
|
+
authServerUrl: mergedAuthServerUrl ?? "",
|
|
2927
|
+
callbackUrl: mergedCallbackUrl ?? ""
|
|
2928
|
+
};
|
|
2929
|
+
setStorage(getStorageKey("host_config"), JSON.stringify(payload));
|
|
2930
|
+
} catch {
|
|
2931
|
+
}
|
|
2932
|
+
}, [mergedTenantCode, mergedApiBaseUrl, mergedAuthServerUrl, mergedCallbackUrl]);
|
|
3125
2933
|
useLayoutEffect(() => {
|
|
3126
2934
|
setStorageKeyPrefix(resolvedTenantKey ?? "");
|
|
3127
2935
|
const adapter = storageAdapter !== void 0 && storageAdapter !== null ? storageAdapter : createSecureSessionStorageAdapter(namespace);
|
|
@@ -3582,6 +3390,6 @@ function useAuthInit() {
|
|
|
3582
3390
|
);
|
|
3583
3391
|
}
|
|
3584
3392
|
|
|
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,
|
|
3393
|
+
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
3394
|
//# sourceMappingURL=index.mjs.map
|
|
3587
3395
|
//# sourceMappingURL=index.mjs.map
|