@enterprisestandard/react 0.0.3-beta.1 → 0.0.3-beta.20251013.2
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.js +67 -43
- package/dist/ui/sign-in-loading.d.ts +1 -1
- package/dist/ui/signed-in.d.ts +1 -1
- package/dist/ui/signed-out.d.ts +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -34,8 +34,8 @@ var jwksCache = new Map;
|
|
|
34
34
|
function sso(config) {
|
|
35
35
|
const configWithDefaults = {
|
|
36
36
|
...config,
|
|
37
|
-
secure: config.secure !== undefined ? config.secure :
|
|
38
|
-
sameSite: config.sameSite !== undefined ? config.sameSite : "
|
|
37
|
+
secure: config.secure !== undefined ? config.secure : true,
|
|
38
|
+
sameSite: config.sameSite !== undefined ? config.sameSite : "Strict",
|
|
39
39
|
cookiePrefix: config.cookiePrefix ?? `es.sso.${config.client_id}`,
|
|
40
40
|
cookiePath: config.cookiePath ?? "/"
|
|
41
41
|
};
|
|
@@ -45,10 +45,10 @@ function sso(config) {
|
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
try {
|
|
48
|
-
const
|
|
49
|
-
if (!
|
|
48
|
+
const { tokens } = await getTokenFromCookies(request);
|
|
49
|
+
if (!tokens)
|
|
50
50
|
return;
|
|
51
|
-
return await parseUser(
|
|
51
|
+
return await parseUser(tokens);
|
|
52
52
|
} catch (error) {
|
|
53
53
|
console.error("Error parsing user from cookies:", error);
|
|
54
54
|
return;
|
|
@@ -232,8 +232,9 @@ function sso(config) {
|
|
|
232
232
|
}
|
|
233
233
|
async function fetchJwks() {
|
|
234
234
|
const url = configWithDefaults.jwks_uri || `${configWithDefaults.authority}/protocol/openid-connect/certs`;
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
const cached = jwksCache.get(url);
|
|
236
|
+
if (cached)
|
|
237
|
+
return cached;
|
|
237
238
|
return retryWithBackoff(async () => {
|
|
238
239
|
if (!configWithDefaults)
|
|
239
240
|
throw new Error("SSO Manager not initialized");
|
|
@@ -333,7 +334,7 @@ function sso(config) {
|
|
|
333
334
|
const refresh_token = getCookie("refresh", req);
|
|
334
335
|
const control = getCookie("control", req, true);
|
|
335
336
|
if (!access_token || !id_token || !refresh_token || !control) {
|
|
336
|
-
return;
|
|
337
|
+
return { tokens: undefined, refreshHeaders: [] };
|
|
337
338
|
}
|
|
338
339
|
let tokenResponse = {
|
|
339
340
|
access_token,
|
|
@@ -343,14 +344,17 @@ function sso(config) {
|
|
|
343
344
|
};
|
|
344
345
|
if (control.expires && refresh_token && Date.now() > new Date(control.expires).getTime()) {
|
|
345
346
|
tokenResponse = await refreshToken(refresh_token);
|
|
347
|
+
const user = await parseUser(tokenResponse);
|
|
348
|
+
const refreshHeaders = createJwtCookies(tokenResponse, user.sso.expires);
|
|
349
|
+
return { tokens: tokenResponse, refreshHeaders };
|
|
346
350
|
}
|
|
347
|
-
return tokenResponse;
|
|
351
|
+
return { tokens: tokenResponse, refreshHeaders: [] };
|
|
348
352
|
}
|
|
349
353
|
async function getJwt(request) {
|
|
350
|
-
const
|
|
351
|
-
if (!
|
|
354
|
+
const { tokens } = await getTokenFromCookies(request);
|
|
355
|
+
if (!tokens)
|
|
352
356
|
return;
|
|
353
|
-
return
|
|
357
|
+
return tokens.access_token;
|
|
354
358
|
}
|
|
355
359
|
function createCookie(name, value, expires) {
|
|
356
360
|
name = `${configWithDefaults.cookiePrefix}.${name}`;
|
|
@@ -395,32 +399,39 @@ function sso(config) {
|
|
|
395
399
|
return callbackHandler(request);
|
|
396
400
|
}
|
|
397
401
|
if (userUrl === path) {
|
|
398
|
-
const
|
|
399
|
-
if (!
|
|
402
|
+
const { tokens, refreshHeaders } = await getTokenFromCookies(request);
|
|
403
|
+
if (!tokens) {
|
|
400
404
|
return new Response("User not logged in", { status: 401 });
|
|
401
405
|
}
|
|
406
|
+
const user = await parseUser(tokens);
|
|
402
407
|
return new Response(JSON.stringify(user), {
|
|
403
|
-
headers: [["Content-Type", "application/json"]]
|
|
408
|
+
headers: [["Content-Type", "application/json"], ...refreshHeaders]
|
|
404
409
|
});
|
|
405
410
|
}
|
|
406
411
|
if (tokenUrl === path) {
|
|
407
|
-
const
|
|
408
|
-
if (!
|
|
412
|
+
const { tokens, refreshHeaders } = await getTokenFromCookies(request);
|
|
413
|
+
if (!tokens) {
|
|
409
414
|
return new Response("User not logged in", { status: 401 });
|
|
410
415
|
}
|
|
411
416
|
return new Response(JSON.stringify({
|
|
412
|
-
token:
|
|
413
|
-
expires:
|
|
417
|
+
token: tokens.access_token,
|
|
418
|
+
expires: tokens.expires
|
|
414
419
|
}), {
|
|
415
|
-
headers: [["Content-Type", "application/json"]]
|
|
420
|
+
headers: [["Content-Type", "application/json"], ...refreshHeaders]
|
|
416
421
|
});
|
|
417
422
|
}
|
|
418
423
|
if (refreshUrl === path) {
|
|
419
|
-
const
|
|
420
|
-
if (!
|
|
424
|
+
const refresh_token = getCookie("refresh", request);
|
|
425
|
+
if (!refresh_token) {
|
|
421
426
|
return new Response("User not logged in", { status: 401 });
|
|
422
427
|
}
|
|
423
|
-
|
|
428
|
+
const newTokenResponse = await refreshToken(refresh_token);
|
|
429
|
+
const user = await parseUser(newTokenResponse);
|
|
430
|
+
const refreshHeaders = createJwtCookies(newTokenResponse, user.sso.expires);
|
|
431
|
+
return new Response("Refresh Complete", {
|
|
432
|
+
status: 200,
|
|
433
|
+
headers: refreshHeaders
|
|
434
|
+
});
|
|
424
435
|
}
|
|
425
436
|
if (loginUrl === "*" || loginUrl === path) {
|
|
426
437
|
return initiateLogin({
|
|
@@ -609,38 +620,38 @@ async function handler(request, config) {
|
|
|
609
620
|
return sso2.handler(request, config);
|
|
610
621
|
}
|
|
611
622
|
// src/ui/sign-in-loading.tsx
|
|
612
|
-
import {
|
|
623
|
+
import { jsx, Fragment } from "react/jsx-runtime";
|
|
613
624
|
function SignInLoading({ complete = false, children }) {
|
|
614
625
|
const { isLoading } = useUser();
|
|
615
626
|
if (isLoading && !complete)
|
|
616
|
-
return /* @__PURE__ */
|
|
627
|
+
return /* @__PURE__ */ jsx(Fragment, {
|
|
617
628
|
children
|
|
618
|
-
}
|
|
619
|
-
return
|
|
629
|
+
});
|
|
630
|
+
return null;
|
|
620
631
|
}
|
|
621
632
|
// src/ui/signed-in.tsx
|
|
622
|
-
import {
|
|
633
|
+
import { jsx as jsx2, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
623
634
|
function SignedIn({ children }) {
|
|
624
635
|
const { user } = useUser();
|
|
625
636
|
if (user)
|
|
626
|
-
return /* @__PURE__ */
|
|
637
|
+
return /* @__PURE__ */ jsx2(Fragment2, {
|
|
627
638
|
children
|
|
628
|
-
}
|
|
629
|
-
return
|
|
639
|
+
});
|
|
640
|
+
return null;
|
|
630
641
|
}
|
|
631
642
|
// src/ui/signed-out.tsx
|
|
632
|
-
import {
|
|
643
|
+
import { jsx as jsx3, Fragment as Fragment3 } from "react/jsx-runtime";
|
|
633
644
|
function SignedOut({ children }) {
|
|
634
|
-
const { user } = useUser();
|
|
635
|
-
if (user)
|
|
636
|
-
return
|
|
637
|
-
return /* @__PURE__ */
|
|
645
|
+
const { user, isLoading } = useUser();
|
|
646
|
+
if (user || isLoading)
|
|
647
|
+
return null;
|
|
648
|
+
return /* @__PURE__ */ jsx3(Fragment3, {
|
|
638
649
|
children
|
|
639
|
-
}
|
|
650
|
+
});
|
|
640
651
|
}
|
|
641
652
|
// src/ui/sso-provider.tsx
|
|
642
653
|
import { createContext, useCallback, useContext, useEffect, useState } from "react";
|
|
643
|
-
import {
|
|
654
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
644
655
|
var CTX = createContext(undefined);
|
|
645
656
|
var generateStorageKey = (tenantId) => {
|
|
646
657
|
return `es-sso-user-${tenantId.replace(/[^a-zA-Z0-9]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}`;
|
|
@@ -707,6 +718,12 @@ function SSOProvider({
|
|
|
707
718
|
setIsLoading(true);
|
|
708
719
|
try {
|
|
709
720
|
const response = await fetch(userUrl);
|
|
721
|
+
if (response.status === 401) {
|
|
722
|
+
setUserState(null);
|
|
723
|
+
saveUserToStorage(null);
|
|
724
|
+
setIsLoading(false);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
710
727
|
if (!response.ok) {
|
|
711
728
|
throw new Error(`Failed to fetch user: ${response.status} ${response.statusText}`);
|
|
712
729
|
}
|
|
@@ -728,8 +745,8 @@ function SSOProvider({
|
|
|
728
745
|
const storedUser = loadUserFromStorage();
|
|
729
746
|
if (storedUser) {
|
|
730
747
|
setUserState(storedUser);
|
|
731
|
-
|
|
732
|
-
|
|
748
|
+
}
|
|
749
|
+
if (userUrl) {
|
|
733
750
|
fetchUserFromUrl();
|
|
734
751
|
} else {
|
|
735
752
|
setIsLoading(false);
|
|
@@ -769,10 +786,10 @@ function SSOProvider({
|
|
|
769
786
|
tokenUrl,
|
|
770
787
|
refreshUrl
|
|
771
788
|
};
|
|
772
|
-
return /* @__PURE__ */
|
|
789
|
+
return /* @__PURE__ */ jsx4(CTX.Provider, {
|
|
773
790
|
value: contextValue,
|
|
774
791
|
children
|
|
775
|
-
}
|
|
792
|
+
});
|
|
776
793
|
}
|
|
777
794
|
function useUser() {
|
|
778
795
|
const context = useContext(CTX);
|
|
@@ -799,6 +816,13 @@ function useToken() {
|
|
|
799
816
|
setError(null);
|
|
800
817
|
try {
|
|
801
818
|
const response = await fetch(url);
|
|
819
|
+
if (response.status === 401) {
|
|
820
|
+
context.setUser(null);
|
|
821
|
+
setToken(null);
|
|
822
|
+
setExpires(null);
|
|
823
|
+
setIsLoading(false);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
802
826
|
if (!response.ok) {
|
|
803
827
|
throw new Error(`Failed to fetch JWT: ${response.status} ${response.statusText}`);
|
|
804
828
|
}
|
|
@@ -814,7 +838,7 @@ function useToken() {
|
|
|
814
838
|
} finally {
|
|
815
839
|
setIsLoading(false);
|
|
816
840
|
}
|
|
817
|
-
}, []);
|
|
841
|
+
}, [context]);
|
|
818
842
|
const refresh = useCallback(async () => {
|
|
819
843
|
const url = refreshUrl || tokenUrl;
|
|
820
844
|
if (!url) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { PropsWithChildren } from 'react';
|
|
2
2
|
export declare function SignInLoading({ complete, children }: {
|
|
3
3
|
complete?: boolean;
|
|
4
|
-
} & PropsWithChildren): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
} & PropsWithChildren): import("react/jsx-runtime").JSX.Element | null;
|
package/dist/ui/signed-in.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { PropsWithChildren } from 'react';
|
|
2
|
-
export declare function SignedIn({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function SignedIn({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element | null;
|
package/dist/ui/signed-out.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { PropsWithChildren } from 'react';
|
|
2
|
-
export declare function SignedOut({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function SignedOut({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element | null;
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enterprisestandard/react",
|
|
3
|
-
"version": "0.0.3-beta.
|
|
3
|
+
"version": "0.0.3-beta.20251013.2",
|
|
4
4
|
"description": "Enterprise Standard React Components",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "bun run build.ts"
|
|
9
|
-
"prepublishOnly": "bun run build"
|
|
8
|
+
"build": "bun run build.ts"
|
|
10
9
|
},
|
|
11
10
|
"types": "./dist/index.d.ts",
|
|
12
11
|
"exports": {
|
|
@@ -30,6 +29,7 @@
|
|
|
30
29
|
"access": "public"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
32
|
+
"@types/react": "^18.0.0",
|
|
33
33
|
"typescript": "^5.0.0"
|
|
34
34
|
},
|
|
35
35
|
"author": "enterprisestandard",
|