diff --git a/apps/dashboard/src/lib/auth/index.ts b/apps/dashboard/src/lib/auth/index.ts index 3f129c53c..1782fc1d6 100644 --- a/apps/dashboard/src/lib/auth/index.ts +++ b/apps/dashboard/src/lib/auth/index.ts @@ -8,6 +8,7 @@ import { headers } from "next/headers"; import { cache } from "react"; import { adapter } from "./adapter"; +import { logger } from "./logger"; import { GitHubProvider, GoogleProvider, @@ -51,6 +52,7 @@ const { } = NextAuth({ // debug: true, adapter, + logger, providers: [ GitHubProvider, GoogleProvider, diff --git a/apps/dashboard/src/lib/auth/logger.ts b/apps/dashboard/src/lib/auth/logger.ts new file mode 100644 index 000000000..1d4291b3d --- /dev/null +++ b/apps/dashboard/src/lib/auth/logger.ts @@ -0,0 +1,27 @@ +import type { LoggerInstance } from "@auth/core/types"; +// Import from next-auth, not @auth/core: guarantees the same class next-auth +// throws, even if the catalog and next-auth pin different @auth/core versions. +import { AuthError } from "next-auth"; + +/** + * Auth.js' default logger, minus `UnknownAction`: scanners probing + * `/api/auth/` already get a 400, and each probe would otherwise + * reach Sentry as a new issue via captureConsoleIntegration. + */ +export const logger: Partial = { + error(error) { + if (error instanceof AuthError && error.type === "UnknownAction") return; + + const name = error instanceof AuthError ? error.type : error.name; + console.error(`[auth][error] ${name}: ${error.message}`); + + const cause = error.cause; + if (cause && typeof cause === "object" && "err" in cause) { + const { err, ...data } = cause as { err: unknown }; + if (err instanceof Error) console.error("[auth][cause]:", err.stack); + console.error("[auth][details]:", JSON.stringify(data, null, 2)); + } else if (error.stack) { + console.error(error.stack.replace(/.*/, "").substring(1)); + } + }, +}; diff --git a/apps/status-page/src/lib/auth/index.ts b/apps/status-page/src/lib/auth/index.ts index 80fad5f04..eef4f7b90 100644 --- a/apps/status-page/src/lib/auth/index.ts +++ b/apps/status-page/src/lib/auth/index.ts @@ -7,6 +7,7 @@ import { headers } from "next/headers"; import { getValidCustomDomain } from "../domain"; import { getQueryClient, trpc } from "../trpc/server"; import { adapter } from "./adapter"; +import { logger } from "./logger"; import { ResendProvider } from "./providers"; export type { DefaultSession }; @@ -14,6 +15,7 @@ export type { DefaultSession }; export const { handlers, signIn, signOut, auth } = NextAuth({ debug: process.env.NODE_ENV === "development", adapter, + logger, providers: [ResendProvider], callbacks: { async signIn(params) { diff --git a/apps/status-page/src/lib/auth/logger.ts b/apps/status-page/src/lib/auth/logger.ts new file mode 100644 index 000000000..1d4291b3d --- /dev/null +++ b/apps/status-page/src/lib/auth/logger.ts @@ -0,0 +1,27 @@ +import type { LoggerInstance } from "@auth/core/types"; +// Import from next-auth, not @auth/core: guarantees the same class next-auth +// throws, even if the catalog and next-auth pin different @auth/core versions. +import { AuthError } from "next-auth"; + +/** + * Auth.js' default logger, minus `UnknownAction`: scanners probing + * `/api/auth/` already get a 400, and each probe would otherwise + * reach Sentry as a new issue via captureConsoleIntegration. + */ +export const logger: Partial = { + error(error) { + if (error instanceof AuthError && error.type === "UnknownAction") return; + + const name = error instanceof AuthError ? error.type : error.name; + console.error(`[auth][error] ${name}: ${error.message}`); + + const cause = error.cause; + if (cause && typeof cause === "object" && "err" in cause) { + const { err, ...data } = cause as { err: unknown }; + if (err instanceof Error) console.error("[auth][cause]:", err.stack); + console.error("[auth][details]:", JSON.stringify(data, null, 2)); + } else if (error.stack) { + console.error(error.stack.replace(/.*/, "").substring(1)); + } + }, +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24599a9ae..e1339ea40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,8 +16,8 @@ catalogs: specifier: 3.0.190 version: 3.0.190 '@auth/core': - specifier: 0.40.0 - version: 0.40.0 + specifier: 0.41.2 + version: 0.41.2 '@auth/drizzle-adapter': specifier: 1.11.2 version: 1.11.2 @@ -559,7 +559,7 @@ importers: version: 3.0.190(react@19.2.6)(zod@4.1.13) '@auth/core': specifier: 'catalog:' - version: 0.40.0 + version: 0.41.2 '@auth/drizzle-adapter': specifier: 'catalog:' version: 1.11.2 @@ -1081,7 +1081,7 @@ importers: dependencies: '@auth/core': specifier: 'catalog:' - version: 0.40.0 + version: 0.41.2 '@auth/drizzle-adapter': specifier: 'catalog:' version: 1.11.2 @@ -1313,7 +1313,7 @@ importers: dependencies: '@auth/core': specifier: 'catalog:' - version: 0.40.0 + version: 0.41.2 '@auth/drizzle-adapter': specifier: 'catalog:' version: 1.11.2 @@ -3193,20 +3193,6 @@ packages: peerDependencies: zod: ^4.0.0 - '@auth/core@0.40.0': - resolution: {integrity: sha512-n53uJE0RH5SqZ7N1xZoMKekbHfQgjd0sAEyUbE+IYJnmuQkbvuZnXItCU7d+i7Fj8VGOgqvNO7Mw4YfBTlZeQw==} - peerDependencies: - '@simplewebauthn/browser': ^9.0.1 - '@simplewebauthn/server': ^9.0.2 - nodemailer: ^6.8.0 - peerDependenciesMeta: - '@simplewebauthn/browser': - optional: true - '@simplewebauthn/server': - optional: true - nodemailer: - optional: true - '@auth/core@0.41.2': resolution: {integrity: sha512-Hx5MNBxN2fJTbJKGUKAA0wca43D0Akl3TvufY54Gn8lop7F+34vU1zA1pn0vQfIoVuLIrpfc2nkyjwIaPJMW7w==} peerDependencies: @@ -11936,14 +11922,6 @@ snapshots: openapi3-ts: 4.5.0 zod: 4.1.13 - '@auth/core@0.40.0': - dependencies: - '@panva/hkdf': 1.2.1 - jose: 6.1.3 - oauth4webapi: 3.8.3 - preact: 10.24.3 - preact-render-to-string: 6.5.11(preact@10.24.3) - '@auth/core@0.41.2': dependencies: '@panva/hkdf': 1.2.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9f4d8f5fa..cc969f6cf 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -32,7 +32,7 @@ catalog: "@astrojs/sitemap": 3.7.2 "@astrojs/starlight": 0.37.7 "@astrojs/starlight-tailwind": 4.0.2 - "@auth/core": 0.40.0 + "@auth/core": 0.41.2 "@auth/drizzle-adapter": 1.11.2 "@aws-sdk/client-s3": 3.1051.0 "@bufbuild/buf": 1.69.0