@civic/auth
Advanced tools
Comparing version 0.1.5-beta.1 to 0.1.5-beta.2
@@ -5,3 +5,5 @@ import type { EmptyObject, User } from "../../types.js"; | ||
idToken: string | undefined; | ||
fetchUser: (abortController?: AbortController) => Promise<void>; | ||
isPending: boolean; | ||
}; | ||
//# sourceMappingURL=useUserCookie.d.ts.map |
@@ -9,2 +9,4 @@ "use strict"; | ||
const types_js_1 = require("../../shared/lib/types.js"); | ||
const usePrevious_js_1 = require("./usePrevious.js"); | ||
const react_2 = require("react"); | ||
const getUserAndTokenFromCookie = () => (0, cookies_js_1.getWindowCookieValue)([ | ||
@@ -25,39 +27,57 @@ { | ||
const [idToken, setIdToken] = (0, react_1.useState)(); | ||
const [userChanged, setUserChanged] = (0, react_1.useState)(false); | ||
const hasRunRef = (0, react_1.useRef)(false); | ||
const [isPending, startTransition] = (0, react_2.useTransition)(); | ||
const router = (0, navigation_js_1.useRouter)(); | ||
const prevUser = (0, usePrevious_js_1.usePrevious)(user); | ||
const prevPending = (0, usePrevious_js_1.usePrevious)(isPending); | ||
const fetchUser = (0, react_1.useCallback)(async (abortController) => { | ||
if (abortController.signal.aborted) | ||
if (abortController?.signal.aborted) | ||
return; | ||
if (!hasRunRef.current) { | ||
const response = getUserAndTokenFromCookie() || {}; | ||
const userData = response[types_js_1.UserStorage.USER]; | ||
const tokenData = response[types_js_1.OAuthTokens.ID_TOKEN]; | ||
if (abortController.signal.aborted) | ||
return; | ||
setIdToken(tokenData); | ||
setUser(userData || null); | ||
} | ||
const response = getUserAndTokenFromCookie() || {}; | ||
const userData = response[types_js_1.UserStorage.USER]; | ||
const tokenData = response[types_js_1.OAuthTokens.ID_TOKEN]; | ||
if (abortController?.signal.aborted) | ||
return; | ||
setIdToken(tokenData); | ||
setUser(userData || null); | ||
}, []); | ||
// call fetch immediately after a refresh | ||
(0, react_1.useEffect)(() => { | ||
const abortController = new AbortController(); | ||
const intervalId = setInterval(() => { | ||
if (prevPending && !isPending) { | ||
fetchUser(); | ||
} | ||
}, [prevPending, isPending, fetchUser]); | ||
(0, react_1.useEffect)(() => { | ||
if (prevUser !== user) { | ||
setUserChanged(true); | ||
} | ||
}, [user, prevUser]); | ||
(0, react_1.useEffect)(() => { | ||
let abortController = new AbortController(); | ||
const cookieListener = () => { | ||
abortController = new AbortController(); | ||
fetchUser(abortController); | ||
}, 2000); | ||
const handleFocus = () => { | ||
fetchUser(abortController); | ||
}; | ||
window.addEventListener("focus", handleFocus); | ||
// call fetchUser on load to get initial user if present | ||
document.addEventListener("visibilitychange", cookieListener); | ||
window.addEventListener("storage", cookieListener); | ||
window.addEventListener("focus", cookieListener); | ||
fetchUser(abortController); | ||
const intervalId = setInterval(cookieListener, 2000); | ||
return () => { | ||
abortController.abort(); | ||
document.removeEventListener("visibilitychange", cookieListener); | ||
window.removeEventListener("storage", cookieListener); | ||
window.removeEventListener("focus", cookieListener); | ||
clearInterval(intervalId); | ||
window.removeEventListener("focus", handleFocus); | ||
}; | ||
}, [fetchUser]); | ||
(0, react_1.useEffect)(() => { | ||
if (user) { | ||
if (userChanged) { | ||
if (!hasRunRef.current) { | ||
hasRunRef.current = true; | ||
router.refresh(); | ||
setUserChanged(false); | ||
startTransition(() => { | ||
router.refresh(); | ||
}); | ||
} | ||
@@ -68,6 +88,7 @@ } | ||
} | ||
}, [user, router]); | ||
return { user, idToken }; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [userChanged]); | ||
return { user, idToken, fetchUser, isPending }; | ||
}; | ||
exports.useUserCookie = useUserCookie; | ||
//# sourceMappingURL=useUserCookie.js.map |
@@ -59,3 +59,4 @@ "use strict"; | ||
const index_js_1 = require("../../reactjs/index.js"); | ||
const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode = "iframe", ...props }) => { | ||
const useIsInIframe_js_1 = require("../../shared/hooks/useIsInIframe.js"); | ||
const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode = "iframe", user, fetchUser, ...props }) => { | ||
const { iframeMode, resolvedConfig } = props; | ||
@@ -66,7 +67,15 @@ const { iframeRef } = (0, useIframe_js_1.useIframe)(); | ||
const pkceConsumer = new PKCE_js_1.ConfidentialClientPKCEConsumer(challengeUrl); | ||
const [isSigningOut, setIsSigningOut] = (0, react_1.useState)(false); | ||
const { data: session } = (0, index_js_1.useSession)(); | ||
const { user } = (0, useUserCookie_js_1.useUserCookie)(); | ||
const postSignOut = (0, react_1.useCallback)(async () => { | ||
setIsSigningOut(true); | ||
// user is signed out, manually update the user from cookies to not wait for polling | ||
await fetchUser(); | ||
await props?.onSignOut?.(); | ||
}, [props]); | ||
}, [fetchUser, props]); | ||
(0, react_1.useEffect)(() => { | ||
if (!session?.authenticated) { | ||
setIsSigningOut(false); | ||
} | ||
}, [session?.authenticated]); | ||
const { signIn, signOut } = (0, useSignIn_js_1.useSignIn)({ | ||
@@ -88,3 +97,3 @@ postSignOut, | ||
react_1.default.createElement(IFrameAndLoading_js_1.IFrameAndLoading, { error: null, isLoading: isLoading, showIframeOnLogout: true }), | ||
isLoading && (react_1.default.createElement(BlockDisplay_js_1.BlockDisplay, null, | ||
(isLoading || isSigningOut) && (react_1.default.createElement(BlockDisplay_js_1.BlockDisplay, null, | ||
react_1.default.createElement(LoadingIcon_js_1.LoadingIcon, null))), | ||
@@ -94,4 +103,10 @@ children))); | ||
const CivicNextAuthProviderInternal = ({ children, ...props }) => { | ||
const isLoading = false; | ||
const { user, idToken } = (0, useUserCookie_js_1.useUserCookie)(); | ||
const isInIframe = (0, useIsInIframe_js_1.useIsInIframe)(); | ||
// if the SDK loads in an iframe, we show the loading spinner as the iframe | ||
// will be waiting to be minimized | ||
const isLoading = isInIframe; | ||
const { user, idToken, fetchUser, isPending } = (0, useUserCookie_js_1.useUserCookie)(); | ||
(0, react_1.useEffect)(() => { | ||
console.log("isPending", isPending); | ||
}, [isPending]); | ||
const session = { | ||
@@ -102,3 +117,3 @@ authenticated: !!user, | ||
return (react_1.default.createElement(SessionProvider_js_1.SessionProvider, { data: session, isLoading: isLoading }, | ||
react_1.default.createElement(CivicNextAuthTokenProviderInternal, { ...props, isLoading: isLoading }, children))); | ||
react_1.default.createElement(CivicNextAuthTokenProviderInternal, { ...props, user: user, idToken: idToken, fetchUser: fetchUser, isLoading: isLoading || isPending }, children))); | ||
}; | ||
@@ -105,0 +120,0 @@ const CivicNextAuthProvider = ({ children, ...props }) => { |
@@ -45,2 +45,3 @@ "use strict"; | ||
const IFrameAndLoading_js_1 = require("../../shared/components/IFrameAndLoading.js"); | ||
const useIsInIframe_js_1 = require("../../shared/hooks/useIsInIframe.js"); | ||
// Global this object setup | ||
@@ -88,3 +89,6 @@ let globalThisObject; | ||
}, [iframeMode, redirectUrl, isAuthenticated, iframeRef, signIn]); | ||
const isLoading = tokenExchangeInProgress || !authConfig; | ||
const isInIframe = (0, useIsInIframe_js_1.useIsInIframe)(); | ||
// if the SDK loads in an iframe, we show the loading spinner as the iframe | ||
// will be waiting to be minimized | ||
const isLoading = tokenExchangeInProgress || !authConfig || isInIframe; | ||
const value = (0, react_1.useMemo)(() => ({ | ||
@@ -91,0 +95,0 @@ isLoading, |
@@ -1,2 +0,2 @@ | ||
export declare const VERSION = "@civic/auth:0.1.5-beta.1"; | ||
export declare const VERSION = "@civic/auth:0.1.5-beta.2"; | ||
//# sourceMappingURL=version.d.ts.map |
@@ -5,3 +5,3 @@ "use strict"; | ||
exports.VERSION = void 0; | ||
exports.VERSION = "@civic/auth:0.1.5-beta.1"; | ||
exports.VERSION = "@civic/auth:0.1.5-beta.2"; | ||
//# sourceMappingURL=version.js.map |
@@ -5,3 +5,5 @@ import type { EmptyObject, User } from "../../types.js"; | ||
idToken: string | undefined; | ||
fetchUser: (abortController?: AbortController) => Promise<void>; | ||
isPending: boolean; | ||
}; | ||
//# sourceMappingURL=useUserCookie.d.ts.map |
@@ -6,2 +6,4 @@ "use client"; | ||
import { OAuthTokens, UserStorage } from "../../shared/lib/types.js"; | ||
import { usePrevious } from "./usePrevious.js"; | ||
import { useTransition } from "react"; | ||
const getUserAndTokenFromCookie = () => getWindowCookieValue([ | ||
@@ -22,39 +24,57 @@ { | ||
const [idToken, setIdToken] = useState(); | ||
const [userChanged, setUserChanged] = useState(false); | ||
const hasRunRef = useRef(false); | ||
const [isPending, startTransition] = useTransition(); | ||
const router = useRouter(); | ||
const prevUser = usePrevious(user); | ||
const prevPending = usePrevious(isPending); | ||
const fetchUser = useCallback(async (abortController) => { | ||
if (abortController.signal.aborted) | ||
if (abortController?.signal.aborted) | ||
return; | ||
if (!hasRunRef.current) { | ||
const response = getUserAndTokenFromCookie() || {}; | ||
const userData = response[UserStorage.USER]; | ||
const tokenData = response[OAuthTokens.ID_TOKEN]; | ||
if (abortController.signal.aborted) | ||
return; | ||
setIdToken(tokenData); | ||
setUser(userData || null); | ||
} | ||
const response = getUserAndTokenFromCookie() || {}; | ||
const userData = response[UserStorage.USER]; | ||
const tokenData = response[OAuthTokens.ID_TOKEN]; | ||
if (abortController?.signal.aborted) | ||
return; | ||
setIdToken(tokenData); | ||
setUser(userData || null); | ||
}, []); | ||
// call fetch immediately after a refresh | ||
useEffect(() => { | ||
const abortController = new AbortController(); | ||
const intervalId = setInterval(() => { | ||
if (prevPending && !isPending) { | ||
fetchUser(); | ||
} | ||
}, [prevPending, isPending, fetchUser]); | ||
useEffect(() => { | ||
if (prevUser !== user) { | ||
setUserChanged(true); | ||
} | ||
}, [user, prevUser]); | ||
useEffect(() => { | ||
let abortController = new AbortController(); | ||
const cookieListener = () => { | ||
abortController = new AbortController(); | ||
fetchUser(abortController); | ||
}, 2000); | ||
const handleFocus = () => { | ||
fetchUser(abortController); | ||
}; | ||
window.addEventListener("focus", handleFocus); | ||
// call fetchUser on load to get initial user if present | ||
document.addEventListener("visibilitychange", cookieListener); | ||
window.addEventListener("storage", cookieListener); | ||
window.addEventListener("focus", cookieListener); | ||
fetchUser(abortController); | ||
const intervalId = setInterval(cookieListener, 2000); | ||
return () => { | ||
abortController.abort(); | ||
document.removeEventListener("visibilitychange", cookieListener); | ||
window.removeEventListener("storage", cookieListener); | ||
window.removeEventListener("focus", cookieListener); | ||
clearInterval(intervalId); | ||
window.removeEventListener("focus", handleFocus); | ||
}; | ||
}, [fetchUser]); | ||
useEffect(() => { | ||
if (user) { | ||
if (userChanged) { | ||
if (!hasRunRef.current) { | ||
hasRunRef.current = true; | ||
router.refresh(); | ||
setUserChanged(false); | ||
startTransition(() => { | ||
router.refresh(); | ||
}); | ||
} | ||
@@ -65,5 +85,6 @@ } | ||
} | ||
}, [user, router]); | ||
return { user, idToken }; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [userChanged]); | ||
return { user, idToken, fetchUser, isPending }; | ||
}; | ||
//# sourceMappingURL=useUserCookie.js.map |
@@ -23,3 +23,4 @@ "use client"; | ||
import { useSession } from "../../reactjs/index.js"; | ||
const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode = "iframe", ...props }) => { | ||
import { useIsInIframe } from "../../shared/hooks/useIsInIframe.js"; | ||
const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode = "iframe", user, fetchUser, ...props }) => { | ||
const { iframeMode, resolvedConfig } = props; | ||
@@ -30,7 +31,15 @@ const { iframeRef } = useIframe(); | ||
const pkceConsumer = new ConfidentialClientPKCEConsumer(challengeUrl); | ||
const [isSigningOut, setIsSigningOut] = useState(false); | ||
const { data: session } = useSession(); | ||
const { user } = useUserCookie(); | ||
const postSignOut = useCallback(async () => { | ||
setIsSigningOut(true); | ||
// user is signed out, manually update the user from cookies to not wait for polling | ||
await fetchUser(); | ||
await props?.onSignOut?.(); | ||
}, [props]); | ||
}, [fetchUser, props]); | ||
useEffect(() => { | ||
if (!session?.authenticated) { | ||
setIsSigningOut(false); | ||
} | ||
}, [session?.authenticated]); | ||
const { signIn, signOut } = useSignIn({ | ||
@@ -52,3 +61,3 @@ postSignOut, | ||
React.createElement(IFrameAndLoading, { error: null, isLoading: isLoading, showIframeOnLogout: true }), | ||
isLoading && (React.createElement(BlockDisplay, null, | ||
(isLoading || isSigningOut) && (React.createElement(BlockDisplay, null, | ||
React.createElement(LoadingIcon, null))), | ||
@@ -58,4 +67,10 @@ children))); | ||
const CivicNextAuthProviderInternal = ({ children, ...props }) => { | ||
const isLoading = false; | ||
const { user, idToken } = useUserCookie(); | ||
const isInIframe = useIsInIframe(); | ||
// if the SDK loads in an iframe, we show the loading spinner as the iframe | ||
// will be waiting to be minimized | ||
const isLoading = isInIframe; | ||
const { user, idToken, fetchUser, isPending } = useUserCookie(); | ||
useEffect(() => { | ||
console.log("isPending", isPending); | ||
}, [isPending]); | ||
const session = { | ||
@@ -66,3 +81,3 @@ authenticated: !!user, | ||
return (React.createElement(SessionProvider, { data: session, isLoading: isLoading }, | ||
React.createElement(CivicNextAuthTokenProviderInternal, { ...props, isLoading: isLoading }, children))); | ||
React.createElement(CivicNextAuthTokenProviderInternal, { ...props, user: user, idToken: idToken, fetchUser: fetchUser, isLoading: isLoading || isPending }, children))); | ||
}; | ||
@@ -69,0 +84,0 @@ const CivicNextAuthProvider = ({ children, ...props }) => { |
@@ -9,2 +9,3 @@ "use client"; | ||
import { IFrameAndLoading } from "../../shared/components/IFrameAndLoading.js"; | ||
import { useIsInIframe } from "../../shared/hooks/useIsInIframe.js"; | ||
// Global this object setup | ||
@@ -52,3 +53,6 @@ let globalThisObject; | ||
}, [iframeMode, redirectUrl, isAuthenticated, iframeRef, signIn]); | ||
const isLoading = tokenExchangeInProgress || !authConfig; | ||
const isInIframe = useIsInIframe(); | ||
// if the SDK loads in an iframe, we show the loading spinner as the iframe | ||
// will be waiting to be minimized | ||
const isLoading = tokenExchangeInProgress || !authConfig || isInIframe; | ||
const value = useMemo(() => ({ | ||
@@ -55,0 +59,0 @@ isLoading, |
@@ -1,2 +0,2 @@ | ||
export declare const VERSION = "@civic/auth:0.1.5-beta.1"; | ||
export declare const VERSION = "@civic/auth:0.1.5-beta.2"; | ||
//# sourceMappingURL=version.d.ts.map |
// This is an auto-generated file. Do not edit. | ||
export const VERSION = "@civic/auth:0.1.5-beta.1"; | ||
export const VERSION = "@civic/auth:0.1.5-beta.2"; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "@civic/auth", | ||
"version": "0.1.5-beta.1", | ||
"version": "0.1.5-beta.2", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "main": "./dist/cjs/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
1351438
677
10152
11