@conduit-d365/auth 0.2.2 → 0.3.0
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/AuthProvider.d.ts +4 -0
- package/dist/AuthProvider.d.ts.map +1 -1
- package/dist/AuthProvider.js +15 -4
- package/dist/AuthProvider.js.map +1 -1
- package/dist/ProtectedRoute.d.ts +4 -3
- package/dist/ProtectedRoute.d.ts.map +1 -1
- package/dist/ProtectedRoute.js +21 -9
- package/dist/ProtectedRoute.js.map +1 -1
- package/package.json +1 -1
package/dist/AuthProvider.d.ts
CHANGED
|
@@ -18,6 +18,10 @@ interface AuthProviderProps {
|
|
|
18
18
|
* Handles MSAL initialisation, redirect callbacks, and active account
|
|
19
19
|
* management. Children are NOT rendered until MSAL has initialised and
|
|
20
20
|
* any pending redirect promise has been processed.
|
|
21
|
+
*
|
|
22
|
+
* The MSAL instance is created once (via useRef) and initialised in a
|
|
23
|
+
* single useEffect. MsalProvider receives the instance but does NOT
|
|
24
|
+
* re-initialise it — MSAL internally tracks its own init state.
|
|
21
25
|
*/
|
|
22
26
|
export declare function AuthProvider({ clientId, redirectUri, scopes, children, }: AuthProviderProps): import("react/jsx-runtime").JSX.Element | null;
|
|
23
27
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAY1E,qEAAqE;AACrE,eAAO,MAAM,aAAa,qCAAiD,CAAC;AAE5E,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,wBAAgC,CAAC;AAE9D,UAAU,iBAAiB;IACzB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAY1E,qEAAqE;AACrE,eAAO,MAAM,aAAa,qCAAiD,CAAC;AAE5E,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,wBAAgC,CAAC;AAE9D,UAAU,iBAAiB;IACzB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,GACT,EAAE,iBAAiB,kDAoEnB"}
|
package/dist/AuthProvider.js
CHANGED
|
@@ -13,27 +13,38 @@ export const MsalReadyContext = createContext(false);
|
|
|
13
13
|
* Handles MSAL initialisation, redirect callbacks, and active account
|
|
14
14
|
* management. Children are NOT rendered until MSAL has initialised and
|
|
15
15
|
* any pending redirect promise has been processed.
|
|
16
|
+
*
|
|
17
|
+
* The MSAL instance is created once (via useRef) and initialised in a
|
|
18
|
+
* single useEffect. MsalProvider receives the instance but does NOT
|
|
19
|
+
* re-initialise it — MSAL internally tracks its own init state.
|
|
16
20
|
*/
|
|
17
21
|
export function AuthProvider({ clientId, redirectUri, scopes, children, }) {
|
|
18
22
|
const msalInstanceRef = useRef(null);
|
|
19
23
|
const [msalReady, setMsalReady] = useState(false);
|
|
24
|
+
const initStarted = useRef(false);
|
|
20
25
|
if (!msalInstanceRef.current) {
|
|
21
26
|
const config = createMsalConfig({ clientId, redirectUri });
|
|
22
27
|
msalInstanceRef.current = new PublicClientApplication(config);
|
|
23
28
|
}
|
|
24
29
|
const msalInstance = msalInstanceRef.current;
|
|
25
30
|
useEffect(() => {
|
|
31
|
+
// Guard against double-invocation in React StrictMode
|
|
32
|
+
if (initStarted.current)
|
|
33
|
+
return;
|
|
34
|
+
initStarted.current = true;
|
|
26
35
|
const init = async () => {
|
|
27
36
|
await msalInstance.initialize();
|
|
28
|
-
// Process any pending redirect response BEFORE rendering children
|
|
29
|
-
|
|
37
|
+
// Process any pending redirect response BEFORE rendering children.
|
|
38
|
+
// If this returns null after a redirect, MSAL couldn't match the
|
|
39
|
+
// response to a stored request (the root cause of the redirect loop).
|
|
40
|
+
const response = await msalInstance.handleRedirectPromise({
|
|
41
|
+
navigateToLoginRequestUrl: false,
|
|
42
|
+
});
|
|
30
43
|
if (response?.account) {
|
|
31
|
-
// Returning from a login redirect — set the account immediately
|
|
32
44
|
msalInstance.setActiveAccount(response.account);
|
|
33
45
|
}
|
|
34
46
|
else if (!msalInstance.getActiveAccount() &&
|
|
35
47
|
msalInstance.getAllAccounts().length > 0) {
|
|
36
|
-
// Existing session — set first account as active
|
|
37
48
|
msalInstance.setActiveAccount(msalInstance.getAllAccounts()[0]);
|
|
38
49
|
}
|
|
39
50
|
// Listen for future login successes
|
package/dist/AuthProvider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,EACL,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,SAAS,EACT,uBAAuB,GAGxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,qEAAqE;AACrE,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAuB,SAAS,CAAC,CAAC;AAE5E,mEAAmE;AACnE,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAU,KAAK,CAAC,CAAC;AAY9D
|
|
1
|
+
{"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"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"}
|
package/dist/ProtectedRoute.d.ts
CHANGED
|
@@ -7,9 +7,10 @@ interface ProtectedRouteProps {
|
|
|
7
7
|
/**
|
|
8
8
|
* Route guard that requires authentication.
|
|
9
9
|
*
|
|
10
|
-
* While MSAL is initialising, shows a loading
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* While MSAL is initialising or processing a redirect, shows a loading
|
|
11
|
+
* indicator. If the user is not authenticated AND MSAL is completely
|
|
12
|
+
* idle (InteractionStatus.None), triggers a login redirect once per
|
|
13
|
+
* mount. Otherwise renders the children.
|
|
13
14
|
*
|
|
14
15
|
* Usage:
|
|
15
16
|
* <Route path="/projects" element={
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProtectedRoute.d.ts","sourceRoot":"","sources":["../src/ProtectedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ProtectedRoute.d.ts","sourceRoot":"","sources":["../src/ProtectedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAKjD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACpC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,gBAAgB,GACjB,EAAE,mBAAmB,2CA6BrB"}
|
package/dist/ProtectedRoute.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useRef } from "react";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
3
|
import { useAuth } from "./useAuth";
|
|
4
|
+
import { useMsal } from "@azure/msal-react";
|
|
5
|
+
import { InteractionStatus } from "@azure/msal-browser";
|
|
4
6
|
/**
|
|
5
7
|
* Route guard that requires authentication.
|
|
6
8
|
*
|
|
7
|
-
* While MSAL is initialising, shows a loading
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* While MSAL is initialising or processing a redirect, shows a loading
|
|
10
|
+
* indicator. If the user is not authenticated AND MSAL is completely
|
|
11
|
+
* idle (InteractionStatus.None), triggers a login redirect once per
|
|
12
|
+
* mount. Otherwise renders the children.
|
|
10
13
|
*
|
|
11
14
|
* Usage:
|
|
12
15
|
* <Route path="/projects" element={
|
|
@@ -17,15 +20,24 @@ import { useAuth } from "./useAuth";
|
|
|
17
20
|
*/
|
|
18
21
|
export function ProtectedRoute({ children, loadingComponent, }) {
|
|
19
22
|
const { isAuthenticated, isLoading, login } = useAuth();
|
|
23
|
+
const { inProgress } = useMsal();
|
|
20
24
|
const loginTriggered = useRef(false);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (!
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// Only trigger login when MSAL is completely idle and user is not
|
|
27
|
+
// authenticated. This prevents firing loginRedirect while MSAL is
|
|
28
|
+
// still processing a redirect response (which caused the loop).
|
|
29
|
+
if (!isAuthenticated &&
|
|
30
|
+
!isLoading &&
|
|
31
|
+
inProgress === InteractionStatus.None &&
|
|
32
|
+
!loginTriggered.current) {
|
|
26
33
|
loginTriggered.current = true;
|
|
27
34
|
login();
|
|
28
35
|
}
|
|
36
|
+
}, [isAuthenticated, isLoading, inProgress, login]);
|
|
37
|
+
if (isLoading || inProgress !== InteractionStatus.None) {
|
|
38
|
+
return _jsx(_Fragment, { children: loadingComponent ?? _jsx("div", { children: "Loading..." }) });
|
|
39
|
+
}
|
|
40
|
+
if (!isAuthenticated) {
|
|
29
41
|
return _jsx("div", { children: "Redirecting to login..." });
|
|
30
42
|
}
|
|
31
43
|
return _jsx(_Fragment, { children: children });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProtectedRoute.js","sourceRoot":"","sources":["../src/ProtectedRoute.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ProtectedRoute.js","sourceRoot":"","sources":["../src/ProtectedRoute.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAQxD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,gBAAgB,GACI;IACpB,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;IACxD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAAC;IACjC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAErC,SAAS,CAAC,GAAG,EAAE;QACb,kEAAkE;QAClE,kEAAkE;QAClE,gEAAgE;QAChE,IACE,CAAC,eAAe;YAChB,CAAC,SAAS;YACV,UAAU,KAAK,iBAAiB,CAAC,IAAI;YACrC,CAAC,cAAc,CAAC,OAAO,EACvB,CAAC;YACD,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC,EAAE,CAAC,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAEpD,IAAI,SAAS,IAAI,UAAU,KAAK,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACvD,OAAO,4BAAG,gBAAgB,IAAI,uCAAqB,GAAI,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,oDAAkC,CAAC;IAC5C,CAAC;IAED,OAAO,4BAAG,QAAQ,GAAI,CAAC;AACzB,CAAC"}
|