-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: simplify Adapter API #2361
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/nextauthjs/next-auth/4q1cdN9ZmakYQy9zBsorDP4LHYPc |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## next #2361 +/- ##
==========================================
- Coverage 11.56% 11.52% -0.05%
==========================================
Files 85 84 -1
Lines 1314 1319 +5
Branches 370 378 +8
==========================================
Hits 152 152
- Misses 966 970 +4
- Partials 196 197 +1 ☔ View full report in Codecov by Sentry. |
types/adapters.d.ts
Outdated
export interface AdapterSession extends Omit<Session, "expires"> { | ||
expires: Date | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Session["expires"]
is a string by default so it can easily be passed to the client, but it makes more sense to retrieve it as Date
from DB.
See: vercel/next.js#11498
types/adapters.d.ts
Outdated
import { Awaitable } from "./internals/utils" | ||
|
||
export interface AdapterUser extends User { | ||
emailVerified?: Date | null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emailVerified
is always set by createUser
and can be updated by updateUser
in the DB.
6c7f10a
to
7b4a3e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
I noticed one minor thing then coding the neo4j adapter. Most of the dates are instances of JS Date. All except account.expires, which is epoch. Is this intentionally different, or something that should be changed? |
BREAKING CHANGE: `prisma-legacy` is now gone. Use `@next-auth/prisma-adapter`. Any features from the old adapter will be migrated over to the new one eventually. This is done so we can require the same default set of options from all the built-in providers, rather than allowing ambiguity on what an official adapter has to support. The `TypeORM` adapter will probably be the only one migrated as-is, but in the future, we would like to break it down to lighter-weight adapters that only support single databases. Adapters no longer have to return a `getAdapter()` method, they can return the actual adapter methods instead. All the values previously being provided through the arguments of `getAdapter` will now be available in a more digestible format directly in the concerning methods. This behavior was created so that connections could be handled more efficiently. Our review has shown that currently, the TypeORM adapter is the only one that does not handle connections out-of-the-box, so we are going to look into how we can create a wrapper/util function to make it work in the new version. For all other adapters, this will be a huge gain, as with this new API, methods are actually overrideable without creating a whole new custom adapter! 🥳 Example: ```js function MySlightlyCustomAdapter(...args) { const adapter = AdapterFromSomeoneElse(...args) adapter.someMethodIWantToModify = (...args) => { // Much better implementation goes here. } return adapter } ``` **The following method names are changing:** ```diff - getSession + getSessionAndUser ``` This method now requires that you return both the user and the session as `{user, session}`. If any of these could not be retrieved, you will have to return `null` instead. (In other words, this must be a transaction.) This requires one less database call, improving the user session retrieval. Any expiry logic included in the Adapter before is now done in the core as well. ```diff - createVerificationRequest + createVerificationToken ``` Better describes the functionality. This method no longer needs to call `provider.sendVerificationRequest`, we are moving this into the core. This responsibility shouldn't have fallen to the adapter in the first place. `createVerificationToken` will now receive a `VerificationToken` object, which looks like this: ```ts interface VerificationToken { identifier: string expires: Date token: string } ``` The token provided is already hashed, so nothing has to be done, simply write it to your database. (Here we lift up the responsibility from the adapter to hash tokens) ```diff - getVerificationRequest + useVerificationToken ``` Better describes the functionality. It now also has the responsibility to delete the used-up token from the database. Most ORMs should support retrieving the value while deleting it at the same time, so it will reduce the number of database calls. ``` diff - deleteVerificationRequest ``` This method is gone. See `useVerificationToken`. Most of the method signatures have been changed, have a look at the [TypeScript interface](https://github.com/nextauthjs/next-auth/blob/ba4ec5faa357457661ccf55a4981fcef0514dd9b/types/adapters.d.ts) to get a better picture.
In this PR, I am significantly simplifying the
Adapter
API. Hopefully, this will result in a better DX (as adding new adapters will require less boilerplate) and a better UX, as we will now merge database queries into single transactions where possible for fewer database calls and thus faster responses. 🔥If you are using an official adapter, you won't need to do any changes.
getAdapter
Related issues: #779, #876
BREAKING CHANGE:
prisma-legacy
is now gone. Use@next-auth/prisma-adapter
. Any features from the old adapter will be migrated over to the new one eventually. This is done so we can require the same default set of options from all the built-in providers, rather than allowing ambiguity on what an official adapter has to support. TheTypeORM
adapter will probably be the only one migrated as-is, but in the future we would like to break it down to lighter-weight adapters that only support single databases.Adapters no longer have to return a
getAdapter()
method, they can return the actual adapter methods instead. All the values previously being provided through the arguments ofgetAdapter
will now be available in a more digestible format directly in the concerning methods. This behavior was created so that connections could be handled more efficiently. Our review has shown that currently, the TypeORM adapter is the only one that does not handle connections out-of-the-box, so we are going to look into how we can create a wrapper/util function to make it work in the new version. For all other adapters, this will be a huge gain, as with this new API, methods are actually overrideable without creating a whole new custom adapter! 🥳Example:
The following method names are changing:
This method now requires that you return both the user and the session as
{user, session}
. If any of these could not be retrieved, you will have to returnnull
instead. (In other words, this must be a transaction.) This requires one less database call, improving the user session retrieval. Any expiry logic included in the Adapter before is now done in the core as well.Better describes the functionality. This method no longer needs to call
provider.sendVerificationRequest
, we are moving this into the core. This responsibility shouldn't have fallen to the adapter in the first place.createVerificationToken
will now receive aVerificationToken
object, which looks like this:The token provided is already hashed, so nothing has to be done, simply write it to your database. (Here we lift up the responsibility from the adapter to hash tokens)
Better describes the functionality. It now also has the responsibility to delete the used-up token from the database. Most ORMs should support retrieving the value while deleting it at the same time, so it will reduce the number of database calls.
- deleteVerificationRequest
This method is gone. See
useVerificationToken
.Most of the method signatures have been changed, have a look at the TypeScript interface to get a better picture.