## Database
- [x] Databases are now optional - useful with OAuth + JWT if you only need access control
- [x] Updated documentation and added example code for custom database adapters
## JWT
- [x] JWT option is now an object that groups JWT related options together (was a boolean)
- [X] Refactored JWT lib and add AES encryption / decryption as well as signing / verification
- [x] Allows JWT encode/decode methods to be overridden as options
- [x] Contents of JWT can easily customised - without needing to use custom encode/decode
- [x] Exported JWT methods so they can be called from custom API routes
- [x] Updated documentation for new JWT options
## Sessions
- [x] All session options (eg. `maxAge`, `updateAge`) now grouped under single `session` option
- [x] Using JWT for sessions is now enabled from session object (`session.jwt: true`)
- [x] All options involving time now use seconds (instead of milliseconds) for consistency
- [x] Added option to customise the Session object that is returned from `/api/auth/session`
- [x] Update documentation for new Session options
## Other improvements
- [x] Added `allowSignin()` option to control what users / accounts are allowed to sign in
- [x] Refactored `callbackUrlHandler()` - this option is now called `allowCallbackUrl()`
- [x] Minor improvements to NextAuth.js client API methods
- [x] Minor to NextAuth.js API routes
- [x] Minor improvements to built-in error pages
- [x] Refactored database models
All tables now include a `created` column for each row which contains the `datetime` of when the row (e.g. User / Account / Session) was created.
Additionally, sessions now use the name 'expiry' for the expiry `datetime` value for consistency with other models.
* Now has jwt and jwtSecret options
* Set jwt: true to use JWT instead of DB for session
* Enable 'debug: true' to log JWT_SESSION_TOKEN to console if you want to see what it contains
* Magical!
* Database configuration now only needs a single line!
* You can still specify options using query string parameters.
* You can still specify an object, so this is not a breaking change.
These changes fix compatibility issues with common SQL databases including MySQL, MariaDB and Postgres.
* Fixes#147 - datetime now ANSI SQL timestamp
* Fixes#160 - AccessToken and RefreshToken type change from varchar to text
* Adds Docker Compose files to make it easier to test database integration.
TODO:
* Update documentation with configuration examples and latest compatibility info
* Create DB URI parser (currently only object config works)
* Database table/collection name prefix (will default to `next-auth_`)
* MongoDB support
MongoDB has some issues which mean it will require additional work and refactoring to support (while preserving SQL DB support, which is important).
It's going to take some thinking about to get right; MongoDB support might have to be dropped from 2.0 (and follow in a subsequent release) but I'm going to review options and consider the impact before making a call.
* Now accepts 'database' as an option as an alterantive to 'adapter'.
* If specified, 'database' can be a string or object and will load the default adapter.
* The 'adapter' option is still valid, and overrides the 'database' option.
If neither option is specified, displays console error and web error page.
* 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.
* 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.