Skip to content

Commit ffd0601

Browse files
zackdotcomputer0ubbebalazsorban44kripodanubisoft
authored
fix(ts): improve events handlers' types (#1853)
* Constrain the adapters type generics more accurately * Add types for the incoming messages to events callbacks * Code review comments from @lluia * Rebase from trunk and fix merge conflicts * Update documentation * Rip out generics * fix(build): export aliases from client (#1909) * docs(provider): update providers documentation (#1900) * docs(providers): update providers documentation - delineate clearly the 3 provider types (oauth, email, credentials) - make each section structure consistent - update the option list for every provider type - use emojis * docs(providers): instructions on new provider types * docs(providers): remove emojis To stay consistent with the rest of our documentation, for now we should not emojis on the sections of our documentation pages. * docs(providers): reword sentence Co-authored-by: Balázs Orbán <[email protected]> * docs(providers): add tip on overriding options * docs(providers): clarify `params` option usage * docs(providers): make names list inline Co-authored-by: Balázs Orbán <[email protected]> * fix(ts): unset generics defaults for overriding (#1891) Co-authored-by: Lluis Agusti <[email protected]> * fix(ts): tweak Adapter related types (#1914) Contains the following squashed commits: * fix(ts): make first adapter parameter non-optional * fix(ts): make defaulted values non-optional internally * test(ts): fix linting * fix(page): don't pass params to custom signout page (#1912) * For the custom signout page addressed two issues with the query params being added to the signout url. A conditional check on the error value is now made before adding it as a query param. Also added a conditional check on the callbackUrl and if present that then gets appended as a query param to the signout api call. * Changed fix for bug #192 to have no querystring params in the custom signout page url. Co-authored-by: anubisoft <[email protected]> Co-authored-by: Lluis Agusti <[email protected]> * docs(www): fix typo (#1922) * docs(provider): Update IdentityServer 4 demo configuration (#1932) * Responding to code review comments * Fix tests * Fix lint error Co-authored-by: Lluis Agusti <[email protected]> Co-authored-by: Balázs Orbán <[email protected]> Co-authored-by: Kristóf Poduszló <[email protected]> Co-authored-by: Anubisoft <[email protected]> Co-authored-by: anubisoft <[email protected]> Co-authored-by: Ernie Miranda <[email protected]> Co-authored-by: Mathis Møller <[email protected]>
1 parent 7864d47 commit ffd0601

File tree

5 files changed

+173
-95
lines changed

5 files changed

+173
-95
lines changed

types/adapters.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AppOptions } from "./internals"
22
import { User, Profile, Session } from "."
3-
import { EmailConfig, SendVerificationRequest } from "./providers"
3+
import { EmailConfig } from "./providers"
44
import { ConnectionOptions } from "typeorm"
55

66
/** Legacy */

types/index.d.ts

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Minimum TypeScript Version: 3.5
1+
// Minimum TypeScript Version: 3.6
22

33
/// <reference types="node" />
44

@@ -111,7 +111,7 @@ export interface NextAuthOptions {
111111
*
112112
* [Documentation](https://next-auth.js.org/configuration/options#events) | [Events documentation](https://next-auth.js.org/configuration/events)
113113
*/
114-
events?: EventsOptions
114+
events?: Partial<JWTEventCallbacks | SessionEventCallbacks>
115115
/**
116116
* By default NextAuth.js uses a database adapter that uses TypeORM and supports MySQL, MariaDB, Postgres and MongoDB and SQLite databases.
117117
* An alternative adapter that uses Prisma, which currently supports MySQL, MariaDB and Postgres, is also included.
@@ -350,20 +350,61 @@ export interface CookiesOptions {
350350
}
351351

352352
/** [Documentation](https://next-auth.js.org/configuration/events) */
353-
export type EventType =
354-
| "signIn"
355-
| "signOut"
356-
| "createUser"
357-
| "updateUser"
358-
| "linkAccount"
359-
| "session"
360-
| "error"
353+
export type EventCallback<MessageType = unknown> = (
354+
message: MessageType
355+
) => Promise<void>
361356

362-
/** [Documentation](https://next-auth.js.org/configuration/events) */
363-
export type EventCallback = (message: any) => Promise<void>
357+
/**
358+
* If using a `credentials` type auth, the user is the raw response from your
359+
* credential provider.
360+
* For other providers, you'll get the User object from your adapter, the account,
361+
* and an indicator if the user was new to your Adapter.
362+
*/
363+
export interface SignInEventMessage {
364+
user: User
365+
account: Account
366+
isNewUser?: boolean
367+
}
364368

365-
/** [Documentation](https://next-auth.js.org/configuration/events) */
366-
export type EventsOptions = Partial<Record<EventType, EventCallback>>
369+
export interface LinkAccountEventMessage {
370+
user: User
371+
providerAccount: Record<string, unknown>
372+
}
373+
374+
/**
375+
* The various event callbacks you can register for from next-auth
376+
*/
377+
export interface CommonEventCallbacks {
378+
signIn: EventCallback<SignInEventMessage>
379+
createUser: EventCallback<User>
380+
updateUser: EventCallback<User>
381+
linkAccount: EventCallback<LinkAccountEventMessage>
382+
error: EventCallback
383+
}
384+
/**
385+
* The event callbacks will take this form if you are using JWTs:
386+
* signOut will receive the JWT and session will receive the session and JWT.
387+
*/
388+
export interface JWTEventCallbacks extends CommonEventCallbacks {
389+
signOut: EventCallback<JWT>
390+
session: EventCallback<{
391+
session: Session
392+
jwt: JWT
393+
}>
394+
}
395+
/**
396+
* The event callbacks will take this form if you are using Sessions
397+
* and not using JWTs:
398+
* signOut will receive the underlying DB adapter's session object, and session
399+
* will receive the NextAuth client session with extra data.
400+
*/
401+
export interface SessionEventCallbacks extends CommonEventCallbacks {
402+
signOut: EventCallback<Session | null>
403+
session: EventCallback<{ session: Session }>
404+
}
405+
export type EventCallbacks = JWTEventCallbacks | SessionEventCallbacks
406+
407+
export type EventType = keyof EventCallbacks
367408

368409
/** [Documentation](https://next-auth.js.org/configuration/pages) */
369410
export interface PagesOptions {

types/tests/server.test.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
import Providers, {
2-
AppProvider,
3-
EmailConfig,
4-
OAuthConfig,
5-
} from "next-auth/providers"
6-
import { Adapter, AdapterInstance } from "next-auth/adapters"
1+
import Providers, { OAuthConfig } from "next-auth/providers"
2+
import { Adapter } from "next-auth/adapters"
73
import NextAuth, * as NextAuthTypes from "next-auth"
84
import { IncomingMessage, ServerResponse } from "http"
9-
import * as JWTType from "next-auth/jwt"
105
import { Socket } from "net"
116
import { NextApiRequest, NextApiResponse } from "internals/utils"
127
import { AppOptions } from "internals"
@@ -173,22 +168,25 @@ const allConfig: NextAuthTypes.NextAuthOptions = {
173168
},
174169
},
175170
events: {
176-
async signIn(message) {
171+
async signIn(message: NextAuthTypes.SignInEventMessage) {
177172
return undefined
178173
},
179-
async signOut(message) {
174+
async signOut(message: NextAuthTypes.Session | null) {
180175
return undefined
181176
},
182-
async createUser(message) {
177+
async createUser(message: NextAuthTypes.User) {
183178
return undefined
184179
},
185-
async linkAccount(message) {
180+
async updateUser(message: NextAuthTypes.User) {
186181
return undefined
187182
},
188-
async session(message) {
183+
async linkAccount(message: NextAuthTypes.LinkAccountEventMessage) {
189184
return undefined
190185
},
191-
async error(message) {
186+
async session(message: NextAuthTypes.Session) {
187+
return undefined
188+
},
189+
async error(message: any) {
192190
return undefined
193191
},
194192
},

www/docs/configuration/events.md

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,60 @@ Events are asynchronous functions that do not return a response, they are useful
77

88
You can specify a handler for any of these events below, for debugging or for an audit log.
99

10-
```js title="pages/api/auth/[...nextauth].js"
11-
...
12-
events: {
13-
async signIn(message) { /* on successful sign in */ },
14-
async signOut(message) { /* on signout */ },
15-
async createUser(message) { /* user created */ },
16-
async linkAccount(message) { /* account linked to a user */ },
17-
async session(message) { /* session is active */ },
18-
async error(message) { /* error in authentication flow */ }
19-
}
20-
...
21-
```
22-
23-
The content of the message object varies depending on the flow (e.g. OAuth or Email authentication flow, JWT or database sessions, etc) but typically contains a user object and/or contents of the JSON Web Token and other information relevant to the event.
10+
:::note
11+
Execution of your auth API will be blocked by an `await` on your event handler. If your event handler starts any burdensome work it should not block its own promise on that work.
12+
:::
13+
14+
## Events
15+
16+
### signIn
17+
18+
Sent on successful sign in.
19+
20+
The message will be an object and contain:
21+
22+
- `user` (from your adapter or from the provider if a `credentials` type provider)
23+
- `account` (from your adapter or the provider)
24+
- `isNewUser` (whether your adapter had a user for this account already)
25+
26+
### signOut
27+
28+
Sent when the user signs out.
29+
30+
The message object is the JWT, if using them, or the adapter session object for the session that is being ended.
31+
32+
### createUser
33+
34+
Sent when the adapter is told to create a new user.
35+
36+
The message object will be the user.
37+
38+
### updateUser
39+
40+
Sent when the adapter is told to update an existing user. Currently this is only sent when the user verifies their email address.
41+
42+
The message object will be the user.
43+
44+
### linkAccount
45+
46+
Sent when an account in a given provider is linked to a user in our userbase. For example, when a user signs up with Twitter or when an existing user links their Google account.
47+
48+
The message will be an object and contain:
49+
50+
- `user`: The user object from your adapter
51+
- `providerAccount`: The object returned from the provider.
52+
53+
### session
54+
55+
Sent at the end of a request for the current session.
56+
57+
The message will be an object and contain:
58+
59+
- `session`: The session object from your adapter
60+
- `jwt`: If using JWT, the token for this session.
61+
62+
### error
63+
64+
Sent when an error occurs
65+
66+
The message could be any object relevant to describing the error.

0 commit comments

Comments
 (0)