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/README.md +22 -45
- package/dist/index.d.mts +38 -66
- package/dist/index.d.ts +38 -66
- package/dist/index.js +140 -340
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +141 -338
- package/dist/index.mjs.map +1 -1
- package/package.json +53 -53
package/dist/index.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var zod = require('zod');
|
|
4
3
|
var axios = require('axios');
|
|
5
4
|
var react = require('react');
|
|
6
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
6
|
|
|
8
|
-
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
9
7
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
8
|
|
|
11
9
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
@@ -74,13 +72,11 @@ function extractTenantKeyFromUrl(url, config, getStorage3, getKey) {
|
|
|
74
72
|
if (keyFromHost) return keyFromHost;
|
|
75
73
|
const clientCode = config.getClientCode();
|
|
76
74
|
if (clientCode?.trim()) return clientCode.trim();
|
|
77
|
-
const tenantId = config.getTenantId();
|
|
78
|
-
if (tenantId?.trim()) return tenantId.trim();
|
|
79
75
|
return config.getClientCode();
|
|
80
76
|
} catch {
|
|
81
77
|
const clientCode = config.getClientCode();
|
|
82
78
|
if (clientCode?.trim()) return clientCode.trim();
|
|
83
|
-
return config.
|
|
79
|
+
return config.getClientCode();
|
|
84
80
|
}
|
|
85
81
|
}
|
|
86
82
|
function isCallbackUrlFromUrl(url) {
|
|
@@ -811,85 +807,6 @@ function generateState() {
|
|
|
811
807
|
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
812
808
|
}
|
|
813
809
|
|
|
814
|
-
// src/config/env.ts
|
|
815
|
-
var ENV_KEYS = {
|
|
816
|
-
CLIENT_ID: ["VITE_CLIENT_ID", "CLIENT_ID"],
|
|
817
|
-
TENANT_ID: ["VITE_TENANT_ID", "TENANT_ID"],
|
|
818
|
-
CLIENTCODE: ["VITE_CLIENTCODE", "CLIENTCODE"]
|
|
819
|
-
};
|
|
820
|
-
function getEnvValue(keys) {
|
|
821
|
-
try {
|
|
822
|
-
const g = typeof globalThis !== "undefined" ? globalThis : null;
|
|
823
|
-
const env = g?.process && typeof g.process.env === "object" ? g.process.env : null;
|
|
824
|
-
if (env) {
|
|
825
|
-
for (const key of keys) {
|
|
826
|
-
const v = env[key];
|
|
827
|
-
if (v != null && String(v).trim()) return String(v).trim();
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
} catch {
|
|
831
|
-
}
|
|
832
|
-
try {
|
|
833
|
-
const meta = typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== "undefined" ? undefined : void 0;
|
|
834
|
-
if (meta) {
|
|
835
|
-
for (const key of keys) {
|
|
836
|
-
const v = meta[key];
|
|
837
|
-
if (v != null && String(v).trim()) return String(v).trim();
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
} catch {
|
|
841
|
-
}
|
|
842
|
-
return "";
|
|
843
|
-
}
|
|
844
|
-
var FORBIDDEN_WINDOW_KEYS = ["apiBaseUrl", "apiTenantResolutionBaseUrl", "apiAuthBaseUrl", "authServerUrl", "defaultDomain", "API_BASE_URL", "AUTH_SERVER_URL", "DEFAULT_DOMAIN"];
|
|
845
|
-
function getWindowConfigRaw() {
|
|
846
|
-
if (typeof window === "undefined") return null;
|
|
847
|
-
const w = window;
|
|
848
|
-
const raw = w.__AUTH_CONFIG__ ?? w.__APP_CONFIG__;
|
|
849
|
-
if (!raw || typeof raw !== "object") return null;
|
|
850
|
-
for (const forbidden of FORBIDDEN_WINDOW_KEYS) {
|
|
851
|
-
if (forbidden in raw) {
|
|
852
|
-
throw new Error("Attempted to override protected internal configuration");
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
const out = {};
|
|
856
|
-
const map = {
|
|
857
|
-
clientId: "CLIENT_ID",
|
|
858
|
-
tenantId: "TENANT_ID",
|
|
859
|
-
clientcode: "CLIENTCODE"
|
|
860
|
-
};
|
|
861
|
-
for (const [winKey, sdkKey] of Object.entries(map)) {
|
|
862
|
-
const v = raw[winKey];
|
|
863
|
-
if (v != null && typeof v === "string" && v.trim()) out[sdkKey] = v.trim();
|
|
864
|
-
}
|
|
865
|
-
return Object.keys(out).length ? out : null;
|
|
866
|
-
}
|
|
867
|
-
function loadEnvConfig() {
|
|
868
|
-
const partial = {};
|
|
869
|
-
for (const [key, envKeys] of Object.entries(ENV_KEYS)) {
|
|
870
|
-
const v = getEnvValue(envKeys);
|
|
871
|
-
if (v) partial[key] = v;
|
|
872
|
-
}
|
|
873
|
-
return partial;
|
|
874
|
-
}
|
|
875
|
-
function loadWindowConfig() {
|
|
876
|
-
const raw = getWindowConfigRaw();
|
|
877
|
-
if (!raw) return null;
|
|
878
|
-
return raw;
|
|
879
|
-
}
|
|
880
|
-
var schema = zod.z.object({
|
|
881
|
-
CLIENT_ID: zod.z.string().min(1, "CLIENT_ID is required"),
|
|
882
|
-
TENANT_ID: zod.z.string().min(1, "TENANT_ID is required"),
|
|
883
|
-
CLIENTCODE: zod.z.string().min(1, "CLIENTCODE is required")
|
|
884
|
-
});
|
|
885
|
-
function validateConfig(data) {
|
|
886
|
-
return schema.parse(data);
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
// src/config/types.ts
|
|
890
|
-
var INTERNAL_CONFIG_KEYS = ["API_TENANT_RESOLUTION_BASE_URL", "API_AUTH_BASE_URL", "AUTH_SERVER_URL", "DEFAULT_DOMAIN"];
|
|
891
|
-
var RUNTIME_CONFIG_KEYS = ["CLIENT_ID", "TENANT_ID", "CLIENTCODE"];
|
|
892
|
-
|
|
893
810
|
// src/config/constants.ts
|
|
894
811
|
var OAUTH_CONSTANTS = {
|
|
895
812
|
SCOPES: "openid profile email",
|
|
@@ -917,232 +834,63 @@ var DEFAULT_TOKEN_GRANT_TYPE = OAUTH_CONSTANTS.TOKEN_GRANT_TYPE;
|
|
|
917
834
|
var DEFAULT_REFRESH_GRANT_TYPE = OAUTH_CONSTANTS.REFRESH_GRANT_TYPE;
|
|
918
835
|
|
|
919
836
|
// src/config/index.ts
|
|
920
|
-
var
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
}
|
|
941
|
-
function pickRuntimeConfig(source) {
|
|
942
|
-
if (!source) return {};
|
|
943
|
-
const picked = {};
|
|
944
|
-
for (const key of RUNTIME_CONFIG_KEYS) {
|
|
945
|
-
const value = source[key];
|
|
946
|
-
if (value != null && typeof value === "string") {
|
|
947
|
-
const trimmed = value.trim();
|
|
948
|
-
if (trimmed) picked[key] = trimmed;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
return picked;
|
|
952
|
-
}
|
|
953
|
-
({
|
|
954
|
-
...INTERNAL_CONFIG,
|
|
955
|
-
...RUNTIME_CONFIG_DEFAULTS
|
|
956
|
-
});
|
|
957
|
-
var runtimeOverrides = {};
|
|
958
|
-
var runtimeConfigOverrides = {};
|
|
959
|
-
function mergeRuntime(base, ...sources) {
|
|
960
|
-
let out = { ...base };
|
|
961
|
-
for (const src of sources) {
|
|
962
|
-
if (!src) continue;
|
|
963
|
-
for (const key of Object.keys(src)) {
|
|
964
|
-
const value = src[key];
|
|
965
|
-
if (value != null && String(value).trim() !== "") out[key] = String(value).trim();
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
return out;
|
|
969
|
-
}
|
|
970
|
-
function assertNoInternalOverrides(source) {
|
|
971
|
-
if (!source) return;
|
|
972
|
-
for (const key of INTERNAL_CONFIG_KEYS) {
|
|
973
|
-
if (source[key] !== void 0) throw new Error("Attempted to override protected internal configuration");
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
var INTERNAL_KEY_SET = new Set(INTERNAL_CONFIG_KEYS);
|
|
977
|
-
var HOST_TO_RUNTIME_KEYS = {
|
|
978
|
-
clientId: "CLIENT_ID",
|
|
979
|
-
tenantId: "TENANT_ID",
|
|
980
|
-
clientcode: "CLIENTCODE"
|
|
981
|
-
};
|
|
982
|
-
function sanitizeRuntimeOverrides(source) {
|
|
983
|
-
if (!source) return void 0;
|
|
984
|
-
const filtered = {};
|
|
985
|
-
for (const [key, raw] of Object.entries(source)) {
|
|
986
|
-
if (raw == null) continue;
|
|
987
|
-
if (INTERNAL_KEY_SET.has(key)) continue;
|
|
988
|
-
const trimmed = String(raw).trim();
|
|
989
|
-
if (!trimmed) continue;
|
|
990
|
-
const sdkKey = HOST_TO_RUNTIME_KEYS[key] ?? key;
|
|
991
|
-
filtered[sdkKey] = trimmed;
|
|
992
|
-
}
|
|
993
|
-
const picked = pickRuntimeConfig(filtered);
|
|
994
|
-
return Object.keys(picked).length ? picked : void 0;
|
|
837
|
+
var inMemoryConfig = {};
|
|
838
|
+
function readHostConfigFromStorage() {
|
|
839
|
+
try {
|
|
840
|
+
const raw = getStorage(getStorageKey("host_config"));
|
|
841
|
+
if (!raw) return {};
|
|
842
|
+
const parsed = JSON.parse(raw);
|
|
843
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
844
|
+
} catch {
|
|
845
|
+
return {};
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
function resolveMerged(overrides) {
|
|
849
|
+
const stored = readHostConfigFromStorage();
|
|
850
|
+
const cfg = { ...stored, ...inMemoryConfig, ...overrides ?? {} };
|
|
851
|
+
const trimmed = (v) => v == null ? "" : String(v).trim();
|
|
852
|
+
return {
|
|
853
|
+
apiBaseUrl: trimmed(cfg.apiBaseUrl),
|
|
854
|
+
authServerUrl: trimmed(cfg.authServerUrl),
|
|
855
|
+
callbackUrl: trimmed(cfg.callbackUrl),
|
|
856
|
+
clientCode: trimmed(cfg.clientCode)
|
|
857
|
+
};
|
|
995
858
|
}
|
|
996
859
|
function resolveConfig(overrides) {
|
|
997
|
-
|
|
998
|
-
assertNoInternalOverrides(overrides);
|
|
999
|
-
const windowCfg = loadWindowConfig();
|
|
1000
|
-
const envCfg = loadEnvConfig();
|
|
1001
|
-
const mergedRuntime = mergeRuntime(
|
|
1002
|
-
RUNTIME_CONFIG_DEFAULTS,
|
|
1003
|
-
envCfg,
|
|
1004
|
-
windowCfg ?? void 0,
|
|
1005
|
-
runtimeOverrides,
|
|
1006
|
-
sanitizeRuntimeOverrides(overrides)
|
|
1007
|
-
);
|
|
1008
|
-
const validatedRuntime = validateConfig(mergedRuntime);
|
|
1009
|
-
return { ...INTERNAL_CONFIG, ...validatedRuntime };
|
|
860
|
+
return resolveMerged(overrides);
|
|
1010
861
|
}
|
|
1011
862
|
function getConfig() {
|
|
1012
|
-
return
|
|
863
|
+
return resolveMerged();
|
|
1013
864
|
}
|
|
1014
865
|
function setConfig(overrides) {
|
|
1015
|
-
|
|
1016
|
-
const sanitized = sanitizeRuntimeOverrides(overrides);
|
|
1017
|
-
if (sanitized) runtimeOverrides = { ...runtimeOverrides, ...sanitized };
|
|
1018
|
-
const { basePath, redirectUri } = overrides;
|
|
1019
|
-
if (basePath != null && basePath.trim() !== "") runtimeConfigOverrides = { ...runtimeConfigOverrides, basePath: basePath.trim() };
|
|
1020
|
-
if (redirectUri != null && redirectUri.trim() !== "") runtimeConfigOverrides = { ...runtimeConfigOverrides, redirectUri: redirectUri.trim() };
|
|
866
|
+
inMemoryConfig = { ...inMemoryConfig, ...overrides };
|
|
1021
867
|
}
|
|
1022
868
|
function clearConfigOverrides() {
|
|
1023
|
-
|
|
1024
|
-
runtimeConfigOverrides = {};
|
|
1025
|
-
}
|
|
1026
|
-
function getWindowBasePath() {
|
|
1027
|
-
if (typeof window === "undefined") return "";
|
|
1028
|
-
const w = window;
|
|
1029
|
-
const raw = w.__AUTH_CONFIG__ ?? w.__APP_CONFIG__;
|
|
1030
|
-
const bp = raw?.basePath;
|
|
1031
|
-
if (bp != null && typeof bp === "string" && bp.trim()) return bp.trim();
|
|
1032
|
-
const pathname = window.location.pathname;
|
|
1033
|
-
const segments = pathname.split("/").filter(Boolean);
|
|
1034
|
-
const commonRoutes = ["dashboards", "callback", "confirmation", "client-confirmed", "client-provisioned", "approval-completed"];
|
|
1035
|
-
if (segments.length > 0 && !commonRoutes.includes(segments[0])) {
|
|
1036
|
-
let base = "/" + segments[0];
|
|
1037
|
-
if (base.endsWith("/")) base = base.slice(0, -1);
|
|
1038
|
-
return base;
|
|
1039
|
-
}
|
|
1040
|
-
return "";
|
|
1041
|
-
}
|
|
1042
|
-
function getBasePath() {
|
|
1043
|
-
if (runtimeConfigOverrides.basePath != null && runtimeConfigOverrides.basePath !== "") return runtimeConfigOverrides.basePath;
|
|
1044
|
-
return getWindowBasePath();
|
|
869
|
+
inMemoryConfig = {};
|
|
1045
870
|
}
|
|
1046
871
|
function getRedirectUri2() {
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
}
|
|
1050
|
-
return
|
|
1051
|
-
}
|
|
1052
|
-
function hasRuntimeConfig() {
|
|
1053
|
-
return loadWindowConfig() !== null || Object.keys(runtimeOverrides).length > 0;
|
|
872
|
+
const cfg = resolveMerged();
|
|
873
|
+
if (cfg.callbackUrl) return cfg.callbackUrl;
|
|
874
|
+
if (typeof window !== "undefined") return `${window.location.origin}/callback`;
|
|
875
|
+
return "";
|
|
1054
876
|
}
|
|
1055
877
|
var Config = {
|
|
1056
|
-
|
|
1057
|
-
return
|
|
1058
|
-
},
|
|
1059
|
-
getApiAuthBaseUrl() {
|
|
1060
|
-
return getConfig().API_AUTH_BASE_URL;
|
|
878
|
+
getApiBaseUrl() {
|
|
879
|
+
return resolveMerged().apiBaseUrl;
|
|
1061
880
|
},
|
|
1062
881
|
getAuthServerUrl() {
|
|
1063
|
-
return
|
|
1064
|
-
},
|
|
1065
|
-
getDefaultDomain() {
|
|
1066
|
-
return getConfig().DEFAULT_DOMAIN;
|
|
1067
|
-
},
|
|
1068
|
-
getClientId() {
|
|
1069
|
-
return getConfig().CLIENT_ID;
|
|
1070
|
-
},
|
|
1071
|
-
getTenantId() {
|
|
1072
|
-
return getConfig().TENANT_ID;
|
|
882
|
+
return resolveMerged().authServerUrl;
|
|
1073
883
|
},
|
|
1074
884
|
getClientCode() {
|
|
1075
|
-
return
|
|
885
|
+
return resolveMerged().clientCode;
|
|
1076
886
|
},
|
|
1077
887
|
getRedirectUri() {
|
|
1078
888
|
return getRedirectUri2();
|
|
1079
889
|
},
|
|
1080
|
-
getBasePath() {
|
|
1081
|
-
return getBasePath();
|
|
1082
|
-
},
|
|
1083
|
-
hasRuntimeConfig() {
|
|
1084
|
-
return hasRuntimeConfig();
|
|
1085
|
-
},
|
|
1086
890
|
getAll() {
|
|
1087
|
-
|
|
1088
|
-
return {
|
|
1089
|
-
apiTenantResolutionBaseUrl: c.API_TENANT_RESOLUTION_BASE_URL,
|
|
1090
|
-
apiAuthBaseUrl: c.API_AUTH_BASE_URL,
|
|
1091
|
-
authServerUrl: c.AUTH_SERVER_URL,
|
|
1092
|
-
defaultDomain: c.DEFAULT_DOMAIN,
|
|
1093
|
-
clientId: c.CLIENT_ID,
|
|
1094
|
-
tenantId: c.TENANT_ID,
|
|
1095
|
-
clientCode: c.CLIENTCODE,
|
|
1096
|
-
redirectUri: getRedirectUri2(),
|
|
1097
|
-
basePath: getBasePath()
|
|
1098
|
-
};
|
|
891
|
+
return resolveMerged();
|
|
1099
892
|
}
|
|
1100
893
|
};
|
|
1101
|
-
({
|
|
1102
|
-
AUTH_SERVER_URL: Config.getAuthServerUrl(),
|
|
1103
|
-
CLIENT_ID: Config.getClientId(),
|
|
1104
|
-
TENANT_ID: Config.getTenantId(),
|
|
1105
|
-
CLIENTCODE: Config.getClientCode()
|
|
1106
|
-
});
|
|
1107
|
-
function getEnvConfig() {
|
|
1108
|
-
const authServerUrl = Config.getAuthServerUrl();
|
|
1109
|
-
const clientId = Config.getClientId();
|
|
1110
|
-
const tenantId = Config.getTenantId();
|
|
1111
|
-
const redirectUri = Config.getRedirectUri();
|
|
1112
|
-
try {
|
|
1113
|
-
new URL(authServerUrl);
|
|
1114
|
-
new URL(redirectUri);
|
|
1115
|
-
} catch {
|
|
1116
|
-
return Promise.resolve(null);
|
|
1117
|
-
}
|
|
1118
|
-
return Promise.resolve({
|
|
1119
|
-
authServerUrl: authServerUrl.trim(),
|
|
1120
|
-
clientId: clientId.trim(),
|
|
1121
|
-
redirectUri: redirectUri.trim(),
|
|
1122
|
-
tenantId: tenantId.trim()
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
function getEnvConfigSync() {
|
|
1126
|
-
const authServerUrl = Config.getAuthServerUrl();
|
|
1127
|
-
const clientId = Config.getClientId();
|
|
1128
|
-
const tenantId = Config.getTenantId();
|
|
1129
|
-
const redirectUri = Config.getRedirectUri();
|
|
1130
|
-
try {
|
|
1131
|
-
new URL(authServerUrl);
|
|
1132
|
-
new URL(redirectUri);
|
|
1133
|
-
} catch {
|
|
1134
|
-
return null;
|
|
1135
|
-
}
|
|
1136
|
-
return {
|
|
1137
|
-
authServerUrl: authServerUrl.trim(),
|
|
1138
|
-
clientId: clientId.trim(),
|
|
1139
|
-
redirectUri: redirectUri.trim(),
|
|
1140
|
-
tenantId: tenantId.trim()
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
function hasEnvFallback() {
|
|
1144
|
-
return getEnvConfigSync() !== null;
|
|
1145
|
-
}
|
|
1146
894
|
|
|
1147
895
|
// src/utils/validation.ts
|
|
1148
896
|
function isValidGuid(guid) {
|
|
@@ -1296,7 +1044,8 @@ function storeTenantConfig(config) {
|
|
|
1296
1044
|
if (!validation.isValid) {
|
|
1297
1045
|
logger.warn("Tenant ID validation failed", { tenantId: config.tenantId });
|
|
1298
1046
|
}
|
|
1299
|
-
|
|
1047
|
+
const authServerToStore = Config.getAuthServerUrl() || config.authServer;
|
|
1048
|
+
setStorage(STORAGE_KEYS.authServerUrl, authServerToStore);
|
|
1300
1049
|
setStorage(STORAGE_KEYS.clientId, config.client.clientId);
|
|
1301
1050
|
setStorage(STORAGE_KEYS.redirectUri, Config.getRedirectUri());
|
|
1302
1051
|
setStorage(STORAGE_KEYS.tenantId, config.tenantId);
|
|
@@ -1307,6 +1056,22 @@ function storeTenantConfig(config) {
|
|
|
1307
1056
|
async function initiateAuthFlow(config) {
|
|
1308
1057
|
try {
|
|
1309
1058
|
logger.info("Initiating OAuth authorization flow");
|
|
1059
|
+
const authServerFromProps = Config.getAuthServerUrl();
|
|
1060
|
+
const authServerEffective = (authServerFromProps || config?.authServer || "").replace(/\/+$/, "");
|
|
1061
|
+
const redirectUriEffective = Config.getRedirectUri();
|
|
1062
|
+
const storedTenantId = getStorage(STORAGE_KEYS.tenantId);
|
|
1063
|
+
const storedClientId = getStorage(STORAGE_KEYS.clientId);
|
|
1064
|
+
const tenantIdEffective = storedTenantId || config?.tenantId || "";
|
|
1065
|
+
const clientIdEffective = storedClientId || config?.client?.clientId || "";
|
|
1066
|
+
logger.debug("[initiateAuthFlow] Resolved inputs", {
|
|
1067
|
+
authServerFromProps: authServerFromProps ? "(provided)" : "(empty)",
|
|
1068
|
+
authServerEffective,
|
|
1069
|
+
redirectUriEffective,
|
|
1070
|
+
tenantIdEffective,
|
|
1071
|
+
clientIdEffective,
|
|
1072
|
+
scopes: config?.client?.scopes,
|
|
1073
|
+
hasRuntime: !!getAuthRuntime()
|
|
1074
|
+
});
|
|
1310
1075
|
const token = getAccessToken();
|
|
1311
1076
|
if (token && !isAccessTokenExpired()) {
|
|
1312
1077
|
logger.debug("Valid token already exists, skipping auth flow");
|
|
@@ -1328,10 +1093,17 @@ async function initiateAuthFlow(config) {
|
|
|
1328
1093
|
}
|
|
1329
1094
|
}
|
|
1330
1095
|
setFlowFlags();
|
|
1331
|
-
if (!config?.authServer || !config.client?.clientId || !config.client?.redirectUri) {
|
|
1096
|
+
if (!(Config.getAuthServerUrl() || config?.authServer) || !config.client?.clientId || !config.client?.redirectUri) {
|
|
1097
|
+
logger.error("[initiateAuthFlow] Missing required tenant config", {
|
|
1098
|
+
authServerEffective,
|
|
1099
|
+
clientId: config?.client?.clientId,
|
|
1100
|
+
redirectUriFromTenantApi: config?.client?.redirectUri,
|
|
1101
|
+
redirectUriEffective
|
|
1102
|
+
});
|
|
1332
1103
|
throw new Error("Invalid tenant configuration for auth flow");
|
|
1333
1104
|
}
|
|
1334
1105
|
storeTenantConfig(config);
|
|
1106
|
+
logger.debug("[initiateAuthFlow] Stored tenant config, generating PKCE");
|
|
1335
1107
|
const codeVerifier = generateCodeVerifier();
|
|
1336
1108
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
1337
1109
|
const state = generateState();
|
|
@@ -1340,6 +1112,10 @@ async function initiateAuthFlow(config) {
|
|
|
1340
1112
|
setStorage(STORAGE_KEYS.codeVerifier, codeVerifier);
|
|
1341
1113
|
setStorage(STORAGE_KEYS.state, state);
|
|
1342
1114
|
const authUrl = buildAuthorizationUrl(config, codeChallenge, state);
|
|
1115
|
+
logger.debug("[initiateAuthFlow] Built authorization URL", {
|
|
1116
|
+
authServerEffective,
|
|
1117
|
+
urlPrefix: authUrl?.slice(0, 80)
|
|
1118
|
+
});
|
|
1343
1119
|
if (!authUrl || !(authUrl.startsWith("http://") || authUrl.startsWith("https://"))) {
|
|
1344
1120
|
throw new Error("Invalid authorization URL generated");
|
|
1345
1121
|
}
|
|
@@ -1351,8 +1127,15 @@ async function initiateAuthFlow(config) {
|
|
|
1351
1127
|
logger.info("Redirecting to authorization server");
|
|
1352
1128
|
emitAuthEvent(AuthEventNames.LOGIN_STARTED, { tenantKey: config.tenantKey });
|
|
1353
1129
|
const runtime = getAuthRuntime();
|
|
1354
|
-
if (runtime)
|
|
1355
|
-
|
|
1130
|
+
if (runtime) {
|
|
1131
|
+
logger.debug("[initiateAuthFlow] Redirect via runtime.urlProvider.redirect");
|
|
1132
|
+
runtime.urlProvider.redirect(authUrl);
|
|
1133
|
+
} else if (typeof window !== "undefined") {
|
|
1134
|
+
logger.debug("[initiateAuthFlow] Redirect via window.location.replace");
|
|
1135
|
+
window.location.replace(authUrl);
|
|
1136
|
+
} else {
|
|
1137
|
+
logger.error("[initiateAuthFlow] No runtime and no window; cannot redirect", { authUrl });
|
|
1138
|
+
}
|
|
1356
1139
|
} catch (error) {
|
|
1357
1140
|
clearFlowFlags();
|
|
1358
1141
|
logger.error("Failed to initiate auth flow", {
|
|
@@ -1362,9 +1145,10 @@ async function initiateAuthFlow(config) {
|
|
|
1362
1145
|
}
|
|
1363
1146
|
}
|
|
1364
1147
|
function buildAuthorizationUrl(config, codeChallenge, state) {
|
|
1148
|
+
const authServerBase = (Config.getAuthServerUrl() || config.authServer || "").replace(/\/+$/, "");
|
|
1365
1149
|
if (isLocalhost2()) {
|
|
1366
1150
|
logger.debug("Building authorization URL", {
|
|
1367
|
-
authServer:
|
|
1151
|
+
authServer: authServerBase,
|
|
1368
1152
|
clientId: config.client.clientId,
|
|
1369
1153
|
redirectUri: config.client.redirectUri,
|
|
1370
1154
|
scopes: config.client.scopes
|
|
@@ -1385,7 +1169,7 @@ function buildAuthorizationUrl(config, codeChallenge, state) {
|
|
|
1385
1169
|
code_challenge: codeChallenge,
|
|
1386
1170
|
code_challenge_method: DEFAULT_CODE_CHALLENGE_METHOD
|
|
1387
1171
|
});
|
|
1388
|
-
return `${
|
|
1172
|
+
return `${authServerBase}/connect/authorize?${params.toString()}`;
|
|
1389
1173
|
}
|
|
1390
1174
|
|
|
1391
1175
|
// src/strategies/oauth2-pkce/token-exchange.ts
|
|
@@ -1415,7 +1199,7 @@ function storeTokens(tokenData) {
|
|
|
1415
1199
|
async function exchangeCodeForTokens(params) {
|
|
1416
1200
|
try {
|
|
1417
1201
|
const { code, codeVerifier, clientId, redirectUri } = params;
|
|
1418
|
-
const apiAuthBaseUrl = Config.
|
|
1202
|
+
const apiAuthBaseUrl = Config.getAuthServerUrl();
|
|
1419
1203
|
const tokenUrl = `${apiAuthBaseUrl}/oauth/token`;
|
|
1420
1204
|
const body = new URLSearchParams({
|
|
1421
1205
|
grant_type: DEFAULT_TOKEN_GRANT_TYPE,
|
|
@@ -1489,7 +1273,7 @@ async function refreshAccessToken() {
|
|
|
1489
1273
|
});
|
|
1490
1274
|
throw new Error("Cannot refresh token: missing required data");
|
|
1491
1275
|
}
|
|
1492
|
-
const apiAuthBaseUrl = Config.
|
|
1276
|
+
const apiAuthBaseUrl = Config.getApiBaseUrl();
|
|
1493
1277
|
const tokenUrl = `${apiAuthBaseUrl}/oauth/refresh`;
|
|
1494
1278
|
const body = new URLSearchParams({
|
|
1495
1279
|
grant_type: DEFAULT_REFRESH_GRANT_TYPE,
|
|
@@ -1886,40 +1670,15 @@ function mergeConfigWithProps(apiEnvConfig, propsConfig, tenantKey) {
|
|
|
1886
1670
|
}
|
|
1887
1671
|
};
|
|
1888
1672
|
}
|
|
1889
|
-
async function buildTenantConfigFromEnv() {
|
|
1890
|
-
const envConfig = await getEnvConfig();
|
|
1891
|
-
if (!envConfig) return null;
|
|
1892
|
-
return {
|
|
1893
|
-
tenantId: envConfig.tenantId,
|
|
1894
|
-
authServer: envConfig.authServerUrl,
|
|
1895
|
-
client: {
|
|
1896
|
-
clientId: envConfig.clientId,
|
|
1897
|
-
redirectUri: envConfig.redirectUri,
|
|
1898
|
-
scopes: "openid profile email"
|
|
1899
|
-
}
|
|
1900
|
-
};
|
|
1901
|
-
}
|
|
1902
1673
|
async function resolveTenantConfig(tenantKey, tenantResolver) {
|
|
1903
1674
|
if (!tenantKey) return null;
|
|
1904
1675
|
const propsConfig = getPropsConfig();
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
apiEnvConfig = await tenantResolver.resolve(tenantKey);
|
|
1908
|
-
apiResolved = !!apiEnvConfig;
|
|
1909
|
-
if (!apiEnvConfig) {
|
|
1910
|
-
apiEnvConfig = await buildTenantConfigFromEnv();
|
|
1911
|
-
}
|
|
1912
|
-
if (!apiEnvConfig) return null;
|
|
1913
|
-
if (!apiResolved && propsConfig) {
|
|
1914
|
-
const mergedConfig = mergeConfigWithProps(apiEnvConfig, propsConfig, tenantKey);
|
|
1915
|
-
removeStorage(getStorageKey("props_config"));
|
|
1916
|
-
logger.info("Merged props config with ENV fallback config");
|
|
1917
|
-
return mergedConfig;
|
|
1918
|
-
}
|
|
1676
|
+
const resolved = await tenantResolver.resolve(tenantKey);
|
|
1677
|
+
if (!resolved) return null;
|
|
1919
1678
|
removeStorage(getStorageKey("props_config"));
|
|
1920
1679
|
return {
|
|
1921
|
-
...
|
|
1922
|
-
tenantKey: tenantKey ||
|
|
1680
|
+
...propsConfig ? mergeConfigWithProps(resolved, propsConfig, tenantKey) : resolved,
|
|
1681
|
+
tenantKey: tenantKey || resolved.tenantKey
|
|
1923
1682
|
};
|
|
1924
1683
|
}
|
|
1925
1684
|
async function resolveTenantConfigCached(tenantKey, tenantResolver) {
|
|
@@ -2113,6 +1872,8 @@ var LoginFlow = class {
|
|
|
2113
1872
|
const { runtime } = context;
|
|
2114
1873
|
const { logger: log } = runtime;
|
|
2115
1874
|
const getUrl = () => runtime.urlProvider.getCurrentUrl();
|
|
1875
|
+
const url = getUrl();
|
|
1876
|
+
log.debug("[LoginFlow] Start", { url: url.href, pathname: url.pathname, search: url.search });
|
|
2116
1877
|
const callbackProcessed = getStorage(getStorageKey("callback_processed")) === "true";
|
|
2117
1878
|
const token = getAccessToken();
|
|
2118
1879
|
if (callbackProcessed && !token) {
|
|
@@ -2122,7 +1883,8 @@ var LoginFlow = class {
|
|
|
2122
1883
|
}
|
|
2123
1884
|
const wasStateMismatch = getStorage(getStorageKey("state_mismatch")) === "true";
|
|
2124
1885
|
if (wasStateMismatch) removeStorage(getStorageKey("state_mismatch"));
|
|
2125
|
-
const tenantKey = getTenantKeyFromRuntime(
|
|
1886
|
+
const tenantKey = getTenantKeyFromRuntime(url, runtime.configProvider);
|
|
1887
|
+
log.debug("[LoginFlow] Tenant key resolved", { tenantKey: tenantKey ?? "(null)" });
|
|
2126
1888
|
if (!tenantKey) {
|
|
2127
1889
|
throw new SanitizedError(
|
|
2128
1890
|
"TENANT_KEY_RESOLUTION_FAILED",
|
|
@@ -2130,7 +1892,15 @@ var LoginFlow = class {
|
|
|
2130
1892
|
new Error("Tenant key missing")
|
|
2131
1893
|
);
|
|
2132
1894
|
}
|
|
1895
|
+
log.debug("[LoginFlow] Resolving tenant config", { tenantKey });
|
|
2133
1896
|
const tenantConfig = await resolveTenantConfigCached(tenantKey, runtime.tenantResolver);
|
|
1897
|
+
log.debug("[LoginFlow] Tenant config resolved", {
|
|
1898
|
+
ok: !!tenantConfig,
|
|
1899
|
+
tenantId: tenantConfig?.tenantId,
|
|
1900
|
+
authServer: tenantConfig?.authServer ? "(set)" : "(empty)",
|
|
1901
|
+
clientId: tenantConfig?.client?.clientId,
|
|
1902
|
+
redirectUri: tenantConfig?.client?.redirectUri
|
|
1903
|
+
});
|
|
2134
1904
|
if (!tenantConfig) {
|
|
2135
1905
|
throw new SanitizedError(
|
|
2136
1906
|
"TENANT_CONFIG_RESOLUTION_FAILED",
|
|
@@ -2140,7 +1910,9 @@ var LoginFlow = class {
|
|
|
2140
1910
|
}
|
|
2141
1911
|
setTenantKey(tenantKey);
|
|
2142
1912
|
storeTenantConfig(tenantConfig);
|
|
1913
|
+
log.debug("[LoginFlow] Stored tenant config, initiating auth flow");
|
|
2143
1914
|
await initiateAuthFlow(tenantConfig);
|
|
1915
|
+
log.debug("[LoginFlow] Auth flow initiated (redirect should happen)");
|
|
2144
1916
|
return { completed: true };
|
|
2145
1917
|
}
|
|
2146
1918
|
};
|
|
@@ -2723,7 +2495,7 @@ async function logout(tenantKey) {
|
|
|
2723
2495
|
try {
|
|
2724
2496
|
stopStorageWatcher();
|
|
2725
2497
|
stopCookieWatcher();
|
|
2726
|
-
const apiAuthBaseUrl = Config.
|
|
2498
|
+
const apiAuthBaseUrl = Config.getAuthServerUrl();
|
|
2727
2499
|
let serverLogoutSuccess = false;
|
|
2728
2500
|
let serverResponse;
|
|
2729
2501
|
if (apiAuthBaseUrl) {
|
|
@@ -2822,16 +2594,16 @@ function useAuthContext() {
|
|
|
2822
2594
|
var ongoingRequests = /* @__PURE__ */ new Map();
|
|
2823
2595
|
var DEFAULT_SCOPES2 = OAUTH_CONSTANTS.SCOPES;
|
|
2824
2596
|
function getResolvedTenantBaseUrl() {
|
|
2825
|
-
let base = Config.
|
|
2597
|
+
let base = Config.getApiBaseUrl();
|
|
2826
2598
|
if (typeof window !== "undefined" && (!base || base.startsWith("/"))) {
|
|
2827
|
-
base = window.location.origin + (base || "
|
|
2599
|
+
base = window.location.origin + (base || "");
|
|
2828
2600
|
}
|
|
2829
2601
|
return base;
|
|
2830
2602
|
}
|
|
2831
2603
|
var PUBLIC_CODE_PREFIX = "public-";
|
|
2832
2604
|
function getTenantByCodeUrl(tenantCode) {
|
|
2833
2605
|
const apiTenantResolutionBaseUrl = getResolvedTenantBaseUrl();
|
|
2834
|
-
const base = apiTenantResolutionBaseUrl.replace(/\/api
|
|
2606
|
+
const base = (apiTenantResolutionBaseUrl || "").replace(/\/api(?:\/v1)?\/?$/, "") || apiTenantResolutionBaseUrl;
|
|
2835
2607
|
return `${base}/api/v1/tenant/public/tenants/by-code/${encodeURIComponent(tenantCode)}`;
|
|
2836
2608
|
}
|
|
2837
2609
|
async function resolveTenant(tenantKey) {
|
|
@@ -2867,7 +2639,9 @@ async function resolveTenant(tenantKey) {
|
|
|
2867
2639
|
if (!tenant.id || !tenant.clientCode) return null;
|
|
2868
2640
|
const authServer = Config.getAuthServerUrl();
|
|
2869
2641
|
const redirectUri = Config.getRedirectUri();
|
|
2870
|
-
if (!authServer || !redirectUri)
|
|
2642
|
+
if (!authServer || !redirectUri) {
|
|
2643
|
+
return null;
|
|
2644
|
+
}
|
|
2871
2645
|
const clientCodeWithPrefix = tenant.clientCode.startsWith(PUBLIC_CODE_PREFIX) ? tenant.clientCode : `${PUBLIC_CODE_PREFIX}${tenant.clientCode}`;
|
|
2872
2646
|
const config = {
|
|
2873
2647
|
tenantId: tenant.id,
|
|
@@ -2880,6 +2654,7 @@ async function resolveTenant(tenantKey) {
|
|
|
2880
2654
|
scopes: DEFAULT_SCOPES2
|
|
2881
2655
|
}
|
|
2882
2656
|
};
|
|
2657
|
+
console.log("config====", config);
|
|
2883
2658
|
logger.debug("Resolved tenant config", { tenantCode });
|
|
2884
2659
|
return config;
|
|
2885
2660
|
} catch (error) {
|
|
@@ -2941,13 +2716,10 @@ function createBrowserUrlProvider() {
|
|
|
2941
2716
|
}
|
|
2942
2717
|
function createConfigProvider() {
|
|
2943
2718
|
return {
|
|
2944
|
-
getApiBaseUrl: () => Config.
|
|
2719
|
+
getApiBaseUrl: () => Config.getApiBaseUrl(),
|
|
2945
2720
|
getAuthServerUrl: () => Config.getAuthServerUrl(),
|
|
2946
2721
|
getRedirectUri: () => Config.getRedirectUri(),
|
|
2947
|
-
|
|
2948
|
-
getTenantId: () => Config.getTenantId(),
|
|
2949
|
-
getClientCode: () => Config.getClientCode(),
|
|
2950
|
-
getBasePath: () => Config.getBasePath()
|
|
2722
|
+
getClientCode: () => Config.getClientCode()
|
|
2951
2723
|
};
|
|
2952
2724
|
}
|
|
2953
2725
|
function createTenantResolver() {
|
|
@@ -3111,6 +2883,9 @@ function AuthProvider({
|
|
|
3111
2883
|
children,
|
|
3112
2884
|
autoInit = true,
|
|
3113
2885
|
tenantCode,
|
|
2886
|
+
apiBaseUrl,
|
|
2887
|
+
authServerUrl,
|
|
2888
|
+
callbackUrl,
|
|
3114
2889
|
appId = "",
|
|
3115
2890
|
storageAdapter
|
|
3116
2891
|
}) {
|
|
@@ -3122,13 +2897,40 @@ function AuthProvider({
|
|
|
3122
2897
|
const initRanRef = react.useRef(false);
|
|
3123
2898
|
const engineRef = react.useRef(null);
|
|
3124
2899
|
react.useLayoutEffect(() => {
|
|
3125
|
-
|
|
3126
|
-
|
|
2900
|
+
logger.debug("[AuthProvider] Host config props", {
|
|
2901
|
+
tenantCode: tenantCode ?? "(not provided)",
|
|
2902
|
+
apiBaseUrl: apiBaseUrl ? apiBaseUrl : "(empty)",
|
|
2903
|
+
authServerUrl: authServerUrl ? authServerUrl : "(empty)",
|
|
2904
|
+
callbackUrl: callbackUrl ? callbackUrl : "(empty)"
|
|
2905
|
+
});
|
|
2906
|
+
if (!authServerUrl || !authServerUrl.trim()) {
|
|
2907
|
+
logger.warn("[AuthProvider] authServerUrl missing from host props");
|
|
2908
|
+
}
|
|
2909
|
+
if (!callbackUrl || !callbackUrl.trim()) {
|
|
2910
|
+
logger.warn("[AuthProvider] callbackUrl missing from host props");
|
|
3127
2911
|
}
|
|
2912
|
+
setConfig({
|
|
2913
|
+
...tenantCode ? { tenantCode } : {},
|
|
2914
|
+
...apiBaseUrl ? { apiBaseUrl } : {},
|
|
2915
|
+
...authServerUrl ? { authServerUrl } : {},
|
|
2916
|
+
...callbackUrl ? { callbackUrl } : {}
|
|
2917
|
+
});
|
|
3128
2918
|
return () => {
|
|
3129
2919
|
clearConfigOverrides();
|
|
3130
2920
|
};
|
|
3131
|
-
}, [tenantCode]);
|
|
2921
|
+
}, [tenantCode, apiBaseUrl, authServerUrl, callbackUrl]);
|
|
2922
|
+
react.useEffect(() => {
|
|
2923
|
+
try {
|
|
2924
|
+
const payload = {
|
|
2925
|
+
tenantCode: tenantCode ?? "",
|
|
2926
|
+
apiBaseUrl: apiBaseUrl ?? "",
|
|
2927
|
+
authServerUrl: authServerUrl ?? "",
|
|
2928
|
+
callbackUrl: callbackUrl ?? ""
|
|
2929
|
+
};
|
|
2930
|
+
setStorage(getStorageKey("host_config"), JSON.stringify(payload));
|
|
2931
|
+
} catch {
|
|
2932
|
+
}
|
|
2933
|
+
}, [tenantCode, apiBaseUrl, authServerUrl, callbackUrl]);
|
|
3132
2934
|
react.useLayoutEffect(() => {
|
|
3133
2935
|
setStorageKeyPrefix(resolvedTenantKey ?? "");
|
|
3134
2936
|
const adapter = storageAdapter !== void 0 && storageAdapter !== null ? storageAdapter : createSecureSessionStorageAdapter(namespace);
|
|
@@ -3612,11 +3414,9 @@ exports.extractTenantKey = extractTenantKey;
|
|
|
3612
3414
|
exports.getAccessToken = getAccessToken2;
|
|
3613
3415
|
exports.getAuthRuntime = getAuthRuntime;
|
|
3614
3416
|
exports.getConfig = getConfig;
|
|
3615
|
-
exports.getEnvConfig = getEnvConfig;
|
|
3616
3417
|
exports.getStorageAdapter = getStorageAdapter;
|
|
3617
3418
|
exports.getStorageNamespace = getStorageNamespace;
|
|
3618
3419
|
exports.getStoredAccessToken = getAccessToken;
|
|
3619
|
-
exports.hasEnvFallback = hasEnvFallback;
|
|
3620
3420
|
exports.isAccessTokenExpired = isAccessTokenExpired;
|
|
3621
3421
|
exports.isCallbackUrl = isCallbackUrl;
|
|
3622
3422
|
exports.logout = logout;
|