mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29b67b6647 | ||
|
|
910514c6e2 | ||
|
|
111e7aabdf | ||
|
|
a113ef6fab | ||
|
|
b7cca484cf | ||
|
|
e293e786a8 | ||
|
|
82dd6ba3e4 |
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -2,8 +2,10 @@ name: Release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- canary
|
||||
- 'master'
|
||||
- 'next'
|
||||
- '3.x'
|
||||
pull_request:
|
||||
jobs:
|
||||
release:
|
||||
name: 'Release'
|
||||
|
||||
@@ -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
|
||||
@@ -69,11 +72,13 @@ async function NextAuthHandler (req, res, userOptions) {
|
||||
const providers = parseProviders({ providers: userOptions.providers, baseUrl, basePath })
|
||||
const provider = providers.find(({ id }) => id === providerId)
|
||||
|
||||
if (provider &&
|
||||
provider.type === 'oauth' && provider.version?.startsWith('2') &&
|
||||
(!provider.protection && provider.state !== false)
|
||||
if (
|
||||
provider?.type === 'oauth' &&
|
||||
provider?.version?.startsWith('2') &&
|
||||
!provider?.protection
|
||||
) {
|
||||
provider.protection = 'state' // Default to state, as we did in 3.1 REVIEW: should we use "pkce" or "none" as default?
|
||||
// Default to state, as we did in 3.1 REVIEW: should we use "pkce" or "none" as default?
|
||||
provider.protection = 'state'
|
||||
}
|
||||
|
||||
const maxAge = 30 * 24 * 60 * 60 // Sessions expire after 30 days of being idle
|
||||
@@ -127,7 +132,8 @@ async function NextAuthHandler (req, res, userOptions) {
|
||||
...defaultCallbacks,
|
||||
...userOptions.callbacks
|
||||
},
|
||||
pkce: {}
|
||||
pkce: {},
|
||||
logger
|
||||
}
|
||||
|
||||
await callbackUrlHandler(req, res)
|
||||
@@ -220,6 +226,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:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
// @ts-check
|
||||
import { h } from 'preact' // eslint-disable-line no-unused-vars
|
||||
import render from 'preact-render-to-string'
|
||||
|
||||
/** Renders an error page. */
|
||||
export default function error ({ baseUrl, basePath, error, res }) {
|
||||
/**
|
||||
* Renders an error page.
|
||||
* @param {{
|
||||
* baseUrl: string
|
||||
* basePath: string
|
||||
* error?: string
|
||||
* res: import("..").NextAuthResponse
|
||||
* }} params
|
||||
*/
|
||||
export default function error ({ baseUrl, basePath, error = 'default', res }) {
|
||||
const signinPageUrl = `${baseUrl}${basePath}/signin`
|
||||
|
||||
const errors = {
|
||||
@@ -44,7 +53,7 @@ export default function error ({ baseUrl, basePath, error, res }) {
|
||||
}
|
||||
}
|
||||
|
||||
const { statusCode, heading, message, signin } = errors[error.toLowerCase()] || errors.default
|
||||
const { statusCode, heading, message, signin } = errors[error.toLowerCase()]
|
||||
|
||||
res.status(statusCode)
|
||||
|
||||
|
||||
@@ -65,18 +65,13 @@ export default async function callback (req, res) {
|
||||
|
||||
try {
|
||||
const signInCallbackResponse = await callbacks.signIn(userOrProfile, account, OAuthProfile)
|
||||
if (signInCallbackResponse === false) {
|
||||
if (!signInCallbackResponse) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=AccessDenied`)
|
||||
} else if (typeof signInCallbackResponse === 'string') {
|
||||
return res.redirect(signInCallbackResponse)
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
// TODO: Remove in a future major release
|
||||
logger.warn('SIGNIN_CALLBACK_REJECT_REDIRECT')
|
||||
return res.redirect(error)
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
|
||||
// Sign user in
|
||||
@@ -161,18 +156,13 @@ export default async function callback (req, res) {
|
||||
// Check if user is allowed to sign in
|
||||
try {
|
||||
const signInCallbackResponse = await callbacks.signIn(profile, account, { email })
|
||||
if (signInCallbackResponse === false) {
|
||||
if (!signInCallbackResponse) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=AccessDenied`)
|
||||
} else if (typeof signInCallbackResponse === 'string') {
|
||||
return res.redirect(signInCallbackResponse)
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
// TODO: Remove in a future major release
|
||||
logger.warn('SIGNIN_CALLBACK_REJECT_REDIRECT')
|
||||
return res.redirect(error)
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
|
||||
// Sign user in
|
||||
@@ -236,12 +226,11 @@ export default async function callback (req, res) {
|
||||
userObjectReturnedFromAuthorizeHandler = await provider.authorize(credentials)
|
||||
if (!userObjectReturnedFromAuthorizeHandler) {
|
||||
return res.status(401).redirect(`${baseUrl}${basePath}/error?error=CredentialsSignin&provider=${encodeURIComponent(provider.id)}`)
|
||||
} else if (typeof userObjectReturnedFromAuthorizeHandler === 'string') {
|
||||
return res.redirect(userObjectReturnedFromAuthorizeHandler)
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
return res.redirect(error)
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
|
||||
const user = userObjectReturnedFromAuthorizeHandler
|
||||
@@ -249,14 +238,13 @@ export default async function callback (req, res) {
|
||||
|
||||
try {
|
||||
const signInCallbackResponse = await callbacks.signIn(user, account, credentials)
|
||||
if (signInCallbackResponse === false) {
|
||||
if (!signInCallbackResponse) {
|
||||
return res.status(403).redirect(`${baseUrl}${basePath}/error?error=AccessDenied`)
|
||||
} else if (typeof signInCallbackResponse === 'string') {
|
||||
return res.redirect(signInCallbackResponse)
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
return res.redirect(error)
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
|
||||
const defaultJwtPayload = {
|
||||
|
||||
@@ -45,18 +45,13 @@ export default async function signin (req, res) {
|
||||
// Check if user is allowed to sign in
|
||||
try {
|
||||
const signInCallbackResponse = await callbacks.signIn(profile, account, { email, verificationRequest: true })
|
||||
if (signInCallbackResponse === false) {
|
||||
if (!signInCallbackResponse) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=AccessDenied`)
|
||||
} else if (typeof signInCallbackResponse === 'string') {
|
||||
return res.redirect(signInCallbackResponse)
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
// TODO: Remove in a future major release
|
||||
logger.warn('SIGNIN_CALLBACK_REJECT_REDIRECT')
|
||||
return res.redirect(error)
|
||||
return res.redirect(`${baseUrl}${basePath}/error?error=${encodeURIComponent(error)}`)
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -113,9 +113,10 @@ providers: [
|
||||
```
|
||||
|
||||
:::tip
|
||||
If you think your custom provider might be useful to others, we encourage you to open a PR and add it to the built-in list so others can discover it much more easily! You only need to add two files:
|
||||
1. Your config: [`src/providers/{provider}.js`](https://github.com/nextauthjs/next-auth/tree/main/src/providers)
|
||||
2. Provider documentation: [`www/docs/providers/{provider}.md`](https://github.com/nextauthjs/next-auth/tree/main/www/docs/providers)
|
||||
If you think your custom provider might be useful to others, we encourage you to open a PR and add it to the built-in list so others can discover it much more easily! You only need to add three changes:
|
||||
1. Add your config: [`src/providers/{provider}.js`](https://github.com/nextauthjs/next-auth/tree/main/src/providers)
|
||||
2. Re-export your config: at [`src/providers/index.js`](https://github.com/nextauthjs/next-auth/blob/main/src/providers/index.js)
|
||||
3. Add provider documentation: [`www/docs/providers/{provider}.md`](https://github.com/nextauthjs/next-auth/tree/main/www/docs/providers)
|
||||
|
||||
You can look at the existing built-in providers for inspiration.
|
||||
:::
|
||||
|
||||
@@ -46,32 +46,4 @@ You can use [node-jose-tools](https://www.npmjs.com/package/node-jose-tools) to
|
||||
|
||||
**Option 2**: Specify custom encode/decode functions on the jwt object. This gives you complete control over signing / verification / etc.
|
||||
|
||||
#### JWT_AUTO_GENERATED_ENCRYPTION_KEY
|
||||
|
||||
#### SIGNIN_CALLBACK_REJECT_REDIRECT
|
||||
|
||||
You returned something in the `signIn` callback, that is being deprecated.
|
||||
|
||||
You probably had something similar in the callback:
|
||||
```js
|
||||
return Promise.reject("/some/url")
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```js
|
||||
throw "/some/url"
|
||||
```
|
||||
|
||||
To remedy this, simply return the url instead:
|
||||
|
||||
```js
|
||||
return "/some/url"
|
||||
```
|
||||
|
||||
|
||||
#### STATE_OPTION_DEPRECATION
|
||||
You provided `state: true` or `state: false` as a provider option. This is being deprecated in a later release in favour of `protection: "state"` and `protection: "none"` respectively. To remedy this warning:
|
||||
|
||||
- If you use `state: true`, just simply remove it. The default is `protection: "state"` already..
|
||||
- If you use `state: false`, set `protection: "none"`.
|
||||
#### JWT_AUTO_GENERATED_ENCRYPTION_KEY
|
||||
Reference in New Issue
Block a user