251127:1700 Frontend Start Build

This commit is contained in:
admin
2025-11-27 17:08:49 +07:00
parent 6abb746e08
commit 4f3aa87a93
1795 changed files with 893474 additions and 10 deletions

View File

@@ -0,0 +1,13 @@
import type { NextAuthConfig } from "./index.js";
import type { NextAuthResult, Session } from "../index.js";
type SignInParams = Parameters<NextAuthResult["signIn"]>;
export declare function signIn(provider: SignInParams[0], options: FormData | ({
redirectTo?: string | undefined;
redirect?: boolean | undefined;
} & Record<string, any>) | undefined, authorizationParams: SignInParams[2], config: NextAuthConfig): Promise<any>;
type SignOutParams = Parameters<NextAuthResult["signOut"]>;
export declare function signOut(options: SignOutParams[0], config: NextAuthConfig): Promise<any>;
type UpdateParams = Parameters<NextAuthResult["unstable_update"]>;
export declare function update(data: UpdateParams[0], config: NextAuthConfig): Promise<Session | null>;
export {};
//# sourceMappingURL=actions.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/lib/actions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAG1D,KAAK,YAAY,GAAG,UAAU,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAA;AACxD,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EACzB,OAAO;;;oCAAsB,EAC7B,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC,EACpC,MAAM,EAAE,cAAc,gBAuEvB;AAED,KAAK,aAAa,GAAG,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAA;AAC1D,wBAAsB,OAAO,CAC3B,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EACzB,MAAM,EAAE,cAAc,gBAyBvB;AAED,KAAK,YAAY,GAAG,UAAU,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAA;AACjE,wBAAsB,MAAM,CAC1B,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EACrB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAqBzB"}

View File

@@ -0,0 +1,86 @@
import { Auth, raw, skipCSRFCheck, createActionURL } from "@auth/core";
// @ts-expect-error Next.js does not yet correctly use the `package.json#exports` field
import { headers as nextHeaders, cookies } from "next/headers";
// @ts-expect-error Next.js does not yet correctly use the `package.json#exports` field
import { redirect } from "next/navigation";
export async function signIn(provider, options = {}, authorizationParams, config) {
const headers = new Headers(await nextHeaders());
const { redirect: shouldRedirect = true, redirectTo, ...rest } = options instanceof FormData ? Object.fromEntries(options) : options;
const callbackUrl = redirectTo?.toString() ?? headers.get("Referer") ?? "/";
const signInURL = createActionURL("signin",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"), headers, process.env, config);
if (!provider) {
signInURL.searchParams.append("callbackUrl", callbackUrl);
if (shouldRedirect)
redirect(signInURL.toString());
return signInURL.toString();
}
let url = `${signInURL}/${provider}?${new URLSearchParams(authorizationParams)}`;
let foundProvider = {};
for (const providerConfig of config.providers) {
const { options, ...defaults } = typeof providerConfig === "function" ? providerConfig() : providerConfig;
const id = options?.id ?? defaults.id;
if (id === provider) {
foundProvider = {
id,
type: options?.type ?? defaults.type,
};
break;
}
}
if (!foundProvider.id) {
const url = `${signInURL}?${new URLSearchParams({ callbackUrl })}`;
if (shouldRedirect)
redirect(url);
return url;
}
if (foundProvider.type === "credentials") {
url = url.replace("signin", "callback");
}
headers.set("Content-Type", "application/x-www-form-urlencoded");
const body = new URLSearchParams({ ...rest, callbackUrl });
const req = new Request(url, { method: "POST", headers, body });
const res = await Auth(req, { ...config, raw, skipCSRFCheck });
const cookieJar = await cookies();
for (const c of res?.cookies ?? [])
cookieJar.set(c.name, c.value, c.options);
const responseUrl = res instanceof Response ? res.headers.get("Location") : res.redirect;
// NOTE: if for some unexpected reason the responseUrl is not set,
// we redirect to the original url
const redirectUrl = responseUrl ?? url;
if (shouldRedirect)
return redirect(redirectUrl);
return redirectUrl;
}
export async function signOut(options, config) {
const headers = new Headers(await nextHeaders());
headers.set("Content-Type", "application/x-www-form-urlencoded");
const url = createActionURL("signout",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"), headers, process.env, config);
const callbackUrl = options?.redirectTo ?? headers.get("Referer") ?? "/";
const body = new URLSearchParams({ callbackUrl });
const req = new Request(url, { method: "POST", headers, body });
const res = await Auth(req, { ...config, raw, skipCSRFCheck });
const cookieJar = await cookies();
for (const c of res?.cookies ?? [])
cookieJar.set(c.name, c.value, c.options);
if (options?.redirect ?? true)
return redirect(res.redirect);
return res;
}
export async function update(data, config) {
const headers = new Headers(await nextHeaders());
headers.set("Content-Type", "application/json");
const url = createActionURL("session",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"), headers, process.env, config);
const body = JSON.stringify({ data });
const req = new Request(url, { method: "POST", headers, body });
const res = await Auth(req, { ...config, raw, skipCSRFCheck });
const cookieJar = await cookies();
for (const c of res?.cookies ?? [])
cookieJar.set(c.name, c.value, c.options);
return res.body;
}

View File

@@ -0,0 +1,104 @@
import * as React from "react";
import type { ProviderId, ProviderType } from "@auth/core/providers";
import type { Session } from "@auth/core/types";
import { AuthError } from "@auth/core/errors";
/** @todo */
export declare class ClientSessionError extends AuthError {
}
export interface AuthClientConfig {
baseUrl: string;
basePath: string;
baseUrlServer: string;
basePathServer: string;
/** Stores last session response */
_session?: Session | null | undefined;
/** Used for timestamp since last sycned (in seconds) */
_lastSync: number;
/**
* Stores the `SessionProvider`'s session update method to be able to
* trigger session updates from places like `signIn` or `signOut`
*/
_getSession: (...args: any[]) => any;
}
export interface UseSessionOptions<R extends boolean> {
required: R;
/** Defaults to `signIn` */
onUnauthenticated?: () => void;
}
export interface ClientSafeProvider {
id: ProviderId;
name: string;
type: ProviderType;
signinUrl: string;
callbackUrl: string;
redirectTo: string;
}
export interface SignInOptions<Redirect extends boolean = true> extends Record<string, unknown> {
/** @deprecated Use `redirectTo` instead. */
callbackUrl?: string;
/**
* Specify where the user should be redirected to after a successful signin.
*
* By default, it is the page the sign-in was initiated from.
*/
redirectTo?: string;
/**
* You might want to deal with the signin response on the same page, instead of redirecting to another page.
* For example, if an error occurs (like wrong credentials given by the user), you might want to show an inline error message on the input field.
*
* For this purpose, you can set this to option `redirect: false`.
*/
redirect?: Redirect;
}
export interface SignInResponse {
error: string | undefined;
code: string | undefined;
status: number;
ok: boolean;
url: string | null;
}
/** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1) */
export interface SignOutResponse {
url: string;
}
export interface SignOutParams<Redirect extends boolean = true> {
/** @deprecated Use `redirectTo` instead. */
callbackUrl?: string;
/**
* If you pass `redirect: false`, the page will not reload.
* The session will be deleted, and `useSession` is notified, so any indication about the user will be shown as logged out automatically.
* It can give a very nice experience for the user.
*/
redirectTo?: string;
/** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */
redirect?: Redirect;
}
/**
* If you have session expiry times of 30 days (the default) or more, then you probably don't need to change any of the default options.
*
* However, if you need to customize the session behavior and/or are using short session expiry times, you can pass options to the provider to customize the behavior of the {@link useSession} hook.
*/
export interface SessionProviderProps {
children: React.ReactNode;
session?: Session | null;
baseUrl?: string;
basePath?: string;
/**
* A time interval (in seconds) after which the session will be re-fetched.
* If set to `0` (default), the session is not polled.
*/
refetchInterval?: number;
/**
* `SessionProvider` automatically refetches the session when the user switches between windows.
* This option activates this behaviour if set to `true` (default).
*/
refetchOnWindowFocus?: boolean;
/**
* Set to `false` to stop polling when the device has no internet access offline (determined by `navigator.onLine`)
*
* [`navigator.onLine` documentation](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine)
*/
refetchWhenOffline?: false;
}
//# sourceMappingURL=client.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/lib/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,KAAK,EAAkB,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAK7C,YAAY;AACZ,qBAAa,kBAAmB,SAAQ,SAAS;CAAG;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAA;IACrC,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,WAAW,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;CACrC;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,OAAO;IAClD,QAAQ,EAAE,CAAC,CAAA;IACX,2BAA2B;IAC3B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,UAAU,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,YAAY,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,OAAO,GAAG,IAAI,CAC5D,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/B,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,OAAO,CAAA;IACX,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACnB;AAYD,yGAAyG;AACzG,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,OAAO,GAAG,IAAI;IAC5D,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wGAAwG;IACxG,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,KAAK,CAAA;CAC3B"}

View File

@@ -0,0 +1,95 @@
"use client";
import * as React from "react";
import { AuthError } from "@auth/core/errors";
/** @todo */
class ClientFetchError extends AuthError {
}
/** @todo */
export class ClientSessionError extends AuthError {
}
// ------------------------ Internal ------------------------
/**
* If passed 'appContext' via getInitialProps() in _app.js
* then get the req object from ctx and use that for the
* req value to allow `fetchData` to
* work seemlessly in getInitialProps() on server side
* pages *and* in _app.js.
* @internal
*/
export async function fetchData(path, __NEXTAUTH, logger, req = {}) {
const url = `${apiBaseUrl(__NEXTAUTH)}/${path}`;
try {
const options = {
headers: {
"Content-Type": "application/json",
...(req?.headers?.cookie ? { cookie: req.headers.cookie } : {}),
},
};
if (req?.body) {
options.body = JSON.stringify(req.body);
options.method = "POST";
}
const res = await fetch(url, options);
const data = await res.json();
if (!res.ok)
throw data;
return data;
}
catch (error) {
logger.error(new ClientFetchError(error.message, error));
return null;
}
}
/** @internal */
export function apiBaseUrl(__NEXTAUTH) {
if (typeof window === "undefined") {
// Return absolute path when called server side
return `${__NEXTAUTH.baseUrlServer}${__NEXTAUTH.basePathServer}`;
}
// Return relative path when called client side
return __NEXTAUTH.basePath;
}
/** @internal */
export function useOnline() {
const [isOnline, setIsOnline] = React.useState(typeof navigator !== "undefined" ? navigator.onLine : false);
const setOnline = () => setIsOnline(true);
const setOffline = () => setIsOnline(false);
React.useEffect(() => {
window.addEventListener("online", setOnline);
window.addEventListener("offline", setOffline);
return () => {
window.removeEventListener("online", setOnline);
window.removeEventListener("offline", setOffline);
};
}, []);
return isOnline;
}
/**
* Returns the number of seconds elapsed since January 1, 1970 00:00:00 UTC.
* @internal
*/
export function now() {
return Math.floor(Date.now() / 1000);
}
/**
* Returns an `URL` like object to make requests/redirects from server-side
* @internal
*/
export function parseUrl(url) {
const defaultUrl = new URL("http://localhost:3000/api/auth");
if (url && !url.startsWith("http")) {
url = `https://${url}`;
}
const _url = new URL(url || defaultUrl);
const path = (_url.pathname === "/" ? defaultUrl.pathname : _url.pathname)
// Remove trailing slash
.replace(/\/$/, "");
const base = `${_url.origin}${path}`;
return {
origin: _url.origin,
host: _url.host,
path,
base,
toString: () => base,
};
}

13
frontend/.ignored_node_modules/next-auth/lib/env.d.ts generated vendored Normal file
View File

@@ -0,0 +1,13 @@
import { NextRequest } from "next/server";
import type { NextAuthConfig } from "./index.js";
/** If `NEXTAUTH_URL` or `AUTH_URL` is defined, override the request's URL. */
export declare function reqWithEnvURL(req: NextRequest): NextRequest;
/**
* For backwards compatibility, `next-auth` checks for `NEXTAUTH_URL`
* and the `basePath` by default is `/api/auth` instead of `/auth`
* (which is the default for all other Auth.js integrations).
*
* For the same reason, `NEXTAUTH_SECRET` is also checked.
*/
export declare function setEnvDefaults(config: NextAuthConfig): void;
//# sourceMappingURL=env.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/lib/env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGhD,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,WAAW,CAM3D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,QAepD"}

View File

@@ -0,0 +1,39 @@
// @ts-expect-error Next.js does not yet correctly use the `package.json#exports` field
import { NextRequest } from "next/server";
import { setEnvDefaults as coreSetEnvDefaults } from "@auth/core";
/** If `NEXTAUTH_URL` or `AUTH_URL` is defined, override the request's URL. */
export function reqWithEnvURL(req) {
const url = process.env.AUTH_URL ?? process.env.NEXTAUTH_URL;
if (!url)
return req;
const { origin: envOrigin } = new URL(url);
const { href, origin } = req.nextUrl;
return new NextRequest(href.replace(origin, envOrigin), req);
}
/**
* For backwards compatibility, `next-auth` checks for `NEXTAUTH_URL`
* and the `basePath` by default is `/api/auth` instead of `/auth`
* (which is the default for all other Auth.js integrations).
*
* For the same reason, `NEXTAUTH_SECRET` is also checked.
*/
export function setEnvDefaults(config) {
try {
config.secret ?? (config.secret = process.env.AUTH_SECRET ?? process.env.NEXTAUTH_SECRET);
const url = process.env.AUTH_URL ?? process.env.NEXTAUTH_URL;
if (!url)
return;
const { pathname } = new URL(url);
if (pathname === "/")
return;
config.basePath || (config.basePath = pathname);
}
catch {
// Catching and swallowing potential URL parsing errors, we'll fall
// back to `/api/auth` below.
}
finally {
config.basePath || (config.basePath = "/api/auth");
coreSetEnvDefaults(process.env, config, true);
}
}

View File

@@ -0,0 +1,56 @@
import { type AuthConfig } from "@auth/core";
import { NextResponse } from "next/server";
import type { Awaitable, Session } from "@auth/core/types";
import type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next";
import type { AppRouteHandlerFn } from "./types.js";
import type { NextFetchEvent, NextMiddleware, NextRequest } from "next/server";
/** Configure NextAuth.js. */
export interface NextAuthConfig extends Omit<AuthConfig, "raw"> {
/**
* Callbacks are asynchronous functions you can use to control what happens when an auth-related action is performed.
* Callbacks **allow you to implement access controls without a database** or to **integrate with external databases or APIs**.
*/
callbacks?: AuthConfig["callbacks"] & {
/**
* Invoked when a user needs authorization, using [Middleware](https://nextjs.org/docs/advanced-features/middleware).
*
* You can override this behavior by returning a {@link NextResponse}.
*
* @example
* ```ts title="app/auth.ts"
* async authorized({ request, auth }) {
* const url = request.nextUrl
*
* if(request.method === "POST") {
* const { authToken } = (await request.json()) ?? {}
* // If the request has a valid auth token, it is authorized
* const valid = await validateAuthToken(authToken)
* if(valid) return true
* return NextResponse.json("Invalid auth token", { status: 401 })
* }
*
* // Logged in users are authenticated, otherwise redirect to login page
* return !!auth.user
* }
* ```
*
* :::warning
* If you are returning a redirect response, make sure that the page you are redirecting to is not protected by this callback,
* otherwise you could end up in an infinite redirect loop.
* :::
*/
authorized?: (params: {
/** The request to be authorized. */
request: NextRequest;
/** The authenticated user or token, if any. */
auth: Session | null;
}) => Awaitable<boolean | NextResponse | Response | undefined>;
};
}
export interface NextAuthRequest extends NextRequest {
auth: Session | null;
}
export type NextAuthMiddleware = (request: NextAuthRequest, event: NextFetchEvent) => ReturnType<NextMiddleware>;
export type WithAuthArgs = [NextAuthRequest, any] | [NextAuthMiddleware] | [AppRouteHandlerFn] | [NextApiRequest, NextApiResponse] | [GetServerSidePropsContext] | [];
export declare function initAuth(config: NextAuthConfig | ((request: NextRequest | undefined) => Awaitable<NextAuthConfig>), onLazyLoad?: (config: NextAuthConfig) => void): (...args: WithAuthArgs) => Promise<any> | ((...args: Parameters<NextAuthMiddleware | AppRouteHandlerFn>) => Promise<Response>);
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAInE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1C,OAAO,KAAK,EAAc,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACtE,OAAO,KAAK,EACV,yBAAyB,EACzB,cAAc,EACd,eAAe,EAChB,MAAM,MAAM,CAAA;AACb,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9E,6BAA6B;AAC7B,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC;IAC7D;;;OAGG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG;QACpC;;;;;;;;;;;;;;;;;;;;;;;;;;;WA2BG;QACH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE;YACpB,oCAAoC;YACpC,OAAO,EAAE,WAAW,CAAA;YACpB,+CAA+C;YAC/C,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;SACrB,KAAK,SAAS,CAAC,OAAO,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAA;KAC/D,CAAA;CACF;AAuCD,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,cAAc,KAClB,UAAU,CAAC,cAAc,CAAC,CAAA;AAE/B,MAAM,MAAM,YAAY,GACpB,CAAC,eAAe,EAAE,GAAG,CAAC,GACtB,CAAC,kBAAkB,CAAC,GACpB,CAAC,iBAAiB,CAAC,GACnB,CAAC,cAAc,EAAE,eAAe,CAAC,GACjC,CAAC,yBAAyB,CAAC,GAC3B,EAAE,CAAA;AAMN,wBAAgB,QAAQ,CACtB,MAAM,EACF,cAAc,GACd,CAAC,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,KAAK,SAAS,CAAC,cAAc,CAAC,CAAC,EACrE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,aA2D5B,YAAY,+BAqBd,WAAW,kBAAkB,GAAG,iBAAiB,CAAC,wBA0BlE"}

View File

@@ -0,0 +1,187 @@
import { Auth, createActionURL } from "@auth/core";
// @ts-expect-error Next.js does not yet correctly use the `package.json#exports` field
import { headers } from "next/headers";
// @ts-expect-error Next.js does not yet correctly use the `package.json#exports` field
import { NextResponse } from "next/server";
import { reqWithEnvURL } from "./env.js";
async function getSession(headers, config) {
const url = createActionURL("session",
// @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
headers.get("x-forwarded-proto"), headers, process.env, config);
const request = new Request(url, {
headers: { cookie: headers.get("cookie") ?? "" },
});
return Auth(request, {
...config,
callbacks: {
...config.callbacks,
// Since we are server-side, we don't need to filter out the session data
// See https://authjs.dev/getting-started/migrating-to-v5#authenticating-server-side
// TODO: Taint the session data to prevent accidental leakage to the client
// https://react.dev/reference/react/experimental_taintObjectReference
async session(...args) {
const session =
// If the user defined a custom session callback, use that instead
(await config.callbacks?.session?.(...args)) ?? {
...args[0].session,
expires: args[0].session.expires?.toISOString?.() ??
args[0].session.expires,
};
const user = args[0].user ?? args[0].token;
return { user, ...session };
},
},
});
}
function isReqWrapper(arg) {
return typeof arg === "function";
}
export function initAuth(config, onLazyLoad // To set the default env vars
) {
if (typeof config === "function") {
return async (...args) => {
if (!args.length) {
// React Server Components
const _headers = await headers();
const _config = await config(undefined); // Review: Should we pass headers() here instead?
onLazyLoad?.(_config);
return getSession(_headers, _config).then((r) => r.json());
}
if (args[0] instanceof Request) {
// middleware.ts inline
// export { auth as default } from "auth"
const req = args[0];
const ev = args[1];
const _config = await config(req);
onLazyLoad?.(_config);
// args[0] is supposed to be NextRequest but the instanceof check is failing.
return handleAuth([req, ev], _config);
}
if (isReqWrapper(args[0])) {
// middleware.ts wrapper/route.ts
// import { auth } from "auth"
// export default auth((req) => { console.log(req.auth) }})
const userMiddlewareOrRoute = args[0];
return async (...args) => {
const _config = await config(args[0]);
onLazyLoad?.(_config);
return handleAuth(args, _config, userMiddlewareOrRoute);
};
}
// API Routes, getServerSideProps
const request = "req" in args[0] ? args[0].req : args[0];
const response = "res" in args[0] ? args[0].res : args[1];
const _config = await config(request);
onLazyLoad?.(_config);
// @ts-expect-error -- request is NextRequest
return getSession(new Headers(request.headers), _config).then(async (authResponse) => {
const auth = await authResponse.json();
for (const cookie of authResponse.headers.getSetCookie())
if ("headers" in response)
response.headers.append("set-cookie", cookie);
else
response.appendHeader("set-cookie", cookie);
return auth;
});
};
}
return (...args) => {
if (!args.length) {
// React Server Components
return Promise.resolve(headers()).then((h) => getSession(h, config).then((r) => r.json()));
}
if (args[0] instanceof Request) {
// middleware.ts inline
// export { auth as default } from "auth"
const req = args[0];
const ev = args[1];
return handleAuth([req, ev], config);
}
if (isReqWrapper(args[0])) {
// middleware.ts wrapper/route.ts
// import { auth } from "auth"
// export default auth((req) => { console.log(req.auth) }})
const userMiddlewareOrRoute = args[0];
return async (...args) => {
return handleAuth(args, config, userMiddlewareOrRoute).then((res) => {
return res;
});
};
}
// API Routes, getServerSideProps
const request = "req" in args[0] ? args[0].req : args[0];
const response = "res" in args[0] ? args[0].res : args[1];
return getSession(
// @ts-expect-error
new Headers(request.headers), config).then(async (authResponse) => {
const auth = await authResponse.json();
for (const cookie of authResponse.headers.getSetCookie())
if ("headers" in response)
response.headers.append("set-cookie", cookie);
else
response.appendHeader("set-cookie", cookie);
return auth;
});
};
}
async function handleAuth(args, config, userMiddlewareOrRoute) {
const request = reqWithEnvURL(args[0]);
const sessionResponse = await getSession(request.headers, config);
const auth = await sessionResponse.json();
let authorized = true;
if (config.callbacks?.authorized) {
authorized = await config.callbacks.authorized({ request, auth });
}
let response = NextResponse.next?.();
if (authorized instanceof Response) {
// User returned a custom response, like redirecting to a page or 401, respect it
response = authorized;
const redirect = authorized.headers.get("Location");
const { pathname } = request.nextUrl;
// If the user is redirecting to the same NextAuth.js action path as the current request,
// don't allow the redirect to prevent an infinite loop
if (redirect &&
isSameAuthAction(pathname, new URL(redirect).pathname, config)) {
authorized = true;
}
}
else if (userMiddlewareOrRoute) {
// Execute user's middleware/handler with the augmented request
const augmentedReq = request;
augmentedReq.auth = auth;
response =
(await userMiddlewareOrRoute(augmentedReq, args[1])) ??
NextResponse.next();
}
else if (!authorized) {
const signInPage = config.pages?.signIn ?? `${config.basePath}/signin`;
if (request.nextUrl.pathname !== signInPage) {
// Redirect to signin page by default if not authorized
const signInUrl = request.nextUrl.clone();
signInUrl.pathname = signInPage;
signInUrl.searchParams.set("callbackUrl", request.nextUrl.href);
response = NextResponse.redirect(signInUrl);
}
}
const finalResponse = new Response(response?.body, response);
// Preserve cookies from the session response
for (const cookie of sessionResponse.headers.getSetCookie())
finalResponse.headers.append("set-cookie", cookie);
return finalResponse;
}
function isSameAuthAction(requestPath, redirectPath, config) {
const action = redirectPath.replace(`${requestPath}/`, "");
const pages = Object.values(config.pages ?? {});
return ((actions.has(action) || pages.includes(redirectPath)) &&
redirectPath === requestPath);
}
const actions = new Set([
"providers",
"session",
"csrf",
"signin",
"signout",
"callback",
"verify-request",
"error",
]);

View File

@@ -0,0 +1,24 @@
import type { NextRequest } from "next/server";
/**
* AppRouteHandlerFnContext is the context that is passed to the handler as the
* second argument.
*/
export type AppRouteHandlerFnContext = {
params: Promise<any>;
};
/**
* Handler function for app routes. If a non-Response value is returned, an error
* will be thrown.
*/
export type AppRouteHandlerFn = (
/**
* Incoming request object.
*/
req: NextRequest,
/**
* Context properties on the request (including the parameters if this was a
* dynamic route).
*/
ctx: AppRouteHandlerFnContext) => void | Response | Promise<void | Response>;
export type AppRouteHandlers = Record<"GET" | "POST", (req: NextRequest) => Promise<Response>>;
//# sourceMappingURL=types.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/lib/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;CACrB,CAAA;AACD;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;AAC9B;;GAEG;AACH,GAAG,EAAE,WAAW;AAChB;;;GAGG;AACH,GAAG,EAAE,wBAAwB,KAC1B,IAAI,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAA;AAE/C,MAAM,MAAM,gBAAgB,GAAG,MAAM,CACnC,KAAK,GAAG,MAAM,EACd,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CACxC,CAAA"}

View File

@@ -0,0 +1 @@
export {};