* Refactored adapter, with less redundant logic
* Removed logic from models
* Added email verification expiry support (defaults to 24 hours)
* Refactored session expiry handling and unified it with how email expiry works
* Default session expiry is still 30 days
* Now only updates expiry for a session at most once every 24 hours by default, to reduce writes to database
* Email verification max age, session max age and how often sessions are updated (to reduce database writes) are all simple options now
* Invalid sessionTokens are now deleted from the client
* Email verfication messages are now deleted once used (or when expired)
* Debug output is now an option (set `debug: true` to enable)
* Removed confusing options / callback from default adapter (except for passing in custom models/schemas)
* Adapter can now access all next-auth options, to make configuration easier
This makes it possible to configure session tokens to be deleted when the browser window is closed if desired.
Session expiry can now be treated as an optional field (but is always set and enforced by default).
* By default, sessions are 30 day 'rolling sessions' and the timestamp for when they expire is extended when they are accessed to keep them alive.
* When sessions expire (ie after 30 days of inactivity), session object returns empty (as if there is no session) and users must sign in in again.
* Cleaning up old sessions from the database is not currently handled by the default adapter, but I do intend to add some logic to do this (added @TODO).
* The session expiry date can be changed by passing a custom updateSession() callback handler function in the options to the default adapter.
Using a custom `updateSession()` method with the default adapter, it is possible to specify other behaviour:
e.g.
* Disable rolling sessions (e.g. force a new login every X days).
* Create a session expiry date far into the future on initial sign in, so that they effectively never expire.
* Set a decently long max expiry time (e.g. 90+ days) but only actually update the session expiry time if the current expiry time is < 30 days; so that sessions stay valid for 30 days (and at most 90 days of inactivity) so that idle sessions are valid for at least 30 days (and maybe longer) but you don't need to write to your session database as often (useful if slow/expensive).
Note: Adapter options are passed as second option to the default adapter (the first option being the DB connection details). This is probably confusing and might be a design mistake.
const adapter = Adapter.Default({ /* database object * /}, {
updateSession: async (session, isNewSession) => {
// 1st arg is the current session (or null) so it's easy to check current
// expiry date, get user specific info, etc.
// 2nd arg is true if this is a brand new session.
//
// Function should return an ISO date (e.g. toISOString) or false/null to
// prevent an update from being applied; but should always return a session
// if isNewSession is set or the sign in will fail.
}
})
Relying on on Adapter options is a little obtuse / confusing and so I'm considering it an 'advanced option' right now. In future, we might change how session expiry dates and behaviour is set to make it easier.
Note: There are some other updates in this PR, that's just from the linter and some improvements to formatting of contributing guide.
Although previous config worked locally, it turns out it isn't compatible with now.sh.
It turns out when deploying from a subdir (like 'www') on now.sh the contents of the parent directory isn't avalible.
* Now has 'www' directory at root level for the website (was 'docs').
* The 'docs' directory now only contains Markdown docs.
* Docusarus config looks in '../docs' for the docs.
This is deployed with now.sh to https://next-auth-docs.now.sh
* Better error handling, more specific messages.
* Async email option has been removed as was problematic on serverless.
* Refactored email sign in so that sending emails is now handled by the email provider.
* How email configuration works is now more customimzable - and cleanly seperated from database logic.
* Now possible to define logic for async email (e.g. pass messages to a queue) or use any email provider or API.
* Email providers can now set the option 'async' to 'true' to send emails AFTER displaying confirmation page, or to 'false' send emails BEFORE returning to the user. Defaults to false.
Setting it to true is faster for the user, but is hard to debug as it's not easy to know if it worked or not.
* Fixed bug with unsubscribe option.
* Moved oAuth and Email signin handlers together in `lib` dir.
* Added email verification adapater methods
* Added support on sign in page for email providers
* Added check email page
* Added SMTP transport to send email messages
Includes refactoring of model and handlers for the email verification flow.
Brings them into line with other methods.
Not refactoring other getUser* methods at this time as may be helpful for them to be explicit about what will be passed.
* Renamed 'Session ID' to 'Session Token'.
* Applies to model, functions and default cookie name.
* This avoids confusion by seperating it from 'id' property in session model.
* Updated documentation
* `lint` and `lint:fix` now seperate scripts
* Fixed simple linting issues
Still some linter errors as the email sign up flow is a work in progress.
Twitch recently made breaking changes to their oAuth API.
It no longer works like other oAuth 2 providers. The documentation for it is extensive, but poor quality.
This update still has intermittant problems, but as far as I can make out the problem is the API; they have completed their roll out to 100% but it's still failing sometimes.
* Run `npm run lint` to find (and where possible, fix) linting issues.
* Includes some minor refactoring, including directory structure for adapters and models, so that code for an adapter and the models for it sit together.
Background:
I've added elint to try and ensure a consistent style and to uncover hidden bugs.
I don't actually care much about what the rules are, it's just helpful to have a baseline.
If it's hard to get code to be compliant, I would rather we just disable a rule in that block of code until we can figure it out and am totally fine with that.
I'd much prefer that than the chore of maintaining a custom set of rules, which is why I just picked Standard JS.
Unfortunately, there is quite a lot that doesn't match the Standard JS format at this point, so this is going to be a big PR.
The file size has gone down in quite a few places, which is nice. I think it may have uncovered potential bugs.
I've run through the flow and everything seems to work as before, though it took some debugging after refactoring.
I have not yet added eslint to a commit hook and am in two minds about that.
This is an open source project and I'd like to make it easy to maintain, but also to have as low a barrier to entry as possible for contributors.
I'm happy to go with encouraging folks to run the linter and try to fix errors they find and to take on the work of wrangling any issues myself.