Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import type { Adapter, AdapterSession, AdapterUser } from "./adapters.js"
import type {
Account,
AuthAction,
AuthConfigInternal,
Awaitable,
CookiesOptions,
DefaultSession,
Expand Down Expand Up @@ -102,19 +103,22 @@ export async function Auth(
request: Request,
config: AuthConfig
): Promise<Response | ResponseInternal> {
const logger = setLogger(config)
const configWithLogger: AuthConfigInternal = {
...config,
logger: setLogger(config),
}

const internalRequest = await toInternalRequest(request, config)
const internalRequest = await toInternalRequest(request, configWithLogger)
// There was an error parsing the request
if (!internalRequest) return Response.json(`Bad request.`, { status: 400 })

const warningsOrError = assertConfig(internalRequest, config)

if (Array.isArray(warningsOrError)) {
warningsOrError.forEach(logger.warn)
warningsOrError.forEach(configWithLogger.logger.warn)
} else if (warningsOrError) {
// If there's an error in the user config, bail out early
logger.error(warningsOrError)
configWithLogger.logger.error(warningsOrError)
const htmlPages = new Set<AuthAction>([
"signin",
"signout",
Expand Down Expand Up @@ -143,7 +147,7 @@ export async function Auth(
// Either there was no error page configured or the configured one contains infinite redirects
if (!pages?.error || authOnErrorPage) {
if (authOnErrorPage) {
logger.error(
configWithLogger.logger.error(
new ErrorPageLoop(
`The error page ${pages?.error} should not require authentication`
)
Expand All @@ -161,7 +165,10 @@ export async function Auth(
const isRedirect = request.headers?.has("X-Auth-Return-Redirect")
const isRaw = config.raw === raw
try {
const internalResponse = await AuthInternal(internalRequest, config)
const internalResponse = await AuthInternal(
internalRequest,
configWithLogger
)
if (isRaw) return internalResponse

const response = toResponse(internalResponse)
Expand All @@ -172,7 +179,7 @@ export async function Auth(
return Response.json({ url }, { headers: response.headers })
} catch (e) {
const error = e as Error
logger.error(error)
configWithLogger.logger.error(error)

const isAuthError = error instanceof AuthError
if (isAuthError && isRaw && !isRedirect) throw error
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import { init } from "./init.js"
import renderPage from "./pages/index.js"
import * as actions from "./actions/index.js"
import { validateCSRF } from "./actions/callback/oauth/csrf-token.js"

import type { RequestInternal, ResponseInternal } from "../types.js"
import type { AuthConfig } from "../index.js"
import type {
AuthConfigInternal,
RequestInternal,
ResponseInternal,
} from "../types.js"
import { skipCSRFCheck } from "./symbols.js"

export { customFetch, raw, skipCSRFCheck } from "./symbols.js"

/** @internal */
export async function AuthInternal(
request: RequestInternal,
authOptions: AuthConfig
authOptions: AuthConfigInternal
): Promise<ResponseInternal> {
const { action, providerId, error, method } = request

Expand Down
17 changes: 10 additions & 7 deletions packages/core/src/lib/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ import { createCSRFToken } from "./actions/callback/oauth/csrf-token.js"

import { AdapterError, EventError } from "../errors.js"
import parseProviders from "./utils/providers.js"
import { setLogger, type LoggerInstance } from "./utils/logger.js"
import type { LoggerInstance } from "./utils/logger.js"
import { merge } from "./utils/merge.js"

import type { InternalOptions, RequestInternal } from "../types.js"
import type {
AuthConfigInternal,
InternalOptions,
RequestInternal,
} from "../types.js"
import type { AuthConfig } from "../index.js"

interface InitParams {
url: URL
authOptions: AuthConfig
authOptions: AuthConfigInternal
providerId?: string
action: InternalOptions["action"]
/** Callback URL value extracted from the incoming request. */
Expand Down Expand Up @@ -65,7 +69,6 @@ export async function init({
options: InternalOptions
cookies: cookie.Cookie[]
}> {
const logger = setLogger(config)
const { providers, provider } = parseProviders({ url, providerId, config })

const maxAge = 30 * 24 * 60 * 60 // Sessions expire after 30 days of being idle by default
Expand Down Expand Up @@ -129,11 +132,11 @@ export async function init({
...config.jwt,
},
// Event messages
events: eventsErrorHandler(config.events ?? {}, logger),
adapter: adapterErrorHandler(config.adapter, logger),
events: eventsErrorHandler(config.events ?? {}, config.logger),
adapter: adapterErrorHandler(config.adapter, config.logger),
// Callback functions
callbacks: { ...defaultCallbacks, ...config.callbacks },
logger,
logger: config.logger,
callbackUrl: url.origin,
isOnRedirectProxy,
experimental: {
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/lib/utils/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,13 @@ export function setLogger(
...defaultLogger,
}

// Turn off debug logging if `debug` isn't set to `true`
if (!config.debug) newLogger.debug = () => {}

if (config.logger?.error) newLogger.error = config.logger.error
if (config.logger?.warn) newLogger.warn = config.logger.warn
if (config.logger?.debug) newLogger.debug = config.logger.debug

// Disable debug logging if `debug` is not explicitly set to `true`, even if a custom logger is provided
if (!config.debug) newLogger.debug = () => {}
if (config.debug && config.logger?.debug)
newLogger.debug = config.logger.debug

config.logger ??= newLogger
return newLogger
Expand Down
11 changes: 4 additions & 7 deletions packages/core/src/lib/utils/web.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import * as cookie from "../vendored/cookie.js"
import { UnknownAction } from "../../errors.js"
import { setLogger } from "./logger.js"

import type {
AuthAction,
AuthConfigInternal,
RequestInternal,
ResponseInternal,
} from "../../types.js"
import { isAuthAction } from "./actions.js"
import type { AuthConfig } from "../../index.js"

const { parse: parseCookie, serialize: serializeCookie } = cookie

Expand All @@ -26,7 +24,7 @@ async function getBody(req: Request): Promise<Record<string, any> | undefined> {

export async function toInternalRequest(
req: Request,
config: AuthConfig
config: AuthConfigInternal
): Promise<RequestInternal | undefined> {
try {
if (req.method !== "GET" && req.method !== "POST")
Expand Down Expand Up @@ -54,9 +52,8 @@ export async function toInternalRequest(
query: Object.fromEntries(url.searchParams),
}
} catch (e) {
const logger = setLogger(config)
logger.error(e as Error)
logger.debug("request", req)
config.logger.error(e as Error)
config.logger.debug("request", req)
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,7 @@ export interface InternalOptions<TProviderType = ProviderType> {
experimental: NonNullable<AuthConfig["experimental"]>
basePath: string
}

export type AuthConfigInternal = Omit<AuthConfig, "logger"> & {
logger: LoggerInstance
}
56 changes: 56 additions & 0 deletions packages/core/test/logger.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { describe, it, expect, vi } from "vitest"
import { setLogger } from "../src/lib/utils/logger"
import type { AuthConfig } from "../src/types.ts"

describe("setLogger", () => {
it("should return default logger if no custom logger is provided", () => {
const logger = setLogger({})
expect(logger.error).toBeInstanceOf(Function)
expect(logger.debug).toBeInstanceOf(Function)
expect(logger.warn).toBeInstanceOf(Function)
})

it("should override error and warn with custom logger", () => {
const customError = vi.fn()
const customWarn = vi.fn()
const logger = setLogger({
logger: {
error: customError,
warn: customWarn,
},
})
expect(logger.error).toBe(customError)
expect(logger.warn).toBe(customWarn)
expect(logger.debug).toBeInstanceOf(Function)
})

it("should override debug only if debug is true", () => {
const customDebug = vi.fn()
const logger1 = setLogger({
logger: {
debug: customDebug,
},
debug: true,
})
expect(logger1.debug).toBe(customDebug)
expect(logger1.error).toBeInstanceOf(Function)
expect(logger1.warn).toBeInstanceOf(Function)

const logger2 = setLogger({
logger: {
debug: customDebug,
},
debug: false,
})
expect(logger2.debug).not.toBe(customDebug)
expect(logger2.debug).toBeInstanceOf(Function)
expect(logger2.error).toBeInstanceOf(Function)
expect(logger2.warn).toBeInstanceOf(Function)
})

it("should assign the new logger to config.logger if not present", () => {
const config: Partial<AuthConfig> = {}
const logger = setLogger(config)
expect(config.logger).toBe(logger)
})
})
Loading