251127:1700 Frontend Start Build
This commit is contained in:
357
frontend/.ignored_node_modules/next-auth/react.js
generated
vendored
Normal file
357
frontend/.ignored_node_modules/next-auth/react.js
generated
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
/**
|
||||
*
|
||||
* NextAuth.js is the official integration of Auth.js for Next.js applications. It supports both
|
||||
* [Client Components](https://nextjs.org/docs/app/building-your-application/rendering/client-components) and the
|
||||
* [Pages Router](https://nextjs.org/docs/pages). It includes methods for signing in, signing out, hooks, and a React
|
||||
* Context provider to wrap your application and make session data available anywhere.
|
||||
*
|
||||
* For use in [Server Actions](https://nextjs.org/docs/app/api-reference/functions/server-actions), check out [these methods](https://authjs.dev/guides/upgrade-to-v5#methods)
|
||||
*
|
||||
* @module react
|
||||
*/
|
||||
"use client";
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import * as React from "react";
|
||||
import { apiBaseUrl, ClientSessionError, fetchData, now, parseUrl, useOnline, } from "./lib/client.js";
|
||||
// This behaviour mirrors the default behaviour for getting the site name that
|
||||
// happens server side in server/index.js
|
||||
// 1. An empty value is legitimate when the code is being invoked client side as
|
||||
// relative URLs are valid in that context and so defaults to empty.
|
||||
// 2. When invoked server side the value is picked up from an environment
|
||||
// variable and defaults to 'http://localhost:3000'.
|
||||
export const __NEXTAUTH = {
|
||||
baseUrl: parseUrl(process.env.NEXTAUTH_URL ?? process.env.VERCEL_URL).origin,
|
||||
basePath: parseUrl(process.env.NEXTAUTH_URL).path,
|
||||
baseUrlServer: parseUrl(process.env.NEXTAUTH_URL_INTERNAL ??
|
||||
process.env.NEXTAUTH_URL ??
|
||||
process.env.VERCEL_URL).origin,
|
||||
basePathServer: parseUrl(process.env.NEXTAUTH_URL_INTERNAL ?? process.env.NEXTAUTH_URL).path,
|
||||
_lastSync: 0,
|
||||
_session: undefined,
|
||||
_getSession: () => { },
|
||||
};
|
||||
// https://github.com/nextauthjs/next-auth/pull/10762
|
||||
let broadcastChannel = null;
|
||||
function getNewBroadcastChannel() {
|
||||
if (typeof BroadcastChannel === "undefined") {
|
||||
return {
|
||||
postMessage: () => { },
|
||||
addEventListener: () => { },
|
||||
removeEventListener: () => { },
|
||||
name: "next-auth",
|
||||
onmessage: null,
|
||||
onmessageerror: null,
|
||||
close: () => { },
|
||||
dispatchEvent: () => false,
|
||||
};
|
||||
}
|
||||
return new BroadcastChannel("next-auth");
|
||||
}
|
||||
function broadcast() {
|
||||
if (broadcastChannel === null) {
|
||||
broadcastChannel = getNewBroadcastChannel();
|
||||
}
|
||||
return broadcastChannel;
|
||||
}
|
||||
// TODO:
|
||||
const logger = {
|
||||
debug: console.debug,
|
||||
error: console.error,
|
||||
warn: console.warn,
|
||||
};
|
||||
export const SessionContext = React.createContext?.(undefined);
|
||||
/**
|
||||
* React Hook that gives you access to the logged in user's session data and lets you modify it.
|
||||
*
|
||||
* :::info
|
||||
* `useSession` is for client-side use only and when using [Next.js App Router (`app/`)](https://nextjs.org/blog/next-13-4#nextjs-app-router) you should prefer the `auth()` export.
|
||||
* :::
|
||||
*/
|
||||
export function useSession(options) {
|
||||
if (!SessionContext) {
|
||||
throw new Error("React Context is unavailable in Server Components");
|
||||
}
|
||||
// @ts-expect-error Satisfy TS if branch on line below
|
||||
const value = React.useContext(SessionContext);
|
||||
if (!value && process.env.NODE_ENV !== "production") {
|
||||
throw new Error("[next-auth]: `useSession` must be wrapped in a <SessionProvider />");
|
||||
}
|
||||
const { required, onUnauthenticated } = options ?? {};
|
||||
const requiredAndNotLoading = required && value.status === "unauthenticated";
|
||||
React.useEffect(() => {
|
||||
if (requiredAndNotLoading) {
|
||||
const url = `${__NEXTAUTH.basePath}/signin?${new URLSearchParams({
|
||||
error: "SessionRequired",
|
||||
callbackUrl: window.location.href,
|
||||
})}`;
|
||||
if (onUnauthenticated)
|
||||
onUnauthenticated();
|
||||
else
|
||||
window.location.href = url;
|
||||
}
|
||||
}, [requiredAndNotLoading, onUnauthenticated]);
|
||||
if (requiredAndNotLoading) {
|
||||
return {
|
||||
data: value.data,
|
||||
update: value.update,
|
||||
status: "loading",
|
||||
};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
export async function getSession(params) {
|
||||
const session = await fetchData("session", __NEXTAUTH, logger, params);
|
||||
if (params?.broadcast ?? true) {
|
||||
// https://github.com/nextauthjs/next-auth/pull/11470
|
||||
getNewBroadcastChannel().postMessage({
|
||||
event: "session",
|
||||
data: { trigger: "getSession" },
|
||||
});
|
||||
}
|
||||
return session;
|
||||
}
|
||||
/**
|
||||
* Returns the current Cross-Site Request Forgery Token (CSRF Token)
|
||||
* required to make requests that changes state. (e.g. signing in or out, or updating the session).
|
||||
*
|
||||
* [CSRF Prevention: Double Submit Cookie](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie)
|
||||
*/
|
||||
export async function getCsrfToken() {
|
||||
const response = await fetchData("csrf", __NEXTAUTH, logger);
|
||||
return response?.csrfToken ?? "";
|
||||
}
|
||||
export async function getProviders() {
|
||||
return fetchData("providers", __NEXTAUTH, logger);
|
||||
}
|
||||
export async function signIn(provider, options, authorizationParams) {
|
||||
const { callbackUrl, ...rest } = options ?? {};
|
||||
const { redirect = true, redirectTo = callbackUrl ?? window.location.href, ...signInParams } = rest;
|
||||
const baseUrl = apiBaseUrl(__NEXTAUTH);
|
||||
const providers = await getProviders();
|
||||
if (!providers) {
|
||||
const url = `${baseUrl}/error`;
|
||||
window.location.href = url;
|
||||
return; // TODO: Return error if `redirect: false`
|
||||
}
|
||||
if (!provider || !providers[provider]) {
|
||||
const url = `${baseUrl}/signin?${new URLSearchParams({
|
||||
callbackUrl: redirectTo,
|
||||
})}`;
|
||||
window.location.href = url;
|
||||
return; // TODO: Return error if `redirect: false`
|
||||
}
|
||||
const providerType = providers[provider].type;
|
||||
if (providerType === "webauthn") {
|
||||
// TODO: Add docs link with explanation
|
||||
throw new TypeError([
|
||||
`Provider id "${provider}" refers to a WebAuthn provider.`,
|
||||
'Please use `import { signIn } from "next-auth/webauthn"` instead.',
|
||||
].join("\n"));
|
||||
}
|
||||
const signInUrl = `${baseUrl}/${providerType === "credentials" ? "callback" : "signin"}/${provider}`;
|
||||
const csrfToken = await getCsrfToken();
|
||||
const res = await fetch(`${signInUrl}?${new URLSearchParams(authorizationParams)}`, {
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"X-Auth-Return-Redirect": "1",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
...signInParams,
|
||||
csrfToken,
|
||||
callbackUrl: redirectTo,
|
||||
}),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (redirect) {
|
||||
const url = data.url ?? redirectTo;
|
||||
window.location.href = url;
|
||||
// If url contains a hash, the browser does not reload the page. We reload manually
|
||||
if (url.includes("#"))
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
const error = new URL(data.url).searchParams.get("error") ?? undefined;
|
||||
const code = new URL(data.url).searchParams.get("code") ?? undefined;
|
||||
if (res.ok) {
|
||||
await __NEXTAUTH._getSession({ event: "storage" });
|
||||
}
|
||||
return {
|
||||
error,
|
||||
code,
|
||||
status: res.status,
|
||||
ok: res.ok,
|
||||
url: error ? null : data.url,
|
||||
};
|
||||
}
|
||||
export async function signOut(options) {
|
||||
const { redirect = true, redirectTo = options?.callbackUrl ?? window.location.href, } = options ?? {};
|
||||
const baseUrl = apiBaseUrl(__NEXTAUTH);
|
||||
const csrfToken = await getCsrfToken();
|
||||
const res = await fetch(`${baseUrl}/signout`, {
|
||||
method: "post",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"X-Auth-Return-Redirect": "1",
|
||||
},
|
||||
body: new URLSearchParams({ csrfToken, callbackUrl: redirectTo }),
|
||||
});
|
||||
const data = await res.json();
|
||||
broadcast().postMessage({ event: "session", data: { trigger: "signout" } });
|
||||
if (redirect) {
|
||||
const url = data.url ?? redirectTo;
|
||||
window.location.href = url;
|
||||
// If url contains a hash, the browser does not reload the page. We reload manually
|
||||
if (url.includes("#"))
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
await __NEXTAUTH._getSession({ event: "storage" });
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
* [React Context](https://react.dev/learn/passing-data-deeply-with-context) provider to wrap the app (`pages/`) to make session data available anywhere.
|
||||
*
|
||||
* When used, the session state is automatically synchronized across all open tabs/windows and they are all updated whenever they gain or lose focus
|
||||
* or the state changes (e.g. a user signs in or out) when {@link SessionProviderProps.refetchOnWindowFocus} is `true`.
|
||||
*
|
||||
* :::info
|
||||
* `SessionProvider` is for client-side use only and when using [Next.js App Router (`app/`)](https://nextjs.org/blog/next-13-4#nextjs-app-router) you should prefer the `auth()` export.
|
||||
* :::
|
||||
*/
|
||||
export function SessionProvider(props) {
|
||||
if (!SessionContext) {
|
||||
throw new Error("React Context is unavailable in Server Components");
|
||||
}
|
||||
const { children, basePath, refetchInterval, refetchWhenOffline } = props;
|
||||
if (basePath)
|
||||
__NEXTAUTH.basePath = basePath;
|
||||
/**
|
||||
* If session was `null`, there was an attempt to fetch it,
|
||||
* but it failed, but we still treat it as a valid initial value.
|
||||
*/
|
||||
const hasInitialSession = props.session !== undefined;
|
||||
/** If session was passed, initialize as already synced */
|
||||
__NEXTAUTH._lastSync = hasInitialSession ? now() : 0;
|
||||
const [session, setSession] = React.useState(() => {
|
||||
if (hasInitialSession)
|
||||
__NEXTAUTH._session = props.session;
|
||||
return props.session;
|
||||
});
|
||||
/** If session was passed, initialize as not loading */
|
||||
const [loading, setLoading] = React.useState(!hasInitialSession);
|
||||
React.useEffect(() => {
|
||||
__NEXTAUTH._getSession = async ({ event } = {}) => {
|
||||
try {
|
||||
const storageEvent = event === "storage";
|
||||
// We should always update if we don't have a client session yet
|
||||
// or if there are events from other tabs/windows
|
||||
if (storageEvent || __NEXTAUTH._session === undefined) {
|
||||
__NEXTAUTH._lastSync = now();
|
||||
__NEXTAUTH._session = await getSession({
|
||||
broadcast: !storageEvent,
|
||||
});
|
||||
setSession(__NEXTAUTH._session);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
// If there is no time defined for when a session should be considered
|
||||
// stale, then it's okay to use the value we have until an event is
|
||||
// triggered which updates it
|
||||
!event ||
|
||||
// If the client doesn't have a session then we don't need to call
|
||||
// the server to check if it does (if they have signed in via another
|
||||
// tab or window that will come through as a "stroage" event
|
||||
// event anyway)
|
||||
__NEXTAUTH._session === null ||
|
||||
// Bail out early if the client session is not stale yet
|
||||
now() < __NEXTAUTH._lastSync) {
|
||||
return;
|
||||
}
|
||||
// An event or session staleness occurred, update the client session.
|
||||
__NEXTAUTH._lastSync = now();
|
||||
__NEXTAUTH._session = await getSession();
|
||||
setSession(__NEXTAUTH._session);
|
||||
}
|
||||
catch (error) {
|
||||
logger.error(new ClientSessionError(error.message, error));
|
||||
}
|
||||
finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
__NEXTAUTH._getSession();
|
||||
return () => {
|
||||
__NEXTAUTH._lastSync = 0;
|
||||
__NEXTAUTH._session = undefined;
|
||||
__NEXTAUTH._getSession = () => { };
|
||||
};
|
||||
}, []);
|
||||
React.useEffect(() => {
|
||||
const handle = () => __NEXTAUTH._getSession({ event: "storage" });
|
||||
// Listen for storage events and update session if event fired from
|
||||
// another window (but suppress firing another event to avoid a loop)
|
||||
// Fetch new session data but tell it to not to fire another event to
|
||||
// avoid an infinite loop.
|
||||
// Note: We could pass session data through and do something like
|
||||
// `setData(message.data)` but that can cause problems depending
|
||||
// on how the session object is being used in the client; it is
|
||||
// more robust to have each window/tab fetch it's own copy of the
|
||||
// session object rather than share it across instances.
|
||||
broadcast().addEventListener("message", handle);
|
||||
return () => broadcast().removeEventListener("message", handle);
|
||||
}, []);
|
||||
React.useEffect(() => {
|
||||
const { refetchOnWindowFocus = true } = props;
|
||||
// Listen for when the page is visible, if the user switches tabs
|
||||
// and makes our tab visible again, re-fetch the session, but only if
|
||||
// this feature is not disabled.
|
||||
const visibilityHandler = () => {
|
||||
if (refetchOnWindowFocus && document.visibilityState === "visible")
|
||||
__NEXTAUTH._getSession({ event: "visibilitychange" });
|
||||
};
|
||||
document.addEventListener("visibilitychange", visibilityHandler, false);
|
||||
return () => document.removeEventListener("visibilitychange", visibilityHandler, false);
|
||||
}, [props.refetchOnWindowFocus]);
|
||||
const isOnline = useOnline();
|
||||
// TODO: Flip this behavior in next major version
|
||||
const shouldRefetch = refetchWhenOffline !== false || isOnline;
|
||||
React.useEffect(() => {
|
||||
if (refetchInterval && shouldRefetch) {
|
||||
const refetchIntervalTimer = setInterval(() => {
|
||||
if (__NEXTAUTH._session) {
|
||||
__NEXTAUTH._getSession({ event: "poll" });
|
||||
}
|
||||
}, refetchInterval * 1000);
|
||||
return () => clearInterval(refetchIntervalTimer);
|
||||
}
|
||||
}, [refetchInterval, shouldRefetch]);
|
||||
const value = React.useMemo(() => ({
|
||||
data: session,
|
||||
status: loading
|
||||
? "loading"
|
||||
: session
|
||||
? "authenticated"
|
||||
: "unauthenticated",
|
||||
async update(data) {
|
||||
if (loading)
|
||||
return;
|
||||
setLoading(true);
|
||||
const newSession = await fetchData("session", __NEXTAUTH, logger, typeof data === "undefined"
|
||||
? undefined
|
||||
: { body: { csrfToken: await getCsrfToken(), data } });
|
||||
setLoading(false);
|
||||
if (newSession) {
|
||||
setSession(newSession);
|
||||
broadcast().postMessage({
|
||||
event: "session",
|
||||
data: { trigger: "getSession" },
|
||||
});
|
||||
}
|
||||
return newSession;
|
||||
},
|
||||
}), [session, loading]);
|
||||
return (
|
||||
// @ts-expect-error
|
||||
_jsx(SessionContext.Provider, { value: value, children: children }));
|
||||
}
|
||||
Reference in New Issue
Block a user