mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82dd6ba3e4 |
@@ -1,84 +1,83 @@
|
||||
const Adapter = (config, options = {}) => {
|
||||
async function getAdapter (appOptions) {
|
||||
const { logger } = appOptions
|
||||
// Display debug output if debug option enabled
|
||||
function _debug (...args) {
|
||||
if (appOptions.debug) {
|
||||
console.log('[next-auth][debug]', ...args)
|
||||
}
|
||||
function debug (debugCode, ...args) {
|
||||
logger.debug(`ADAPTER_${debugCode}`, ...args)
|
||||
}
|
||||
|
||||
async function createUser (profile) {
|
||||
_debug('createUser', profile)
|
||||
debug('createUser', profile)
|
||||
return null
|
||||
}
|
||||
|
||||
async function getUser (id) {
|
||||
_debug('getUser', id)
|
||||
debug('getUser', id)
|
||||
return null
|
||||
}
|
||||
|
||||
async function getUserByEmail (email) {
|
||||
_debug('getUserByEmail', email)
|
||||
debug('getUserByEmail', email)
|
||||
return null
|
||||
}
|
||||
|
||||
async function getUserByProviderAccountId (providerId, providerAccountId) {
|
||||
_debug('getUserByProviderAccountId', providerId, providerAccountId)
|
||||
debug('getUserByProviderAccountId', providerId, providerAccountId)
|
||||
return null
|
||||
}
|
||||
|
||||
async function updateUser (user) {
|
||||
_debug('updateUser', user)
|
||||
debug('updateUser', user)
|
||||
return null
|
||||
}
|
||||
|
||||
async function deleteUser (userId) {
|
||||
_debug('deleteUser', userId)
|
||||
debug('deleteUser', userId)
|
||||
return null
|
||||
}
|
||||
|
||||
async function linkAccount (userId, providerId, providerType, providerAccountId, refreshToken, accessToken, accessTokenExpires) {
|
||||
_debug('linkAccount', userId, providerId, providerType, providerAccountId, refreshToken, accessToken, accessTokenExpires)
|
||||
debug('linkAccount', userId, providerId, providerType, providerAccountId, refreshToken, accessToken, accessTokenExpires)
|
||||
return null
|
||||
}
|
||||
|
||||
async function unlinkAccount (userId, providerId, providerAccountId) {
|
||||
_debug('unlinkAccount', userId, providerId, providerAccountId)
|
||||
debug('unlinkAccount', userId, providerId, providerAccountId)
|
||||
return null
|
||||
}
|
||||
|
||||
async function createSession (user) {
|
||||
_debug('createSession', user)
|
||||
debug('createSession', user)
|
||||
return null
|
||||
}
|
||||
|
||||
async function getSession (sessionToken) {
|
||||
_debug('getSession', sessionToken)
|
||||
debug('getSession', sessionToken)
|
||||
return null
|
||||
}
|
||||
|
||||
async function updateSession (session, force) {
|
||||
_debug('updateSession', session)
|
||||
debug('updateSession', session)
|
||||
return null
|
||||
}
|
||||
|
||||
async function deleteSession (sessionToken) {
|
||||
_debug('deleteSession', sessionToken)
|
||||
debug('deleteSession', sessionToken)
|
||||
return null
|
||||
}
|
||||
|
||||
async function createVerificationRequest (identifier, url, token, secret, provider) {
|
||||
_debug('createVerificationRequest', identifier)
|
||||
debug('createVerificationRequest', identifier)
|
||||
return null
|
||||
}
|
||||
|
||||
async function getVerificationRequest (identifier, token, secret, provider) {
|
||||
_debug('getVerificationRequest', identifier, token)
|
||||
debug('getVerificationRequest', identifier, token)
|
||||
return null
|
||||
}
|
||||
|
||||
async function deleteVerificationRequest (identifier, token, secret, provider) {
|
||||
_debug('deleteVerification', identifier, token)
|
||||
debug('deleteVerification', identifier, token)
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { createHash, randomBytes } from 'crypto'
|
||||
|
||||
import { CreateUserError } from '../../lib/errors'
|
||||
import logger from '../../lib/logger'
|
||||
|
||||
const Adapter = (config) => {
|
||||
const {
|
||||
@@ -21,6 +20,7 @@ const Adapter = (config) => {
|
||||
}
|
||||
|
||||
async function getAdapter (appOptions) {
|
||||
const { logger } = appOptions
|
||||
function debug (debugCode, ...args) {
|
||||
logger.debug(`PRISMA_${debugCode}`, ...args)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { CreateUserError } from '../../lib/errors'
|
||||
import adapterConfig from './lib/config'
|
||||
import adapterTransform from './lib/transform'
|
||||
import Models from './models'
|
||||
import logger from '../../lib/logger'
|
||||
|
||||
import { updateConnectionEntities } from './lib/utils'
|
||||
|
||||
const Adapter = (typeOrmConfig, options = {}) => {
|
||||
@@ -41,6 +41,12 @@ const Adapter = (typeOrmConfig, options = {}) => {
|
||||
let connection = null
|
||||
|
||||
async function getAdapter (appOptions) {
|
||||
const { logger } = appOptions
|
||||
// Display debug output if debug option enabled
|
||||
function debug (debugCode, ...args) {
|
||||
logger.debug(`TYPEORM_${debugCode}`, ...args)
|
||||
}
|
||||
|
||||
// Helper function to reuse / restablish connections
|
||||
// (useful if they drop when after being idle)
|
||||
async function _connect () {
|
||||
@@ -77,12 +83,6 @@ const Adapter = (typeOrmConfig, options = {}) => {
|
||||
// https://github.com/typeorm/typeorm/blob/master/docs/entity-manager-api.md
|
||||
const { manager } = connection
|
||||
|
||||
// Display debug output if debug option enabled
|
||||
// @TODO Refactor logger so is passed in appOptions
|
||||
function debug (debugCode, ...args) {
|
||||
logger.debug(`TYPEORM_${debugCode}`, ...args)
|
||||
}
|
||||
|
||||
// The models are primarily designed for ANSI SQL database, but some
|
||||
// flexiblity is required in the adapter to support non-SQL databases such
|
||||
// as MongoDB which have different pragmas.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// We use HTTP POST requests with CSRF Tokens to protect against CSRF attacks.
|
||||
|
||||
import { useState, useEffect, useContext, createContext, createElement } from 'react'
|
||||
import logger from '../lib/logger'
|
||||
import _logger, { proxyLogger } from '../lib/logger'
|
||||
import parseUrl from '../lib/parse-url'
|
||||
|
||||
// This behaviour mirrors the default behaviour for getting the site name that
|
||||
@@ -37,6 +37,8 @@ const __NEXTAUTH = {
|
||||
_getSession: () => {}
|
||||
}
|
||||
|
||||
const logger = proxyLogger(_logger, __NEXTAUTH.basePath)
|
||||
|
||||
// Add event listners on load
|
||||
if (typeof window !== 'undefined') {
|
||||
if (__NEXTAUTH._eventListenersAdded === false) {
|
||||
|
||||
5
src/lib/logger.d.ts
vendored
Normal file
5
src/lib/logger.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface LoggerInstance {
|
||||
warn: (code?: string, ...message: unknown[]) => void
|
||||
error: (code?: string, ...message: unknown[]) => void
|
||||
debug: (code?: string, ...message: unknown[]) => void
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
const logger = {
|
||||
/** @type {import("./logger").LoggerInstance} */
|
||||
const _logger = {
|
||||
error (code, ...message) {
|
||||
console.error(
|
||||
`[next-auth][error][${code.toLowerCase()}]`,
|
||||
@@ -22,4 +23,60 @@ const logger = {
|
||||
}
|
||||
}
|
||||
|
||||
export default logger
|
||||
/**
|
||||
* Override the built-in logger.
|
||||
* Any `undefined` level will use the default logger.
|
||||
* @param {Partial<import("./logger").LoggerInstance>} newLogger
|
||||
*/
|
||||
export function setLogger (newLogger = {}) {
|
||||
if (newLogger.error) _logger.error = newLogger.error
|
||||
if (newLogger.warn) _logger.warn = newLogger.warn
|
||||
if (newLogger.debug) _logger.debug = newLogger.debug
|
||||
}
|
||||
|
||||
export default _logger
|
||||
|
||||
/**
|
||||
* Serializes client-side log messages and sends them to the server
|
||||
* @param {import("./logger").LoggerInstance} logger
|
||||
* @param {string} basePath
|
||||
* @return {import("./logger").LoggerInstance}
|
||||
*/
|
||||
export function proxyLogger (logger = _logger, basePath) {
|
||||
try {
|
||||
if (typeof window === 'undefined') {
|
||||
return logger
|
||||
}
|
||||
|
||||
const clientLogger = {}
|
||||
for (const level in logger) {
|
||||
clientLogger[level] = (code, ...message) => {
|
||||
_logger[level](code, ...message) // Log on client as usual
|
||||
|
||||
const url = `${basePath}/_log`
|
||||
const body = new URLSearchParams({
|
||||
level,
|
||||
code,
|
||||
message: JSON.stringify(message.map(m => {
|
||||
if (m instanceof Error) {
|
||||
// Serializing errors: https://iaincollins.medium.com/error-handling-in-javascript-a6172ccdf9af
|
||||
return { name: m.name, message: m.message, stack: m.stack }
|
||||
}
|
||||
return m
|
||||
}))
|
||||
})
|
||||
if (navigator.sendBeacon) {
|
||||
return navigator.sendBeacon(url, body)
|
||||
}
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body
|
||||
})
|
||||
}
|
||||
}
|
||||
return clientLogger
|
||||
} catch {
|
||||
return _logger
|
||||
}
|
||||
}
|
||||
|
||||
5
src/server/index.d.ts
vendored
5
src/server/index.d.ts
vendored
@@ -1,4 +1,5 @@
|
||||
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
||||
import { LoggerInstance } from 'src/lib/logger'
|
||||
import { CallbacksOptions } from './lib/callbacks'
|
||||
import { CookiesOptions } from './lib/cookie'
|
||||
import { EventsOptions } from './lib/events'
|
||||
@@ -59,10 +60,12 @@ export interface NextAuthOptions {
|
||||
useSecureCookies?: boolean
|
||||
/** @docs https://next-auth.js.org/configuration/options#cookies */
|
||||
cookies?: CookiesOptions
|
||||
/** @docs https://next-auth.js.org/configuration/options#logger */
|
||||
logger: LoggerInstance
|
||||
}
|
||||
|
||||
/** Options that are the same both in internal and user provided options. */
|
||||
export type NextAuthSharedOptions = 'pages' | 'jwt' | 'events' | 'callbacks' | 'cookies' | 'secret' | 'adapter' | 'theme' | 'debug'
|
||||
export type NextAuthSharedOptions = 'pages' | 'jwt' | 'events' | 'callbacks' | 'cookies' | 'secret' | 'adapter' | 'theme' | 'debug' | 'logger'
|
||||
|
||||
export interface NextAuthInternalOptions extends Pick<NextAuthOptions, NextAuthSharedOptions> {
|
||||
pkce?: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import adapters from '../adapters'
|
||||
import jwt from '../lib/jwt'
|
||||
import parseUrl from '../lib/parse-url'
|
||||
import logger from '../lib/logger'
|
||||
import logger, { setLogger } from '../lib/logger'
|
||||
import * as cookie from './lib/cookie'
|
||||
import * as defaultEvents from './lib/default-events'
|
||||
import * as defaultCallbacks from './lib/default-callbacks'
|
||||
@@ -27,6 +27,9 @@ if (!process.env.NEXTAUTH_URL) {
|
||||
* @param {import(".").NextAuthOptions} userOptions
|
||||
*/
|
||||
async function NextAuthHandler (req, res, userOptions) {
|
||||
if (userOptions.logger) {
|
||||
setLogger(userOptions.logger)
|
||||
}
|
||||
// If debug enabled, set ENV VAR so that logger logs debug messages
|
||||
if (userOptions.debug) {
|
||||
process.env._NEXTAUTH_DEBUG = true
|
||||
@@ -127,7 +130,8 @@ async function NextAuthHandler (req, res, userOptions) {
|
||||
...defaultCallbacks,
|
||||
...userOptions.callbacks
|
||||
},
|
||||
pkce: {}
|
||||
pkce: {},
|
||||
logger
|
||||
}
|
||||
|
||||
await callbackUrlHandler(req, res)
|
||||
@@ -220,6 +224,21 @@ async function NextAuthHandler (req, res, userOptions) {
|
||||
return routes.callback(req, res)
|
||||
}
|
||||
break
|
||||
case '_log':
|
||||
try {
|
||||
if (!userOptions.logger) return
|
||||
const {
|
||||
code = 'CLIENT_ERROR',
|
||||
level = 'error',
|
||||
message = '[]'
|
||||
} = req.body
|
||||
|
||||
logger[level](code, ...JSON.parse(message))
|
||||
} catch (error) {
|
||||
// If logging itself failed...
|
||||
logger.error('LOGGER_ERROR', error)
|
||||
}
|
||||
return res.end()
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,6 +307,42 @@ Set debug to `true` to enable debug messages for authentication and database ope
|
||||
|
||||
---
|
||||
|
||||
### logger
|
||||
|
||||
* **Default value**: `console`
|
||||
* **Required**: *No*
|
||||
|
||||
#### Description
|
||||
|
||||
Override any of the logger levels (`undefined` levels will use the built-in logger), and intercept logs in NextAuth. You can use this to send NextAuth logs to a third-party logging service.
|
||||
|
||||
Example:
|
||||
```js title="/pages/api/auth/[...nextauth].js"
|
||||
import log from "logging-service"
|
||||
|
||||
export default NextAuth({
|
||||
...
|
||||
logger: {
|
||||
error(code, ...message) {
|
||||
log.error(code, message)
|
||||
},
|
||||
warn(code, ...message) {
|
||||
log.warn(code, message)
|
||||
}
|
||||
debug(code, ...message) {
|
||||
log.debug(code, message)
|
||||
}
|
||||
}
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
:::note
|
||||
If the `debug` level is defined by the user, it will be called regardless of the `debug: false` [option](#debug).
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### theme
|
||||
|
||||
* **Default value**: `"auto"`
|
||||
|
||||
Reference in New Issue
Block a user