mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
6 Commits
@auth/kyse
...
v3.14.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fa71512d1 | ||
|
|
d420eeff9d | ||
|
|
0d863d38bc | ||
|
|
6f9f42a85b | ||
|
|
2160be2a8a | ||
|
|
55eb066793 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -6,10 +6,12 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- next
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- next
|
||||
|
||||
jobs:
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -13,7 +13,7 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, next ]
|
||||
branches: [ main, beta, next ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
|
||||
11
.github/workflows/integration.yml
vendored
11
.github/workflows/integration.yml
vendored
@@ -2,9 +2,10 @@ name: Integration Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- next
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- next
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
@@ -17,7 +18,7 @@ jobs:
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
|
||||
# We use self-hosted runners as cloud based runnners (e.g. AWS, GPC)
|
||||
# fail due to IP Address checks done by providers, which enforce
|
||||
# fail due to IP Address checks done by providers, which enforce
|
||||
# CAPTCHA checks on login request from cloud compute IP addresses to
|
||||
# prevent abuse.
|
||||
runs-on: self-hosted
|
||||
@@ -45,7 +46,7 @@ jobs:
|
||||
- run: npm test
|
||||
# TODO Tests should exit out if env vars not set (currently hangs)
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
NEXTAUTH_TWITTER_ID: ${{secrets.NEXTAUTH_TWITTER_ID}}
|
||||
NEXTAUTH_TWITTER_SECRET: ${{secrets.NEXTAUTH_TWITTER_SECRET}}
|
||||
NEXTAUTH_TWITTER_USERNAME: ${{secrets.NEXTAUTH_TWITTER_USERNAME}}
|
||||
|
||||
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -3,6 +3,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'beta'
|
||||
- 'next'
|
||||
- '3.x'
|
||||
pull_request:
|
||||
|
||||
25
.github/workflows/types.yml
vendored
Normal file
25
.github/workflows/types.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Types
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- next
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- next
|
||||
|
||||
jobs:
|
||||
lint-and-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v1
|
||||
- name: Install dependencies
|
||||
uses: bahmutov/npm-install@v1
|
||||
- name: Check types
|
||||
run: npm run test:types
|
||||
3
.npmignore
Normal file
3
.npmignore
Normal file
@@ -0,0 +1,3 @@
|
||||
./types/tests/
|
||||
./types/tests/tsconfig.json
|
||||
./types/tests/tslint.json
|
||||
3
.prettierrc
Normal file
3
.prettierrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"semi": false
|
||||
}
|
||||
23
config/build-types.js
Normal file
23
config/build-types.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const BUILD_TARGETS = [
|
||||
'index.d.ts',
|
||||
'client.d.ts',
|
||||
'adapters.d.ts',
|
||||
'providers.d.ts',
|
||||
'jwt.d.ts',
|
||||
'_next.d.ts',
|
||||
'_utils.d.ts'
|
||||
]
|
||||
|
||||
BUILD_TARGETS.forEach((target) => {
|
||||
fs.copyFile(
|
||||
path.resolve('types', target),
|
||||
path.join(process.cwd(), target),
|
||||
(err) => {
|
||||
if (err) throw err
|
||||
console.log(`[build-types] copying "${target}" to root folder`)
|
||||
}
|
||||
)
|
||||
})
|
||||
26891
package-lock.json
generated
26891
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@@ -7,9 +7,10 @@
|
||||
"author": "Iain Collins <me@iaincollins.com>",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "npm run build:js && npm run build:css",
|
||||
"build": "npm run build:js && npm run build:css && npm run build:types",
|
||||
"build:js": "babel --config-file ./config/babel.config.json src --out-dir dist",
|
||||
"build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir dist && node config/wrap-css.js",
|
||||
"build:types": "node ./config/build-types.js",
|
||||
"dev": "next | npm run watch:css",
|
||||
"watch": "npm run watch:js | npm run watch:css",
|
||||
"watch:js": "babel --config-file ./config/babel.config.json --watch src --out-dir dist",
|
||||
@@ -17,13 +18,14 @@
|
||||
"test:app:start": "docker-compose -f test/docker/app.yml up -d",
|
||||
"test:app:rebuild": "npm run build && docker-compose -f test/docker/app.yml up -d --build",
|
||||
"test:app:stop": "docker-compose -f test/docker/app.yml down",
|
||||
"test": "npm run test:app:rebuild && npm run test:integration && npm run test:app:stop",
|
||||
"test": "npm run test:app:rebuild && npm run test:integration && npm run test:app:stop && npm run test:types",
|
||||
"test:db": "npm run test:db:mysql && npm run test:db:postgres && npm run test:db:mongodb && npm run test:db:mssql",
|
||||
"test:db:mysql": "node test/mysql.js",
|
||||
"test:db:postgres": "node test/postgres.js",
|
||||
"test:db:mongodb": "node test/mongodb.js",
|
||||
"test:db:mssql": "node test/mssql.js",
|
||||
"test:integration": "mocha test/integration",
|
||||
"test:types": "dtslint types",
|
||||
"db:start": "docker-compose -f test/docker/databases.yml up -d",
|
||||
"db:stop": "docker-compose -f test/docker/databases.yml down",
|
||||
"prepublishOnly": "npm run build",
|
||||
@@ -35,10 +37,17 @@
|
||||
"files": [
|
||||
"dist",
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"providers.js",
|
||||
"providers.d.ts",
|
||||
"adapters.js",
|
||||
"adapters.d.ts",
|
||||
"client.js",
|
||||
"jwt.js"
|
||||
"client.d.ts",
|
||||
"jwt.js",
|
||||
"jwt.d.ts",
|
||||
"_next.d.ts",
|
||||
"_utils.d.ts"
|
||||
],
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
@@ -57,7 +66,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17",
|
||||
"react-dom": "^16.13.1 || ^17"
|
||||
"react-dom": "16.13.1 || ^17"
|
||||
},
|
||||
"peerOptionalDependencies": {
|
||||
"mongodb": "^3.5.9",
|
||||
@@ -81,6 +90,7 @@
|
||||
"conventional-changelog-conventionalcommits": "4.4.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"dotenv": "^8.2.0",
|
||||
"dtslint": "^4.0.8",
|
||||
"eslint": "^7.19.0",
|
||||
"mocha": "^8.1.3",
|
||||
"mongodb": "^3.5.9",
|
||||
@@ -90,6 +100,7 @@
|
||||
"pg": "^8.2.1",
|
||||
"postcss-cli": "^7.1.1",
|
||||
"postcss-nested": "^4.2.1",
|
||||
"prettier": "^2.2.1",
|
||||
"prisma": "^2.16.1",
|
||||
"puppeteer": "^5.2.1",
|
||||
"puppeteer-extra": "^3.1.15",
|
||||
@@ -103,7 +114,8 @@
|
||||
"project": "./tsconfig.json",
|
||||
"ignore": [
|
||||
"test/",
|
||||
"next-env.d.ts"
|
||||
"next-env.d.ts",
|
||||
"types/"
|
||||
],
|
||||
"globals": [
|
||||
"localStorage",
|
||||
@@ -117,4 +129,4 @@
|
||||
"url": "https://github.com/sponsors/balazsorban44"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ module.exports = {
|
||||
branches: [
|
||||
'+([0-9])?(.{+([0-9]),x}).x',
|
||||
'main',
|
||||
{ name: 'beta', prerelease: true },
|
||||
{ name: 'next', prerelease: true }
|
||||
]
|
||||
}
|
||||
|
||||
40
types/_next.d.ts
vendored
Normal file
40
types/_next.d.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import { IncomingMessage, ServerResponse } from "http"
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Types from next@10,
|
||||
// see: https://github.com/microsoft/dtslint/issues/297
|
||||
// ------------------------------------------------------
|
||||
export interface NextApiRequest extends IncomingMessage {
|
||||
query: {
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
cookies: {
|
||||
[key: string]: string
|
||||
}
|
||||
body: any
|
||||
env: any
|
||||
preview?: boolean
|
||||
previewData?: any
|
||||
}
|
||||
|
||||
export type Send<T> = (body: T) => void
|
||||
|
||||
export type NextApiResponse<T = any> = ServerResponse & {
|
||||
send: Send<T>
|
||||
json: Send<T>
|
||||
status: (statusCode: number) => NextApiResponse<T>
|
||||
redirect: ((url: string) => NextApiResponse<T>) &
|
||||
((status: number, url: string) => NextApiResponse<T>)
|
||||
setPreviewData: (
|
||||
data: object | string,
|
||||
options?: {
|
||||
maxAge?: number
|
||||
}
|
||||
) => NextApiResponse<T>
|
||||
clearPreviewData: () => NextApiResponse<T>
|
||||
}
|
||||
|
||||
export type NextApiHandler<T = any> = (
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<T>
|
||||
) => void | Promise<void>
|
||||
12
types/_utils.d.ts
vendored
Normal file
12
types/_utils.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export type NonNullParams<T> = {
|
||||
[K in keyof T]: T[K] extends Record<string, unknown>
|
||||
? NonNullParams<T[K]>
|
||||
: NonNullable<T[K]>
|
||||
}
|
||||
|
||||
export type NullableParams<T> = {
|
||||
[K in keyof T]: T[K] | undefined | null
|
||||
}
|
||||
|
||||
export type WithAdditionalParams<T extends Record<string, any>> = T &
|
||||
Record<string, unknown>
|
||||
242
types/adapters.d.ts
vendored
Normal file
242
types/adapters.d.ts
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
import { ConnectionOptions, EntitySchema } from "typeorm"
|
||||
import { AppOptions, User } from "."
|
||||
import { AppProvider } from "./providers"
|
||||
|
||||
export interface Profile {
|
||||
id: string
|
||||
name: string
|
||||
email: string | null
|
||||
image?: string | null
|
||||
}
|
||||
|
||||
export interface Session {
|
||||
userId: string | number | object
|
||||
expires: Date
|
||||
sessionToken: string
|
||||
accessToken: string
|
||||
}
|
||||
|
||||
export interface VerificationRequest {
|
||||
identifier: string
|
||||
token: string
|
||||
expires: Date
|
||||
}
|
||||
|
||||
export interface SendVerificationRequestParams {
|
||||
identifier: string
|
||||
url: string
|
||||
token: string
|
||||
baseUrl: string
|
||||
provider: AppProvider
|
||||
}
|
||||
|
||||
export type EmailAppProvider = AppProvider & {
|
||||
sendVerificationRequest: (
|
||||
params: SendVerificationRequestParams
|
||||
) => Promise<void>
|
||||
maxAge: number | undefined
|
||||
}
|
||||
|
||||
export interface AdapterInstance<
|
||||
TUser,
|
||||
TProfile,
|
||||
TSession,
|
||||
TVerificationRequest
|
||||
> {
|
||||
createUser: (profile: TProfile) => Promise<TUser>
|
||||
getUser: (id: string) => Promise<TUser | null>
|
||||
getUserByEmail: (email: string) => Promise<TUser | null>
|
||||
getUserByProviderAccountId: (
|
||||
providerId: string,
|
||||
providerAccountId: string
|
||||
) => Promise<TUser | null>
|
||||
updateUser: (user: TUser) => Promise<TUser>
|
||||
linkAccount: (
|
||||
userId: string,
|
||||
providerId: string,
|
||||
providerType: string,
|
||||
providerAccountId: string,
|
||||
refreshToken: string,
|
||||
accessToken: string,
|
||||
accessTokenExpires: number
|
||||
) => Promise<void>
|
||||
createSession: (user: TUser) => Promise<TSession>
|
||||
getSession: (sessionToken: string) => Promise<TSession | null>
|
||||
updateSession: (session: TSession, force?: boolean) => Promise<TSession>
|
||||
deleteSession: (sessionToken: string) => Promise<void>
|
||||
createVerificationRequest?: (
|
||||
email: string,
|
||||
url: string,
|
||||
token: string,
|
||||
secret: string,
|
||||
provider: EmailAppProvider,
|
||||
options: AppOptions
|
||||
) => Promise<TVerificationRequest>
|
||||
getVerificationRequest?: (
|
||||
email: string,
|
||||
verificationToken: string,
|
||||
secret: string,
|
||||
provider: AppProvider
|
||||
) => Promise<TVerificationRequest | null>
|
||||
deleteVerificationRequest?: (
|
||||
email: string,
|
||||
verificationToken: string,
|
||||
secret: string,
|
||||
provider: AppProvider
|
||||
) => Promise<void>
|
||||
}
|
||||
|
||||
interface Adapter<
|
||||
TUser extends User = any,
|
||||
TProfile extends Profile = any,
|
||||
TSession extends Session = any,
|
||||
TVerificationRequest extends VerificationRequest = any
|
||||
> {
|
||||
getAdapter: (
|
||||
appOptions: AppOptions
|
||||
) => Promise<AdapterInstance<TUser, TProfile, TSession, TVerificationRequest>>
|
||||
}
|
||||
|
||||
type Schema<T = any> = EntitySchema<T>["options"]
|
||||
|
||||
interface Adapters {
|
||||
Default: TypeORMAdapter["Adapter"]
|
||||
TypeORM: TypeORMAdapter
|
||||
Prisma: PrismaAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: fix auto-type schema
|
||||
*/
|
||||
|
||||
interface TypeORMAdapter<
|
||||
A extends TypeORMAccountModel = any,
|
||||
U extends TypeORMUserModel = any,
|
||||
S extends TypeORMSessionModel = any,
|
||||
VR extends TypeORMVerificationRequestModel = any
|
||||
> {
|
||||
Adapter: (
|
||||
typeOrmConfig: ConnectionOptions,
|
||||
options?: {
|
||||
models?: {
|
||||
Account?: {
|
||||
model: A
|
||||
schema: Schema<A>
|
||||
}
|
||||
User?: {
|
||||
model: U
|
||||
schema: Schema<U>
|
||||
}
|
||||
Session?: {
|
||||
model: S
|
||||
schema: Schema<S>
|
||||
}
|
||||
VerificationRequest?: {
|
||||
model: VR
|
||||
schema: Schema<VR>
|
||||
}
|
||||
}
|
||||
}
|
||||
) => Adapter<U, Profile, S, VR>
|
||||
Models: {
|
||||
Account: {
|
||||
model: TypeORMAccountModel
|
||||
schema: Schema<TypeORMAccountModel>
|
||||
}
|
||||
User: {
|
||||
model: TypeORMUserModel
|
||||
schema: Schema<TypeORMUserModel>
|
||||
}
|
||||
Session: {
|
||||
model: TypeORMSessionModel
|
||||
schema: Schema<TypeORMSessionModel>
|
||||
}
|
||||
VerificationRequest: {
|
||||
model: TypeORMVerificationRequestModel
|
||||
schema: Schema<TypeORMVerificationRequestModel>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface PrismaAdapter {
|
||||
Adapter: (config: {
|
||||
prisma: any
|
||||
modelMapping?: {
|
||||
User: string
|
||||
Account: string
|
||||
Session: string
|
||||
VerificationRequest: string
|
||||
}
|
||||
}) => Adapter
|
||||
}
|
||||
|
||||
declare const Adapters: Adapters
|
||||
|
||||
declare class TypeORMAccountModel {
|
||||
compoundId: string
|
||||
userId: number
|
||||
providerType: string
|
||||
providerId: string
|
||||
providerAccountId: string
|
||||
refreshToken?: string
|
||||
accessToken?: string
|
||||
accessTokenExpires?: Date
|
||||
|
||||
constructor(
|
||||
userId: number,
|
||||
providerId: string,
|
||||
providerType: string,
|
||||
providerAccountId: string,
|
||||
refreshToken?: string,
|
||||
accessToken?: string,
|
||||
accessTokenExpires?: Date
|
||||
)
|
||||
}
|
||||
|
||||
declare class TypeORMUserModel implements User {
|
||||
name?: string
|
||||
email?: string
|
||||
image?: string
|
||||
emailVerified?: Date
|
||||
|
||||
constructor(
|
||||
name?: string,
|
||||
email?: string,
|
||||
image?: string,
|
||||
emailVerified?: Date
|
||||
)
|
||||
}
|
||||
|
||||
declare class TypeORMSessionModel implements Session {
|
||||
userId: number
|
||||
expires: Date
|
||||
sessionToken: string
|
||||
accessToken: string
|
||||
|
||||
constructor(
|
||||
userId: number,
|
||||
expires: Date,
|
||||
sessionToken?: string,
|
||||
accessToken?: string
|
||||
)
|
||||
}
|
||||
|
||||
declare class TypeORMVerificationRequestModel implements VerificationRequest {
|
||||
identifier: string
|
||||
token: string
|
||||
expires: Date
|
||||
|
||||
constructor(identifier: string, token: string, expires: Date)
|
||||
}
|
||||
|
||||
export default Adapters
|
||||
export {
|
||||
Adapter,
|
||||
Adapters,
|
||||
TypeORMAdapter,
|
||||
TypeORMAccountModel,
|
||||
TypeORMUserModel,
|
||||
TypeORMSessionModel,
|
||||
TypeORMVerificationRequestModel,
|
||||
PrismaAdapter,
|
||||
}
|
||||
97
types/client.d.ts
vendored
Normal file
97
types/client.d.ts
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
import { FC } from "react"
|
||||
import { IncomingMessage } from "http"
|
||||
import { WithAdditionalParams } from "./_utils"
|
||||
import { Session } from "."
|
||||
import { AppProvider, DefaultProviders, Providers } from "./providers"
|
||||
|
||||
interface ContextProviderProps {
|
||||
session: WithAdditionalParams<Session> | null | undefined
|
||||
options?: SetOptionsParams
|
||||
}
|
||||
|
||||
interface SetOptionsParams {
|
||||
baseUrl?: string
|
||||
basePath?: string
|
||||
clientMaxAge?: number
|
||||
keepAlive?: number
|
||||
}
|
||||
|
||||
interface SignInResponse {
|
||||
error: string | undefined
|
||||
status: number
|
||||
ok: boolean
|
||||
url: string | null
|
||||
}
|
||||
|
||||
type ContextProvider = FC<ContextProviderProps>
|
||||
|
||||
interface NextContext {
|
||||
req?: IncomingMessage
|
||||
ctx?: { req: IncomingMessage }
|
||||
}
|
||||
|
||||
declare function useSession(): [Session | null | undefined, boolean]
|
||||
|
||||
declare function providers(): Promise<Record<
|
||||
keyof DefaultProviders | string,
|
||||
AppProvider
|
||||
> | null>
|
||||
declare const getProviders: typeof providers
|
||||
declare function session(
|
||||
context?: NextContext & {
|
||||
triggerEvent?: boolean
|
||||
}
|
||||
): Promise<Session | null>
|
||||
declare const getSession: typeof session
|
||||
declare function csrfToken(context?: NextContext): Promise<string | null>
|
||||
declare const getCsrfToken: typeof csrfToken
|
||||
declare function signin(
|
||||
provider: "credentials" | "email",
|
||||
data?: Record<string, unknown> & {
|
||||
callbackUrl?: string
|
||||
redirect?: false
|
||||
},
|
||||
authorizationParams?:
|
||||
| string
|
||||
| string[][]
|
||||
| Record<string, unknown>
|
||||
| URLSearchParams
|
||||
): Promise<SignInResponse>
|
||||
declare function signin(
|
||||
provider?: string,
|
||||
data?: Record<string, unknown> & {
|
||||
callbackUrl?: string
|
||||
redirect?: boolean
|
||||
},
|
||||
authorizationParams?:
|
||||
| string
|
||||
| string[][]
|
||||
| Record<string, unknown>
|
||||
| URLSearchParams
|
||||
): Promise<void>
|
||||
declare const signIn: typeof signin
|
||||
declare function signout(data?: {
|
||||
callbackUrl?: string
|
||||
redirect?: boolean
|
||||
}): Promise<void>
|
||||
declare const signOut: typeof signout
|
||||
declare function options(options: SetOptionsParams): void
|
||||
declare const setOptions: typeof options
|
||||
declare const Provider: ContextProvider
|
||||
|
||||
export {
|
||||
useSession,
|
||||
session,
|
||||
getSession,
|
||||
providers,
|
||||
getProviders,
|
||||
csrfToken,
|
||||
getCsrfToken,
|
||||
signin,
|
||||
signIn,
|
||||
signout,
|
||||
signOut,
|
||||
options,
|
||||
setOptions,
|
||||
Provider,
|
||||
}
|
||||
169
types/index.d.ts
vendored
Normal file
169
types/index.d.ts
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
// Minimum TypeScript Version: 3.5
|
||||
|
||||
/// <reference types="node" />
|
||||
|
||||
import { ConnectionOptions } from "typeorm"
|
||||
import { Adapter } from "./adapters"
|
||||
import { JWTEncodeParams, JWTDecodeParams, JWTOptions, JWT } from "./jwt"
|
||||
import { AppProvider, Providers } from "./providers"
|
||||
import { NextApiRequest, NextApiResponse, NextApiHandler } from "./_next"
|
||||
import { NonNullParams, WithAdditionalParams } from "./_utils"
|
||||
|
||||
export interface NextAuthOptions {
|
||||
providers: Providers
|
||||
database?: string | Record<string, any> | ConnectionOptions
|
||||
secret?: string
|
||||
session?: SessionOptions
|
||||
jwt?: JWTOptions
|
||||
pages?: PagesOptions
|
||||
callbacks?: CallbacksOptions
|
||||
debug?: boolean
|
||||
adapter?: Adapter
|
||||
events?: EventsOptions
|
||||
useSecureCookies?: boolean
|
||||
cookies?: CookiesOptions
|
||||
logger?: LoggerInstance
|
||||
theme?: "light" | "dark" | "auto"
|
||||
}
|
||||
|
||||
export interface LoggerInstance {
|
||||
warn: (code?: string, ...message: unknown[]) => void
|
||||
error: (code?: string, ...message: unknown[]) => void
|
||||
debug: (code?: string, ...message: unknown[]) => void
|
||||
}
|
||||
|
||||
interface InternalOptions
|
||||
extends Omit<
|
||||
NextAuthOptions,
|
||||
"providers" | "database" | "session" | "useSecureCookie"
|
||||
> {
|
||||
pkce: {
|
||||
code_verifier?: string
|
||||
code_challenge_method?: "S256"
|
||||
}
|
||||
provider?: string
|
||||
baseUrl?: string
|
||||
basePath?: string
|
||||
action?:
|
||||
| "providers"
|
||||
| "session"
|
||||
| "csrf"
|
||||
| "signin"
|
||||
| "signout"
|
||||
| "callback"
|
||||
| "verify-request"
|
||||
| "error"
|
||||
csrfToken?: string
|
||||
}
|
||||
|
||||
export interface AppOptions
|
||||
extends Omit<NextApiRequest, "cookies">,
|
||||
NonNullParams<InternalOptions> {
|
||||
providers: AppProvider[]
|
||||
}
|
||||
|
||||
export interface CallbacksOptions {
|
||||
signIn?:
|
||||
| (() => true)
|
||||
| ((
|
||||
user: User,
|
||||
account: Record<string, unknown>,
|
||||
profile: Record<string, unknown>
|
||||
) => Promise<never | string | boolean>)
|
||||
redirect?: (url: string, baseUrl: string) => Promise<string>
|
||||
session?:
|
||||
| ((session: Session) => WithAdditionalParams<Session>)
|
||||
| ((
|
||||
session: Session,
|
||||
userOrToken: User | JWT
|
||||
) => Promise<WithAdditionalParams<Session>>)
|
||||
jwt?:
|
||||
| ((token: JWT) => WithAdditionalParams<JWT>)
|
||||
| ((
|
||||
token: JWT,
|
||||
user: User,
|
||||
account: Record<string, unknown>,
|
||||
profile: Record<string, unknown>,
|
||||
isNewUser: boolean
|
||||
) => Promise<WithAdditionalParams<JWT>>)
|
||||
}
|
||||
|
||||
export interface CookieOption {
|
||||
name: string
|
||||
options: {
|
||||
httpOnly: boolean
|
||||
sameSite: true | "strict" | "lax" | "none"
|
||||
path?: string
|
||||
secure: boolean
|
||||
maxAge?: number
|
||||
domain?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface CookiesOptions {
|
||||
sessionToken?: CookieOption
|
||||
callbackUrl?: CookieOption
|
||||
csrfToken?: CookieOption
|
||||
pkceCodeVerifier?: CookieOption
|
||||
}
|
||||
|
||||
export type EventType =
|
||||
| "signIn"
|
||||
| "signOut"
|
||||
| "createUser"
|
||||
| "updateUser"
|
||||
| "linkAccount"
|
||||
| "session"
|
||||
| "error"
|
||||
|
||||
export type EventCallback = (message: any) => Promise<void>
|
||||
|
||||
export type EventsOptions = Partial<Record<EventType, EventCallback>>
|
||||
|
||||
export interface PagesOptions {
|
||||
signIn?: string
|
||||
signOut?: string
|
||||
error?: string
|
||||
verifyRequest?: string
|
||||
newUser?: string | null
|
||||
}
|
||||
|
||||
export interface Session {
|
||||
user: WithAdditionalParams<User>
|
||||
accessToken?: string
|
||||
expires: string
|
||||
}
|
||||
|
||||
export interface SessionOptions {
|
||||
jwt?: boolean
|
||||
maxAge?: number
|
||||
updateAge?: number
|
||||
}
|
||||
|
||||
export interface User {
|
||||
name?: string | null
|
||||
email?: string | null
|
||||
image?: string | null
|
||||
}
|
||||
|
||||
export interface NextAuthRequest extends NextApiRequest {
|
||||
options: InternalOptions
|
||||
}
|
||||
export type NextAuthResponse = NextApiResponse
|
||||
|
||||
declare function NextAuthHandler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
options?: NextAuthOptions
|
||||
): ReturnType<NextApiHandler>
|
||||
declare function NextAuth(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
options?: NextAuthOptions
|
||||
): ReturnType<NextApiHandler>
|
||||
declare function NextAuth(
|
||||
options: NextAuthOptions
|
||||
): ReturnType<typeof NextAuthHandler>
|
||||
|
||||
export { NextAuthHandler, NextAuth }
|
||||
export default NextAuth
|
||||
67
types/jwt.d.ts
vendored
Normal file
67
types/jwt.d.ts
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { JWT, JWE } from "jose"
|
||||
import { NextApiRequest } from "./_next"
|
||||
import { WithAdditionalParams } from "./_utils"
|
||||
|
||||
export interface JWT extends Record<string, unknown> {
|
||||
name?: string | null
|
||||
email?: string | null
|
||||
picture?: string | null
|
||||
}
|
||||
|
||||
export interface JWTEncodeParams {
|
||||
token?: WithAdditionalParams<JWT>
|
||||
maxAge?: number
|
||||
secret: string | Buffer
|
||||
signingKey?: string
|
||||
signingOptions?: JWT.SignOptions
|
||||
encryptionKey?: string
|
||||
encryptionOptions?: object
|
||||
encryption?: boolean
|
||||
}
|
||||
|
||||
export interface JWTDecodeParams {
|
||||
token?: string
|
||||
maxAge?: number
|
||||
secret: string | Buffer
|
||||
signingKey?: string
|
||||
verificationKey?: string
|
||||
verificationOptions?: JWT.VerifyOptions<false>
|
||||
encryptionKey?: string
|
||||
decryptionKey?: string
|
||||
decryptionOptions?: JWE.DecryptOptions<false>
|
||||
encryption?: boolean
|
||||
}
|
||||
|
||||
export interface JWTOptions {
|
||||
secret?: string
|
||||
maxAge?: number
|
||||
encryption?: boolean
|
||||
signingKey?: string
|
||||
encryptionKey?: string
|
||||
encode?: (options: JWTEncodeParams) => Promise<string>
|
||||
decode?: (options: JWTDecodeParams) => Promise<WithAdditionalParams<JWT>>
|
||||
}
|
||||
|
||||
declare function encode(args?: JWTEncodeParams): Promise<string>
|
||||
|
||||
declare function decode(
|
||||
args?: JWTDecodeParams & { token: string }
|
||||
): Promise<WithAdditionalParams<JWT>>
|
||||
|
||||
declare function getToken(
|
||||
args?: {
|
||||
req: NextApiRequest
|
||||
secureCookie?: boolean
|
||||
cookieName?: string
|
||||
raw?: string
|
||||
} & JWTDecodeParams
|
||||
): Promise<WithAdditionalParams<JWT>>
|
||||
|
||||
declare function getToken(args?: {
|
||||
req: NextApiRequest
|
||||
secureCookie?: boolean
|
||||
cookieName?: string
|
||||
raw: true
|
||||
}): Promise<string>
|
||||
|
||||
export { encode, decode, getToken }
|
||||
435
types/providers.d.ts
vendored
Normal file
435
types/providers.d.ts
vendored
Normal file
@@ -0,0 +1,435 @@
|
||||
import { User } from "."
|
||||
import { JWT } from "./jwt"
|
||||
import { NonNullParams, NullableParams, WithAdditionalParams } from "./_utils"
|
||||
|
||||
export interface Provider<
|
||||
T extends string | undefined = undefined,
|
||||
U = T extends string ? "oauth" : string
|
||||
> {
|
||||
id: T
|
||||
name: string
|
||||
type: U extends string ? U : "oauth" | "email" | "credentials"
|
||||
version: string
|
||||
scope: string
|
||||
params: { grant_type: string }
|
||||
accessTokenUrl: string
|
||||
requestTokenUrl: string
|
||||
authorizationUrl: string
|
||||
profileUrl: string
|
||||
profile: (
|
||||
profile: Record<string, any>,
|
||||
tokens: any
|
||||
) => (User & { id: string }) | Promise<User & { id: string }>
|
||||
clientId: string
|
||||
clientSecret: string | Record<string, unknown>
|
||||
idToken?: boolean
|
||||
}
|
||||
|
||||
export interface AppProvider extends Pick<Provider, "id" | "name" | "type"> {
|
||||
signinUrl: string
|
||||
callbackUrl: string
|
||||
}
|
||||
|
||||
export interface DefaultProviders {
|
||||
Apple: Apple
|
||||
Attlassian: Atlassian
|
||||
Auth0: Auth0
|
||||
AzureADB2C: AzureADB2C
|
||||
Basecamp: Basecamp
|
||||
BattleNet: BattleNet
|
||||
Box: Box
|
||||
Bungie: Bungie
|
||||
Cognito: Cognito
|
||||
Credentials: Credentials
|
||||
Discord: Discord
|
||||
Email: Email
|
||||
EVEOnline: EVEOnline
|
||||
Facebook: Facebook
|
||||
FACEIT: FACEIT
|
||||
Foursquare: Foursquare
|
||||
FusionAuth: FusionAuth
|
||||
GitHub: GitHub
|
||||
GitLab: GitLab
|
||||
Google: Google
|
||||
IdentityServer4: IdentityServer4
|
||||
Instagram: Instagram
|
||||
Kakao: Kakao
|
||||
LINE: LINE
|
||||
LinkedIn: LinkedIn
|
||||
MailRu: MailRu
|
||||
Medium: Medium
|
||||
Netlify: Netlify
|
||||
Okta: Okta
|
||||
Osso: Osso
|
||||
Reddit: Reddit
|
||||
Salesforce: Salesforce
|
||||
Slack: Slack
|
||||
Spotify: Spotify
|
||||
Strava: Strava
|
||||
Twitch: Twitch
|
||||
Twitter: Twitter
|
||||
VK: VK
|
||||
Yandex: Yandex
|
||||
Zoho: Zoho
|
||||
}
|
||||
|
||||
export type Providers = Array<
|
||||
Provider | ReturnType<DefaultProviders[keyof DefaultProviders]>
|
||||
>
|
||||
|
||||
declare const Providers: DefaultProviders
|
||||
|
||||
export default Providers
|
||||
|
||||
/**
|
||||
* Email
|
||||
*/
|
||||
type Email = (
|
||||
options: ProviderEmailOptions
|
||||
) => NonNullParams<ProviderEmailOptions> & { id: "email"; type: "email" }
|
||||
|
||||
interface VerificationRequestParams extends Provider {
|
||||
identifier: string
|
||||
url: string
|
||||
baseUrl: string
|
||||
token: string
|
||||
provider: ProviderEmailOptions
|
||||
}
|
||||
|
||||
interface ProviderEmailOptions {
|
||||
name?: string
|
||||
server?: string | ProviderEmailServer
|
||||
from?: string
|
||||
maxAge?: number
|
||||
sendVerificationRequest?: (
|
||||
options: VerificationRequestParams
|
||||
) => Promise<void>
|
||||
}
|
||||
|
||||
interface ProviderEmailServer {
|
||||
host: string
|
||||
port: number
|
||||
auth: {
|
||||
user: string
|
||||
pass: string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Credentials
|
||||
*/
|
||||
type Credentials = (
|
||||
options: ProviderCredentialsOptions
|
||||
) => NonNullParams<ProviderCredentialsOptions> & {
|
||||
id: "credentials"
|
||||
type: "credentials"
|
||||
}
|
||||
|
||||
interface ProviderCredentialsOptions {
|
||||
id?: string
|
||||
name: string
|
||||
credentials: CredentialInput
|
||||
authorize: (credentials: Record<string, string>) => Promise<User | null>
|
||||
}
|
||||
|
||||
interface CredentialInput {
|
||||
[key: string]: {
|
||||
label?: string
|
||||
type?: string
|
||||
value?: string
|
||||
placeholder?: string
|
||||
}
|
||||
}
|
||||
|
||||
type OptionsBase = {
|
||||
[K in keyof Omit<Provider, "id">]?: Provider[K]
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider options
|
||||
* @link https://next-auth.js.org/configuration/providers#oauth-provider-options
|
||||
*/
|
||||
interface ProviderCommonOptions extends OptionsBase {
|
||||
authorizationParams?: Record<string, string>
|
||||
clientId: string
|
||||
clientSecret: string
|
||||
headers?: Record<string, any>
|
||||
idToken?: boolean
|
||||
name?: string
|
||||
protection?: "pkce" | "state" | "both" | "none"
|
||||
state?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Apple
|
||||
*/
|
||||
type Apple = (
|
||||
options: ProviderAppleOptions
|
||||
) => Provider<"apple"> & { protection: "none" }
|
||||
|
||||
interface ProviderAppleOptions
|
||||
extends Omit<ProviderCommonOptions, "clientSecret"> {
|
||||
name?: string
|
||||
clientId: string
|
||||
clientSecret: Record<"appleId" | "teamId" | "privateKey" | "keyId", string>
|
||||
}
|
||||
|
||||
interface ProviderAppleSecret {
|
||||
appleId: string
|
||||
teamId: string
|
||||
privateKey: string
|
||||
keyId: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Twitter
|
||||
*/
|
||||
type Twitter = (options: ProviderCommonOptions) => Provider<"twitter">
|
||||
|
||||
/**
|
||||
* Facebook
|
||||
*/
|
||||
type Facebook = (options: ProviderCommonOptions) => Provider<"facebook">
|
||||
|
||||
/**
|
||||
* GitHub
|
||||
*/
|
||||
type GitHub = (options: ProviderGitHubOptions) => Provider<"github">
|
||||
|
||||
interface ProviderGitHubOptions extends Omit<ProviderCommonOptions, "scope"> {
|
||||
scope?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* GitLab
|
||||
*/
|
||||
type GitLab = (options: ProviderCommonOptions) => Provider<"gitlab">
|
||||
|
||||
/**
|
||||
* Slack
|
||||
*/
|
||||
type Slack = (options: ProviderCommonOptions) => Provider<"slack">
|
||||
|
||||
/**
|
||||
* Google
|
||||
*/
|
||||
type Google = (options: ProviderGoogleOptions) => Provider<"google">
|
||||
|
||||
interface ProviderGoogleOptions extends ProviderCommonOptions {
|
||||
authorizationUrl?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth0
|
||||
*/
|
||||
type Auth0 = (
|
||||
options: ProviderAuth0Options
|
||||
) => Provider<"auth0"> & { domain: string }
|
||||
|
||||
interface ProviderAuth0Options extends Omit<ProviderCommonOptions, "profile"> {
|
||||
domain: string
|
||||
profile?: (profile: Auth0Profile) => User & { id: string }
|
||||
}
|
||||
|
||||
interface Auth0Profile {
|
||||
sub: string
|
||||
nickname: string
|
||||
email: string
|
||||
picture: string
|
||||
}
|
||||
|
||||
/**
|
||||
* IS4
|
||||
*/
|
||||
|
||||
type IdentityServer4 = (
|
||||
options: ProviderIS4Options
|
||||
) => Provider<"identity-server4" | string> & { domain: string }
|
||||
|
||||
interface ProviderIS4Options extends Omit<ProviderCommonOptions, "id"> {
|
||||
id: string
|
||||
scope: string
|
||||
domain: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Discord
|
||||
*/
|
||||
type Discord = (options: ProviderCommonOptions) => Provider<"discord">
|
||||
|
||||
/**
|
||||
* Twitch
|
||||
*/
|
||||
type Twitch = (options: ProviderCommonOptions) => Provider<"twitch">
|
||||
|
||||
/**
|
||||
* Okta
|
||||
*/
|
||||
type Okta = (
|
||||
options: ProviderOktaOptions
|
||||
) => Provider<"okta"> & { domain: string }
|
||||
|
||||
interface ProviderOktaOptions extends ProviderCommonOptions {
|
||||
domain: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Battle.net
|
||||
*/
|
||||
type BattleNet = (
|
||||
options: ProviderBattleNetOptions
|
||||
) => Provider<"battlenet"> & { region: string }
|
||||
|
||||
interface ProviderBattleNetOptions extends ProviderCommonOptions {
|
||||
region: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Box
|
||||
*/
|
||||
type Box = (options: ProviderCommonOptions) => Provider<"box">
|
||||
|
||||
/**
|
||||
* Cognito
|
||||
*/
|
||||
type Cognito = (
|
||||
options: ProviderCognitoOptions
|
||||
) => Provider<"cognito"> & { domain: string }
|
||||
|
||||
interface ProviderCognitoOptions extends ProviderCommonOptions {
|
||||
domain: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Yandex
|
||||
*/
|
||||
type Yandex = (options: ProviderCommonOptions) => Provider<"yandex">
|
||||
|
||||
/**
|
||||
* LinkedIn
|
||||
*/
|
||||
type LinkedIn = (options: ProviderLinkedInOptions) => Provider<"linkedin">
|
||||
|
||||
interface ProviderLinkedInOptions extends ProviderCommonOptions {
|
||||
scope?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Spotify
|
||||
*/
|
||||
type Spotify = (options: ProviderSpotifyOptions) => Provider<"spotify">
|
||||
|
||||
interface ProviderSpotifyOptions extends ProviderCommonOptions {
|
||||
scope?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Basecamp
|
||||
*/
|
||||
type Basecamp = (options: ProviderCommonOptions) => Provider<"basecamp">
|
||||
|
||||
/**
|
||||
* Reddit
|
||||
*/
|
||||
type Reddit = (options: ProviderCommonOptions) => Provider<"reddit">
|
||||
|
||||
/**
|
||||
* Atlassian
|
||||
*/
|
||||
type Atlassian = (options: ProviderCommonOptions) => Provider<"atlassian">
|
||||
|
||||
/**
|
||||
* AzureADB2C
|
||||
*/
|
||||
type AzureADB2C = (
|
||||
options: ProviderAzureADB2COptions
|
||||
) => Provider<"azure-ad-b2c">
|
||||
|
||||
interface ProviderAzureADB2COptions extends ProviderCommonOptions {
|
||||
tenantId?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Bungie
|
||||
*/
|
||||
type Bungie = (options: ProviderCommonOptions) => Provider<"bungie">
|
||||
|
||||
/**
|
||||
* EVEOnline
|
||||
*/
|
||||
type EVEOnline = (options: ProviderCommonOptions) => Provider<"eveonline">
|
||||
|
||||
/**
|
||||
* FACEIT
|
||||
*/
|
||||
type FACEIT = (options: ProviderCommonOptions) => Provider<"faceit">
|
||||
|
||||
/**
|
||||
* Foursquare
|
||||
*/
|
||||
type Foursquare = (options: ProviderCommonOptions) => Provider<"foursquare">
|
||||
|
||||
/**
|
||||
* FusionAuth
|
||||
*/
|
||||
type FusionAuth = (options: ProviderFusionAuthOptions) => Provider<"fusionauth">
|
||||
|
||||
interface ProviderFusionAuthOptions extends ProviderCommonOptions {
|
||||
tenantId?: string
|
||||
domain?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Instagram
|
||||
*/
|
||||
type Instagram = (options: ProviderCommonOptions) => Provider<"instagram">
|
||||
|
||||
/**
|
||||
* Kakao
|
||||
*/
|
||||
type Kakao = (options: ProviderCommonOptions) => Provider<"kakao">
|
||||
|
||||
/**
|
||||
* LINE
|
||||
*/
|
||||
type LINE = (options: ProviderCommonOptions) => Provider<"line">
|
||||
|
||||
/**
|
||||
* MailRu
|
||||
*/
|
||||
type MailRu = (options: ProviderCommonOptions) => Provider<"mailru">
|
||||
|
||||
/**
|
||||
* Medium
|
||||
*/
|
||||
type Medium = (options: ProviderCommonOptions) => Provider<"medium">
|
||||
|
||||
/**
|
||||
* Netlify
|
||||
*/
|
||||
type Netlify = (options: ProviderCommonOptions) => Provider<"netlify">
|
||||
|
||||
/**
|
||||
* Osso
|
||||
*/
|
||||
type Osso = (options: ProviderCommonOptions) => Provider<"osso">
|
||||
|
||||
/**
|
||||
* Salesforce
|
||||
*/
|
||||
type Salesforce = (options: ProviderCommonOptions) => Provider<"salesforce">
|
||||
|
||||
/**
|
||||
* Strava
|
||||
*/
|
||||
type Strava = (options: ProviderCommonOptions) => Provider<"strava">
|
||||
|
||||
/**
|
||||
* VK
|
||||
*/
|
||||
type VK = (options: ProviderCommonOptions) => Provider<"vk">
|
||||
|
||||
/**
|
||||
* Zoho
|
||||
*/
|
||||
type Zoho = (options: ProviderCommonOptions) => Provider<"zoho">
|
||||
26
types/tests/adapters.test.ts
Normal file
26
types/tests/adapters.test.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import Adapters, { TypeORMAdapter } from "next-auth/adapters"
|
||||
|
||||
// ExpectType TypeORMAdapter["Adapter"]
|
||||
Adapters.Default({
|
||||
type: "sqlite",
|
||||
database: ":memory:",
|
||||
synchronize: true,
|
||||
})
|
||||
|
||||
// ExpectType TypeORMAdapter
|
||||
Adapters.TypeORM.Adapter({
|
||||
type: "sqlite",
|
||||
database: ":memory:",
|
||||
synchronize: true,
|
||||
})
|
||||
|
||||
// ExpectType PrismaAdapter
|
||||
Adapters.Prisma.Adapter({
|
||||
prisma: {},
|
||||
modelMapping: {
|
||||
User: "foo",
|
||||
Account: "bar",
|
||||
Session: "session",
|
||||
VerificationRequest: "foo",
|
||||
},
|
||||
})
|
||||
83
types/tests/client.test.ts
Normal file
83
types/tests/client.test.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import * as client from "next-auth/client"
|
||||
import { nextReq } from "./test-helpers"
|
||||
|
||||
const clientSession = {
|
||||
user: {
|
||||
name: "Bruce",
|
||||
email: "bruce@lee.com",
|
||||
image: "path/to/img",
|
||||
},
|
||||
accessToken: "123z",
|
||||
expires: "1234",
|
||||
}
|
||||
|
||||
// $ExpectType [Session | null | undefined, boolean]
|
||||
client.useSession()
|
||||
|
||||
// $ExpectType Promise<Session | null>
|
||||
client.getSession({ req: nextReq })
|
||||
|
||||
// $ExpectType Promise<Session | null>
|
||||
client.session({ req: nextReq })
|
||||
|
||||
// $ExpectType Promise<Record<string, AppProvider> | null>
|
||||
client.getProviders()
|
||||
|
||||
// $ExpectType Promise<Record<string, AppProvider> | null>
|
||||
client.providers()
|
||||
|
||||
// $ExpectType Promise<string | null>
|
||||
client.getCsrfToken({ req: nextReq })
|
||||
|
||||
// $ExpectType Promise<string | null>
|
||||
client.csrfToken({ req: nextReq })
|
||||
|
||||
// $ExpectType Promise<void>
|
||||
client.signin("github", { data: "foo", redirect: false }, { login: "username" })
|
||||
|
||||
// $ExpectType Promise<SignInResponse>
|
||||
client.signin("credentials", { data: "foo", redirect: false })
|
||||
|
||||
// $ExpectType Promise<SignInResponse>
|
||||
client.signin("email", { data: "foo", redirect: false })
|
||||
|
||||
// $ExpectType Promise<void>
|
||||
client.signin("email", { data: "foo", redirect: true })
|
||||
|
||||
// $ExpectType Promise<void>
|
||||
client.signout()
|
||||
|
||||
// $ExpectType Promise<void>
|
||||
client.signout({ callbackUrl: "https://foo.com/callback", redirect: true })
|
||||
|
||||
// $ExpectType ReactElement<any, any> | null
|
||||
client.Provider({
|
||||
session: clientSession,
|
||||
options: {
|
||||
baseUrl: "https://foo.com",
|
||||
basePath: "/",
|
||||
clientMaxAge: 1234,
|
||||
},
|
||||
})
|
||||
|
||||
// $ExpectType ReactElement<any, any> | null
|
||||
client.Provider({
|
||||
session: clientSession,
|
||||
})
|
||||
|
||||
// $ExpectType ReactElement<any, any> | null
|
||||
client.Provider({
|
||||
session: undefined,
|
||||
options: {},
|
||||
})
|
||||
|
||||
// $ExpectType ReactElement<any, any> | null
|
||||
client.Provider({
|
||||
session: null,
|
||||
options: {
|
||||
baseUrl: "https://foo.com",
|
||||
basePath: "/",
|
||||
clientMaxAge: 1234,
|
||||
keepAlive: 4321,
|
||||
},
|
||||
})
|
||||
26
types/tests/jwt.test.ts
Normal file
26
types/tests/jwt.test.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as JWTType from "next-auth/jwt"
|
||||
import { nextReq } from "./test-helpers"
|
||||
|
||||
// $ExpectType Promise<string>
|
||||
JWTType.encode({
|
||||
token: { key: "value" },
|
||||
secret: "secret",
|
||||
})
|
||||
|
||||
// $ExpectType Promise<WithAdditionalParams<JWT>>
|
||||
JWTType.decode({
|
||||
token: "token",
|
||||
secret: "secret",
|
||||
})
|
||||
|
||||
// $ExpectType Promise<string>
|
||||
JWTType.getToken({
|
||||
req: nextReq,
|
||||
raw: true,
|
||||
})
|
||||
|
||||
// $ExpectType Promise<WithAdditionalParams<JWT>>
|
||||
JWTType.getToken({
|
||||
req: nextReq,
|
||||
secret: "secret",
|
||||
})
|
||||
259
types/tests/providers.test.ts
Normal file
259
types/tests/providers.test.ts
Normal file
@@ -0,0 +1,259 @@
|
||||
import Providers from "next-auth/providers"
|
||||
|
||||
// $ExpectType NonNullParams<ProviderEmailOptions> & { id: "email"; type: "email"; }
|
||||
Providers.Email({
|
||||
server: "path/to/server",
|
||||
from: "path/from",
|
||||
})
|
||||
|
||||
// $ExpectType NonNullParams<ProviderEmailOptions> & { id: "email"; type: "email"; }
|
||||
Providers.Email({
|
||||
server: {
|
||||
host: "host",
|
||||
port: 123,
|
||||
auth: {
|
||||
user: "foo",
|
||||
pass: "123",
|
||||
},
|
||||
},
|
||||
from: "path/from",
|
||||
})
|
||||
|
||||
// $ExpectType NonNullParams<ProviderCredentialsOptions> & { id: "credentials"; type: "credentials"; }
|
||||
Providers.Credentials({
|
||||
id: "login",
|
||||
name: "account",
|
||||
credentials: {
|
||||
user: {
|
||||
label: "Password",
|
||||
type: "password",
|
||||
},
|
||||
password: {
|
||||
label: "Password",
|
||||
type: "password",
|
||||
},
|
||||
},
|
||||
authorize: async (credentials) => {
|
||||
const user = {
|
||||
/* fetched user */
|
||||
}
|
||||
return user
|
||||
},
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"apple", "oauth"> & { protection: "none"; }
|
||||
Providers.Apple({
|
||||
clientId: "foo123",
|
||||
clientSecret: {
|
||||
appleId: "foo@icloud.com",
|
||||
teamId: "foo",
|
||||
privateKey: "123xyz",
|
||||
keyId: "1234",
|
||||
},
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"twitter", "oauth">
|
||||
Providers.Twitter({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"facebook", "oauth">
|
||||
Providers.Facebook({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"github", "oauth">
|
||||
Providers.GitHub({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"github", "oauth">
|
||||
Providers.GitHub({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
scope: "change:thing read:that",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"gitlab", "oauth">
|
||||
Providers.GitLab({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"slack", "oauth">
|
||||
Providers.Slack({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"google", "oauth">
|
||||
Providers.Google({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"google", "oauth">
|
||||
Providers.Google({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
authorizationUrl: "https://foo.google.com",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"auth0", "oauth"> & { domain: string; }
|
||||
Providers.Auth0({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
domain: "https://foo.auth0.com",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"auth0", "oauth"> & { domain: string; }
|
||||
Providers.Auth0({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
domain: "https://foo.auth0.com",
|
||||
profile: () => ({
|
||||
id: "foo123",
|
||||
name: "foo",
|
||||
email: "foo@bar.io",
|
||||
image: "https://foo.auth0.com/image/1.png",
|
||||
}),
|
||||
})
|
||||
|
||||
// $ExpectType Provider<string, "oauth"> & { domain: string; }
|
||||
Providers.IdentityServer4({
|
||||
id: "identity-server4",
|
||||
name: "IdentityServer4",
|
||||
scope: "change:thing read:that",
|
||||
domain: "https://foo.is4.com",
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"discord", "oauth">
|
||||
Providers.Discord({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
scope: "identify",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"twitch", "oauth">
|
||||
Providers.Twitch({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"okta", "oauth"> & { domain: string; }
|
||||
Providers.Okta({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
domain: "https://foo.auth0.com",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"battlenet", "oauth"> & { region: string; }
|
||||
Providers.BattleNet({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
region: "europe",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"box", "oauth">
|
||||
Providers.Box({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"cognito", "oauth"> & { domain: string; }
|
||||
Providers.Cognito({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
domain: "https://foo.auth0.com",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"yandex", "oauth">
|
||||
Providers.Yandex({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"linkedin", "oauth">
|
||||
Providers.LinkedIn({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
scope: "r_emailaddress r_liteprofile",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"spotify", "oauth">
|
||||
Providers.Spotify({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"spotify", "oauth">
|
||||
Providers.Spotify({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
scope: "user-read-email",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"basecamp", "oauth">
|
||||
Providers.Basecamp({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"reddit", "oauth">
|
||||
Providers.Reddit({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"azure-ad-b2c", "oauth">
|
||||
Providers.AzureADB2C({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
scope: "offline_access User.Read",
|
||||
tenantId: "tenantId",
|
||||
idToken: true,
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"fusionauth", "oauth">
|
||||
Providers.FusionAuth({
|
||||
name: "FusionAuth",
|
||||
domain: "domain",
|
||||
clientId: "clientId",
|
||||
clientSecret: "clientSecret",
|
||||
tenantId: "tenantId",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"faceit", "oauth">
|
||||
Providers.FACEIT({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"instagram", "oauth">
|
||||
Providers.Instagram({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"kakao", "oauth">
|
||||
Providers.Kakao({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"osso", "oauth">
|
||||
Providers.Osso({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
|
||||
// $ExpectType Provider<"zoho", "oauth">
|
||||
Providers.Zoho({
|
||||
clientId: "foo123",
|
||||
clientSecret: "bar123",
|
||||
})
|
||||
255
types/tests/server.test.ts
Normal file
255
types/tests/server.test.ts
Normal file
@@ -0,0 +1,255 @@
|
||||
import Providers, { AppProvider, Provider } from "next-auth/providers"
|
||||
import Adapters, {
|
||||
Adapter,
|
||||
EmailAppProvider,
|
||||
Profile,
|
||||
Session,
|
||||
VerificationRequest,
|
||||
} from "next-auth/adapters"
|
||||
import NextAuth, * as NextAuthTypes from "next-auth"
|
||||
import { IncomingMessage, ServerResponse } from "http"
|
||||
import * as JWTType from "next-auth/jwt"
|
||||
import { Socket } from "net"
|
||||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
|
||||
const req: NextApiRequest = Object.assign(new IncomingMessage(new Socket()), {
|
||||
query: {},
|
||||
cookies: {},
|
||||
body: {},
|
||||
env: {},
|
||||
})
|
||||
|
||||
const res: NextApiResponse = Object.assign(new ServerResponse(req), {
|
||||
send: (body: string) => undefined,
|
||||
json: (body: string) => undefined,
|
||||
status: (code: number) => res,
|
||||
redirect: (statusOrUrl: number | string, url?: string) => res as any,
|
||||
setPreviewData: (data: object | string) => res,
|
||||
clearPreviewData: () => res,
|
||||
})
|
||||
|
||||
const pageOptions = {
|
||||
signin: "path/to/signin",
|
||||
signout: "path/to/signout",
|
||||
error: "path/to/error",
|
||||
verifyRequest: "path/to/verify",
|
||||
newUsers: "path/to/signup",
|
||||
}
|
||||
|
||||
const simpleConfig = {
|
||||
site: "https://foo.com",
|
||||
providers: [
|
||||
Providers.GitHub({
|
||||
clientId: "123",
|
||||
clientSecret: "123",
|
||||
scope:
|
||||
"user public_repo repo repo_deployment repo:status read:repo_hook read:org read:public_key read:gpg_key",
|
||||
}),
|
||||
],
|
||||
}
|
||||
|
||||
const exampleUser: NextAuthTypes.User = {
|
||||
name: "",
|
||||
image: "",
|
||||
email: "",
|
||||
}
|
||||
|
||||
const exampleSession: Session = {
|
||||
userId: "",
|
||||
accessToken: "",
|
||||
sessionToken: "",
|
||||
expires: new Date(),
|
||||
}
|
||||
|
||||
const exampleVerificatoinRequest: VerificationRequest = {
|
||||
identifier: "",
|
||||
token: "",
|
||||
expires: new Date(),
|
||||
}
|
||||
|
||||
const adapter: Adapter<
|
||||
NextAuthTypes.User,
|
||||
Profile,
|
||||
Session,
|
||||
VerificationRequest
|
||||
> = {
|
||||
async getAdapter(appOptions: NextAuthTypes.AppOptions) {
|
||||
return {
|
||||
createUser: async (profile: Profile) => exampleUser,
|
||||
getUser: async (id: string) => exampleUser,
|
||||
getUserByEmail: async (email: string) => exampleUser,
|
||||
getUserByProviderAccountId: async (
|
||||
providerId: string,
|
||||
providerAccountId: string
|
||||
) => exampleUser,
|
||||
updateUser: async (user: NextAuthTypes.User) => exampleUser,
|
||||
linkAccount: async (
|
||||
userId: string,
|
||||
providerId: string,
|
||||
providerType: string,
|
||||
providerAccountId: string,
|
||||
refreshToken: string,
|
||||
accessToken: string,
|
||||
accessTokenExpires: number
|
||||
) => undefined,
|
||||
createSession: async (user: NextAuthTypes.User) => exampleSession,
|
||||
getSession: async (sessionToken: string) => exampleSession,
|
||||
updateSession: async (session: Session, force?: boolean) =>
|
||||
exampleSession,
|
||||
deleteSession: async (sessionToken: string) => undefined,
|
||||
createVerificationRequest: async (
|
||||
email: string,
|
||||
url: string,
|
||||
token: string,
|
||||
secret: string,
|
||||
provider: EmailAppProvider,
|
||||
options: NextAuthTypes.AppOptions
|
||||
) => exampleVerificatoinRequest,
|
||||
getVerificationRequest: async (
|
||||
email: string,
|
||||
verificationToken: string,
|
||||
secret: string,
|
||||
provider: AppProvider
|
||||
) => exampleVerificatoinRequest,
|
||||
deleteVerificationRequest: async (
|
||||
email: string,
|
||||
verificationToken: string,
|
||||
secret: string,
|
||||
provider: AppProvider
|
||||
) => undefined,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const allConfig = {
|
||||
providers: [
|
||||
Providers.Twitter({
|
||||
clientId: "123",
|
||||
clientSecret: "123",
|
||||
}),
|
||||
],
|
||||
database: "path/to/db",
|
||||
debug: true,
|
||||
secret: "my secret",
|
||||
session: {
|
||||
jwt: true,
|
||||
maxAge: 365,
|
||||
updateAge: 60,
|
||||
},
|
||||
jwt: {
|
||||
secret: "secret-thing",
|
||||
maxAge: 365,
|
||||
encryption: true,
|
||||
signingKey: "some-key",
|
||||
encryptionKey: "some-key",
|
||||
encode: async () => "foo",
|
||||
decode: async () => ({}),
|
||||
},
|
||||
pages: pageOptions,
|
||||
callbacks: {
|
||||
async signIn(
|
||||
user: NextAuthTypes.User,
|
||||
account: Record<string, unknown>,
|
||||
profile: Record<string, unknown>
|
||||
) {
|
||||
return true
|
||||
},
|
||||
async redirect(url: string, baseUrl: string) {
|
||||
return "path/to/foo"
|
||||
},
|
||||
async session(
|
||||
session: NextAuthTypes.Session,
|
||||
userOrToken: NextAuthTypes.User
|
||||
) {
|
||||
return { ...session }
|
||||
},
|
||||
async jwt(
|
||||
token: JWTType.JWT,
|
||||
user: NextAuthTypes.User,
|
||||
account: Record<string, unknown>,
|
||||
profile: Record<string, unknown>,
|
||||
isNewUser: boolean
|
||||
) {
|
||||
return token
|
||||
},
|
||||
},
|
||||
events: {
|
||||
async signIn(message: string) {
|
||||
return undefined
|
||||
},
|
||||
async signOut(message: string) {
|
||||
return undefined
|
||||
},
|
||||
async createUser(message: string) {
|
||||
return undefined
|
||||
},
|
||||
async linkAccount(message: string) {
|
||||
return undefined
|
||||
},
|
||||
async session(message: string) {
|
||||
return undefined
|
||||
},
|
||||
async error(message: string) {
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
adapter,
|
||||
useSecureCookies: true,
|
||||
cookies: {
|
||||
sessionToken: {
|
||||
name: "__Secure-next-auth.session-token",
|
||||
options: {
|
||||
httpOnly: true,
|
||||
sameSite: true as true,
|
||||
path: "/",
|
||||
secure: true,
|
||||
domain: "foo.com",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const customProvider: Provider<"google"> = {
|
||||
id: "google",
|
||||
name: "Google",
|
||||
type: "oauth",
|
||||
version: "2.0",
|
||||
scope:
|
||||
"https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
|
||||
params: { grant_type: "authorization_code" },
|
||||
accessTokenUrl: "https://accounts.google.com/o/oauth2/token",
|
||||
requestTokenUrl: "https://accounts.google.com/o/oauth2/auth",
|
||||
authorizationUrl:
|
||||
"https://accounts.google.com/o/oauth2/auth?response_type=code",
|
||||
profileUrl: "https://www.googleapis.com/oauth2/v1/userinfo?alt=json",
|
||||
async profile(profile, tokens) {
|
||||
return {
|
||||
id: profile.id,
|
||||
name: profile.name,
|
||||
email: profile.email,
|
||||
image: profile.picture,
|
||||
}
|
||||
},
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
}
|
||||
|
||||
const customProviderConfig = {
|
||||
site: "https://foo.com",
|
||||
providers: [customProvider],
|
||||
}
|
||||
|
||||
// $ExpectType void | Promise<void>
|
||||
NextAuth(simpleConfig)
|
||||
|
||||
// $ExpectType void | Promise<void>
|
||||
NextAuth(allConfig)
|
||||
|
||||
// $ExpectType void | Promise<void>
|
||||
NextAuth(customProviderConfig)
|
||||
|
||||
// $ExpectType void | Promise<void>
|
||||
NextAuth(req, res, simpleConfig)
|
||||
|
||||
// $ExpectType void | Promise<void>
|
||||
NextAuth(req, res, allConfig)
|
||||
13
types/tests/test-helpers.ts
Normal file
13
types/tests/test-helpers.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { IncomingMessage, ServerResponse } from "http"
|
||||
import { Socket } from "net"
|
||||
import { NextApiRequest } from "next"
|
||||
|
||||
export const nextReq: NextApiRequest = Object.assign(
|
||||
new IncomingMessage(new Socket()),
|
||||
{
|
||||
query: {},
|
||||
cookies: {},
|
||||
body: {},
|
||||
env: {},
|
||||
}
|
||||
)
|
||||
23
types/tsconfig.json
Normal file
23
types/tsconfig.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": ["es6", "dom"],
|
||||
"jsx": "react",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"esModuleInterop": true,
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"next-auth": ["."],
|
||||
"next-auth/providers": ["./providers"],
|
||||
"next-auth/adapters": ["./adapters"],
|
||||
"next-auth/client": ["./client"],
|
||||
"next-auth/jwt": ["./jwt"],
|
||||
"next": ["./_next"]
|
||||
}
|
||||
}
|
||||
}
|
||||
6
types/tslint.json
Normal file
6
types/tslint.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "dtslint/dtslint.json",
|
||||
"rules": {
|
||||
"semicolon": false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user