Skip to content
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

Merged
merged 98 commits into from
Aug 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
b497cae
refactor: handle adapter errors in `server/index.js`
balazsorban44 Jul 12, 2021
1e8db33
feat: don't expose next-auth/errors anymore
balazsorban44 Jul 12, 2021
1ad87e5
chore: remove `peerOptionalDependencies`
balazsorban44 Jul 12, 2021
180cabe
refactor(ts): simplify Adapter interface
balazsorban44 Jul 12, 2021
a0e8df7
chore: remove unnecessary `null` fallbacks
balazsorban44 Jul 12, 2021
0474c07
test(adapter): fix adapter tests
balazsorban44 Jul 12, 2021
b6d2d54
fix(ts): make some user option objects partial
balazsorban44 Jul 12, 2021
59b4026
docs(ts): update adapter documentation
balazsorban44 Jul 12, 2021
7b4a3e0
fix(ts): make `expires` serializable externally
balazsorban44 Jul 12, 2021
5448e1b
chore: remove defaultEvents
balazsorban44 Jul 13, 2021
67165ef
feat(adapter): pass whole account in linkAccount
balazsorban44 Jul 14, 2021
7fd1c9f
docs(provider): format email docs
balazsorban44 Jul 14, 2021
2ee4a0c
feat: simplify verification token flow
balazsorban44 Jul 14, 2021
dce0205
chore: prefer desctructuring
balazsorban44 Jul 14, 2021
fae3711
chore: simplify
balazsorban44 Jul 14, 2021
c4e83f7
refactor: remove unnecessary `id` property from
balazsorban44 Jul 14, 2021
5d13709
docs: rename adapter methods
balazsorban44 Jul 14, 2021
2f8a0cc
Merge branch 'next' into feat/simplify-adapter
balazsorban44 Jul 14, 2021
e5cb9a5
test(adapter): fix adapter test
balazsorban44 Jul 14, 2021
9df50a9
fix(ts): explicitly export type
balazsorban44 Jul 14, 2021
c5cdac9
refactor: create server utils module
balazsorban44 Jul 14, 2021
1c47aa8
feat(adapter): change `createSession` signature
balazsorban44 Jul 14, 2021
89290e4
fix(ts): make `emailVerified` required for AdapterUser
balazsorban44 Jul 14, 2021
5effb77
fix(ts): improve TS types
balazsorban44 Jul 15, 2021
b5231a5
refactor: rename fromNow to fromDate
balazsorban44 Jul 15, 2021
dce1c0a
refactor: rename providerAccount -> account
balazsorban44 Jul 15, 2021
6521f99
feat: always send string to `getUserByEmail`
balazsorban44 Jul 15, 2021
0efc7d2
chore: handle SessionToken as nullable
balazsorban44 Jul 15, 2021
8cf0c74
chore: remove `isSignedIn`, use `user` directly
balazsorban44 Jul 15, 2021
8fde3c8
chore: add internal SessionCookie type
balazsorban44 Jul 15, 2021
8d922e6
chore: format code
balazsorban44 Jul 15, 2021
a2325c2
test: fix ts tests
balazsorban44 Jul 15, 2021
177a4a9
fix: don't save url in VerificationToken
balazsorban44 Jul 15, 2021
befd546
feat: do token expiry check in core
balazsorban44 Jul 15, 2021
13ab1e9
chore(jwt): remove export default from jwt module
balazsorban44 Jul 17, 2021
265057c
fix: correctly call getUserByEmail
balazsorban44 Jul 17, 2021
c554a39
feat: rename `getUserByProviderAccountId` to `getUserByAccount`
balazsorban44 Jul 17, 2021
8ffbc56
chore: clean up code
balazsorban44 Jul 17, 2021
cc8742a
fix: correctly use Account for non-OAuth flows
balazsorban44 Jul 17, 2021
b3f60cc
docs: update adapter method name to getUserByAccount
balazsorban44 Jul 17, 2021
262b352
feat: don't send profile in credentials jwt callback
balazsorban44 Jul 17, 2021
75bcf34
docs: clarify Credentials docs
balazsorban44 Jul 17, 2021
69ca771
fix(ts): require id on User
balazsorban44 Jul 17, 2021
3c24798
test: fix credentials TS test
balazsorban44 Jul 17, 2021
79b3ab7
chore(ts): assume Provider internally for convinience
balazsorban44 Jul 17, 2021
d15afb6
fix: remove isSignedIn non-existent variable reference
balazsorban44 Jul 19, 2021
661b0ee
Merge branch 'next' into feat/simplify-adapter
balazsorban44 Aug 4, 2021
ad68114
chore: update comment
balazsorban44 Aug 6, 2021
5e6a99f
feat: join `getUser` and `getSession` where possible
balazsorban44 Aug 6, 2021
d33c244
feat: assume `deleteSession` returns the session
balazsorban44 Aug 6, 2021
214890d
feat: update TS for adapter
balazsorban44 Aug 6, 2021
ee6ba56
test: fix adapter TS tests
balazsorban44 Aug 6, 2021
8ef7021
fix: fix TS lint errors
balazsorban44 Aug 6, 2021
e3cccef
chore: update adapter types
balazsorban44 Aug 6, 2021
dca7177
feat: remove `displayName` requirement
balazsorban44 Aug 6, 2021
6153437
fix: correct jwt import
balazsorban44 Aug 6, 2021
1bc9e82
fix: correctly access session id
balazsorban44 Aug 6, 2021
395d55c
chore: turn off some ESLint rules
balazsorban44 Aug 6, 2021
71e3766
chore: test PrismaAdapter
balazsorban44 Aug 6, 2021
3695c96
fix: use `sessionToken` instead of `session.id` directly
balazsorban44 Aug 8, 2021
c97cd0f
fix: simplify OAuth1 account
balazsorban44 Aug 8, 2021
f0e3fe4
test: fix session related test
balazsorban44 Aug 8, 2021
541560b
feat: use `randomUUID` if available
balazsorban44 Aug 8, 2021
8c35065
feat: don't lowercase logger codes for easier scanning
balazsorban44 Aug 8, 2021
11e0149
docs: remove `prisma-legacy`
balazsorban44 Aug 8, 2021
ecb95b2
docs: remove more references to old Prisma Adapter
balazsorban44 Aug 8, 2021
5780f8e
docs(adapter): rephrase Model section
balazsorban44 Aug 8, 2021
7bc9b91
docs(adapter): don't mention TypeORM as default
balazsorban44 Aug 8, 2021
f4aa168
docs: improve adapter model and overview docs
balazsorban44 Aug 8, 2021
ba4ec5f
docs(adapter): update adapter creation tutorial
balazsorban44 Aug 8, 2021
3044e71
docs(www): add schema image
ndom91 Aug 13, 2021
4b65419
docs(www): add note about models / tables
ndom91 Aug 13, 2021
969f379
docs(www): schema wording
ndom91 Aug 13, 2021
6d31316
docs(www): update schema image
ndom91 Aug 13, 2021
08511d5
docs(www): test svg database schema image
ndom91 Aug 13, 2021
2216409
docs(www): svg db schema for both color schemes
ndom91 Aug 13, 2021
b01aeea
feat: force the Adapter to create user id
balazsorban44 Aug 13, 2021
66ee2be
feat: force the `account.id` to be string
balazsorban44 Aug 13, 2021
1289475
Merge branch 'feat/simplify-adapter' of github.com:nextauthjs/next-au…
balazsorban44 Aug 13, 2021
b20e217
docs(www): move to png model image
ndom91 Aug 13, 2021
981c3c4
Merge branch 'feat/simplify-adapter' of ssh://github.com/nextauthjs/n…
ndom91 Aug 13, 2021
070cf0e
Merge branch 'next' into feat/simplify-adapter
balazsorban44 Aug 14, 2021
5bf9456
feat: differentiate between `account.id` and `account.providerAccountId`
balazsorban44 Aug 14, 2021
5236e15
chore: improve internal types
balazsorban44 Aug 14, 2021
ecaa976
core: correct adapter method param types
balazsorban44 Aug 14, 2021
d699814
chore: update dev app Prisma schema
balazsorban44 Aug 14, 2021
ac9f971
fix: import internal interface
balazsorban44 Aug 14, 2021
22520e7
fix: use `providerAccountId`
balazsorban44 Aug 14, 2021
eeb7bd4
fix(ts): fix `Account` and `EmailConfig` types
balazsorban44 Aug 14, 2021
4b5e0f3
fix: don't require user.id in credentials provider
balazsorban44 Aug 14, 2021
16c45e2
refactor: simplify email provider
balazsorban44 Aug 14, 2021
b3af152
fix: stringify scope if received as Array
balazsorban44 Aug 14, 2021
6822c64
chore: upgrade deps in dev app
balazsorban44 Aug 14, 2021
4036abb
chore: update NextAuth config in dev app
balazsorban44 Aug 14, 2021
6d8a613
chore: import only `PrismaClient`
balazsorban44 Aug 14, 2021
8e8c64c
chore: remove Prisma adapter
balazsorban44 Aug 14, 2021
1c7f460
docs(adapters): update Prisma schema
balazsorban44 Aug 15, 2021
8a2f8fa
chore: update prisma adapter import in dev app
balazsorban44 Aug 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ app/next-auth
app/dist/css
app/package-lock.json
app/yarn.lock
app/prisma/migrations
app/prisma/dev.db*

# VS
/.vs/slnx.sqlite-journal
Expand Down
15 changes: 2 additions & 13 deletions app/.env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ NEXTAUTH_URL=http://localhost:3000
# https://generate-secret.vercel.app/32 to generate a secret.
# Note: Changing a secret may invalidate existing sessions
# and/or verification tokens.
SECRET=
SECRET=secret

AUTH0_ID=
AUTH0_SECRET=
Expand All @@ -24,15 +24,4 @@ TWITCH_ID=
TWITCH_SECRET=

TWITTER_ID=
TWITTER_SECRET=

# Example configuration for a Gmail account (will need SMTP enabled)
EMAIL_SERVER=smtps://user@gmail.com:password@smtp.gmail.com:465
EMAIL_FROM=user@gmail.com

# Note: If using with Prisma adapter, you need to use a `.env`
# file rather than a `.env.local` file to configure env vars.
# Postgres: DATABASE_URL=postgres://nextauth:password@127.0.0.1:5432/nextauth?synchronize=true
# MySQL: DATABASE_URL=mysql://nextauth:password@127.0.0.1:3306/nextauth?synchronize=true
# MongoDB: DATABASE_URL=mongodb://nextauth:password@127.0.0.1:27017/nextauth?synchronize=true
DATABASE_URL=
TWITTER_SECRET=
4 changes: 4 additions & 0 deletions app/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
12 changes: 8 additions & 4 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
"copy:css": "cpx \"../dist/css/**/*\" dist/css --watch",
"watch:css": "cd .. && npm run watch:css",
"dev:css": "npm-run-all --parallel watch:css copy:css",
"start": "next start"
"start": "next start",
"start:email": "npx fake-smtp-server"
},
"license": "ISC",
"dependencies": {
"next": "^11.0.1",
"nodemailer": "^6.6.1",
"@prisma/client": "^2.29.1",
"fake-smtp-server": "^0.8.0",
"next": "^11.1.0",
"nodemailer": "^6.6.3",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"cpx": "^1.5.0",
"npm-run-all": "^4.1.5"
"npm-run-all": "^4.1.5",
"prisma": "^2.29.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@ import LineProvider from "next-auth/providers/line"
import LinkedInProvider from "next-auth/providers/linkedin"
import MailchimpProvider from "next-auth/providers/mailchimp"
import DiscordProvider from "next-auth/providers/discord"
import OneLoginProvider from "next-auth/providers/onelogin"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()

export default NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
// E-mail
// Start fake e-mail server with `npm run start:email`
EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
server: {
host: "127.0.0.1",
auth: null,
secure: false,
port: 1025,
tls: { rejectUnauthorized: false },
},
}),
// Credentials
CredentialsProvider({
Expand All @@ -34,7 +43,6 @@ export default NextAuth({
async authorize(credentials, req) {
if (credentials.password === "password") {
return {
id: 1,
name: "Fill Murray",
email: "bill@fillmurray.com",
image: "https://www.fillmurray.com/64/64",
Expand Down Expand Up @@ -107,12 +115,10 @@ export default NextAuth({
clientId: process.env.DISCORD_ID,
clientSecret: process.env.DISCORD_SECRET,
}),
OneLoginProvider({
clientId: process.env.ONELOGIN_ID,
clientSecret: process.env.ONELOGIN_SECRET,
issuer: process.env.ONELOGIN_ISSUER,
}),
],
session: {
jwt: true,
},
jwt: {
encryption: true,
secret: process.env.SECRET,
Expand Down
78 changes: 36 additions & 42 deletions app/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,63 +1,57 @@
generator client {
provider = "prisma-client-js"
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
generator client {
provider = "prisma-client-js"
}

model Account {
id Int @default(autoincrement()) @id
compoundId String @unique @map(name: "compound_id")
userId Int @map(name: "user_id")
providerType String @map(name: "provider_type")
providerId String @map(name: "provider_id")
providerAccountId String @map(name: "provider_account_id")
refreshToken String? @map(name: "refresh_token")
accessToken String? @map(name: "access_token")
accessTokenExpires DateTime? @map(name: "access_token_expires")
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")

@@index([providerAccountId], name: "providerAccountId")
@@index([providerId], name: "providerId")
@@index([userId], name: "userId")

@@map(name: "accounts")
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
oauth_token_secret String?
oauth_token String?

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])

@@unique([provider, providerAccountId])
}

model Session {
id Int @default(autoincrement()) @id
userId Int @map(name: "user_id")
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
sessionToken String @unique @map(name: "session_token")
accessToken String @unique @map(name: "access_token")
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")

@@map(name: "sessions")
user User @relation(fields: [userId], references: [id])
}

model User {
id Int @default(autoincrement()) @id
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime? @map(name: "email_verified")
emailVerified DateTime?
image String?
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")

@@map(name: "users")
accounts Account[]
sessions Session[]
}

model VerificationRequest {
id Int @default(autoincrement()) @id
model VerificationToken {
identifier String
token String @unique
expires DateTime
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @default(now()) @map(name: "updated_at")

@@map(name: "verification_requests")
}
@@unique([identifier, token])
}
30 changes: 30 additions & 0 deletions app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": "."
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
4 changes: 0 additions & 4 deletions config/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const MODULE_ENTRIES = {
REACT: "react",
ADAPTERS: "adapters",
JWT: "jwt",
ERRORS: "errors",
}

// Building submodule entries
Expand All @@ -18,8 +17,6 @@ const BUILD_TARGETS = {
"module.exports = require('./dist/client/react').default\n",
[`${MODULE_ENTRIES.JWT}.js`]:
"module.exports = require('./dist/lib/jwt').default\n",
[`${MODULE_ENTRIES.ERRORS}.js`]:
"module.exports = require('./dist/lib/errors').default\n",
}

Object.entries(BUILD_TARGETS).forEach(([target, content]) => {
Expand All @@ -38,7 +35,6 @@ const TYPES_TARGETS = [
`${MODULE_ENTRIES.ADAPTERS}.d.ts`,
"providers",
`${MODULE_ENTRIES.JWT}.d.ts`,
`${MODULE_ENTRIES.ERRORS}.d.ts`,
"internals",
]

Expand Down
10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
".": "./dist/server/index.js",
"./jwt": "./dist/lib/jwt.js",
"./react": "./dist/client/react.js",
"./providers/*": "./dist/providers/*.js",
"./errors": "./dist/lib/errors.js"
"./providers/*": "./dist/providers/*.js"
},
"scripts": {
"build": "npm run build:js && npm run build:css",
Expand All @@ -49,12 +48,9 @@
"index.js",
"index.d.ts",
"providers",
"adapters.js",
"adapters.d.ts",
"react.js",
"react.d.ts",
"errors.js",
"errors.d.ts",
"jwt.js",
"jwt.d.ts",
"internals"
Expand Down Expand Up @@ -148,7 +144,9 @@
"fetch": "readonly"
},
"rules": {
"camelcase": "off"
"camelcase": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/strict-boolean-expressions": "off"
},
"overrides": [
{
Expand Down
28 changes: 0 additions & 28 deletions src/adapters/error-handler.js

This file was deleted.

45 changes: 45 additions & 0 deletions src/lib/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,48 @@ export function upperSnake(s) {
export function capitalize(s) {
return `${s[0].toUpperCase()}${s.slice(1)}`
}

/**
* Wraps an object of methods and adds error handling.
* @param {import("types").EventCallbacks} methods
* @param {import("types").LoggerInstance} logger
* @return {import("types").EventCallbacks}
*/
export function eventsErrorHandler(methods, logger) {
return Object.entries(methods).reduce((acc, [name, method]) => {
acc[name] = async (...args) => {
try {
return await method(...args)
} catch (e) {
logger.error(`${upperSnake(name)}_EVENT_ERROR`, e)
}
}
return acc
}, {})
}

/**
* Handles adapter induced errors.
* @param {import("types/adapters").Adapter} [adapter]
* @param {import("types").LoggerInstance} logger
* @return {import("types/adapters").Adapter}
*/
export function adapterErrorHandler(adapter, logger) {
if (!adapter) return

return Object.keys(adapter).reduce((acc, method) => {
acc[method] = async (...args) => {
try {
logger.debug(`adapter_${method}`, ...args)
const adapterMethod = adapter[method]
return await adapterMethod(...args)
} catch (error) {
logger.error(`adapter_error_${method}`, error)
const e = new UnknownError(error)
e.name = `${capitalize(method)}Error`
throw e
}
}
return acc
}, {})
}
6 changes: 0 additions & 6 deletions src/lib/jwt.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,3 @@ function getDerivedEncryptionKey(secret) {
})
return key
}

export default {
encode,
decode,
getToken,
}
Loading