@enterprisestandard/react 0.0.1 → 0.0.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.d.ts +5 -2
- package/dist/index.js +190 -42
- package/dist/server.d.ts +3 -3
- package/dist/ui/sign-in-loading.d.ts +2 -0
- package/dist/ui/signed-in.d.ts +2 -6
- package/dist/ui/signed-out.d.ts +2 -0
- package/dist/ui/sso-provider.d.ts +19 -0
- package/dist/utils.d.ts +1 -1
- package/dist/vault.d.ts +0 -1
- package/package.json +1 -1
- package/dist/useUser.d.ts +0 -8
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { type IAM } from './iam';
|
|
1
2
|
import { SSOManager } from './sso';
|
|
2
3
|
import { type Vault } from './vault';
|
|
3
|
-
import { type IAM } from './iam';
|
|
4
4
|
export type EnterpriseStandard = {
|
|
5
5
|
ioniteUrl: string;
|
|
6
6
|
appId: string;
|
|
@@ -18,4 +18,7 @@ export declare function enterpriseStandard(appId: string, appKey?: string, initC
|
|
|
18
18
|
export type * from './enterprise-user';
|
|
19
19
|
export { oidcCallbackSchema } from './oidc-schema';
|
|
20
20
|
export * from './server';
|
|
21
|
-
export {
|
|
21
|
+
export { SignInLoading } from './ui/sign-in-loading';
|
|
22
|
+
export { SignedIn } from './ui/signed-in';
|
|
23
|
+
export { SignedOut } from './ui/signed-out';
|
|
24
|
+
export * from './ui/sso-provider';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
// src/iam.ts
|
|
2
|
+
async function iam(config) {
|
|
3
|
+
return {
|
|
4
|
+
url: config.url,
|
|
5
|
+
userEndpoint: config.userEndpoint,
|
|
6
|
+
groupEndpoint: config.groupEndpoint
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
1
10
|
// src/utils.ts
|
|
2
11
|
var defaultInstance;
|
|
3
12
|
function must(value, message = "Assertion failed. Required value is null or undefined.") {
|
|
@@ -28,7 +37,7 @@ class SSOManager {
|
|
|
28
37
|
constructor(config) {
|
|
29
38
|
this.config = {
|
|
30
39
|
...config,
|
|
31
|
-
secure: config.secure === undefined || config.secure === true
|
|
40
|
+
secure: !!(config.secure === undefined || config.secure === true),
|
|
32
41
|
sameSite: config.sameSite === undefined || config.sameSite === "Strict" ? "Strict" : "Lax",
|
|
33
42
|
cookiePrefix: config.cookiePrefix ?? `es.sso.${config.client_id}`,
|
|
34
43
|
cookiePath: config.cookiePath ?? "/"
|
|
@@ -124,12 +133,10 @@ class SSOManager {
|
|
|
124
133
|
if (errorPage) {
|
|
125
134
|
return new Response("Redirecting to error page", {
|
|
126
135
|
status: 302,
|
|
127
|
-
headers: [
|
|
128
|
-
["Location", errorPage]
|
|
129
|
-
]
|
|
136
|
+
headers: [["Location", errorPage]]
|
|
130
137
|
});
|
|
131
138
|
}
|
|
132
|
-
} catch (
|
|
139
|
+
} catch (_err) {
|
|
133
140
|
console.warn("Error parsing the errorPage from the OIDC cookie");
|
|
134
141
|
}
|
|
135
142
|
console.warn("No error page was found in the cookies. The user will be shown a default error page.");
|
|
@@ -148,10 +155,12 @@ class SSOManager {
|
|
|
148
155
|
userName: idToken.preferred_username || "",
|
|
149
156
|
name: idToken.name || "",
|
|
150
157
|
email: idToken.email || "",
|
|
151
|
-
emails: [
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
emails: [
|
|
159
|
+
{
|
|
160
|
+
value: idToken.email || "",
|
|
161
|
+
primary: true
|
|
162
|
+
}
|
|
163
|
+
],
|
|
155
164
|
avatarUrl: idToken.picture,
|
|
156
165
|
sso: {
|
|
157
166
|
profile: {
|
|
@@ -396,15 +405,6 @@ async function vault(url, token) {
|
|
|
396
405
|
};
|
|
397
406
|
}
|
|
398
407
|
|
|
399
|
-
// src/iam.ts
|
|
400
|
-
async function iam(config) {
|
|
401
|
-
return {
|
|
402
|
-
url: config.url,
|
|
403
|
-
userEndpoint: config.userEndpoint,
|
|
404
|
-
groupEndpoint: config.groupEndpoint
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
|
|
408
408
|
// src/oidc-schema.ts
|
|
409
409
|
function oidcCallbackSchema(vendor) {
|
|
410
410
|
return {
|
|
@@ -544,33 +544,177 @@ async function callback(request, es) {
|
|
|
544
544
|
throw unavailable();
|
|
545
545
|
return sso.callbackHandler(request);
|
|
546
546
|
}
|
|
547
|
-
// src/
|
|
548
|
-
import {
|
|
549
|
-
function
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
547
|
+
// src/ui/sign-in-loading.tsx
|
|
548
|
+
import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
|
|
549
|
+
function SignInLoading({ children }) {
|
|
550
|
+
const { isLoading } = useUser();
|
|
551
|
+
if (isLoading)
|
|
552
|
+
return /* @__PURE__ */ jsxDEV(Fragment, {
|
|
553
|
+
children
|
|
554
|
+
}, undefined, false, undefined, this);
|
|
555
|
+
return /* @__PURE__ */ jsxDEV(Fragment, {}, undefined, false, undefined, this);
|
|
556
|
+
}
|
|
557
|
+
// src/ui/signed-in.tsx
|
|
558
|
+
import { jsxDEV as jsxDEV2, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
559
|
+
function SignedIn({ children }) {
|
|
560
|
+
const { user } = useUser();
|
|
561
|
+
if (user)
|
|
562
|
+
return /* @__PURE__ */ jsxDEV2(Fragment2, {
|
|
563
|
+
children
|
|
564
|
+
}, undefined, false, undefined, this);
|
|
565
|
+
return /* @__PURE__ */ jsxDEV2(Fragment2, {}, undefined, false, undefined, this);
|
|
566
|
+
}
|
|
567
|
+
// src/ui/signed-out.tsx
|
|
568
|
+
import { jsxDEV as jsxDEV3, Fragment as Fragment3 } from "react/jsx-dev-runtime";
|
|
569
|
+
function SignedOut({ children }) {
|
|
570
|
+
const { user } = useUser();
|
|
571
|
+
if (user)
|
|
572
|
+
return /* @__PURE__ */ jsxDEV3(Fragment3, {}, undefined, false, undefined, this);
|
|
573
|
+
return /* @__PURE__ */ jsxDEV3(Fragment3, {
|
|
574
|
+
children
|
|
575
|
+
}, undefined, false, undefined, this);
|
|
576
|
+
}
|
|
577
|
+
// src/ui/sso-provider.tsx
|
|
578
|
+
import { createContext, useCallback, useContext, useEffect, useState } from "react";
|
|
579
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
580
|
+
var SSOContext = createContext(undefined);
|
|
581
|
+
var generateStorageKey = (tenantId) => {
|
|
582
|
+
return `es-sso-user-${tenantId.replace(/[^a-zA-Z0-9]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "")}`;
|
|
583
|
+
};
|
|
584
|
+
function SSOProvider({
|
|
585
|
+
tenantId,
|
|
586
|
+
storage = "memory",
|
|
587
|
+
storageKey,
|
|
588
|
+
userUrl,
|
|
589
|
+
disableListener = false,
|
|
590
|
+
children
|
|
591
|
+
}) {
|
|
592
|
+
const [user, setUserState] = useState(null);
|
|
593
|
+
const [isLoading, setIsLoading] = useState(!!userUrl);
|
|
594
|
+
const actualStorageKey = storageKey || (tenantId ? generateStorageKey(tenantId) : "es-sso-user");
|
|
595
|
+
const isValidUser = useCallback((user2) => {
|
|
596
|
+
if (!user2 || !tenantId)
|
|
597
|
+
return true;
|
|
598
|
+
return user2.sso?.tenant?.id === tenantId;
|
|
599
|
+
}, [tenantId]);
|
|
600
|
+
const loadUserFromStorage = useCallback(() => {
|
|
601
|
+
if (storage === "memory")
|
|
602
|
+
return null;
|
|
603
|
+
try {
|
|
604
|
+
const storageObject = storage === "local" ? localStorage : sessionStorage;
|
|
605
|
+
const userData = storageObject.getItem(actualStorageKey);
|
|
606
|
+
if (!userData)
|
|
607
|
+
return null;
|
|
608
|
+
const parsedUser = JSON.parse(userData);
|
|
609
|
+
if (parsedUser.sso?.expires) {
|
|
610
|
+
parsedUser.sso.expires = new Date(parsedUser.sso.expires);
|
|
611
|
+
}
|
|
612
|
+
return isValidUser(parsedUser) ? parsedUser : null;
|
|
613
|
+
} catch (error) {
|
|
614
|
+
console.error("Error loading user from storage:", error);
|
|
615
|
+
return null;
|
|
616
|
+
}
|
|
617
|
+
}, [storage, actualStorageKey, isValidUser]);
|
|
618
|
+
const saveUserToStorage = useCallback((user2) => {
|
|
619
|
+
if (storage === "memory")
|
|
620
|
+
return;
|
|
621
|
+
try {
|
|
622
|
+
const storageObject = storage === "local" ? localStorage : sessionStorage;
|
|
623
|
+
if (user2 === null) {
|
|
624
|
+
storageObject.removeItem(actualStorageKey);
|
|
625
|
+
} else {
|
|
626
|
+
storageObject.setItem(actualStorageKey, JSON.stringify(user2));
|
|
627
|
+
}
|
|
628
|
+
} catch (error) {
|
|
629
|
+
console.error("Error saving user to storage:", error);
|
|
630
|
+
}
|
|
631
|
+
}, [storage, actualStorageKey]);
|
|
632
|
+
const setUser = useCallback((newUser) => {
|
|
633
|
+
if (newUser && !isValidUser(newUser))
|
|
634
|
+
return;
|
|
635
|
+
setUserState(newUser);
|
|
636
|
+
saveUserToStorage(newUser);
|
|
637
|
+
}, [isValidUser, saveUserToStorage]);
|
|
638
|
+
const fetchUserFromUrl = useCallback(async () => {
|
|
639
|
+
if (!userUrl)
|
|
640
|
+
return;
|
|
641
|
+
setIsLoading(true);
|
|
642
|
+
try {
|
|
643
|
+
const response = await fetch(userUrl);
|
|
644
|
+
if (!response.ok) {
|
|
645
|
+
throw new Error(`Failed to fetch user: ${response.status} ${response.statusText}`);
|
|
646
|
+
}
|
|
647
|
+
const userData = await response.json();
|
|
648
|
+
if (userData.sso?.expires && typeof userData.sso.expires === "string") {
|
|
649
|
+
userData.sso.expires = new Date(userData.sso.expires);
|
|
650
|
+
}
|
|
651
|
+
if (isValidUser(userData)) {
|
|
652
|
+
setUserState(userData);
|
|
653
|
+
saveUserToStorage(userData);
|
|
654
|
+
}
|
|
655
|
+
} catch (error) {
|
|
656
|
+
console.error("Error fetching user from URL:", error);
|
|
657
|
+
} finally {
|
|
658
|
+
setIsLoading(false);
|
|
659
|
+
}
|
|
660
|
+
}, [userUrl, isValidUser, saveUserToStorage]);
|
|
554
661
|
useEffect(() => {
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
662
|
+
const storedUser = loadUserFromStorage();
|
|
663
|
+
if (storedUser) {
|
|
664
|
+
setUserState(storedUser);
|
|
665
|
+
setIsLoading(false);
|
|
666
|
+
} else if (userUrl) {
|
|
667
|
+
fetchUserFromUrl();
|
|
668
|
+
} else {
|
|
669
|
+
setIsLoading(false);
|
|
670
|
+
}
|
|
671
|
+
}, [loadUserFromStorage, userUrl, fetchUserFromUrl]);
|
|
672
|
+
useEffect(() => {
|
|
673
|
+
console.log(disableListener, storage, actualStorageKey);
|
|
674
|
+
if (disableListener || storage === "memory")
|
|
675
|
+
return;
|
|
676
|
+
console.log("set up listener");
|
|
677
|
+
const handleStorageChange = (event) => {
|
|
678
|
+
console.log("lsitened", actualStorageKey);
|
|
679
|
+
if (event.key !== actualStorageKey)
|
|
680
|
+
return;
|
|
681
|
+
if (event.newValue === null) {
|
|
682
|
+
setUserState(null);
|
|
683
|
+
} else {
|
|
684
|
+
try {
|
|
685
|
+
const parsedUser = JSON.parse(event.newValue);
|
|
686
|
+
if (parsedUser.sso?.expires) {
|
|
687
|
+
parsedUser.sso.expires = new Date(parsedUser.sso.expires);
|
|
688
|
+
}
|
|
689
|
+
if (isValidUser(parsedUser)) {
|
|
690
|
+
setUserState(parsedUser);
|
|
691
|
+
}
|
|
692
|
+
} catch (error) {
|
|
693
|
+
console.error("Error parsing user from storage event:", error);
|
|
564
694
|
}
|
|
565
|
-
} catch (error) {
|
|
566
|
-
console.error("Error fetching user:", error);
|
|
567
|
-
setUser(undefined);
|
|
568
695
|
}
|
|
569
|
-
setIsLoading(false);
|
|
570
696
|
};
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
697
|
+
window.addEventListener("storage", handleStorageChange);
|
|
698
|
+
return () => {
|
|
699
|
+
window.removeEventListener("storage", handleStorageChange);
|
|
700
|
+
};
|
|
701
|
+
}, [disableListener, storage, actualStorageKey, isValidUser]);
|
|
702
|
+
const contextValue = {
|
|
703
|
+
user,
|
|
704
|
+
setUser,
|
|
705
|
+
isLoading
|
|
706
|
+
};
|
|
707
|
+
return /* @__PURE__ */ jsxDEV4(SSOContext.Provider, {
|
|
708
|
+
value: contextValue,
|
|
709
|
+
children
|
|
710
|
+
}, undefined, false, undefined, this);
|
|
711
|
+
}
|
|
712
|
+
function useUser() {
|
|
713
|
+
const context = useContext(SSOContext);
|
|
714
|
+
if (context === undefined) {
|
|
715
|
+
throw new Error("useUser must be used within a SSOProvider");
|
|
716
|
+
}
|
|
717
|
+
return context;
|
|
574
718
|
}
|
|
575
719
|
|
|
576
720
|
// src/index.ts
|
|
@@ -616,5 +760,9 @@ export {
|
|
|
616
760
|
getUser,
|
|
617
761
|
getRequiredUser,
|
|
618
762
|
enterpriseStandard,
|
|
619
|
-
callback
|
|
763
|
+
callback,
|
|
764
|
+
SignedOut,
|
|
765
|
+
SignedIn,
|
|
766
|
+
SignInLoading,
|
|
767
|
+
SSOProvider
|
|
620
768
|
};
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EnterpriseStandard
|
|
2
|
-
export declare function getUser(request: Request, es?: EnterpriseStandard): Promise<EnterpriseUser | undefined>;
|
|
3
|
-
export declare function getRequiredUser(request: Request, es?: EnterpriseStandard): Promise<EnterpriseUser>;
|
|
1
|
+
import type { EnterpriseStandard } from '.';
|
|
2
|
+
export declare function getUser(request: Request, es?: EnterpriseStandard): Promise<import("./enterprise-user").EnterpriseUser | undefined>;
|
|
3
|
+
export declare function getRequiredUser(request: Request, es?: EnterpriseStandard): Promise<import("./enterprise-user").EnterpriseUser>;
|
|
4
4
|
export declare function initiateLogin(landingPage: string, errorPage?: string, es?: EnterpriseStandard): Promise<Response>;
|
|
5
5
|
export declare function callback(request: Request, es?: EnterpriseStandard): Promise<Response>;
|
package/dist/ui/signed-in.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
import { PropsWithChildren } from
|
|
2
|
-
|
|
3
|
-
export type Props = {
|
|
4
|
-
es?: EnterpriseStandard;
|
|
5
|
-
} & PropsWithChildren;
|
|
6
|
-
export declare function SignedIn({ es, children }: Props): import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
import type { PropsWithChildren } from 'react';
|
|
2
|
+
export declare function SignedIn({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { EnterpriseUser } from '../enterprise-user';
|
|
3
|
+
type StorageType = 'local' | 'session' | 'memory';
|
|
4
|
+
interface SSOProviderProps {
|
|
5
|
+
tenantId?: string;
|
|
6
|
+
storage?: StorageType;
|
|
7
|
+
storageKey?: string;
|
|
8
|
+
userUrl?: string;
|
|
9
|
+
disableListener?: boolean;
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
interface SSOContextValue {
|
|
13
|
+
user: EnterpriseUser | null;
|
|
14
|
+
setUser: (user: EnterpriseUser | null) => void;
|
|
15
|
+
isLoading: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function SSOProvider({ tenantId, storage, storageKey, userUrl, disableListener, children, }: SSOProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export declare function useUser(): SSOContextValue;
|
|
19
|
+
export {};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { EnterpriseStandard } from '.';
|
|
2
2
|
export declare function must<T>(value: T | undefined | null, message?: string): T;
|
|
3
3
|
export declare function setDefaultInstance(es: EnterpriseStandard): void;
|
|
4
4
|
export declare function getDefaultInstance(): EnterpriseStandard | undefined;
|
package/dist/vault.d.ts
CHANGED
package/package.json
CHANGED