You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

@auth/core

Package Overview
Dependencies
7
Maintainers
2
Versions
90
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.23.0 to 0.24.0

lib/utils/parse-url.d.ts

11

errors.d.ts

@@ -188,7 +188,7 @@ type ErrorOptions = Error | Record<string, unknown>;

/**
* Auth.js requires a secret to be set, but none was not found. This is used to encrypt cookies, JWTs and other sensitive data.
* Auth.js requires a secret or multiple secrets to be set, but none was not found. This is used to encrypt cookies, JWTs and other sensitive data.
*
* :::note
* If you are using a framework like Next.js, we try to automatically infer the secret from the `AUTH_SECRET` environment variable.
* Alternatively, you can also explicitly set the [`AuthConfig.secret`](https://authjs.dev/reference/core#secret).
* If you are using a framework like Next.js, we try to automatically infer the secret from the `AUTH_SECRET`, `AUTH_SECRET_1`, etc. environment variables.
* Alternatively, you can also explicitly set the [`AuthConfig.secret`](https://authjs.dev/reference/core#secret) option.
* :::

@@ -198,6 +198,3 @@ *

* :::tip
* You can generate a good secret value:
* - On Unix systems: type `openssl rand -hex 32` in the terminal
* - Or generate one [online](https://generate-secret.vercel.app/32)
*
* To generate a random string, you can use the Auth.js CLI: `npx auth secret`
* :::

@@ -204,0 +201,0 @@ */

@@ -204,7 +204,7 @@ /**

/**
* Auth.js requires a secret to be set, but none was not found. This is used to encrypt cookies, JWTs and other sensitive data.
* Auth.js requires a secret or multiple secrets to be set, but none was not found. This is used to encrypt cookies, JWTs and other sensitive data.
*
* :::note
* If you are using a framework like Next.js, we try to automatically infer the secret from the `AUTH_SECRET` environment variable.
* Alternatively, you can also explicitly set the [`AuthConfig.secret`](https://authjs.dev/reference/core#secret).
* If you are using a framework like Next.js, we try to automatically infer the secret from the `AUTH_SECRET`, `AUTH_SECRET_1`, etc. environment variables.
* Alternatively, you can also explicitly set the [`AuthConfig.secret`](https://authjs.dev/reference/core#secret) option.
* :::

@@ -214,6 +214,3 @@ *

* :::tip
* You can generate a good secret value:
* - On Unix systems: type `openssl rand -hex 32` in the terminal
* - Or generate one [online](https://generate-secret.vercel.app/32)
*
* To generate a random string, you can use the Auth.js CLI: `npx auth secret`
* :::

@@ -220,0 +217,0 @@ */

@@ -73,8 +73,12 @@ /**

* A random string used to hash tokens, sign cookies and generate cryptographic keys.
* To generate a random string, you can use the following command:
*
* - On Unix systems, type `openssl rand -hex 32` in the terminal
* - Or generate one [online](https://generate-secret.vercel.app/32)
* To generate a random string, you can use the Auth.js CLI: `npx auth secret`
*
* @note
* You can also pass an array of secrets, in which case the first secret that successfully
* decrypts the JWT will be used. This is useful for rotating secrets without invalidating existing sessions.
* The newer secret should be added to the start of the array, which will be used for all new sessions.
*
*/
secret?: string;
secret?: string | string[];
/**

@@ -81,0 +85,0 @@ * Configure your session like if you want to use JWT or a database,

@@ -96,3 +96,3 @@ /**

/** Used in combination with `salt`, to derive the encryption secret for JWTs. */
secret: string;
secret: string | string[];
/** The JWT payload. */

@@ -104,4 +104,11 @@ token?: Payload;

salt: string;
/** Used in combination with `salt`, to derive the encryption secret for JWTs. */
secret: string;
/**
* Used in combination with `salt`, to derive the encryption secret for JWTs.
*
* @note
* You can also pass an array of secrets, in which case the first secret that successfully
* decrypts the JWT will be used. This is useful for rotating secrets without invalidating existing sessions.
* The newer secret should be added to the start of the array, which will be used for all new sessions.
*/
secret: string | string[];
/** The Auth.js issued JWT to be decoded */

@@ -108,0 +115,0 @@ token?: string;

@@ -39,3 +39,3 @@ /**

import { hkdf } from "@panva/hkdf";
import { EncryptJWT, jwtDecrypt } from "jose";
import { EncryptJWT, base64url, calculateJwkThumbprint, jwtDecrypt } from "jose";
import { SessionStore } from "./lib/utils/cookie.js";

@@ -51,6 +51,8 @@ import { MissingSecret } from "./errors.js";

const { token = {}, secret, maxAge = DEFAULT_MAX_AGE, salt } = params;
const encryptionSecret = await getDerivedEncryptionKey(enc, secret, salt);
const secrets = Array.isArray(secret) ? secret : [secret];
const encryptionSecret = await getDerivedEncryptionKey(enc, secrets[0], salt);
const thumbprint = await calculateJwkThumbprint({ kty: "oct", k: base64url.encode(encryptionSecret) }, `sha${encryptionSecret.byteLength << 3}`);
// @ts-expect-error `jose` allows any object as payload.
return await new EncryptJWT(token)
.setProtectedHeader({ alg, enc })
.setProtectedHeader({ alg, enc, kid: thumbprint })
.setIssuedAt()

@@ -64,8 +66,19 @@ .setExpirationTime(now() + maxAge)

const { token, secret, salt } = params;
const secrets = Array.isArray(secret) ? secret : [secret];
if (!token)
return null;
const { payload } = await jwtDecrypt(token, async ({ enc }) => await getDerivedEncryptionKey(enc, secret, salt), {
const { payload } = await jwtDecrypt(token, async ({ kid, enc }) => {
for (const secret of secrets) {
const encryptionSecret = await getDerivedEncryptionKey(enc, secret, salt);
if (kid === undefined)
return encryptionSecret;
const thumbprint = await calculateJwkThumbprint({ kty: "oct", k: base64url.encode(encryptionSecret) }, `sha${encryptionSecret.byteLength << 3}`);
if (kid === thumbprint)
return encryptionSecret;
}
throw new Error("no matching decryption secret");
}, {
clockTolerance: 15,
keyManagementAlgorithms: [alg],
contentEncryptionAlgorithms: [enc, "A256GCM"]
contentEncryptionAlgorithms: [enc, "A256GCM"],
});

@@ -72,0 +85,0 @@ return payload;

@@ -33,3 +33,3 @@ import * as checks from "./checks.js";

as = {
issuer: provider.issuer ?? "https://authjs.dev",
issuer: provider.issuer ?? "https://authjs.dev", // TODO: review fallback issuer
token_endpoint: token?.url.toString(),

@@ -36,0 +36,0 @@ userinfo_endpoint: userinfo?.url.toString(),

@@ -86,6 +86,4 @@ import * as jwt from "../jwt.js";

jwt: {
// Asserted in assert.ts
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
secret: authOptions.secret,
maxAge: authOptions.session?.maxAge ?? maxAge,
secret: authOptions.secret, // Asserted in assert.ts
maxAge: authOptions.session?.maxAge ?? maxAge, // default to same as `session.maxAge`
encode: jwt.encode,

@@ -92,0 +90,0 @@ decode: jwt.decode,

{
"name": "@auth/core",
"version": "0.23.0",
"version": "0.24.0",
"description": "Authentication for the Web.",

@@ -33,4 +33,3 @@ "keywords": [

"providers",
"src",
"!vitest.config.js"
"src"
],

@@ -67,4 +66,4 @@ "exports": {

"@panva/hkdf": "^1.1.1",
"@types/cookie": "0.6.0",
"cookie": "0.6.0",
"@types/cookie": "0.6.0",
"jose": "^5.1.3",

@@ -89,5 +88,3 @@ "oauth4webapi": "^2.4.0",

"postcss": "8.4.19",
"postcss-nested": "6.0.0",
"vite": "^5.0.12",
"vitest": "^1.2.1"
"postcss-nested": "6.0.0"
},

@@ -99,5 +96,5 @@ "scripts": {

"dev": "pnpm css && pnpm providers && tsc -w",
"test": "vitest",
"test": "vitest -c ../utils/vitest.config.ts",
"providers": "node scripts/generate-providers"
}
}

@@ -82,3 +82,3 @@ /**

name: profile.name,
email: null,
email: null, // trakt does not provide user emails
image: profile.images.avatar.full, // trakt does not allow hotlinking

@@ -85,0 +85,0 @@ };

@@ -261,7 +261,7 @@ type ErrorOptions = Error | Record<string, unknown>

/**
* Auth.js requires a secret to be set, but none was not found. This is used to encrypt cookies, JWTs and other sensitive data.
* Auth.js requires a secret or multiple secrets to be set, but none was not found. This is used to encrypt cookies, JWTs and other sensitive data.
*
* :::note
* If you are using a framework like Next.js, we try to automatically infer the secret from the `AUTH_SECRET` environment variable.
* Alternatively, you can also explicitly set the [`AuthConfig.secret`](https://authjs.dev/reference/core#secret).
* If you are using a framework like Next.js, we try to automatically infer the secret from the `AUTH_SECRET`, `AUTH_SECRET_1`, etc. environment variables.
* Alternatively, you can also explicitly set the [`AuthConfig.secret`](https://authjs.dev/reference/core#secret) option.
* :::

@@ -271,6 +271,3 @@ *

* :::tip
* You can generate a good secret value:
* - On Unix systems: type `openssl rand -hex 32` in the terminal
* - Or generate one [online](https://generate-secret.vercel.app/32)
*
* To generate a random string, you can use the Auth.js CLI: `npx auth secret`
* :::

@@ -277,0 +274,0 @@ */

@@ -214,8 +214,12 @@ /**

* A random string used to hash tokens, sign cookies and generate cryptographic keys.
* To generate a random string, you can use the following command:
*
* - On Unix systems, type `openssl rand -hex 32` in the terminal
* - Or generate one [online](https://generate-secret.vercel.app/32)
* To generate a random string, you can use the Auth.js CLI: `npx auth secret`
*
* @note
* You can also pass an array of secrets, in which case the first secret that successfully
* decrypts the JWT will be used. This is useful for rotating secrets without invalidating existing sessions.
* The newer secret should be added to the start of the array, which will be used for all new sessions.
*
*/
secret?: string
secret?: string | string[]
/**

@@ -222,0 +226,0 @@ * Configure your session like if you want to use JWT or a database,

@@ -40,3 +40,3 @@ /**

import { hkdf } from "@panva/hkdf"
import { EncryptJWT, jwtDecrypt } from "jose"
import { EncryptJWT, base64url, calculateJwkThumbprint, jwtDecrypt } from "jose"
import { SessionStore } from "./lib/utils/cookie.js"

@@ -54,2 +54,3 @@ import { Awaitable } from "./types.js"

const enc = "A256CBC-HS512"
type Digest = Parameters<typeof calculateJwkThumbprint>[1]

@@ -59,6 +60,12 @@ /** Issues a JWT. By default, the JWT is encrypted using "A256CBC-HS512". */

const { token = {}, secret, maxAge = DEFAULT_MAX_AGE, salt } = params
const encryptionSecret = await getDerivedEncryptionKey(enc, secret, salt)
const secrets = Array.isArray(secret) ? secret : [secret]
const encryptionSecret = await getDerivedEncryptionKey(enc, secrets[0], salt)
const thumbprint = await calculateJwkThumbprint(
{ kty: "oct", k: base64url.encode(encryptionSecret) },
`sha${encryptionSecret.byteLength << 3}` as Digest
)
// @ts-expect-error `jose` allows any object as payload.
return await new EncryptJWT(token)
.setProtectedHeader({ alg, enc })
.setProtectedHeader({ alg, enc, kid: thumbprint })
.setIssuedAt()

@@ -75,10 +82,28 @@ .setExpirationTime(now() + maxAge)

const { token, secret, salt } = params
const secrets = Array.isArray(secret) ? secret : [secret]
if (!token) return null
const { payload } = await jwtDecrypt(
token,
async ({ enc }) => await getDerivedEncryptionKey(enc, secret, salt),
async ({ kid, enc }) => {
for (const secret of secrets) {
const encryptionSecret = await getDerivedEncryptionKey(
enc,
secret,
salt
)
if (kid === undefined) return encryptionSecret
const thumbprint = await calculateJwkThumbprint(
{ kty: "oct", k: base64url.encode(encryptionSecret) },
`sha${encryptionSecret.byteLength << 3}` as Digest
)
if (kid === thumbprint) return encryptionSecret
}
throw new Error("no matching decryption secret")
},
{
clockTolerance: 15,
keyManagementAlgorithms: [alg],
contentEncryptionAlgorithms: [enc, "A256GCM"]
contentEncryptionAlgorithms: [enc, "A256GCM"],
}

@@ -218,3 +243,3 @@ )

/** Used in combination with `salt`, to derive the encryption secret for JWTs. */
secret: string
secret: string | string[]
/** The JWT payload. */

@@ -227,4 +252,11 @@ token?: Payload

salt: string
/** Used in combination with `salt`, to derive the encryption secret for JWTs. */
secret: string
/**
* Used in combination with `salt`, to derive the encryption secret for JWTs.
*
* @note
* You can also pass an array of secrets, in which case the first secret that successfully
* decrypts the JWT will be used. This is useful for rotating secrets without invalidating existing sessions.
* The newer secret should be added to the start of the array, which will be used for all new sessions.
*/
secret: string | string[]
/** The Auth.js issued JWT to be decoded */

@@ -237,5 +269,7 @@ token?: string

* The secret used to encode/decode the Auth.js issued JWT.
* It can be an array of secrets, in which case the first secret that successfully
* decrypts the JWT will be used. This is useful for rotating secrets without invalidating existing sessions.
* @internal
*/
secret: string
secret: string | string[]
/**

@@ -242,0 +276,0 @@ * The maximum age of the Auth.js issued JWT in seconds.

@@ -134,5 +134,3 @@ import * as jwt from "../jwt.js"

jwt: {
// Asserted in assert.ts
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
secret: authOptions.secret!,
secret: authOptions.secret!, // Asserted in assert.ts
maxAge: authOptions.session?.maxAge ?? maxAge, // default to same as `session.maxAge`

@@ -139,0 +137,0 @@ encode: jwt.encode,

@@ -556,3 +556,3 @@ /**

csrfTokenVerified?: boolean
secret: string
secret: string | string[]
theme: Theme

@@ -559,0 +559,0 @@ debug: boolean

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc