@auth/core
Advanced tools
Comparing version 0.18.0 to 0.18.1
@@ -13,3 +13,3 @@ /** | ||
* | ||
* Before you continue, Auth.js has a list of {@link https://authjs.dev/reference/adapters/overview official database adapters}. If your database is listed there, you | ||
* Before you continue, Auth.js has a list of {@link https://authjs.dev/reference/core/getting-started/adapters official database adapters}. If your database is listed there, you | ||
* probably do not need to create your own. If you are using a data solution that cannot be integrated with an official adapter, this module will help you create a compatible adapter. | ||
@@ -25,3 +25,3 @@ * | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -90,2 +90,49 @@ * ``` | ||
* | ||
* ## Models | ||
* | ||
* Auth.js can be used with any database. Models tell you what structures Auth.js expects from your database. Models will vary slightly depending on which adapter you use, but in general, will have a similar structure to the graph below. Each model can be extended with additional fields. | ||
* | ||
* :::note | ||
* Auth.js / NextAuth.js uses `camelCase` for its database rows while respecting the conventional `snake_case` formatting for OAuth-related values. If the mixed casing is an issue for you, most adapters have a dedicated documentation section on how to force a casing convention. | ||
* ::: | ||
* | ||
* ```mermaid | ||
* erDiagram | ||
* User ||--|{ Account : "" | ||
* User { | ||
* string id | ||
* string name | ||
* string email | ||
* timestamp emailVerified | ||
* string image | ||
* } | ||
* User ||--|{ Session : "" | ||
* Session { | ||
* string id | ||
* timestamp expires | ||
* string sessionToken | ||
* string userId | ||
* } | ||
* Account { | ||
* string id | ||
* string userId | ||
* string type | ||
* string provider | ||
* string providerAccountId | ||
* string refresh_token | ||
* string access_token | ||
* int expires_at | ||
* string token_type | ||
* string scope | ||
* string id_token | ||
* string session_state | ||
* } | ||
* User ||--|{ VerificationToken : "" | ||
* VerificationToken { | ||
* string identifier | ||
* string token | ||
* timestamp expires | ||
* } | ||
* ``` | ||
* | ||
* ## Testing | ||
@@ -134,3 +181,3 @@ * | ||
/** | ||
* Whether the user has verified their email address via an [Email provider](https://authjs.dev/reference/core/providers_email). | ||
* Whether the user has verified their email address via an [Email provider](https://authjs.dev/reference/core/providers/email). | ||
* It is `null` if the user has not signed in with the Email provider yet, or the date of the first successful signin. | ||
@@ -145,3 +192,3 @@ */ | ||
* - OAuth/OIDC accounts, which are created when a user signs in with an OAuth provider. | ||
* - Email accounts, which are created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers_email). | ||
* - Email accounts, which are created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers/email). | ||
* | ||
@@ -181,3 +228,3 @@ * One user can have multiple accounts. | ||
* A verification token is a temporary token that is used to sign in a user via their email address. | ||
* It is created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers_email). | ||
* It is created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers/email). | ||
* When the user clicks the link in the email, the token and email is sent back to the server | ||
@@ -221,3 +268,3 @@ * where it is hashed and compared to the value in the database. | ||
getUserByAccount?(providerAccountId: Pick<AdapterAccount, "provider" | "providerAccountId">): Awaitable<AdapterUser | null>; | ||
updateUser?(user: Partial<AdapterUser> & Pick<AdapterUser, 'id'>): Awaitable<AdapterUser>; | ||
updateUser?(user: Partial<AdapterUser> & Pick<AdapterUser, "id">): Awaitable<AdapterUser>; | ||
/** @todo This method is currently not invoked yet. */ | ||
@@ -227,3 +274,3 @@ deleteUser?(userId: string): Promise<void> | Awaitable<AdapterUser | null | undefined>; | ||
* This method is invoked internally (but optionally can be used for manual linking). | ||
* It creates an [Account](https://authjs.dev/reference/adapters#models) in the database. | ||
* It creates an [Account](https://authjs.dev/reference/core/adapters#models) in the database. | ||
*/ | ||
@@ -230,0 +277,0 @@ linkAccount?(account: AdapterAccount): Promise<void> | Awaitable<AdapterAccount | null | undefined>; |
@@ -13,3 +13,3 @@ /** | ||
* | ||
* Before you continue, Auth.js has a list of {@link https://authjs.dev/reference/adapters/overview official database adapters}. If your database is listed there, you | ||
* Before you continue, Auth.js has a list of {@link https://authjs.dev/reference/core/getting-started/adapters official database adapters}. If your database is listed there, you | ||
* probably do not need to create your own. If you are using a data solution that cannot be integrated with an official adapter, this module will help you create a compatible adapter. | ||
@@ -25,3 +25,3 @@ * | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -90,2 +90,49 @@ * ``` | ||
* | ||
* ## Models | ||
* | ||
* Auth.js can be used with any database. Models tell you what structures Auth.js expects from your database. Models will vary slightly depending on which adapter you use, but in general, will have a similar structure to the graph below. Each model can be extended with additional fields. | ||
* | ||
* :::note | ||
* Auth.js / NextAuth.js uses `camelCase` for its database rows while respecting the conventional `snake_case` formatting for OAuth-related values. If the mixed casing is an issue for you, most adapters have a dedicated documentation section on how to force a casing convention. | ||
* ::: | ||
* | ||
* ```mermaid | ||
* erDiagram | ||
* User ||--|{ Account : "" | ||
* User { | ||
* string id | ||
* string name | ||
* string email | ||
* timestamp emailVerified | ||
* string image | ||
* } | ||
* User ||--|{ Session : "" | ||
* Session { | ||
* string id | ||
* timestamp expires | ||
* string sessionToken | ||
* string userId | ||
* } | ||
* Account { | ||
* string id | ||
* string userId | ||
* string type | ||
* string provider | ||
* string providerAccountId | ||
* string refresh_token | ||
* string access_token | ||
* int expires_at | ||
* string token_type | ||
* string scope | ||
* string id_token | ||
* string session_state | ||
* } | ||
* User ||--|{ VerificationToken : "" | ||
* VerificationToken { | ||
* string identifier | ||
* string token | ||
* timestamp expires | ||
* } | ||
* ``` | ||
* | ||
* ## Testing | ||
@@ -92,0 +139,0 @@ * |
@@ -27,3 +27,3 @@ interface ErrorCause extends Record<string, unknown> { | ||
* | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers_oauth), possible causes are: | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers/oauth), possible causes are: | ||
* - The user denied access to the application | ||
@@ -36,3 +36,3 @@ * - There was an error parsing the OAuth Profile: | ||
* | ||
* For an [Email provider](https://authjs.dev/reference/core/providers_email), possible causes are: | ||
* For an [Email provider](https://authjs.dev/reference/core/providers/email), possible causes are: | ||
* - The provided email/token combination was invalid/missing: | ||
@@ -45,3 +45,3 @@ * Check if the provider's `sendVerificationRequest` method correctly sends the email. | ||
* | ||
* For a [Credentials provider](https://authjs.dev/reference/core/providers_credentials), possible causes are: | ||
* For a [Credentials provider](https://authjs.dev/reference/core/providers/credentials), possible causes are: | ||
* - The `authorize` method threw an uncaught error: | ||
@@ -128,3 +128,3 @@ * Check the provider's `authorize` method. | ||
* response could not be parsed. This could for example happen if the provider's API | ||
* changed, or the [`OAuth2Config.profile`](https://authjs.dev/reference/core/providers_oauth#profile) method is not implemented correctly. | ||
* changed, or the [`OAuth2Config.profile`](https://authjs.dev/reference/core/providers/oauth#profile) method is not implemented correctly. | ||
*/ | ||
@@ -148,3 +148,3 @@ export declare class OAuthProfileParseError extends AuthError { | ||
* | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers_oauth), possible causes are: | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers/oauth), possible causes are: | ||
* - The Authorization Server is not compliant with the [OAuth 2.0 specifcation](https://www.ietf.org/rfc/rfc6749.html) | ||
@@ -154,4 +154,4 @@ * Check the details in the error message. | ||
* | ||
* For an [Email provider](https://authjs.dev/reference/core/providers_email), possible causes are: | ||
* - The email sent from the client is invalid, could not be normalized by [`EmailConfig.normalizeIdentifier`](https://authjs.dev/reference/core/providers_email#normalizeidentifier) | ||
* For an [Email provider](https://authjs.dev/reference/core/providers/email), possible causes are: | ||
* - The email sent from the client is invalid, could not be normalized by [`EmailConfig.normalizeIdentifier`](https://authjs.dev/reference/core/providers/email#normalizeidentifier) | ||
* - The provided email/token combination has expired: | ||
@@ -158,0 +158,0 @@ * Ask the user to log in again. |
@@ -43,3 +43,3 @@ export class AuthError extends Error { | ||
* | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers_oauth), possible causes are: | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers/oauth), possible causes are: | ||
* - The user denied access to the application | ||
@@ -52,3 +52,3 @@ * - There was an error parsing the OAuth Profile: | ||
* | ||
* For an [Email provider](https://authjs.dev/reference/core/providers_email), possible causes are: | ||
* For an [Email provider](https://authjs.dev/reference/core/providers/email), possible causes are: | ||
* - The provided email/token combination was invalid/missing: | ||
@@ -61,3 +61,3 @@ * Check if the provider's `sendVerificationRequest` method correctly sends the email. | ||
* | ||
* For a [Credentials provider](https://authjs.dev/reference/core/providers_credentials), possible causes are: | ||
* For a [Credentials provider](https://authjs.dev/reference/core/providers/credentials), possible causes are: | ||
* - The `authorize` method threw an uncaught error: | ||
@@ -144,3 +144,3 @@ * Check the provider's `authorize` method. | ||
* response could not be parsed. This could for example happen if the provider's API | ||
* changed, or the [`OAuth2Config.profile`](https://authjs.dev/reference/core/providers_oauth#profile) method is not implemented correctly. | ||
* changed, or the [`OAuth2Config.profile`](https://authjs.dev/reference/core/providers/oauth#profile) method is not implemented correctly. | ||
*/ | ||
@@ -164,3 +164,3 @@ export class OAuthProfileParseError extends AuthError { | ||
* | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers_oauth), possible causes are: | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers/oauth), possible causes are: | ||
* - The Authorization Server is not compliant with the [OAuth 2.0 specifcation](https://www.ietf.org/rfc/rfc6749.html) | ||
@@ -170,4 +170,4 @@ * Check the details in the error message. | ||
* | ||
* For an [Email provider](https://authjs.dev/reference/core/providers_email), possible causes are: | ||
* - The email sent from the client is invalid, could not be normalized by [`EmailConfig.normalizeIdentifier`](https://authjs.dev/reference/core/providers_email#normalizeidentifier) | ||
* For an [Email provider](https://authjs.dev/reference/core/providers/email), possible causes are: | ||
* - The email sent from the client is invalid, could not be normalized by [`EmailConfig.normalizeIdentifier`](https://authjs.dev/reference/core/providers/email#normalizeidentifier) | ||
* - The provided email/token combination has expired: | ||
@@ -174,0 +174,0 @@ * Ask the user to log in again. |
@@ -16,3 +16,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -113,3 +113,3 @@ * ``` | ||
* | ||
* [Documentation](https://authjs.dev/reference/configuration/auth-config#session) | [Adapter](https://authjs.dev/reference/configuration/auth-config#adapter) | [About JSON Web Tokens](https://authjs.dev/reference/faq#json-web-tokens) | ||
* [Documentation](https://authjs.dev/reference/core#authconfig#session) | [Adapter](https://authjs.dev/reference/core#authconfig#adapter) | [About JSON Web Tokens](https://authjs.dev/reference/faq#json-web-tokens) | ||
*/ | ||
@@ -281,3 +281,3 @@ strategy?: "jwt" | "database"; | ||
* | ||
* See also: [Guide: Securing a Preview Deployment](https://authjs.dev/guides/basics/deployment#securing-a-preview-deployment) | ||
* See also: [Guide: Securing a Preview Deployment](https://authjs.dev/getting-started/deployment#securing-a-preview-deployment) | ||
*/ | ||
@@ -284,0 +284,0 @@ redirectProxyUrl?: string; |
@@ -16,3 +16,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -19,0 +19,0 @@ * ``` |
36
jwt.d.ts
@@ -18,3 +18,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -45,7 +45,6 @@ * ``` | ||
export declare function decode<Payload = JWT>(params: JWTDecodeParams): Promise<Payload | null>; | ||
export interface GetTokenParams<R extends boolean = false> { | ||
export interface GetTokenParams<R extends boolean = false> extends Pick<JWTDecodeParams, "salt" | "secret"> { | ||
/** The request containing the JWT either in the cookies or in the `Authorization` header. */ | ||
req: Request | { | ||
cookies: Record<string, string>; | ||
headers: Record<string, string>; | ||
headers: Headers | Record<string, string>; | ||
}; | ||
@@ -65,7 +64,2 @@ /** | ||
raw?: R; | ||
/** | ||
* The same `secret` used in the `NextAuth` configuration. | ||
* Defaults to the `AUTH_SECRET` environment variable. | ||
*/ | ||
secret?: string; | ||
decode?: JWTOptions["decode"]; | ||
@@ -77,3 +71,2 @@ logger?: LoggerInstance | Console; | ||
* or the raw JWT string. We look for the JWT in the either the cookies, or the `Authorization` header. | ||
* [Documentation](https://authjs.dev/guides/basics/securing-pages-and-api-routes#using-gettoken) | ||
*/ | ||
@@ -95,6 +88,2 @@ export declare function getToken<R extends boolean = false>(params: GetTokenParams<R>): Promise<R extends true ? string : JWT | null>; | ||
export interface JWTEncodeParams<Payload = JWT> { | ||
/** The JWT payload. */ | ||
token?: Payload; | ||
/** The secret used to encode the Auth.js issued JWT. */ | ||
secret: string; | ||
/** | ||
@@ -106,18 +95,19 @@ * The maximum age of the Auth.js issued JWT in seconds. | ||
maxAge?: number; | ||
/** Used in combination with `secret`, to derive the encryption secret for JWTs. */ | ||
salt: string; | ||
/** Used in combination with `salt`, to derive the encryption secret for JWTs. */ | ||
secret: string; | ||
/** The JWT payload. */ | ||
token?: Payload; | ||
} | ||
export interface JWTDecodeParams { | ||
/** Used in combination with `secret`, to derive the encryption secret for JWTs. */ | ||
salt: string; | ||
/** Used in combination with `salt`, to derive the encryption secret for JWTs. */ | ||
secret: string; | ||
/** The Auth.js issued JWT to be decoded */ | ||
token?: string; | ||
/** The secret used to decode the Auth.js issued JWT. */ | ||
secret: string; | ||
} | ||
export interface JWTOptions { | ||
/** | ||
* The secret used to encode/decode the Auth.js issued JWT. | ||
* | ||
* @deprecated Set the `AUTH_SECRET` environment variable or | ||
* use the top-level `secret` option instead | ||
*/ | ||
secret: string; | ||
/** | ||
* The maximum age of the Auth.js issued JWT in seconds. | ||
@@ -124,0 +114,0 @@ * |
33
jwt.js
@@ -18,3 +18,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -43,2 +43,3 @@ * ``` | ||
import { MissingSecret } from "./errors.js"; | ||
import { parse } from "cookie"; | ||
const DEFAULT_MAX_AGE = 30 * 24 * 60 * 60; // 30 days | ||
@@ -48,4 +49,4 @@ const now = () => (Date.now() / 1000) | 0; | ||
export async function encode(params) { | ||
const { token = {}, secret, maxAge = DEFAULT_MAX_AGE } = params; | ||
const encryptionSecret = await getDerivedEncryptionKey(secret); | ||
const { token = {}, secret, maxAge = DEFAULT_MAX_AGE, salt } = params; | ||
const encryptionSecret = await getDerivedEncryptionKey(secret, salt); | ||
// @ts-expect-error `jose` allows any object as payload. | ||
@@ -61,6 +62,6 @@ return await new EncryptJWT(token) | ||
export async function decode(params) { | ||
const { token, secret } = params; | ||
const { token, secret, salt } = params; | ||
if (!token) | ||
return null; | ||
const encryptionSecret = await getDerivedEncryptionKey(secret); | ||
const encryptionSecret = await getDerivedEncryptionKey(secret, salt); | ||
const { payload } = await jwtDecrypt(token, encryptionSecret, { | ||
@@ -72,6 +73,5 @@ clockTolerance: 15, | ||
export async function getToken(params) { | ||
const { req, secureCookie = process.env.NEXTAUTH_URL?.startsWith("https://") ?? | ||
!!process.env.VERCEL, cookieName = secureCookie | ||
? "__Secure-next-auth.session-token" | ||
: "next-auth.session-token", raw, decode: _decode = decode, logger = console, secret = process.env.AUTH_SECRET, } = params; | ||
const { secureCookie, cookieName = secureCookie | ||
? "__Secure-auth.session-token" | ||
: "auth.session-token", decode: _decode = decode, salt = cookieName, secret, logger = console, raw, req, } = params; | ||
if (!req) | ||
@@ -81,9 +81,6 @@ throw new Error("Must pass `req` to JWT getToken()"); | ||
throw new MissingSecret("Must pass `secret` if not set to JWT getToken()"); | ||
const sessionStore = new SessionStore({ name: cookieName, options: { secure: secureCookie } }, | ||
// @ts-expect-error | ||
{ cookies: req.cookies, headers: req.headers }, logger); | ||
const headers = req.headers instanceof Headers ? req.headers : new Headers(req.headers); | ||
const sessionStore = new SessionStore({ name: cookieName, options: { secure: secureCookie } }, parse(headers.get("cookie") ?? ""), logger); | ||
let token = sessionStore.value; | ||
const authorizationHeader = req.headers instanceof Headers | ||
? req.headers.get("authorization") | ||
: req.headers.authorization; | ||
const authorizationHeader = headers.get("authorization"); | ||
if (!token && authorizationHeader?.split(" ")[0] === "Bearer") { | ||
@@ -98,3 +95,3 @@ const urlEncodedToken = authorizationHeader.split(" ")[1]; | ||
try { | ||
return await _decode({ token, secret }); | ||
return await _decode({ token, secret, salt }); | ||
} | ||
@@ -105,4 +102,4 @@ catch { | ||
} | ||
async function getDerivedEncryptionKey(secret) { | ||
return await hkdf("sha256", secret, "", "Auth.js Generated Encryption Key", 32); | ||
async function getDerivedEncryptionKey(keyMaterial, salt) { | ||
return await hkdf("sha256", keyMaterial, salt, `Auth.js Generated Encryption Key (${salt})`, 32); | ||
} |
@@ -37,3 +37,4 @@ import { OAuthAccountNotLinked } from "../errors.js"; | ||
try { | ||
session = await jwt.decode({ ...jwt, token: sessionToken }); | ||
const salt = options.cookies.sessionToken.name; | ||
session = await jwt.decode({ ...jwt, token: sessionToken, salt }); | ||
if (session && "sub" in session && session.sub) { | ||
@@ -40,0 +41,0 @@ user = await getUser(session.sub); |
@@ -1,2 +0,2 @@ | ||
import type { CookieOption, CookiesOptions, LoggerInstance } from "../types.js"; | ||
import type { CookieOption, CookiesOptions, LoggerInstance, RequestInternal } from "../types.js"; | ||
/** Stringified form of `JWT`. Extract the content with `jwt.decode` */ | ||
@@ -29,6 +29,3 @@ export type JWTString = string; | ||
#private; | ||
constructor(option: CookieOption, req: Partial<{ | ||
cookies: any; | ||
headers: any; | ||
}>, logger: LoggerInstance | Console); | ||
constructor(option: CookieOption, cookies: RequestInternal["cookies"], logger: LoggerInstance | Console); | ||
/** | ||
@@ -35,0 +32,0 @@ * The JWT Session or database Session ID |
@@ -18,3 +18,3 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
// "Cookie estimated to be ", | ||
// serialize(`__Secure.next-auth.session-token.0`, "", { | ||
// serialize(`__Secure.authjs.session-token.0`, "", { | ||
// expires: new Date(), | ||
@@ -32,3 +32,3 @@ // httpOnly: true, | ||
// Based on commented out section above | ||
const ESTIMATED_EMPTY_COOKIE_SIZE = 163; | ||
const ESTIMATED_EMPTY_COOKIE_SIZE = 160; | ||
const CHUNK_SIZE = ALLOWED_COOKIE_SIZE - ESTIMATED_EMPTY_COOKIE_SIZE; | ||
@@ -50,3 +50,3 @@ /** | ||
sessionToken: { | ||
name: `${cookiePrefix}next-auth.session-token`, | ||
name: `${cookiePrefix}authjs.session-token`, | ||
options: { | ||
@@ -60,3 +60,3 @@ httpOnly: true, | ||
callbackUrl: { | ||
name: `${cookiePrefix}next-auth.callback-url`, | ||
name: `${cookiePrefix}authjs.callback-url`, | ||
options: { | ||
@@ -72,3 +72,3 @@ httpOnly: true, | ||
// NB: The `__Host-` prefix is stricter than the `__Secure-` prefix. | ||
name: `${useSecureCookies ? "__Host-" : ""}next-auth.csrf-token`, | ||
name: `${useSecureCookies ? "__Host-" : ""}authjs.csrf-token`, | ||
options: { | ||
@@ -82,3 +82,3 @@ httpOnly: true, | ||
pkceCodeVerifier: { | ||
name: `${cookiePrefix}next-auth.pkce.code_verifier`, | ||
name: `${cookiePrefix}authjs.pkce.code_verifier`, | ||
options: { | ||
@@ -93,3 +93,3 @@ httpOnly: true, | ||
state: { | ||
name: `${cookiePrefix}next-auth.state`, | ||
name: `${cookiePrefix}authjs.state`, | ||
options: { | ||
@@ -104,3 +104,3 @@ httpOnly: true, | ||
nonce: { | ||
name: `${cookiePrefix}next-auth.nonce`, | ||
name: `${cookiePrefix}authjs.nonce`, | ||
options: { | ||
@@ -116,3 +116,3 @@ httpOnly: true, | ||
export class SessionStore { | ||
constructor(option, req, logger) { | ||
constructor(option, cookies, logger) { | ||
_SessionStore_instances.add(this); | ||
@@ -124,24 +124,10 @@ _SessionStore_chunks.set(this, {}); | ||
__classPrivateFieldSet(this, _SessionStore_option, option, "f"); | ||
const { cookies } = req; | ||
const { name: cookieName } = option; | ||
if (typeof cookies?.getAll === "function") { | ||
// Next.js ^v13.0.1 (Edge Env) | ||
for (const { name, value } of cookies.getAll()) { | ||
if (name.startsWith(cookieName)) { | ||
__classPrivateFieldGet(this, _SessionStore_chunks, "f")[name] = value; | ||
} | ||
} | ||
if (!cookies) | ||
return; | ||
const { name: sessionCookiePrefix } = option; | ||
for (const [name, value] of Object.entries(cookies)) { | ||
if (!name.startsWith(sessionCookiePrefix) || !value) | ||
continue; | ||
__classPrivateFieldGet(this, _SessionStore_chunks, "f")[name] = value; | ||
} | ||
else if (cookies instanceof Map) { | ||
for (const name of cookies.keys()) { | ||
if (name.startsWith(cookieName)) | ||
__classPrivateFieldGet(this, _SessionStore_chunks, "f")[name] = cookies.get(name); | ||
} | ||
} | ||
else { | ||
for (const name in cookies) { | ||
if (name.startsWith(cookieName)) | ||
__classPrivateFieldGet(this, _SessionStore_chunks, "f")[name] = cookies[name]; | ||
} | ||
} | ||
} | ||
@@ -160,3 +146,3 @@ /** | ||
// Use the sorted keys to join the chunks in the correct order | ||
return sortedKeys.map(key => __classPrivateFieldGet(this, _SessionStore_chunks, "f")[key]).join(""); | ||
return sortedKeys.map((key) => __classPrivateFieldGet(this, _SessionStore_chunks, "f")[key]).join(""); | ||
} | ||
@@ -163,0 +149,0 @@ /** |
@@ -21,3 +21,3 @@ import { UnknownAction } from "../errors.js"; | ||
}); | ||
const sessionStore = new SessionStore(options.cookies.sessionToken, request, options.logger); | ||
const sessionStore = new SessionStore(options.cookies.sessionToken, request.cookies, options.logger); | ||
if (method === "GET") { | ||
@@ -24,0 +24,0 @@ const render = renderPage({ ...options, query: request.query, cookies }); |
@@ -14,5 +14,6 @@ import * as jose from "jose"; | ||
token.data = data; | ||
const name = cookies[type].name; | ||
return { | ||
name: cookies[type].name, | ||
value: await encode({ ...options.jwt, maxAge, token }), | ||
name, | ||
value: await encode({ ...options.jwt, maxAge, token, salt: name }), | ||
options: { ...cookies[type].options, expires }, | ||
@@ -47,2 +48,3 @@ }; | ||
token: codeVerifier, | ||
salt: options.cookies.pkceCodeVerifier.name, | ||
}); | ||
@@ -100,2 +102,3 @@ if (!value?.value) | ||
token: state, | ||
salt: options.cookies.state.name, | ||
}); | ||
@@ -142,3 +145,7 @@ if (!encodedState?.value) | ||
throw new InvalidCheck("Nonce cookie was missing."); | ||
const value = await decode({ ...options.jwt, token: nonce }); | ||
const value = await decode({ | ||
...options.jwt, | ||
token: nonce, | ||
salt: options.cookies.nonce.name, | ||
}); | ||
if (!value?.value) | ||
@@ -145,0 +152,0 @@ throw new InvalidCheck("Nonce value could not be parsed."); |
@@ -57,3 +57,3 @@ import { OAuthProfileParseError } from "../errors.js"; | ||
* Returns basic user profile from the userinfo response/`id_token` claims. | ||
* @see https://authjs.dev/reference/adapters#user | ||
* @see https://authjs.dev/reference/core/adapters#user | ||
* @see https://openid.net/specs/openid-connect-core-1_0.html#IDToken | ||
@@ -77,3 +77,3 @@ * @see https://openid.net/specs/openid-connect-core-1_0.html#UserInfo | ||
* @see https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse | ||
* @see https://authjs.dev/reference/adapters#account | ||
* @see https://authjs.dev/reference/core/adapters#account | ||
*/ | ||
@@ -80,0 +80,0 @@ const defaultAccount = (account) => { |
@@ -77,4 +77,5 @@ import { CallbackRouteError, OAuthCallbackError, Verification, } from "../../errors.js"; | ||
else { | ||
const salt = options.cookies.sessionToken.name; | ||
// Encode token | ||
const newToken = await jwt.encode({ ...jwt, token }); | ||
const newToken = await jwt.encode({ ...jwt, token, salt }); | ||
// Set cookie expiry date | ||
@@ -167,4 +168,5 @@ const cookieExpires = new Date(); | ||
else { | ||
const salt = options.cookies.sessionToken.name; | ||
// Encode token | ||
const newToken = await jwt.encode({ ...jwt, token }); | ||
const newToken = await jwt.encode({ ...jwt, token, salt }); | ||
// Set cookie expiry date | ||
@@ -248,4 +250,5 @@ const cookieExpires = new Date(); | ||
else { | ||
const salt = options.cookies.sessionToken.name; | ||
// Encode token | ||
const newToken = await jwt.encode({ ...jwt, token }); | ||
const newToken = await jwt.encode({ ...jwt, token, salt }); | ||
// Set cookie expiry date | ||
@@ -252,0 +255,0 @@ const cookieExpires = new Date(); |
@@ -17,8 +17,9 @@ import { JWTSessionError, SessionTokenError } from "../../errors.js"; | ||
try { | ||
const decodedToken = await jwt.decode({ ...jwt, token: sessionToken }); | ||
if (!decodedToken) | ||
const salt = options.cookies.sessionToken.name; | ||
const payload = await jwt.decode({ ...jwt, token: sessionToken, salt }); | ||
if (!payload) | ||
throw new Error("Invalid JWT"); | ||
// @ts-expect-error | ||
const token = await callbacks.jwt({ | ||
token: decodedToken, | ||
token: payload, | ||
...(isUpdate && { trigger: "update" }), | ||
@@ -40,6 +41,3 @@ session: newSession, | ||
// Refresh JWT expiry by re-signing it, with an updated expiry date | ||
const newToken = await jwt.encode({ | ||
...jwt, | ||
token, | ||
}); | ||
const newToken = await jwt.encode({ ...jwt, token, salt }); | ||
// Set cookie, to also update expiry date on cookie | ||
@@ -46,0 +44,0 @@ const sessionCookies = sessionStore.chunk(newToken, { |
@@ -16,3 +16,4 @@ import { SignOutError } from "../../errors.js"; | ||
if (session.strategy === "jwt") { | ||
const token = await jwt.decode({ ...jwt, token: sessionToken }); | ||
const salt = options.cookies.sessionToken.name; | ||
const token = await jwt.decode({ ...jwt, token: sessionToken, salt }); | ||
await events.signOut?.({ token }); | ||
@@ -19,0 +20,0 @@ } |
@@ -6,3 +6,3 @@ import { AuthError } from "../../errors.js"; | ||
* | ||
* [Documentation](https://authjs.dev/reference/configuration/auth-config#logger) | ||
* [Documentation](https://authjs.dev/reference/core#authconfig#logger) | ||
*/ | ||
@@ -9,0 +9,0 @@ export interface LoggerInstance extends Record<string, Function> { |
{ | ||
"name": "@auth/core", | ||
"version": "0.18.0", | ||
"version": "0.18.1", | ||
"description": "Authentication for the Web.", | ||
@@ -64,6 +64,6 @@ "keywords": [ | ||
"dependencies": { | ||
"@panva/hkdf": "^1.0.4", | ||
"@panva/hkdf": "^1.1.1", | ||
"cookie": "0.5.0", | ||
"jose": "^4.11.1", | ||
"oauth4webapi": "^2.0.6", | ||
"jose": "^5.1.0", | ||
"oauth4webapi": "^2.3.0", | ||
"preact": "10.11.3", | ||
@@ -87,4 +87,3 @@ "preact-render-to-string": "5.2.3" | ||
"postcss": "8.4.19", | ||
"postcss-nested": "6.0.0", | ||
"@auth/tsconfig": "0.0.0" | ||
"postcss-nested": "6.0.0" | ||
}, | ||
@@ -91,0 +90,0 @@ "scripts": { |
@@ -202,3 +202,3 @@ /** | ||
* :::note | ||
* 42 returns a field on `Account` called `created_at` which is a number. See the [docs](https://api.intra.42.fr/apidoc/guides/getting_started#make-basic-requests). Make sure to add this field to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/adapters). | ||
* 42 returns a field on `Account` called `created_at` which is a number. See the [docs](https://api.intra.42.fr/apidoc/guides/getting_started#make-basic-requests). Make sure to add this field to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/core/adapters). | ||
* ::: | ||
@@ -205,0 +205,0 @@ * By default, Auth.js assumes that the 42School provider is |
@@ -30,3 +30,3 @@ /** | ||
* :::note | ||
* 42 returns a field on `Account` called `created_at` which is a number. See the [docs](https://api.intra.42.fr/apidoc/guides/getting_started#make-basic-requests). Make sure to add this field to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/adapters). | ||
* 42 returns a field on `Account` called `created_at` which is a number. See the [docs](https://api.intra.42.fr/apidoc/guides/getting_started#make-basic-requests). Make sure to add this field to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/core/adapters). | ||
* ::: | ||
@@ -33,0 +33,0 @@ * By default, Auth.js assumes that the 42School provider is |
@@ -108,4 +108,4 @@ /** | ||
* AppleProvider({ | ||
* clientId: process.env.GITHUB_ID, | ||
* clientSecret: process.env.GITHUB_SECRET, | ||
* clientId: process.env.APPLE_ID, | ||
* clientSecret: process.env.APPLE_SECRET, | ||
* }), | ||
@@ -112,0 +112,0 @@ * ], |
@@ -32,4 +32,4 @@ /** | ||
* AppleProvider({ | ||
* clientId: process.env.GITHUB_ID, | ||
* clientSecret: process.env.GITHUB_SECRET, | ||
* clientId: process.env.APPLE_ID, | ||
* clientSecret: process.env.APPLE_SECRET, | ||
* }), | ||
@@ -36,0 +36,0 @@ * ], |
@@ -58,5 +58,2 @@ /** | ||
* providers: [BoxyHQ({ | ||
* id: "boxyhq-saml-oidc", | ||
* wellKnown: `http://localhost:5225/.well-known/openid-configuration`, | ||
* authorization: { params: { scope: "openid email" } }, | ||
* clientId: BOXYHQ_SAML_CLIENT_ID, | ||
@@ -63,0 +60,0 @@ * clientSecret: BOXYHQ_SAML_CLIENT_SECRET, |
@@ -41,5 +41,2 @@ /** | ||
* providers: [BoxyHQ({ | ||
* id: "boxyhq-saml-oidc", | ||
* wellKnown: `http://localhost:5225/.well-known/openid-configuration`, | ||
* authorization: { params: { scope: "openid email" } }, | ||
* clientId: BOXYHQ_SAML_CLIENT_ID, | ||
@@ -46,0 +43,0 @@ * clientSecret: BOXYHQ_SAML_CLIENT_SECRET, |
@@ -61,3 +61,3 @@ /** | ||
return { | ||
id: "clickup", | ||
id: "click-up", | ||
name: "ClickUp", | ||
@@ -64,0 +64,0 @@ type: "oauth", |
@@ -60,13 +60,18 @@ import type { CommonProviderOptions } from "./index.js"; | ||
* | ||
* :::warning **NOTE** | ||
* :::caution | ||
* The functionality provided for credentials-based authentication is intentionally limited to discourage the use of passwords due to the inherent security risks of the username-password model. | ||
* | ||
* The functionality provided for credentials based authentication is | ||
* **intentionally limited** to _discourage_ use of passwords | ||
* due to the _inherent security risks_ associated with them | ||
* and the _additional complexity_ associated | ||
* with supporting usernames and passwords. | ||
* OAuth providers spend significant amounts of money, time, and engineering effort to build: | ||
* | ||
* - abuse detection (bot-protection, rate-limiting) | ||
* - password management (password reset, credential stuffing, rotation) | ||
* - data security (encryption/salting, strength validation) | ||
* | ||
* and much more for authentication solutions. It is likely that your application would benefit from leveraging these battle-tested solutions rather than try to rebuild them from scratch. | ||
* | ||
* If you'd still like to build password-based authentication for your application despite these risks, Auth.js gives you full control to do so. | ||
* | ||
* ::: | ||
* | ||
* See the [callbacks documentation](/reference/configuration/auth-config#callbacks) for more information on how to interact with the token. For example, you can add additional information to the token by returning an object from the `jwt()` callback: | ||
* See the [callbacks documentation](/reference/core#authconfig#callbacks) for more information on how to interact with the token. For example, you can add additional information to the token by returning an object from the `jwt()` callback: | ||
* | ||
@@ -73,0 +78,0 @@ * ```js |
@@ -10,13 +10,18 @@ /** | ||
* | ||
* :::warning **NOTE** | ||
* :::caution | ||
* The functionality provided for credentials-based authentication is intentionally limited to discourage the use of passwords due to the inherent security risks of the username-password model. | ||
* | ||
* The functionality provided for credentials based authentication is | ||
* **intentionally limited** to _discourage_ use of passwords | ||
* due to the _inherent security risks_ associated with them | ||
* and the _additional complexity_ associated | ||
* with supporting usernames and passwords. | ||
* OAuth providers spend significant amounts of money, time, and engineering effort to build: | ||
* | ||
* - abuse detection (bot-protection, rate-limiting) | ||
* - password management (password reset, credential stuffing, rotation) | ||
* - data security (encryption/salting, strength validation) | ||
* | ||
* and much more for authentication solutions. It is likely that your application would benefit from leveraging these battle-tested solutions rather than try to rebuild them from scratch. | ||
* | ||
* If you'd still like to build password-based authentication for your application despite these risks, Auth.js gives you full control to do so. | ||
* | ||
* ::: | ||
* | ||
* See the [callbacks documentation](/reference/configuration/auth-config#callbacks) for more information on how to interact with the token. For example, you can add additional information to the token by returning an object from the `jwt()` callback: | ||
* See the [callbacks documentation](/reference/core#authconfig#callbacks) for more information on how to interact with the token. For example, you can add additional information to the token by returning an object from the `jwt()` callback: | ||
* | ||
@@ -23,0 +28,0 @@ * ```js |
@@ -69,3 +69,3 @@ /** | ||
return { | ||
id: "duende-identityserver6", | ||
id: "duende-identity-server6", | ||
name: "DuendeIdentityServer6", | ||
@@ -72,0 +72,0 @@ type: "oidc", |
@@ -76,3 +76,3 @@ import type { CommonProviderOptions } from "./index.js"; | ||
* | ||
* [Normalizing the email address](https://authjs.dev/reference/core/providers_email#normalizing-the-email-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax) | ||
* [Normalizing the email address](https://authjs.dev/reference/core/providers/email#normalizing-the-email-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax) | ||
*/ | ||
@@ -177,3 +177,3 @@ normalizeIdentifier?: (identifier: string) => string; | ||
* | ||
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/adapters) for storing the Email verification token. | ||
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/core/adapters) for storing the Email verification token. | ||
* | ||
@@ -180,0 +180,0 @@ * 5. You can now sign in with an email address at `/api/auth/signin`. |
@@ -81,3 +81,3 @@ import { createTransport } from "nodemailer"; | ||
* | ||
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/adapters) for storing the Email verification token. | ||
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/core/adapters) for storing the Email verification token. | ||
* | ||
@@ -84,0 +84,0 @@ * 5. You can now sign in with an email address at `/api/auth/signin`. |
@@ -9,3 +9,3 @@ /** | ||
* | ||
* @module providers/fushionauth | ||
* @module providers/fusionauth | ||
*/ | ||
@@ -12,0 +12,0 @@ import type { OAuthConfig, OAuthUserConfig } from "./oauth.js"; |
@@ -18,10 +18,11 @@ /** | ||
exp: number; | ||
family_name: string; | ||
family_name?: string; | ||
given_name: string; | ||
hd: string; | ||
hd?: string; | ||
iat: number; | ||
iss: string; | ||
jti: string; | ||
jti?: string; | ||
locale?: string; | ||
name: string; | ||
nbf: number; | ||
nbf?: number; | ||
picture: string; | ||
@@ -28,0 +29,0 @@ sub: string; |
@@ -81,3 +81,3 @@ import type { Client } from "oauth4webapi"; | ||
* | ||
* @see [Database Adapter: User model](https://authjs.dev/reference/adapters#user) | ||
* @see [Database Adapter: User model](https://authjs.dev/reference/core/adapters#user) | ||
*/ | ||
@@ -90,4 +90,4 @@ profile?: ProfileCallback<Profile>; | ||
* :::note | ||
* You need to adjust your database's [Account model](https://authjs.dev/reference/adapters#account) to match the returned properties. | ||
* Check out the documentation of your [database adapter](https://authjs.dev/reference/adapters) for more information. | ||
* You need to adjust your database's [Account model](https://authjs.dev/reference/core/adapters#account) to match the returned properties. | ||
* Check out the documentation of your [database adapter](https://authjs.dev/reference/core/adapters) for more information. | ||
* ::: | ||
@@ -116,3 +116,3 @@ * | ||
* | ||
* @see [Database Adapter: Account model](https://authjs.dev/reference/adapters#account) | ||
* @see [Database Adapter: Account model](https://authjs.dev/reference/core/adapters#account) | ||
* @see https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse | ||
@@ -119,0 +119,0 @@ * @see https://www.ietf.org/rfc/rfc6749.html#section-5.1 |
@@ -9,3 +9,3 @@ /** | ||
* | ||
* @module providers/saleforce | ||
* @module providers/salesforce | ||
*/ | ||
@@ -12,0 +12,0 @@ import type { OAuthConfig, OAuthUserConfig } from "./index.js"; |
@@ -149,3 +149,3 @@ /** | ||
* Twitter is currently the only built-in provider using the OAuth 1.0 spec. | ||
* This means that you won't receive an `access_token` or `refresh_token`, but an `oauth_token` and `oauth_token_secret` respectively. Remember to add these to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/adapters). | ||
* This means that you won't receive an `access_token` or `refresh_token`, but an `oauth_token` and `oauth_token_secret` respectively. Remember to add these to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/core/adapters). | ||
* | ||
@@ -152,0 +152,0 @@ * :::tip |
@@ -47,3 +47,3 @@ /** | ||
* Twitter is currently the only built-in provider using the OAuth 1.0 spec. | ||
* This means that you won't receive an `access_token` or `refresh_token`, but an `oauth_token` and `oauth_token_secret` respectively. Remember to add these to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/adapters). | ||
* This means that you won't receive an `access_token` or `refresh_token`, but an `oauth_token` and `oauth_token_secret` respectively. Remember to add these to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/core/adapters). | ||
* | ||
@@ -50,0 +50,0 @@ * :::tip |
@@ -13,3 +13,3 @@ /** | ||
* | ||
* Before you continue, Auth.js has a list of {@link https://authjs.dev/reference/adapters/overview official database adapters}. If your database is listed there, you | ||
* Before you continue, Auth.js has a list of {@link https://authjs.dev/reference/core/getting-started/adapters official database adapters}. If your database is listed there, you | ||
* probably do not need to create your own. If you are using a data solution that cannot be integrated with an official adapter, this module will help you create a compatible adapter. | ||
@@ -25,3 +25,3 @@ * | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -90,2 +90,49 @@ * ``` | ||
* | ||
* ## Models | ||
* | ||
* Auth.js can be used with any database. Models tell you what structures Auth.js expects from your database. Models will vary slightly depending on which adapter you use, but in general, will have a similar structure to the graph below. Each model can be extended with additional fields. | ||
* | ||
* :::note | ||
* Auth.js / NextAuth.js uses `camelCase` for its database rows while respecting the conventional `snake_case` formatting for OAuth-related values. If the mixed casing is an issue for you, most adapters have a dedicated documentation section on how to force a casing convention. | ||
* ::: | ||
* | ||
* ```mermaid | ||
* erDiagram | ||
* User ||--|{ Account : "" | ||
* User { | ||
* string id | ||
* string name | ||
* string email | ||
* timestamp emailVerified | ||
* string image | ||
* } | ||
* User ||--|{ Session : "" | ||
* Session { | ||
* string id | ||
* timestamp expires | ||
* string sessionToken | ||
* string userId | ||
* } | ||
* Account { | ||
* string id | ||
* string userId | ||
* string type | ||
* string provider | ||
* string providerAccountId | ||
* string refresh_token | ||
* string access_token | ||
* int expires_at | ||
* string token_type | ||
* string scope | ||
* string id_token | ||
* string session_state | ||
* } | ||
* User ||--|{ VerificationToken : "" | ||
* VerificationToken { | ||
* string identifier | ||
* string token | ||
* timestamp expires | ||
* } | ||
* ``` | ||
* | ||
* ## Testing | ||
@@ -139,3 +186,3 @@ * | ||
/** | ||
* Whether the user has verified their email address via an [Email provider](https://authjs.dev/reference/core/providers_email). | ||
* Whether the user has verified their email address via an [Email provider](https://authjs.dev/reference/core/providers/email). | ||
* It is `null` if the user has not signed in with the Email provider yet, or the date of the first successful signin. | ||
@@ -151,3 +198,3 @@ */ | ||
* - OAuth/OIDC accounts, which are created when a user signs in with an OAuth provider. | ||
* - Email accounts, which are created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers_email). | ||
* - Email accounts, which are created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers/email). | ||
* | ||
@@ -189,3 +236,3 @@ * One user can have multiple accounts. | ||
* A verification token is a temporary token that is used to sign in a user via their email address. | ||
* It is created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers_email). | ||
* It is created when a user signs in with an [Email provider](https://authjs.dev/reference/core/providers/email). | ||
* When the user clicks the link in the email, the token and email is sent back to the server | ||
@@ -232,3 +279,5 @@ * where it is hashed and compared to the value in the database. | ||
): Awaitable<AdapterUser | null> | ||
updateUser?(user: Partial<AdapterUser> & Pick<AdapterUser, 'id'>): Awaitable<AdapterUser> | ||
updateUser?( | ||
user: Partial<AdapterUser> & Pick<AdapterUser, "id"> | ||
): Awaitable<AdapterUser> | ||
/** @todo This method is currently not invoked yet. */ | ||
@@ -240,3 +289,3 @@ deleteUser?( | ||
* This method is invoked internally (but optionally can be used for manual linking). | ||
* It creates an [Account](https://authjs.dev/reference/adapters#models) in the database. | ||
* It creates an [Account](https://authjs.dev/reference/core/adapters#models) in the database. | ||
*/ | ||
@@ -243,0 +292,0 @@ linkAccount?( |
@@ -44,3 +44,3 @@ interface ErrorCause extends Record<string, unknown> {} | ||
* | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers_oauth), possible causes are: | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers/oauth), possible causes are: | ||
* - The user denied access to the application | ||
@@ -53,3 +53,3 @@ * - There was an error parsing the OAuth Profile: | ||
* | ||
* For an [Email provider](https://authjs.dev/reference/core/providers_email), possible causes are: | ||
* For an [Email provider](https://authjs.dev/reference/core/providers/email), possible causes are: | ||
* - The provided email/token combination was invalid/missing: | ||
@@ -62,3 +62,3 @@ * Check if the provider's `sendVerificationRequest` method correctly sends the email. | ||
* | ||
* For a [Credentials provider](https://authjs.dev/reference/core/providers_credentials), possible causes are: | ||
* For a [Credentials provider](https://authjs.dev/reference/core/providers/credentials), possible causes are: | ||
* - The `authorize` method threw an uncaught error: | ||
@@ -145,3 +145,3 @@ * Check the provider's `authorize` method. | ||
* response could not be parsed. This could for example happen if the provider's API | ||
* changed, or the [`OAuth2Config.profile`](https://authjs.dev/reference/core/providers_oauth#profile) method is not implemented correctly. | ||
* changed, or the [`OAuth2Config.profile`](https://authjs.dev/reference/core/providers/oauth#profile) method is not implemented correctly. | ||
*/ | ||
@@ -165,3 +165,3 @@ export class OAuthProfileParseError extends AuthError {} | ||
* | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers_oauth), possible causes are: | ||
* For an [OAuth provider](https://authjs.dev/reference/core/providers/oauth), possible causes are: | ||
* - The Authorization Server is not compliant with the [OAuth 2.0 specifcation](https://www.ietf.org/rfc/rfc6749.html) | ||
@@ -171,4 +171,4 @@ * Check the details in the error message. | ||
* | ||
* For an [Email provider](https://authjs.dev/reference/core/providers_email), possible causes are: | ||
* - The email sent from the client is invalid, could not be normalized by [`EmailConfig.normalizeIdentifier`](https://authjs.dev/reference/core/providers_email#normalizeidentifier) | ||
* For an [Email provider](https://authjs.dev/reference/core/providers/email), possible causes are: | ||
* - The email sent from the client is invalid, could not be normalized by [`EmailConfig.normalizeIdentifier`](https://authjs.dev/reference/core/providers/email#normalizeidentifier) | ||
* - The provided email/token combination has expired: | ||
@@ -175,0 +175,0 @@ * Ask the user to log in again. |
@@ -16,3 +16,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -208,3 +208,3 @@ * ``` | ||
* | ||
* [Documentation](https://authjs.dev/reference/configuration/auth-config#session) | [Adapter](https://authjs.dev/reference/configuration/auth-config#adapter) | [About JSON Web Tokens](https://authjs.dev/reference/faq#json-web-tokens) | ||
* [Documentation](https://authjs.dev/reference/core#authconfig#session) | [Adapter](https://authjs.dev/reference/core#authconfig#adapter) | [About JSON Web Tokens](https://authjs.dev/reference/faq#json-web-tokens) | ||
*/ | ||
@@ -376,5 +376,5 @@ strategy?: "jwt" | "database" | ||
* | ||
* See also: [Guide: Securing a Preview Deployment](https://authjs.dev/guides/basics/deployment#securing-a-preview-deployment) | ||
* See also: [Guide: Securing a Preview Deployment](https://authjs.dev/getting-started/deployment#securing-a-preview-deployment) | ||
*/ | ||
redirectProxyUrl?: string | ||
} |
@@ -18,3 +18,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -46,2 +46,3 @@ * ``` | ||
import { MissingSecret } from "./errors.js" | ||
import { parse } from "cookie" | ||
@@ -54,4 +55,4 @@ const DEFAULT_MAX_AGE = 30 * 24 * 60 * 60 // 30 days | ||
export async function encode<Payload = JWT>(params: JWTEncodeParams<Payload>) { | ||
const { token = {}, secret, maxAge = DEFAULT_MAX_AGE } = params | ||
const encryptionSecret = await getDerivedEncryptionKey(secret) | ||
const { token = {}, secret, maxAge = DEFAULT_MAX_AGE, salt } = params | ||
const encryptionSecret = await getDerivedEncryptionKey(secret, salt) | ||
// @ts-expect-error `jose` allows any object as payload. | ||
@@ -70,5 +71,5 @@ return await new EncryptJWT(token) | ||
): Promise<Payload | null> { | ||
const { token, secret } = params | ||
const { token, secret, salt } = params | ||
if (!token) return null | ||
const encryptionSecret = await getDerivedEncryptionKey(secret) | ||
const encryptionSecret = await getDerivedEncryptionKey(secret, salt) | ||
const { payload } = await jwtDecrypt(token, encryptionSecret, { | ||
@@ -80,7 +81,6 @@ clockTolerance: 15, | ||
export interface GetTokenParams<R extends boolean = false> { | ||
export interface GetTokenParams<R extends boolean = false> | ||
extends Pick<JWTDecodeParams, "salt" | "secret"> { | ||
/** The request containing the JWT either in the cookies or in the `Authorization` header. */ | ||
req: | ||
| Request | ||
| { cookies: Record<string, string>; headers: Record<string, string> } | ||
req: Request | { headers: Headers | Record<string, string> } | ||
/** | ||
@@ -99,7 +99,2 @@ * Use secure prefix for cookie name, unless URL in `NEXTAUTH_URL` is http:// | ||
raw?: R | ||
/** | ||
* The same `secret` used in the `NextAuth` configuration. | ||
* Defaults to the `AUTH_SECRET` environment variable. | ||
*/ | ||
secret?: string | ||
decode?: JWTOptions["decode"] | ||
@@ -112,3 +107,2 @@ logger?: LoggerInstance | Console | ||
* or the raw JWT string. We look for the JWT in the either the cookies, or the `Authorization` header. | ||
* [Documentation](https://authjs.dev/guides/basics/securing-pages-and-api-routes#using-gettoken) | ||
*/ | ||
@@ -122,12 +116,12 @@ export async function getToken<R extends boolean = false>( | ||
const { | ||
req, | ||
secureCookie = process.env.NEXTAUTH_URL?.startsWith("https://") ?? | ||
!!process.env.VERCEL, | ||
secureCookie, | ||
cookieName = secureCookie | ||
? "__Secure-next-auth.session-token" | ||
: "next-auth.session-token", | ||
raw, | ||
? "__Secure-auth.session-token" | ||
: "auth.session-token", | ||
decode: _decode = decode, | ||
salt = cookieName, | ||
secret, | ||
logger = console, | ||
secret = process.env.AUTH_SECRET, | ||
raw, | ||
req, | ||
} = params | ||
@@ -139,6 +133,8 @@ | ||
const headers = | ||
req.headers instanceof Headers ? req.headers : new Headers(req.headers) | ||
const sessionStore = new SessionStore( | ||
{ name: cookieName, options: { secure: secureCookie } }, | ||
// @ts-expect-error | ||
{ cookies: req.cookies, headers: req.headers }, | ||
parse(headers.get("cookie") ?? ""), | ||
logger | ||
@@ -149,6 +145,3 @@ ) | ||
const authorizationHeader = | ||
req.headers instanceof Headers | ||
? req.headers.get("authorization") | ||
: req.headers.authorization | ||
const authorizationHeader = headers.get("authorization") | ||
@@ -165,3 +158,3 @@ if (!token && authorizationHeader?.split(" ")[0] === "Bearer") { | ||
try { | ||
return await _decode({ token, secret }) | ||
return await _decode({ token, secret, salt }) | ||
} catch { | ||
@@ -172,8 +165,11 @@ return null | ||
async function getDerivedEncryptionKey(secret: string) { | ||
async function getDerivedEncryptionKey( | ||
keyMaterial: Parameters<typeof hkdf>[1], | ||
salt: Parameters<typeof hkdf>[2] | ||
) { | ||
return await hkdf( | ||
"sha256", | ||
secret, | ||
"", | ||
"Auth.js Generated Encryption Key", | ||
keyMaterial, | ||
salt, | ||
`Auth.js Generated Encryption Key (${salt})`, | ||
32 | ||
@@ -198,6 +194,2 @@ ) | ||
export interface JWTEncodeParams<Payload = JWT> { | ||
/** The JWT payload. */ | ||
token?: Payload | ||
/** The secret used to encode the Auth.js issued JWT. */ | ||
secret: string | ||
/** | ||
@@ -209,9 +201,17 @@ * The maximum age of the Auth.js issued JWT in seconds. | ||
maxAge?: number | ||
/** Used in combination with `secret`, to derive the encryption secret for JWTs. */ | ||
salt: string | ||
/** Used in combination with `salt`, to derive the encryption secret for JWTs. */ | ||
secret: string | ||
/** The JWT payload. */ | ||
token?: Payload | ||
} | ||
export interface JWTDecodeParams { | ||
/** Used in combination with `secret`, to derive the encryption secret for JWTs. */ | ||
salt: string | ||
/** Used in combination with `salt`, to derive the encryption secret for JWTs. */ | ||
secret: string | ||
/** The Auth.js issued JWT to be decoded */ | ||
token?: string | ||
/** The secret used to decode the Auth.js issued JWT. */ | ||
secret: string | ||
} | ||
@@ -222,5 +222,3 @@ | ||
* The secret used to encode/decode the Auth.js issued JWT. | ||
* | ||
* @deprecated Set the `AUTH_SECRET` environment variable or | ||
* use the top-level `secret` option instead | ||
* @internal | ||
*/ | ||
@@ -227,0 +225,0 @@ secret: string |
@@ -75,3 +75,4 @@ import { OAuthAccountNotLinked } from "../errors.js" | ||
try { | ||
session = await jwt.decode({ ...jwt, token: sessionToken }) | ||
const salt = options.cookies.sessionToken.name | ||
session = await jwt.decode({ ...jwt, token: sessionToken, salt }) | ||
if (session && "sub" in session && session.sub) { | ||
@@ -78,0 +79,0 @@ user = await getUser(session.sub) |
@@ -1,2 +0,7 @@ | ||
import type { CookieOption, CookiesOptions, LoggerInstance } from "../types.js" | ||
import type { | ||
CookieOption, | ||
CookiesOptions, | ||
LoggerInstance, | ||
RequestInternal, | ||
} from "../types.js" | ||
@@ -8,3 +13,3 @@ // Uncomment to recalculate the estimated size | ||
// "Cookie estimated to be ", | ||
// serialize(`__Secure.next-auth.session-token.0`, "", { | ||
// serialize(`__Secure.authjs.session-token.0`, "", { | ||
// expires: new Date(), | ||
@@ -23,3 +28,3 @@ // httpOnly: true, | ||
// Based on commented out section above | ||
const ESTIMATED_EMPTY_COOKIE_SIZE = 163 | ||
const ESTIMATED_EMPTY_COOKIE_SIZE = 160 | ||
const CHUNK_SIZE = ALLOWED_COOKIE_SIZE - ESTIMATED_EMPTY_COOKIE_SIZE | ||
@@ -60,3 +65,3 @@ | ||
sessionToken: { | ||
name: `${cookiePrefix}next-auth.session-token`, | ||
name: `${cookiePrefix}authjs.session-token`, | ||
options: { | ||
@@ -70,3 +75,3 @@ httpOnly: true, | ||
callbackUrl: { | ||
name: `${cookiePrefix}next-auth.callback-url`, | ||
name: `${cookiePrefix}authjs.callback-url`, | ||
options: { | ||
@@ -82,3 +87,3 @@ httpOnly: true, | ||
// NB: The `__Host-` prefix is stricter than the `__Secure-` prefix. | ||
name: `${useSecureCookies ? "__Host-" : ""}next-auth.csrf-token`, | ||
name: `${useSecureCookies ? "__Host-" : ""}authjs.csrf-token`, | ||
options: { | ||
@@ -92,3 +97,3 @@ httpOnly: true, | ||
pkceCodeVerifier: { | ||
name: `${cookiePrefix}next-auth.pkce.code_verifier`, | ||
name: `${cookiePrefix}authjs.pkce.code_verifier`, | ||
options: { | ||
@@ -103,3 +108,3 @@ httpOnly: true, | ||
state: { | ||
name: `${cookiePrefix}next-auth.state`, | ||
name: `${cookiePrefix}authjs.state`, | ||
options: { | ||
@@ -114,3 +119,3 @@ httpOnly: true, | ||
nonce: { | ||
name: `${cookiePrefix}next-auth.nonce`, | ||
name: `${cookiePrefix}authjs.nonce`, | ||
options: { | ||
@@ -139,3 +144,3 @@ httpOnly: true, | ||
option: CookieOption, | ||
req: Partial<{ cookies: any; headers: any }>, | ||
cookies: RequestInternal["cookies"], | ||
logger: LoggerInstance | Console | ||
@@ -145,21 +150,9 @@ ) { | ||
this.#option = option | ||
if (!cookies) return | ||
const { cookies } = req | ||
const { name: cookieName } = option | ||
const { name: sessionCookiePrefix } = option | ||
if (typeof cookies?.getAll === "function") { | ||
// Next.js ^v13.0.1 (Edge Env) | ||
for (const { name, value } of cookies.getAll()) { | ||
if (name.startsWith(cookieName)) { | ||
this.#chunks[name] = value | ||
} | ||
} | ||
} else if (cookies instanceof Map) { | ||
for (const name of cookies.keys()) { | ||
if (name.startsWith(cookieName)) this.#chunks[name] = cookies.get(name) | ||
} | ||
} else { | ||
for (const name in cookies) { | ||
if (name.startsWith(cookieName)) this.#chunks[name] = cookies[name] | ||
} | ||
for (const [name, value] of Object.entries(cookies)) { | ||
if (!name.startsWith(sessionCookiePrefix) || !value) continue | ||
this.#chunks[name] = value | ||
} | ||
@@ -172,13 +165,13 @@ } | ||
*/ | ||
get value() { | ||
get value() { | ||
// Sort the chunks by their keys before joining | ||
const sortedKeys = Object.keys(this.#chunks).sort((a, b) => { | ||
const aSuffix = parseInt(a.split(".").pop() || "0"); | ||
const bSuffix = parseInt(b.split(".").pop() || "0"); | ||
return aSuffix - bSuffix; | ||
}); | ||
const aSuffix = parseInt(a.split(".").pop() || "0") | ||
const bSuffix = parseInt(b.split(".").pop() || "0") | ||
return aSuffix - bSuffix | ||
}) | ||
// Use the sorted keys to join the chunks in the correct order | ||
return sortedKeys.map(key => this.#chunks[key]).join(""); | ||
return sortedKeys.map((key) => this.#chunks[key]).join("") | ||
} | ||
@@ -185,0 +178,0 @@ |
@@ -39,3 +39,3 @@ import { UnknownAction } from "../errors.js" | ||
options.cookies.sessionToken, | ||
request, | ||
request.cookies, | ||
options.logger | ||
@@ -42,0 +42,0 @@ ) |
@@ -33,5 +33,6 @@ import * as jose from "jose" | ||
if (type === "state" && data) token.data = data | ||
const name = cookies[type].name | ||
return { | ||
name: cookies[type].name, | ||
value: await encode({ ...options.jwt, maxAge, token }), | ||
name, | ||
value: await encode({ ...options.jwt, maxAge, token, salt: name }), | ||
options: { ...cookies[type].options, expires }, | ||
@@ -79,2 +80,3 @@ } | ||
token: codeVerifier, | ||
salt: options.cookies.pkceCodeVerifier.name, | ||
}) | ||
@@ -161,2 +163,3 @@ | ||
token: state, | ||
salt: options.cookies.state.name, | ||
}) | ||
@@ -216,3 +219,7 @@ | ||
const value = await decode<CheckPayload>({ ...options.jwt, token: nonce }) | ||
const value = await decode<CheckPayload>({ | ||
...options.jwt, | ||
token: nonce, | ||
salt: options.cookies.nonce.name, | ||
}) | ||
@@ -219,0 +226,0 @@ if (!value?.value) |
@@ -89,3 +89,3 @@ import { OAuthProfileParseError } from "../errors.js" | ||
* Returns basic user profile from the userinfo response/`id_token` claims. | ||
* @see https://authjs.dev/reference/adapters#user | ||
* @see https://authjs.dev/reference/core/adapters#user | ||
* @see https://openid.net/specs/openid-connect-core-1_0.html#IDToken | ||
@@ -109,3 +109,3 @@ * @see https://openid.net/specs/openid-connect-core-1_0.html#UserInfo | ||
* @see https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse | ||
* @see https://authjs.dev/reference/adapters#account | ||
* @see https://authjs.dev/reference/core/adapters#account | ||
*/ | ||
@@ -112,0 +112,0 @@ const defaultAccount: AccountCallback = (account) => { |
@@ -144,4 +144,5 @@ import { | ||
} else { | ||
const salt = options.cookies.sessionToken.name | ||
// Encode token | ||
const newToken = await jwt.encode({ ...jwt, token }) | ||
const newToken = await jwt.encode({ ...jwt, token, salt }) | ||
@@ -256,4 +257,5 @@ // Set cookie expiry date | ||
} else { | ||
const salt = options.cookies.sessionToken.name | ||
// Encode token | ||
const newToken = await jwt.encode({ ...jwt, token }) | ||
const newToken = await jwt.encode({ ...jwt, token, salt }) | ||
@@ -354,4 +356,5 @@ // Set cookie expiry date | ||
} else { | ||
const salt = options.cookies.sessionToken.name | ||
// Encode token | ||
const newToken = await jwt.encode({ ...jwt, token }) | ||
const newToken = await jwt.encode({ ...jwt, token, salt }) | ||
@@ -358,0 +361,0 @@ // Set cookie expiry date |
@@ -37,9 +37,10 @@ import { JWTSessionError, SessionTokenError } from "../../errors.js" | ||
try { | ||
const decodedToken = await jwt.decode({ ...jwt, token: sessionToken }) | ||
const salt = options.cookies.sessionToken.name | ||
const payload = await jwt.decode({ ...jwt, token: sessionToken, salt }) | ||
if (!decodedToken) throw new Error("Invalid JWT") | ||
if (!payload) throw new Error("Invalid JWT") | ||
// @ts-expect-error | ||
const token = await callbacks.jwt({ | ||
token: decodedToken, | ||
token: payload, | ||
...(isUpdate && { trigger: "update" }), | ||
@@ -65,6 +66,3 @@ session: newSession, | ||
// Refresh JWT expiry by re-signing it, with an updated expiry date | ||
const newToken = await jwt.encode({ | ||
...jwt, | ||
token, | ||
}) | ||
const newToken = await jwt.encode({ ...jwt, token, salt }) | ||
@@ -71,0 +69,0 @@ // Set cookie, to also update expiry date on cookie |
@@ -24,3 +24,4 @@ import { SignOutError } from "../../errors.js" | ||
if (session.strategy === "jwt") { | ||
const token = await jwt.decode({ ...jwt, token: sessionToken }) | ||
const salt = options.cookies.sessionToken.name | ||
const token = await jwt.decode({ ...jwt, token: sessionToken, salt }) | ||
await events.signOut?.({ token }) | ||
@@ -27,0 +28,0 @@ } else { |
@@ -8,3 +8,3 @@ import { AuthError } from "../../errors.js" | ||
* | ||
* [Documentation](https://authjs.dev/reference/configuration/auth-config#logger) | ||
* [Documentation](https://authjs.dev/reference/core#authconfig#logger) | ||
*/ | ||
@@ -11,0 +11,0 @@ export interface LoggerInstance extends Record<string, Function> { |
@@ -194,3 +194,3 @@ /** | ||
* :::note | ||
* 42 returns a field on `Account` called `created_at` which is a number. See the [docs](https://api.intra.42.fr/apidoc/guides/getting_started#make-basic-requests). Make sure to add this field to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/adapters). | ||
* 42 returns a field on `Account` called `created_at` which is a number. See the [docs](https://api.intra.42.fr/apidoc/guides/getting_started#make-basic-requests). Make sure to add this field to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/core/adapters). | ||
* ::: | ||
@@ -197,0 +197,0 @@ * By default, Auth.js assumes that the 42School provider is |
@@ -118,4 +118,4 @@ /** | ||
* AppleProvider({ | ||
* clientId: process.env.GITHUB_ID, | ||
* clientSecret: process.env.GITHUB_SECRET, | ||
* clientId: process.env.APPLE_ID, | ||
* clientSecret: process.env.APPLE_SECRET, | ||
* }), | ||
@@ -122,0 +122,0 @@ * ], |
@@ -35,3 +35,3 @@ /** | ||
* #### Configuration | ||
* | ||
* | ||
* For OAuth 2.0 Flow: | ||
@@ -44,5 +44,5 @@ *```js | ||
* const response = await Auth(request, { | ||
* providers: [BoxyHQ({ | ||
* providers: [BoxyHQ({ | ||
* authorization: { params: { scope: "" } }, // This is needed for OAuth 2.0 flow, otherwise default to openid | ||
* clientId: BOXYHQ_SAML_CLIENT_ID, | ||
* clientId: BOXYHQ_SAML_CLIENT_ID, | ||
* clientSecret: BOXYHQ_SAML_CLIENT_SECRET, | ||
@@ -54,3 +54,3 @@ * issuer: BOXYHQ_SAML_ISSUER | ||
* For OIDC Flow: | ||
* | ||
* | ||
*```js | ||
@@ -62,7 +62,4 @@ * import Auth from "@auth/core" | ||
* const response = await Auth(request, { | ||
* providers: [BoxyHQ({ | ||
* id: "boxyhq-saml-oidc", | ||
* wellKnown: `http://localhost:5225/.well-known/openid-configuration`, | ||
* authorization: { params: { scope: "openid email" } }, | ||
* clientId: BOXYHQ_SAML_CLIENT_ID, | ||
* providers: [BoxyHQ({ | ||
* clientId: BOXYHQ_SAML_CLIENT_ID, | ||
* clientSecret: BOXYHQ_SAML_CLIENT_SECRET, | ||
@@ -69,0 +66,0 @@ * issuer: BOXYHQ_SAML_ISSUER |
@@ -76,3 +76,3 @@ /** | ||
return { | ||
id: "clickup", | ||
id: "click-up", | ||
name: "ClickUp", | ||
@@ -79,0 +79,0 @@ type: "oauth", |
@@ -71,14 +71,19 @@ import type { CommonProviderOptions } from "./index.js" | ||
* | ||
* :::warning **NOTE** | ||
* :::caution | ||
* The functionality provided for credentials-based authentication is intentionally limited to discourage the use of passwords due to the inherent security risks of the username-password model. | ||
* | ||
* The functionality provided for credentials based authentication is | ||
* **intentionally limited** to _discourage_ use of passwords | ||
* due to the _inherent security risks_ associated with them | ||
* and the _additional complexity_ associated | ||
* with supporting usernames and passwords. | ||
* OAuth providers spend significant amounts of money, time, and engineering effort to build: | ||
* | ||
* - abuse detection (bot-protection, rate-limiting) | ||
* - password management (password reset, credential stuffing, rotation) | ||
* - data security (encryption/salting, strength validation) | ||
* | ||
* and much more for authentication solutions. It is likely that your application would benefit from leveraging these battle-tested solutions rather than try to rebuild them from scratch. | ||
* | ||
* If you'd still like to build password-based authentication for your application despite these risks, Auth.js gives you full control to do so. | ||
* | ||
* ::: | ||
* | ||
* See the [callbacks documentation](/reference/configuration/auth-config#callbacks) for more information on how to interact with the token. For example, you can add additional information to the token by returning an object from the `jwt()` callback: | ||
* | ||
* | ||
* See the [callbacks documentation](/reference/core#authconfig#callbacks) for more information on how to interact with the token. For example, you can add additional information to the token by returning an object from the `jwt()` callback: | ||
* | ||
* ```js | ||
@@ -85,0 +90,0 @@ * callbacks: { |
@@ -90,3 +90,3 @@ /** | ||
return { | ||
id: "duende-identityserver6", | ||
id: "duende-identity-server6", | ||
name: "DuendeIdentityServer6", | ||
@@ -93,0 +93,0 @@ type: "oidc", |
@@ -98,3 +98,3 @@ import type { CommonProviderOptions } from "./index.js" | ||
* | ||
* [Normalizing the email address](https://authjs.dev/reference/core/providers_email#normalizing-the-email-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax) | ||
* [Normalizing the email address](https://authjs.dev/reference/core/providers/email#normalizing-the-email-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax) | ||
*/ | ||
@@ -211,3 +211,3 @@ normalizeIdentifier?: (identifier: string) => string | ||
* | ||
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/adapters) for storing the Email verification token. | ||
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/core/adapters) for storing the Email verification token. | ||
* | ||
@@ -214,0 +214,0 @@ * 5. You can now sign in with an email address at `/api/auth/signin`. |
@@ -9,3 +9,3 @@ /** | ||
* | ||
* @module providers/fushionauth | ||
* @module providers/fusionauth | ||
*/ | ||
@@ -12,0 +12,0 @@ import type { OAuthConfig, OAuthUserConfig } from "./oauth.js" |
@@ -19,10 +19,11 @@ /** | ||
exp: number | ||
family_name: string | ||
family_name?: string | ||
given_name: string | ||
hd: string | ||
hd?: string | ||
iat: number | ||
iss: string | ||
jti: string | ||
jti?: string | ||
locale?: string | ||
name: string | ||
nbf: number | ||
nbf?: number | ||
picture: string | ||
@@ -29,0 +30,0 @@ sub: string |
@@ -151,3 +151,3 @@ import type { Client } from "oauth4webapi" | ||
* | ||
* @see [Database Adapter: User model](https://authjs.dev/reference/adapters#user) | ||
* @see [Database Adapter: User model](https://authjs.dev/reference/core/adapters#user) | ||
*/ | ||
@@ -160,4 +160,4 @@ profile?: ProfileCallback<Profile> | ||
* :::note | ||
* You need to adjust your database's [Account model](https://authjs.dev/reference/adapters#account) to match the returned properties. | ||
* Check out the documentation of your [database adapter](https://authjs.dev/reference/adapters) for more information. | ||
* You need to adjust your database's [Account model](https://authjs.dev/reference/core/adapters#account) to match the returned properties. | ||
* Check out the documentation of your [database adapter](https://authjs.dev/reference/core/adapters) for more information. | ||
* ::: | ||
@@ -186,3 +186,3 @@ * | ||
* | ||
* @see [Database Adapter: Account model](https://authjs.dev/reference/adapters#account) | ||
* @see [Database Adapter: Account model](https://authjs.dev/reference/core/adapters#account) | ||
* @see https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse | ||
@@ -189,0 +189,0 @@ * @see https://www.ietf.org/rfc/rfc6749.html#section-5.1 |
@@ -9,3 +9,3 @@ /** | ||
* | ||
* @module providers/saleforce | ||
* @module providers/salesforce | ||
*/ | ||
@@ -12,0 +12,0 @@ import type { OAuthConfig, OAuthUserConfig } from "./index.js" |
@@ -11,3 +11,3 @@ /** | ||
*/ | ||
import { TokenSet } from "src/types.js" | ||
import { TokenSet } from "../types.js" | ||
import type { OAuthConfig, OAuthUserConfig } from "./index.js" | ||
@@ -14,0 +14,0 @@ |
@@ -151,3 +151,3 @@ /** | ||
* Twitter is currently the only built-in provider using the OAuth 1.0 spec. | ||
* This means that you won't receive an `access_token` or `refresh_token`, but an `oauth_token` and `oauth_token_secret` respectively. Remember to add these to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/adapters). | ||
* This means that you won't receive an `access_token` or `refresh_token`, but an `oauth_token` and `oauth_token_secret` respectively. Remember to add these to your database schema, in case if you are using an [Adapter](https://authjs.dev/reference/core/adapters). | ||
* | ||
@@ -154,0 +154,0 @@ * :::tip |
@@ -7,3 +7,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -85,3 +85,3 @@ * ``` | ||
* | ||
* [Documentation](https://authjs.dev/reference/configuration/auth-config#theme) | | ||
* [Documentation](https://authjs.dev/reference/core#authconfig#theme) | | ||
* [Pages](https://authjs.dev/guides/basics/pages) | ||
@@ -132,3 +132,3 @@ */ | ||
* | ||
* @see https://authjs.dev/reference/adapters#user | ||
* @see https://authjs.dev/reference/core/adapters#user | ||
*/ | ||
@@ -291,4 +291,4 @@ userId?: string | ||
* Resources: | ||
* - [Credentials Provider](https://authjs.dev/reference/core/providers_credentials) | ||
* - [User database model](https://authjs.dev/reference/adapters#user) | ||
* - [Credentials Provider](https://authjs.dev/reference/core/providers/credentials) | ||
* - [User database model](https://authjs.dev/reference/core/adapters#user) | ||
*/ | ||
@@ -328,3 +328,3 @@ user: User | AdapterUser | ||
/** [Documentation](https://authjs.dev/reference/configuration/auth-config#cookies) */ | ||
/** [Documentation](https://authjs.dev/reference/core#cookies) */ | ||
export interface CookieOption { | ||
@@ -335,3 +335,3 @@ name: string | ||
/** [Documentation](https://authjs.dev/reference/configuration/auth-config#cookies) */ | ||
/** [Documentation](https://authjs.dev/reference/core#cookies) */ | ||
export interface CookiesOptions { | ||
@@ -445,5 +445,5 @@ sessionToken: CookieOption | ||
* | ||
* [`useSession`](https://authjs.dev/reference/react/#usesession) | | ||
* [`useSession`](https://authjs.devreference/nextjs/react/#usesession) | | ||
* [`getSession`](https://authjs.dev/reference/utilities#getsession) | | ||
* [`SessionProvider`](https://authjs.dev/reference/react#sessionprovider) | | ||
* [`SessionProvider`](https://authjs.devreference/nextjs/react#sessionprovider) | | ||
* [`session` callback](https://authjs.dev/guides/basics/callbacks#jwt-callback) | ||
@@ -493,4 +493,4 @@ */ | ||
* - **`"callback"`**: | ||
* - **`GET`**: Handles the callback from an [OAuth provider](https://authjs.dev/reference/core/providers_oauth). | ||
* - **`POST`**: Handles the callback from a [Credentials provider](https://authjs.dev/reference/core/providers_credentials). | ||
* - **`GET`**: Handles the callback from an [OAuth provider](https://authjs.dev/reference/core/providers/oauth). | ||
* - **`POST`**: Handles the callback from a [Credentials provider](https://authjs.dev/reference/core/providers/credentials). | ||
* - **`"csrf"`**: Returns the raw CSRF token, which is saved in a cookie (encrypted). | ||
@@ -497,0 +497,0 @@ * It is used for CSRF protection, implementing the [double submit cookie](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie) technique. |
@@ -7,3 +7,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -70,3 +70,3 @@ * ``` | ||
* | ||
* [Documentation](https://authjs.dev/reference/configuration/auth-config#theme) | | ||
* [Documentation](https://authjs.dev/reference/core#authconfig#theme) | | ||
* [Pages](https://authjs.dev/guides/basics/pages) | ||
@@ -113,3 +113,3 @@ */ | ||
* | ||
* @see https://authjs.dev/reference/adapters#user | ||
* @see https://authjs.dev/reference/core/adapters#user | ||
*/ | ||
@@ -267,4 +267,4 @@ userId?: string; | ||
* Resources: | ||
* - [Credentials Provider](https://authjs.dev/reference/core/providers_credentials) | ||
* - [User database model](https://authjs.dev/reference/adapters#user) | ||
* - [Credentials Provider](https://authjs.dev/reference/core/providers/credentials) | ||
* - [User database model](https://authjs.dev/reference/core/adapters#user) | ||
*/ | ||
@@ -303,3 +303,3 @@ user: User | AdapterUser; | ||
} | ||
/** [Documentation](https://authjs.dev/reference/configuration/auth-config#cookies) */ | ||
/** [Documentation](https://authjs.dev/reference/core#cookies) */ | ||
export interface CookieOption { | ||
@@ -309,3 +309,3 @@ name: string; | ||
} | ||
/** [Documentation](https://authjs.dev/reference/configuration/auth-config#cookies) */ | ||
/** [Documentation](https://authjs.dev/reference/core#cookies) */ | ||
export interface CookiesOptions { | ||
@@ -408,5 +408,5 @@ sessionToken: CookieOption; | ||
* | ||
* [`useSession`](https://authjs.dev/reference/react/#usesession) | | ||
* [`useSession`](https://authjs.devreference/nextjs/react/#usesession) | | ||
* [`getSession`](https://authjs.dev/reference/utilities#getsession) | | ||
* [`SessionProvider`](https://authjs.dev/reference/react#sessionprovider) | | ||
* [`SessionProvider`](https://authjs.devreference/nextjs/react#sessionprovider) | | ||
* [`session` callback](https://authjs.dev/guides/basics/callbacks#jwt-callback) | ||
@@ -438,4 +438,4 @@ */ | ||
* - **`"callback"`**: | ||
* - **`GET`**: Handles the callback from an [OAuth provider](https://authjs.dev/reference/core/providers_oauth). | ||
* - **`POST`**: Handles the callback from a [Credentials provider](https://authjs.dev/reference/core/providers_credentials). | ||
* - **`GET`**: Handles the callback from an [OAuth provider](https://authjs.dev/reference/core/providers/oauth). | ||
* - **`POST`**: Handles the callback from a [Credentials provider](https://authjs.dev/reference/core/providers/credentials). | ||
* - **`"csrf"`**: Returns the raw CSRF token, which is saved in a cookie (encrypted). | ||
@@ -442,0 +442,0 @@ * It is used for CSRF protection, implementing the [double submit cookie](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie) technique. |
@@ -7,3 +7,3 @@ /** | ||
* | ||
* ```bash npm2yarn2pnpm | ||
* ```bash npm2yarn | ||
* npm install @auth/core | ||
@@ -10,0 +10,0 @@ * ``` |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
1352300
7
34376
1
+ Addedjose@5.9.6(transitive)
- Removedjose@4.15.9(transitive)
Updated@panva/hkdf@^1.1.1
Updatedjose@^5.1.0
Updatedoauth4webapi@^2.3.0