mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
43 Commits
@auth/dgra
...
@auth/core
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e459d2d7e2 | ||
|
|
db1fd9007c | ||
|
|
0439fc5fc6 | ||
|
|
d0dd2ababc | ||
|
|
ba58d48dba | ||
|
|
a8d76ed440 | ||
|
|
3d7b8720db | ||
|
|
1e886b97bc | ||
|
|
ecb14ccecd | ||
|
|
8cee24d4ab | ||
|
|
0189a197be | ||
|
|
c44bf75c65 | ||
|
|
cf13b6c7e3 | ||
|
|
dc1a79e547 | ||
|
|
78964c115b | ||
|
|
7fa51e2a61 | ||
|
|
a79774f6e8 | ||
|
|
f779f05906 | ||
|
|
3245c02eac | ||
|
|
a8dfc8ebb1 | ||
|
|
1b80a18dd4 | ||
|
|
50a88bb878 | ||
|
|
a359a562ce | ||
|
|
7edb9cf53f | ||
|
|
018b086c4f | ||
|
|
173000a068 | ||
|
|
8fcd46b0fc | ||
|
|
d5d1313914 | ||
|
|
3285d04241 | ||
|
|
fe442522ef | ||
|
|
6c9dfff45f | ||
|
|
ef50916ec2 | ||
|
|
8e771a2993 | ||
|
|
06a7149b66 | ||
|
|
662e0942cb | ||
|
|
91c71a175b | ||
|
|
3b8c75297b | ||
|
|
5d06fa5852 | ||
|
|
e7a52077c5 | ||
|
|
6e4516a9f8 | ||
|
|
8a0b11fcd6 | ||
|
|
f925e0c2a5 | ||
|
|
de4e20cc04 |
1
.github/ISSUE_TEMPLATE/2_bug_provider.yml
vendored
1
.github/ISSUE_TEMPLATE/2_bug_provider.yml
vendored
@@ -37,6 +37,7 @@ body:
|
||||
- "Bungie"
|
||||
- "Cognito"
|
||||
- "Coinbase"
|
||||
- "Descope"
|
||||
- "Discord"
|
||||
- "Dropbox"
|
||||
- "EVE Online"
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/3_bug_adapter.yml
vendored
14
.github/ISSUE_TEMPLATE/3_bug_adapter.yml
vendored
@@ -23,18 +23,18 @@ body:
|
||||
- "Custom adapter"
|
||||
- "@auth/dgraph-adapter"
|
||||
- "@auth/dynamodb-adapter"
|
||||
- "@next-auth/fauna-adapter"
|
||||
- "@next-auth/firebase-adapter"
|
||||
- "@auth/fauna-adapter"
|
||||
- "@auth/firebase-adapter"
|
||||
- "@auth/mikro-orm-adapter"
|
||||
- "@auth/mongodb-adapter"
|
||||
- "@next-auth/neo4j-adapter"
|
||||
- "@next-auth/pouchdb-adapter"
|
||||
- "@auth/neo4j-adapter"
|
||||
- "@auth/pouchdb-adapter"
|
||||
- "@auth/prisma-adapter"
|
||||
- "@next-auth/sequelize-adapter"
|
||||
- "@next-auth/supabase-adapter"
|
||||
- "@auth/sequelize-adapter"
|
||||
- "@auth/supabase-adapter"
|
||||
- "@auth/typeorm-adapter"
|
||||
- "@auth/upstash-redis-adapter"
|
||||
- "@next-auth/xata-adapter"
|
||||
- "@auth/xata-adapter"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
14
.github/issue-labeler.yml
vendored
14
.github/issue-labeler.yml
vendored
@@ -7,10 +7,10 @@ dynamodb:
|
||||
- "@auth/dynamodb-adapter"
|
||||
|
||||
fauna:
|
||||
- "@next-auth/fauna-adapter"
|
||||
- "@auth/fauna-adapter"
|
||||
|
||||
firebase:
|
||||
- "@next-auth/firebase-adapter"
|
||||
- "@auth/firebase-adapter"
|
||||
|
||||
mikro-orm:
|
||||
- "@auth/mikro-orm-adapter"
|
||||
@@ -19,19 +19,19 @@ mongodb:
|
||||
- "@auth/mongodb-adapter"
|
||||
|
||||
neo4j:
|
||||
- "@next-auth/neo4j-adapter"
|
||||
- "@auth/neo4j-adapter"
|
||||
|
||||
pouchdb:
|
||||
- "@next-auth/pouchdb-adapter"
|
||||
- "@auth/pouchdb-adapter"
|
||||
|
||||
prisma:
|
||||
- "@auth/prisma-adapter"
|
||||
|
||||
sequelize:
|
||||
- "@next-auth/sequelize-adapter"
|
||||
- "@auth/sequelize-adapter"
|
||||
|
||||
supabase:
|
||||
- "@next-auth/supabase-adapter"
|
||||
- "@auth/supabase-adapter"
|
||||
|
||||
typeorm:
|
||||
- "@auth/typeorm-adapter"
|
||||
@@ -40,4 +40,4 @@ upstash-redis:
|
||||
- "@auth/upstash-redis-adapter"
|
||||
|
||||
xata:
|
||||
- "@next-auth/xata-adapter"
|
||||
- "@auth/xata-adapter"
|
||||
|
||||
@@ -13,6 +13,9 @@ AUTH0_ID=
|
||||
AUTH0_SECRET=
|
||||
AUTH0_ISSUER=
|
||||
|
||||
DESCOPE_ID=
|
||||
DESCOPE_SECRET=
|
||||
|
||||
KEYCLOAK_ID=
|
||||
KEYCLOAK_SECRET=
|
||||
KEYCLOAK_ISSUER=
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
},
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@next-auth/fauna-adapter": "workspace:*",
|
||||
"@auth/fauna-adapter": "workspace:*",
|
||||
"@auth/prisma-adapter": "workspace:*",
|
||||
"@next-auth/supabase-adapter": "workspace:*",
|
||||
"@auth/supabase-adapter": "workspace:*",
|
||||
"@auth/typeorm-adapter": "workspace:*",
|
||||
"@prisma/client": "^3",
|
||||
"@supabase/supabase-js": "^2.0.5",
|
||||
|
||||
@@ -44,7 +44,7 @@ import WorkOS from "next-auth/providers/workos"
|
||||
|
||||
// // Fauna
|
||||
// import { Client as FaunaClient } from "faunadb"
|
||||
// import { FaunaAdapter } from "@next-auth/fauna-adapter"
|
||||
// import { FaunaAdapter } from "@auth/fauna-adapter"
|
||||
// const opts = { secret: process.env.FAUNA_SECRET, domain: process.env.FAUNA_DOMAIN }
|
||||
// const client = globalThis.fauna || new FaunaClient(opts)
|
||||
// if (process.env.NODE_ENV !== "production") globalThis.fauna = client
|
||||
@@ -60,7 +60,7 @@ import WorkOS from "next-auth/providers/workos"
|
||||
// })
|
||||
|
||||
// // Supabase
|
||||
// import { SupabaseAdapter } from "@next-auth/supabase-adapter"
|
||||
// import { SupabaseAdapter } from "@auth/supabase-adapter"
|
||||
// const adapter = SupabaseAdapter({
|
||||
// url: process.env.NEXT_PUBLIC_SUPABASE_URL,
|
||||
// secret: process.env.SUPABASE_SERVICE_ROLE_KEY,
|
||||
@@ -78,45 +78,130 @@ export const authOptions: NextAuthOptions = {
|
||||
credentials: { password: { label: "Password", type: "password" } },
|
||||
async authorize(credentials) {
|
||||
if (credentials.password !== "pw") return null
|
||||
return { name: "Fill Murray", email: "bill@fillmurray.com", image: "https://www.fillmurray.com/64/64", id: "1", foo: "" }
|
||||
return {
|
||||
name: "Fill Murray",
|
||||
email: "bill@fillmurray.com",
|
||||
image: "https://www.fillmurray.com/64/64",
|
||||
id: "1",
|
||||
foo: "",
|
||||
}
|
||||
},
|
||||
}),
|
||||
Apple({ clientId: process.env.APPLE_ID, clientSecret: process.env.APPLE_SECRET }),
|
||||
Auth0({ clientId: process.env.AUTH0_ID, clientSecret: process.env.AUTH0_SECRET, issuer: process.env.AUTH0_ISSUER }),
|
||||
Apple({
|
||||
clientId: process.env.APPLE_ID,
|
||||
clientSecret: process.env.APPLE_SECRET,
|
||||
}),
|
||||
Auth0({
|
||||
clientId: process.env.AUTH0_ID,
|
||||
clientSecret: process.env.AUTH0_SECRET,
|
||||
issuer: process.env.AUTH0_ISSUER,
|
||||
}),
|
||||
AzureAD({
|
||||
clientId: process.env.AZURE_AD_CLIENT_ID,
|
||||
clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
|
||||
tenantId: process.env.AZURE_AD_TENANT_ID,
|
||||
}),
|
||||
AzureB2C({ clientId: process.env.AZURE_B2C_ID, clientSecret: process.env.AZURE_B2C_SECRET, issuer: process.env.AZURE_B2C_ISSUER }),
|
||||
BoxyHQSAML({ issuer: "https://jackson-demo.boxyhq.com", clientId: "tenant=boxyhq.com&product=saml-demo.boxyhq.com", clientSecret: "dummy" }),
|
||||
AzureB2C({
|
||||
clientId: process.env.AZURE_B2C_ID,
|
||||
clientSecret: process.env.AZURE_B2C_SECRET,
|
||||
issuer: process.env.AZURE_B2C_ISSUER,
|
||||
}),
|
||||
BoxyHQSAML({
|
||||
issuer: "https://jackson-demo.boxyhq.com",
|
||||
clientId: "tenant=boxyhq.com&product=saml-demo.boxyhq.com",
|
||||
clientSecret: "dummy",
|
||||
}),
|
||||
// Cognito({ clientId: process.env.COGNITO_ID, clientSecret: process.env.COGNITO_SECRET, issuer: process.env.COGNITO_ISSUER }),
|
||||
Discord({ clientId: process.env.DISCORD_ID, clientSecret: process.env.DISCORD_SECRET }),
|
||||
DuendeIDS6({ clientId: "interactive.confidential", clientSecret: "secret", issuer: "https://demo.duendesoftware.com" }),
|
||||
Facebook({ clientId: process.env.FACEBOOK_ID, clientSecret: process.env.FACEBOOK_SECRET }),
|
||||
Foursquare({ clientId: process.env.FOURSQUARE_ID, clientSecret: process.env.FOURSQUARE_SECRET }),
|
||||
Freshbooks({ clientId: process.env.FRESHBOOKS_ID, clientSecret: process.env.FRESHBOOKS_SECRET }),
|
||||
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET }),
|
||||
Gitlab({ clientId: process.env.GITLAB_ID, clientSecret: process.env.GITLAB_SECRET }),
|
||||
Google({ clientId: process.env.GOOGLE_ID, clientSecret: process.env.GOOGLE_SECRET }),
|
||||
Discord({
|
||||
clientId: process.env.DISCORD_ID,
|
||||
clientSecret: process.env.DISCORD_SECRET,
|
||||
}),
|
||||
DuendeIDS6({
|
||||
clientId: "interactive.confidential",
|
||||
clientSecret: "secret",
|
||||
issuer: "https://demo.duendesoftware.com",
|
||||
}),
|
||||
Facebook({
|
||||
clientId: process.env.FACEBOOK_ID,
|
||||
clientSecret: process.env.FACEBOOK_SECRET,
|
||||
}),
|
||||
Foursquare({
|
||||
clientId: process.env.FOURSQUARE_ID,
|
||||
clientSecret: process.env.FOURSQUARE_SECRET,
|
||||
}),
|
||||
Freshbooks({
|
||||
clientId: process.env.FRESHBOOKS_ID,
|
||||
clientSecret: process.env.FRESHBOOKS_SECRET,
|
||||
}),
|
||||
GitHub({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
Gitlab({
|
||||
clientId: process.env.GITLAB_ID,
|
||||
clientSecret: process.env.GITLAB_SECRET,
|
||||
}),
|
||||
Google({
|
||||
clientId: process.env.GOOGLE_ID,
|
||||
clientSecret: process.env.GOOGLE_SECRET,
|
||||
}),
|
||||
// IDS4({ clientId: process.env.IDS4_ID, clientSecret: process.env.IDS4_SECRET, issuer: process.env.IDS4_ISSUER }),
|
||||
Instagram({ clientId: process.env.INSTAGRAM_ID, clientSecret: process.env.INSTAGRAM_SECRET }),
|
||||
Instagram({
|
||||
clientId: process.env.INSTAGRAM_ID,
|
||||
clientSecret: process.env.INSTAGRAM_SECRET,
|
||||
}),
|
||||
// Keycloak({ clientId: process.env.KEYCLOAK_ID, clientSecret: process.env.KEYCLOAK_SECRET, issuer: process.env.KEYCLOAK_ISSUER }),
|
||||
Line({ clientId: process.env.LINE_ID, clientSecret: process.env.LINE_SECRET }),
|
||||
LinkedIn({ clientId: process.env.LINKEDIN_ID, clientSecret: process.env.LINKEDIN_SECRET }),
|
||||
Mailchimp({ clientId: process.env.MAILCHIMP_ID, clientSecret: process.env.MAILCHIMP_SECRET }),
|
||||
Line({
|
||||
clientId: process.env.LINE_ID,
|
||||
clientSecret: process.env.LINE_SECRET,
|
||||
}),
|
||||
LinkedIn({
|
||||
clientId: process.env.LINKEDIN_ID,
|
||||
clientSecret: process.env.LINKEDIN_SECRET,
|
||||
}),
|
||||
Mailchimp({
|
||||
clientId: process.env.MAILCHIMP_ID,
|
||||
clientSecret: process.env.MAILCHIMP_SECRET,
|
||||
}),
|
||||
// Okta({ clientId: process.env.OKTA_ID, clientSecret: process.env.OKTA_SECRET, issuer: process.env.OKTA_ISSUER }),
|
||||
Osu({ clientId: process.env.OSU_CLIENT_ID, clientSecret: process.env.OSU_CLIENT_SECRET }),
|
||||
Patreon({ clientId: process.env.PATREON_ID, clientSecret: process.env.PATREON_SECRET }),
|
||||
Slack({ clientId: process.env.SLACK_ID, clientSecret: process.env.SLACK_SECRET }),
|
||||
Spotify({ clientId: process.env.SPOTIFY_ID, clientSecret: process.env.SPOTIFY_SECRET }),
|
||||
Trakt({ clientId: process.env.TRAKT_ID, clientSecret: process.env.TRAKT_SECRET }),
|
||||
Twitch({ clientId: process.env.TWITCH_ID, clientSecret: process.env.TWITCH_SECRET }),
|
||||
Twitter({ clientId: process.env.TWITTER_ID, clientSecret: process.env.TWITTER_SECRET }),
|
||||
Osu({
|
||||
clientId: process.env.OSU_CLIENT_ID,
|
||||
clientSecret: process.env.OSU_CLIENT_SECRET,
|
||||
}),
|
||||
Patreon({
|
||||
clientId: process.env.PATREON_ID,
|
||||
clientSecret: process.env.PATREON_SECRET,
|
||||
}),
|
||||
Slack({
|
||||
clientId: process.env.SLACK_ID,
|
||||
clientSecret: process.env.SLACK_SECRET,
|
||||
}),
|
||||
Spotify({
|
||||
clientId: process.env.SPOTIFY_ID,
|
||||
clientSecret: process.env.SPOTIFY_SECRET,
|
||||
}),
|
||||
Trakt({
|
||||
clientId: process.env.TRAKT_ID,
|
||||
clientSecret: process.env.TRAKT_SECRET,
|
||||
}),
|
||||
Twitch({
|
||||
clientId: process.env.TWITCH_ID,
|
||||
clientSecret: process.env.TWITCH_SECRET,
|
||||
}),
|
||||
Twitter({
|
||||
clientId: process.env.TWITTER_ID,
|
||||
clientSecret: process.env.TWITTER_SECRET,
|
||||
}),
|
||||
// TwitterLegacy({ clientId: process.env.TWITTER_LEGACY_ID, clientSecret: process.env.TWITTER_LEGACY_SECRET }),
|
||||
Vk({ clientId: process.env.VK_ID, clientSecret: process.env.VK_SECRET }),
|
||||
Wikimedia({ clientId: process.env.WIKIMEDIA_ID, clientSecret: process.env.WIKIMEDIA_SECRET }),
|
||||
WorkOS({ clientId: process.env.WORKOS_ID, clientSecret: process.env.WORKOS_SECRET }),
|
||||
Wikimedia({
|
||||
clientId: process.env.WIKIMEDIA_ID,
|
||||
clientSecret: process.env.WIKIMEDIA_SECRET,
|
||||
}),
|
||||
WorkOS({
|
||||
clientId: process.env.WORKOS_ID,
|
||||
clientSecret: process.env.WORKOS_SECRET,
|
||||
}),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ BEYOND_IDENTITY_CLIENT_ID=
|
||||
BEYOND_IDENTITY_CLIENT_SECRET=
|
||||
BEYOND_IDENTITY_ISSUER=
|
||||
|
||||
DESCOPE_ID=
|
||||
DESCOPE_SECRET=
|
||||
|
||||
GITHUB_ID=
|
||||
GITHUB_SECRET=
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*",
|
||||
"@next-auth/fauna-adapter": "workspace:*",
|
||||
"@auth/fauna-adapter": "workspace:*",
|
||||
"@auth/prisma-adapter": "workspace:*",
|
||||
"@next-auth/supabase-adapter": "workspace:*",
|
||||
"@auth/supabase-adapter": "workspace:*",
|
||||
"@auth/typeorm-adapter": "workspace:*",
|
||||
"@prisma/client": "^3",
|
||||
"@supabase/supabase-js": "^2.0.5",
|
||||
|
||||
@@ -10,6 +10,7 @@ import BeyondIdentity from "@auth/core/providers/beyondidentity"
|
||||
import BoxyHQSAML from "@auth/core/providers/boxyhq-saml"
|
||||
// import Cognito from "@auth/core/providers/cognito"
|
||||
import Credentials from "@auth/core/providers/credentials"
|
||||
import Descope from "@auth/core/providers/descope"
|
||||
import Discord from "@auth/core/providers/discord"
|
||||
import DuendeIDS6 from "@auth/core/providers/duende-identity-server6"
|
||||
// import Email from "@auth/core/providers/email"
|
||||
@@ -48,7 +49,7 @@ import WorkOS from "@auth/core/providers/workos"
|
||||
|
||||
// // Fauna
|
||||
// import { Client as FaunaClient } from "faunadb"
|
||||
// import { FaunaAdapter } from "@next-auth/fauna-adapter"
|
||||
// import { FaunaAdapter } from "@auth/fauna-adapter"
|
||||
// const opts = { secret: process.env.FAUNA_SECRET, domain: process.env.FAUNA_DOMAIN }
|
||||
// const client = globalThis.fauna || new FaunaClient(opts)
|
||||
// if (process.env.NODE_ENV !== "production") globalThis.fauna = client
|
||||
@@ -64,7 +65,7 @@ import WorkOS from "@auth/core/providers/workos"
|
||||
// })
|
||||
|
||||
// // Supabase
|
||||
// import { SupabaseAdapter } from "@next-auth/supabase-adapter"
|
||||
// import { SupabaseAdapter } from "@auth/supabase-adapter"
|
||||
// const adapter = SupabaseAdapter({
|
||||
// url: process.env.NEXT_PUBLIC_SUPABASE_URL,
|
||||
// secret: process.env.SUPABASE_SERVICE_ROLE_KEY,
|
||||
@@ -94,9 +95,14 @@ export const authConfig: AuthConfig = {
|
||||
tenantId: process.env.AZURE_AD_TENANT_ID,
|
||||
}),
|
||||
AzureB2C({ clientId: process.env.AZURE_B2C_ID, clientSecret: process.env.AZURE_B2C_SECRET, issuer: process.env.AZURE_B2C_ISSUER }),
|
||||
BeyondIdentity({ clientId: process.env.BEYOND_IDENTITY_CLIENT_ID, clientSecret: process.env.BEYOND_IDENTITY_CLIENT_SECRET, issuer: process.env.BEYOND_IDENTITY_ISSUER }),
|
||||
BeyondIdentity({
|
||||
clientId: process.env.BEYOND_IDENTITY_CLIENT_ID,
|
||||
clientSecret: process.env.BEYOND_IDENTITY_CLIENT_SECRET,
|
||||
issuer: process.env.BEYOND_IDENTITY_ISSUER,
|
||||
}),
|
||||
BoxyHQSAML({ issuer: "https://jackson-demo.boxyhq.com", clientId: "tenant=boxyhq.com&product=saml-demo.boxyhq.com", clientSecret: "dummy" }),
|
||||
// Cognito({ clientId: process.env.COGNITO_ID, clientSecret: process.env.COGNITO_SECRET, issuer: process.env.COGNITO_ISSUER }),
|
||||
Descope({ clientId: process.env.DESCOPE_ID, clientSecret: process.env.DESCOPE_SECRET }),
|
||||
Discord({ clientId: process.env.DISCORD_ID, clientSecret: process.env.DISCORD_SECRET }),
|
||||
DuendeIDS6({ clientId: "interactive.confidential", clientSecret: "secret", issuer: "https://demo.duendesoftware.com" }),
|
||||
Facebook({ clientId: process.env.FACEBOOK_ID, clientSecret: process.env.FACEBOOK_SECRET }),
|
||||
|
||||
@@ -6,6 +6,9 @@ AUTH0_ID=
|
||||
AUTH0_SECRET=
|
||||
AUTH0_ISSUER=
|
||||
|
||||
DESCOPE_ID=
|
||||
DESCOPE_SECRET=
|
||||
|
||||
FACEBOOK_ID=
|
||||
FACEBOOK_SECRET=
|
||||
|
||||
|
||||
2
apps/examples/nextjs/process.d.ts
vendored
2
apps/examples/nextjs/process.d.ts
vendored
@@ -12,5 +12,7 @@ declare namespace NodeJS {
|
||||
GOOGLE_SECRET: string
|
||||
AUTH0_ID: string
|
||||
AUTH0_SECRET: string
|
||||
DESCOPE_ID: string
|
||||
DESCOPE_SECRET: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ Most OAuth providers cannot be configured with multiple callback URLs or using a
|
||||
|
||||
However, Auth.js **supports Preview deployments**, even **with OAuth providers**:
|
||||
|
||||
1. Determine a stable deployment URL. Eg.: A deployment whose URL does not change between builds, for example. `auth.yourdomain.com`),
|
||||
1. Determine a stable deployment URL. Eg.: A deployment whose URL does not change between builds, for example. `auth.yourdomain.com` (using a subdomain is not a requirement, this can simply be the main site's URL too.),
|
||||
2. Set `AUTH_REDIRECT_PROXY_URL` to that URL, adding the path up until your `[...nextauth]` route. Eg.: (`https://auth.yourdomain.com/api/auth`)
|
||||
3. For your OAuth provider, set the callback URL using the stable deployment URL. Eg.: For GitHub `https://auth.yourdomain.com/api/auth/callback/github`)
|
||||
|
||||
@@ -42,6 +42,9 @@ However, Auth.js **supports Preview deployments**, even **with OAuth providers**
|
||||
To support preview deployments, the `AUTH_SECRET` value needs to be the same for the stable deployment and deployments that will need OAuth support.
|
||||
:::
|
||||
|
||||
:::note
|
||||
If you are storing users in a [database](reference/adapters), we recommend using a different OAuth app for development/production so that you don't mix your test and production user base.
|
||||
:::
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
|
||||
@@ -112,6 +112,7 @@ providers: [
|
||||
identifier: email,
|
||||
url,
|
||||
provider: { server, from },
|
||||
request // for example can be used to get the user agent (`request.headers.get("user-agent")`) to parse and pass on to the user in the email so they can be more confident they originated the request
|
||||
}) {
|
||||
/* your function */
|
||||
},
|
||||
|
||||
@@ -7,6 +7,7 @@ const icons = [
|
||||
"/img/providers/apple.svg",
|
||||
"/img/providers/auth0.svg",
|
||||
"/img/providers/cognito.svg",
|
||||
"/img/providers/descope.svg",
|
||||
"/img/providers/battlenet.svg",
|
||||
"/img/providers/box.svg",
|
||||
"/img/providers/facebook.svg",
|
||||
|
||||
50
docs/static/img/providers/descope.svg
vendored
Normal file
50
docs/static/img/providers/descope.svg
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="194.7px" height="215.2px" viewBox="0 0 194.7 215.2" style="enable-background:new 0 0 194.7 215.2;" xml:space="preserve"
|
||||
>
|
||||
<style type="text/css">
|
||||
.st0{fill:url(#SVGID_1_);}
|
||||
.st1{fill:url(#SVGID_00000004519561486438896460000001266960168497785022_);}
|
||||
.st2{fill:url(#SVGID_00000049204468076180615810000015113731544435055266_);}
|
||||
.st3{fill:url(#SVGID_00000116951257355544416270000003794629356563808950_);}
|
||||
</style>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="68.3919" y1="222.1531" x2="185.0265" y2="41.0264">
|
||||
<stop offset="1.481436e-07" style="stop-color:#0083B5"/>
|
||||
<stop offset="0.4173" style="stop-color:#00FFFF"/>
|
||||
<stop offset="0.9952" style="stop-color:#6FF12D"/>
|
||||
</linearGradient>
|
||||
<path class="st0" d="M129.8,174.7c7.6-1.6,14-4.8,19.2-9.7c7.7-7.3,8.8-17.1,8.8-29.4V80.7c0-12.3-1.1-22.1-8.8-29.4
|
||||
c-5.2-4.9-11.6-8.1-19.2-9.7V15.4c12.5,1.8,22.9,6.5,31,14.2c10.6,10,19.9,23.5,19.9,40.5v75c0,17-9.3,30.5-19.9,40.5
|
||||
c-8.1,7.7-18.5,12.4-31,14.2V174.7z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000040544740507634666800000017273841385603649669_" gradientUnits="userSpaceOnUse" x1="5.037" y1="181.3564" x2="121.6716" y2="0.2297">
|
||||
<stop offset="1.481436e-07" style="stop-color:#0083B5"/>
|
||||
<stop offset="0.4173" style="stop-color:#00FFFF"/>
|
||||
<stop offset="0.9952" style="stop-color:#6FF12D"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000040544740507634666800000017273841385603649669_);" d="M33.9,29.6c8.1-7.7,18.5-12.4,31-14.2
|
||||
v26.3c-7.6,1.6-14,4.8-19.2,9.7c-7.7,7.3-8.8,17-8.8,29.2v55.1c0,12.3,1.1,22.1,8.8,29.4c5.2,4.9,11.6,8.1,19.2,9.7v25.1
|
||||
c-12.5-1.8-22.9-6.5-31-14.2c-10.6-10-19.9-23.5-19.9-40.5V69.8C13.9,53,23.2,39.6,33.9,29.6z"/>
|
||||
<g>
|
||||
|
||||
<linearGradient id="SVGID_00000060713993868866928010000000698955780952733088_" gradientUnits="userSpaceOnUse" x1="22.0278" y1="192.2974" x2="138.6624" y2="11.1707">
|
||||
<stop offset="1.481436e-07" style="stop-color:#0083B5"/>
|
||||
<stop offset="0.4173" style="stop-color:#00FFFF"/>
|
||||
<stop offset="0.9952" style="stop-color:#6FF12D"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000060713993868866928010000000698955780952733088_);" d="M120.2,87.8l8.5-13.7l-17.8-9.4
|
||||
l-7.5,14.2c-1.1,2.1-3.1,3.3-5.5,3.3c-2.3,0-4.4-1.2-5.5-3.3L85,64.7L67.3,74l12.3,19.7L120.2,87.8z"/>
|
||||
|
||||
<linearGradient id="SVGID_00000115475840050352750520000000840372054167564949_" gradientUnits="userSpaceOnUse" x1="37.9651" y1="202.5601" x2="154.5998" y2="21.4334">
|
||||
<stop offset="1.481436e-07" style="stop-color:#0083B5"/>
|
||||
<stop offset="0.4173" style="stop-color:#00FFFF"/>
|
||||
<stop offset="0.9952" style="stop-color:#6FF12D"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000115475840050352750520000000840372054167564949_);" d="M142.4,97.7l-87.8,0.8v17.7l27.5-0.1
|
||||
l-14.8,23.8l17.7,9.3l7.5-14.2c1.1-2.1,3.1-3.3,5.5-3.3c2.3,0,4.4,1.2,5.5,3.3l7.5,14.2l17.8-9.4l-12-19.3L93.7,116l48.7-0.2V97.7
|
||||
z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@auth/dynamodb-adapter",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "AWS DynamoDB adapter for next-auth.",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
|
||||
@@ -265,9 +265,8 @@ export function DynamoDBAdapter(
|
||||
const data = await client.update({
|
||||
TableName,
|
||||
Key: {
|
||||
// next-auth type is incorrect it should be Partial<AdapterUser> & {id: string} instead of just Partial<AdapterUser>
|
||||
[pk]: `USER#${user.id as string}`,
|
||||
[sk]: `USER#${user.id as string}`,
|
||||
[pk]: `USER#${user.id}`,
|
||||
[sk]: `USER#${user.id}`,
|
||||
},
|
||||
UpdateExpression,
|
||||
ExpressionAttributeNames,
|
||||
|
||||
1
packages/adapter-fauna/.npmrc
Normal file
1
packages/adapter-fauna/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
<h3 align="center"><b>Fauna Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@next-auth/fauna-adapter">
|
||||
<a href="https://npm.im/@auth/fauna-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@next-auth/fauna-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@next-auth/fauna-adapter?color=green&label=@next-auth/fauna-adapter&style=flat-square">
|
||||
<a href="https://npm.im/@auth/fauna-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/fauna-adapter?color=green&label=@auth/fauna-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@next-auth/fauna-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@next-auth/fauna-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
<a href="https://www.npmtrends.com/@auth/fauna-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/fauna-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
{
|
||||
"name": "@next-auth/fauna-adapter",
|
||||
"version": "1.0.4",
|
||||
"description": "Fauna Adapter for NextAuth",
|
||||
"name": "@auth/fauna-adapter",
|
||||
"version": "1.0.0",
|
||||
"description": "Fauna Adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
],
|
||||
"author": "Bhanu Teja P",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Nico Domino",
|
||||
"email": "yo@ndo.dev"
|
||||
},
|
||||
{
|
||||
"name": "Balázs Orbán",
|
||||
"email": "info@balazsorban.com"
|
||||
}
|
||||
"Nico Domino <yo@ndo.dev>",
|
||||
"Balázs Orbán <info@balazsorban.com>"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
@@ -41,19 +43,20 @@
|
||||
"migrate": "fauna-schema-migrate generate",
|
||||
"test": "./tests/test.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"faunadb": "^4.3.0",
|
||||
"next-auth": "^4"
|
||||
"faunadb": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fauna-labs/fauna-schema-migrate": "^2.1.3",
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@next-auth/tsconfig": "workspace:*",
|
||||
"faunadb": "^4.3.0",
|
||||
"jest": "^27.4.3",
|
||||
"next-auth": "workspace:*"
|
||||
"jest": "^27.4.3"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@next-auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,10 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @next-auth/fauna-adapter faunadb
|
||||
* npm install @auth/fauna-adapter faunadb
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/fauna-adapter
|
||||
* @module @auth/fauna-adapter
|
||||
*/
|
||||
import {
|
||||
Client as FaunaClient,
|
||||
@@ -44,7 +44,7 @@ import {
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
} from "@auth/core/adapters"
|
||||
|
||||
export const collections = {
|
||||
Users: Collection("users"),
|
||||
@@ -137,7 +137,7 @@ export function query(f: FaunaClient, format: (...args: any) => any) {
|
||||
* ```javascript title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { Client as FaunaClient } from "faunadb"
|
||||
* import { FaunaAdapter } from "@next-auth/fauna-adapter"
|
||||
* import { FaunaAdapter } from "@auth/fauna-adapter"
|
||||
*
|
||||
* const client = new FaunaClient({
|
||||
* secret: "secret",
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"extends": "@next-auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"exclude": ["tests", "dist", "jest.config.js"]
|
||||
}
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
1
packages/adapter-firebase/.npmrc
Normal file
1
packages/adapter-firebase/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
<h3 align="center"><b>Firebase Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@next-auth/firebase-adapter">
|
||||
<a href="https://npm.im/@auth/firebase-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@next-auth/firebase-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@next-auth/firebase-adapter?color=green&label=@next-auth/firebase-adapter&style=flat-square">
|
||||
<a href="https://npm.im/@auth/firebase-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/firebase-adapter?color=green&label=@auth/firebase-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@next-auth/firebase-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@next-auth/firebase-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
<a href="https://www.npmtrends.com/@auth/firebase-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/firebase-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@next-auth/firebase-adapter",
|
||||
"version": "2.0.1",
|
||||
"description": "Firebase adapter for next-auth.",
|
||||
"name": "@auth/firebase-adapter",
|
||||
"version": "1.0.0",
|
||||
"description": "Firebase adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
@@ -13,17 +13,18 @@
|
||||
"Alex Meuer <github@alexmeuer.com>"
|
||||
],
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"*.js",
|
||||
"*.d.ts*"
|
||||
],
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
@@ -40,16 +41,17 @@
|
||||
"build": "tsc",
|
||||
"test": "firebase emulators:exec --only firestore --project next-auth-test 'jest -c tests/jest.config.js'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"firebase-admin": "^11.4.1",
|
||||
"next-auth": "^4"
|
||||
"firebase-admin": "^11.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@next-auth/tsconfig": "workspace:*",
|
||||
"firebase-admin": "^11.4.1",
|
||||
"firebase-tools": "^11.16.1",
|
||||
"jest": "^29.3.1",
|
||||
"next-auth": "workspace:*"
|
||||
"jest": "^29.3.1"
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,10 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @next-auth/firebase-adapter firebase-admin
|
||||
* npm install @auth/firebase-adapter firebase-admin
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/firebase-adapter
|
||||
* @module @auth/firebase-adapter
|
||||
*/
|
||||
|
||||
import { type AppOptions, getApps, initializeApp } from "firebase-admin/app"
|
||||
@@ -33,7 +33,7 @@ import type {
|
||||
AdapterAccount,
|
||||
AdapterSession,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
} from "@auth/core/adapters"
|
||||
|
||||
/** Configure the Firebase Adapter. */
|
||||
export interface FirebaseAdapterConfig extends AppOptions {
|
||||
@@ -52,7 +52,7 @@ export interface FirebaseAdapterConfig extends AppOptions {
|
||||
* @example
|
||||
* ```ts title="pages/api/auth/[...nextauth].ts"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { FirestoreAdapter } from "@next-auth/firebase-adapter"
|
||||
* import { FirestoreAdapter } from "@auth/firebase-adapter"
|
||||
*
|
||||
* export default NextAuth({
|
||||
* adapter: FirestoreAdapter({ namingStrategy: "snake_case" })
|
||||
@@ -78,7 +78,7 @@ export interface FirebaseAdapterConfig extends AppOptions {
|
||||
* @example
|
||||
* ```ts title="pages/api/auth/[...nextauth].ts"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { FirestoreAdapter } from "@next-auth/firebase-adapter"
|
||||
* import { FirestoreAdapter } from "@auth/firebase-adapter"
|
||||
*
|
||||
* export default NextAuth({
|
||||
* adapter: FirestoreAdapter(),
|
||||
@@ -95,7 +95,7 @@ export interface FirebaseAdapterConfig extends AppOptions {
|
||||
* @example
|
||||
* ```ts title="pages/api/auth/[...nextauth].ts"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { FirestoreAdapter } from "@next-auth/firebase-adapter"
|
||||
* import { FirestoreAdapter } from "@auth/firebase-adapter"
|
||||
* import { cert } from "firebase-admin/app"
|
||||
*
|
||||
* export default NextAuth({
|
||||
@@ -125,7 +125,7 @@ export interface FirebaseAdapterConfig extends AppOptions {
|
||||
* @example
|
||||
* ```ts title="pages/api/auth/[...nextauth].ts"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { FirestoreAdapter } from "@next-auth/firebase-adapter"
|
||||
* import { FirestoreAdapter } from "@auth/firebase-adapter"
|
||||
* import { firestore } from "lib/firestore"
|
||||
*
|
||||
* export default NextAuth({
|
||||
@@ -428,7 +428,7 @@ export function collectionsFactory(
|
||||
*
|
||||
* @example
|
||||
* ```ts title="lib/firestore.ts"
|
||||
* import { initFirestore } from "@next-auth/firebase-adapter"
|
||||
* import { initFirestore } from "@auth/firebase-adapter"
|
||||
* import { cert } from "firebase-admin/app"
|
||||
*
|
||||
* export const firestore = initFirestore({
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"extends": "@next-auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
@@ -18,6 +19,7 @@
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"tests"
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/mikro-orm-adapter",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "MikroORM adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
|
||||
@@ -24,7 +24,7 @@ import type { Adapter } from "@auth/core/adapters"
|
||||
|
||||
import { MikroORM, wrap } from "@mikro-orm/core"
|
||||
|
||||
import * as defaultEntities from "./lib/entities"
|
||||
import * as defaultEntities from "./lib/entities.js"
|
||||
|
||||
export { defaultEntities }
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
<h3 align="center"><b>Neo4j Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@next-auth/neo4j-adapter">
|
||||
<a href="https://npm.im/@auth/neo4j-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@next-auth/neo4j-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@next-auth/neo4j-adapter?color=green&label=@next-auth/neo4j-adapter&style=flat-square">
|
||||
<a href="https://npm.im/@auth/neo4j-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/neo4j-adapter?color=green&label=@auth/neo4j-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@next-auth/neo4j-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@next-auth/neo4j-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
<a href="https://www.npmtrends.com/@auth/neo4j-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/neo4j-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@next-auth/neo4j-adapter",
|
||||
"version": "1.0.6",
|
||||
"description": "neo4j adapter for next-auth.",
|
||||
"name": "@auth/neo4j-adapter",
|
||||
"version": "1.0.0",
|
||||
"description": "neo4j adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
@@ -11,7 +11,19 @@
|
||||
"contributors": [
|
||||
"Balázs Orbán <info@balazsorban.com>"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
@@ -28,24 +40,18 @@
|
||||
"test": "./tests/test.sh",
|
||||
"build": "tsc"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
"dist"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"neo4j-driver": "^4.0.0 || ^5.7.0",
|
||||
"next-auth": "^4"
|
||||
"neo4j-driver": "^4.0.0 || ^5.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@next-auth/tsconfig": "workspace:*",
|
||||
"@types/uuid": "^8.3.3",
|
||||
"jest": "^27.4.3",
|
||||
"neo4j-driver": "^5.7.0",
|
||||
"next-auth": "workspace:*"
|
||||
"neo4j-driver": "^5.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^8.3.2"
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@next-auth/adapter-test/jest"
|
||||
|
||||
@@ -9,17 +9,13 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @next-auth/neo4j-adapter neo4j-driver
|
||||
* npm install @auth/neo4j-adapter neo4j-driver
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/neo4j-adapter
|
||||
* @module @auth/neo4j-adapter
|
||||
*/
|
||||
import type { Session } from "neo4j-driver"
|
||||
import type { Adapter } from "next-auth/adapters"
|
||||
import { v4 as uuid } from "uuid"
|
||||
|
||||
import { client, format } from "./utils"
|
||||
export { format }
|
||||
import { type Session, isInt, integer } from "neo4j-driver"
|
||||
import type { Adapter } from "@auth/core/adapters"
|
||||
|
||||
/** This is the interface of the Neo4j adapter options. The Neo4j adapter takes a {@link https://neo4j.com/docs/bolt/current/driver-api/#driver-session Neo4j session} as its only argument. */
|
||||
export interface Neo4jOptions extends Session {}
|
||||
@@ -31,7 +27,7 @@ export interface Neo4jOptions extends Session {}
|
||||
*
|
||||
* ```javascript title="pages/api/auth/[...nextauth].js"
|
||||
* import neo4j from "neo4j-driver"
|
||||
* import { Neo4jAdapter } from "@next-auth/neo4j-adapter"
|
||||
* import { Neo4jAdapter } from "@auth/neo4j-adapter"
|
||||
*
|
||||
* const driver = neo4j.driver(
|
||||
* "bolt://localhost",
|
||||
@@ -134,7 +130,7 @@ export function Neo4jAdapter(session: Session): Adapter {
|
||||
|
||||
return {
|
||||
async createUser(data) {
|
||||
const user: any = { id: uuid(), ...data }
|
||||
const user = { id: crypto.randomUUID(), ...data }
|
||||
await write(`CREATE (u:User $data)`, user)
|
||||
return user
|
||||
},
|
||||
@@ -288,3 +284,69 @@ export function Neo4jAdapter(session: Session): Adapter {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/honeinc/is-iso-date/blob/master/index.js
|
||||
const isoDateRE =
|
||||
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/
|
||||
|
||||
function isDate(value: any) {
|
||||
return value && isoDateRE.test(value) && !isNaN(Date.parse(value))
|
||||
}
|
||||
|
||||
export const format = {
|
||||
/** Takes a plain old JavaScript object and turns it into a Neo4j compatible object */
|
||||
to(object: Record<string, any>) {
|
||||
const newObject: Record<string, unknown> = {}
|
||||
for (const key in object) {
|
||||
const value = object[key]
|
||||
if (value instanceof Date) newObject[key] = value.toISOString()
|
||||
else newObject[key] = value
|
||||
}
|
||||
return newObject
|
||||
},
|
||||
/** Takes a Neo4j object and returns a plain old JavaScript object */
|
||||
from<T = Record<string, unknown>>(object?: Record<string, any>): T | null {
|
||||
const newObject: Record<string, unknown> = {}
|
||||
if (!object) return null
|
||||
for (const key in object) {
|
||||
const value = object[key]
|
||||
if (isDate(value)) {
|
||||
newObject[key] = new Date(value)
|
||||
} else if (isInt(value)) {
|
||||
if (integer.inSafeRange(value)) newObject[key] = value.toNumber()
|
||||
else newObject[key] = value.toString()
|
||||
} else {
|
||||
newObject[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return newObject as T
|
||||
},
|
||||
}
|
||||
|
||||
function client(session: Session) {
|
||||
return {
|
||||
/** Reads values from the database */
|
||||
async read<T>(statement: string, values?: any): Promise<T | null> {
|
||||
const result = await session.readTransaction((tx) =>
|
||||
tx.run(statement, values)
|
||||
)
|
||||
|
||||
return format.from<T>(result?.records[0]?.get(0)) ?? null
|
||||
},
|
||||
/**
|
||||
* Reads/writes values from/to the database.
|
||||
* Properties are available under `$data`
|
||||
*/
|
||||
async write<T extends Record<string, any>>(
|
||||
statement: string,
|
||||
values: T
|
||||
): Promise<any> {
|
||||
const result = await session.writeTransaction((tx) =>
|
||||
tx.run(statement, { data: format.to(values) })
|
||||
)
|
||||
|
||||
return format.from<T>(result?.records[0]?.toObject())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
import type { Session } from "neo4j-driver"
|
||||
import { isInt, integer } from "neo4j-driver"
|
||||
|
||||
// https://github.com/honeinc/is-iso-date/blob/master/index.js
|
||||
const isoDateRE =
|
||||
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/
|
||||
|
||||
function isDate(value: any) {
|
||||
return value && isoDateRE.test(value) && !isNaN(Date.parse(value))
|
||||
}
|
||||
|
||||
export const format = {
|
||||
/** Takes a plain old JavaScript object and turns it into a Neo4j compatible object */
|
||||
to(object: Record<string, any>) {
|
||||
const newObject: Record<string, unknown> = {}
|
||||
for (const key in object) {
|
||||
const value = object[key]
|
||||
if (value instanceof Date) newObject[key] = value.toISOString()
|
||||
else newObject[key] = value
|
||||
}
|
||||
return newObject
|
||||
},
|
||||
/** Takes a Neo4j object and returns a plain old JavaScript object */
|
||||
from<T = Record<string, unknown>>(object?: Record<string, any>): T | null {
|
||||
const newObject: Record<string, unknown> = {}
|
||||
if (!object) return null
|
||||
for (const key in object) {
|
||||
const value = object[key]
|
||||
if (isDate(value)) {
|
||||
newObject[key] = new Date(value)
|
||||
} else if (isInt(value)) {
|
||||
if (integer.inSafeRange(value)) newObject[key] = value.toNumber()
|
||||
else newObject[key] = value.toString()
|
||||
} else {
|
||||
newObject[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return newObject as T
|
||||
},
|
||||
}
|
||||
|
||||
export function client(session: Session) {
|
||||
return {
|
||||
/** Reads values from the database */
|
||||
async read<T>(statement: string, values?: any): Promise<T | null> {
|
||||
const result = await session.readTransaction((tx) =>
|
||||
tx.run(statement, values)
|
||||
)
|
||||
|
||||
return format.from<T>(result?.records[0]?.get(0)) ?? null
|
||||
},
|
||||
/**
|
||||
* Reads/writes values from/to the database.
|
||||
* Properties are available under `$data`
|
||||
*/
|
||||
async write<T extends Record<string, any>>(
|
||||
statement: string,
|
||||
values: T
|
||||
): Promise<any> {
|
||||
const result = await session.writeTransaction((tx) =>
|
||||
tx.run(statement, { data: format.to(values) })
|
||||
)
|
||||
|
||||
return format.from<T>(result?.records[0]?.toObject())
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import statements from "./resources/statements"
|
||||
|
||||
import { Neo4jAdapter, format } from "../src"
|
||||
|
||||
globalThis.crypto ??= require("node:crypto").webcrypto
|
||||
|
||||
const driver = neo4j.driver(
|
||||
"bolt://localhost",
|
||||
neo4j.auth.basic("neo4j", "password")
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"extends": "@next-auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"exclude": ["tests", "dist", "jest.config.js"]
|
||||
}
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
<h3 align="center"><b>PouchDB Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@next-auth/pouchdb-adapter">
|
||||
<a href="https://npm.im/@auth/pouchdb-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@next-auth/pouchdb-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@next-auth/pouchdb-adapter?color=green&label=@next-auth/pouchdb-adapter&style=flat-square">
|
||||
<a href="https://npm.im/@auth/pouchdb-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/pouchdb-adapter?color=green&label=@auth/pouchdb-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@next-auth/pouchdb-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@next-auth/pouchdb-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
<a href="https://www.npmtrends.com/@auth/pouchdb-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/pouchdb-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@next-auth/pouchdb-adapter",
|
||||
"name": "@auth/pouchdb-adapter",
|
||||
"version": "1.0.0",
|
||||
"description": "PouchDB adapter for next-auth.",
|
||||
"homepage": "https://authjs.dev",
|
||||
@@ -38,19 +38,17 @@
|
||||
"src"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"next-auth": "^4",
|
||||
"pouchdb": "^8.0.1",
|
||||
"pouchdb-find": "^8.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ulid": "2.3.0"
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@next-auth/tsconfig": "workspace:*",
|
||||
"@types/pouchdb": "^6.4.0",
|
||||
"jest": "^27.4.3",
|
||||
"next-auth": "workspace:*",
|
||||
"pouchdb": "^8.0.1",
|
||||
"pouchdb-adapter-memory": "^8.0.1",
|
||||
"pouchdb-find": "^8.0.1"
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth pouchdb pouchdb-find @next-auth/pouchdb-adapter
|
||||
* npm install pouchdb pouchdb-find @auth/pouchdb-adapter
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/pouchdb-adapter
|
||||
* @module @auth/pouchdb-adapter
|
||||
*/
|
||||
|
||||
import type {
|
||||
@@ -21,8 +21,7 @@ import type {
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
import { ulid } from "ulid"
|
||||
} from "@auth/core/adapters"
|
||||
|
||||
type PrefixConfig = Record<
|
||||
"user" | "account" | "session" | "verificationToken",
|
||||
@@ -99,7 +98,7 @@ export interface PouchDBAdapterOptions {
|
||||
* ```javascript title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import GoogleProvider from "next-auth/providers/google"
|
||||
* import { PouchDBAdapter } from "@next-auth/pouchdb-adapter"
|
||||
* import { PouchDBAdapter } from "@auth/pouchdb-adapter"
|
||||
* import PouchDB from "pouchdb"
|
||||
*
|
||||
* // Setup your PouchDB instance and database
|
||||
@@ -154,7 +153,7 @@ export function PouchDBAdapter(options: PouchDBAdapterOptions): Adapter {
|
||||
|
||||
return {
|
||||
async createUser(user) {
|
||||
const doc = { ...user, _id: [userPrefix, ulid()].join("_") }
|
||||
const doc = { ...user, _id: [userPrefix, crypto.randomUUID()].join("_") }
|
||||
await pouchdb.put(doc)
|
||||
return { ...user, id: doc._id }
|
||||
},
|
||||
@@ -220,7 +219,10 @@ export function PouchDBAdapter(options: PouchDBAdapterOptions): Adapter {
|
||||
async deleteUser(id) {},
|
||||
|
||||
async linkAccount(account) {
|
||||
const doc = { ...account, _id: [accountPrefix, ulid()].join("_") }
|
||||
const doc = {
|
||||
...account,
|
||||
_id: [accountPrefix, crypto.randomUUID()].join("_"),
|
||||
}
|
||||
await (pouchdb as unknown as PouchDB.Database<AdapterAccount>).put(doc)
|
||||
|
||||
return { ...account, id: doc._id }
|
||||
@@ -245,7 +247,7 @@ export function PouchDBAdapter(options: PouchDBAdapterOptions): Adapter {
|
||||
|
||||
async createSession(data) {
|
||||
const doc = {
|
||||
_id: [sessionPrefix, ulid()].join("_"),
|
||||
_id: [sessionPrefix, crypto.randomUUID()].join("_"),
|
||||
...data,
|
||||
}
|
||||
await (pouchdb as unknown as PouchDB.Database<AdapterSession>).put(doc)
|
||||
@@ -317,7 +319,7 @@ export function PouchDBAdapter(options: PouchDBAdapterOptions): Adapter {
|
||||
|
||||
async createVerificationToken(data) {
|
||||
await (pouchdb as unknown as PouchDB.Database<VerificationToken>).put({
|
||||
_id: [verificationTokenPrefix, ulid()].join("_"),
|
||||
_id: [verificationTokenPrefix, crypto.randomUUID()].join("_"),
|
||||
...data,
|
||||
})
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@ import {
|
||||
import PouchDB from "pouchdb"
|
||||
import find from "pouchdb-find"
|
||||
import memoryAdapter from "pouchdb-adapter-memory"
|
||||
import { ulid } from "ulid"
|
||||
import {
|
||||
AdapterAccount,
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
} from "@auth/core/adapters"
|
||||
|
||||
globalThis.crypto ??= require("node:crypto").webcrypto
|
||||
|
||||
// pouchdb setup
|
||||
PouchDB.plugin(memoryAdapter).plugin(find)
|
||||
@@ -31,7 +32,7 @@ PouchDB.on("destroyed", function () {
|
||||
const disconnect = async () => {
|
||||
if (!pouchdbIsDestroyed) await pouchdb.destroy()
|
||||
}
|
||||
pouchdb = new PouchDB(ulid(), { adapter: "memory" })
|
||||
pouchdb = new PouchDB(crypto.randomUUID(), { adapter: "memory" })
|
||||
|
||||
// Basic tests
|
||||
runBasicTests({
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"extends": "@next-auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"outDir": ".",
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"exclude": ["tests", "jest.config.js"]
|
||||
}
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/prisma-adapter",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "Prisma adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev/reference/adapter/prisma",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
|
||||
@@ -21,7 +21,7 @@ import type { Adapter, AdapterAccount } from "@auth/core/adapters"
|
||||
/**
|
||||
* ## Setup
|
||||
*
|
||||
* Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object:
|
||||
* Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object:
|
||||
*
|
||||
* ```js title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
<h3 align="center"><b>Sequelize Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@next-auth/sequelize-adapter">
|
||||
<a href="https://npm.im/@auth/sequelize-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@next-auth/sequelize-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@next-auth/sequelize-adapter?color=green&label=@next-auth/sequelize-adapter&style=flat-square">
|
||||
<a href="https://npm.im/@auth/sequelize-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/sequelize-adapter?color=green&label=@auth/sequelize-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@next-auth/sequelize-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@next-auth/sequelize-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
<a href="https://www.npmtrends.com/@auth/sequelize-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/sequelize-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
{
|
||||
"name": "@next-auth/sequelize-adapter",
|
||||
"version": "1.0.8",
|
||||
"description": "Sequelize adapter for next-auth.",
|
||||
"name": "@auth/sequelize-adapter",
|
||||
"version": "1.0.1",
|
||||
"description": "Sequelize adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "github.com/luke-j",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
@@ -21,22 +33,19 @@
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"test:wip": "jest",
|
||||
"test": "jest",
|
||||
"build": "tsc"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next-auth": "^4",
|
||||
"sequelize": "^6.6.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@next-auth/tsconfig": "workspace:*",
|
||||
"jest": "^27.4.3",
|
||||
"next-auth": "workspace:*",
|
||||
"sequelize": "^6.6.5"
|
||||
},
|
||||
"jest": {
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @next-auth/sequelize-adapter sequelize
|
||||
* npm install next-auth @auth/sequelize-adapter sequelize
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/sequelize-adapter
|
||||
* @module @auth/sequelize-adapter
|
||||
*/
|
||||
import type {
|
||||
Adapter,
|
||||
@@ -20,13 +20,14 @@ import type {
|
||||
AdapterAccount,
|
||||
AdapterSession,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
} from "@auth/core/adapters"
|
||||
import { Sequelize, Model, ModelCtor } from "sequelize"
|
||||
import * as defaultModels from "./models"
|
||||
import * as defaultModels from "./models.js"
|
||||
|
||||
export { defaultModels as models }
|
||||
|
||||
// @see https://sequelize.org/master/manual/typescript.html
|
||||
//@ts-expect-error
|
||||
interface AccountInstance
|
||||
extends Model<AdapterAccount, Partial<AdapterAccount>>,
|
||||
AdapterAccount {}
|
||||
@@ -70,7 +71,7 @@ export interface SequelizeAdapterOptions {
|
||||
*
|
||||
* ```javascript title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import SequelizeAdapter from "@next-auth/sequelize-adapter"
|
||||
* import SequelizeAdapter from "@auth/sequelize-adapter"
|
||||
* import { Sequelize } from "sequelize"
|
||||
*
|
||||
* // https://sequelize.org/master/manual/getting-started.html#connecting-to-a-database
|
||||
@@ -93,7 +94,7 @@ export interface SequelizeAdapterOptions {
|
||||
*
|
||||
* ```js
|
||||
* import NextAuth from "next-auth"
|
||||
* import SequelizeAdapter from "@next-auth/sequelize-adapter"
|
||||
* import SequelizeAdapter from "@auth/sequelize-adapter"
|
||||
* import Sequelize from 'sequelize'
|
||||
*
|
||||
* const sequelize = new Sequelize("sqlite::memory:")
|
||||
@@ -117,7 +118,7 @@ export interface SequelizeAdapterOptions {
|
||||
*
|
||||
* ```js
|
||||
* import NextAuth from "next-auth"
|
||||
* import SequelizeAdapter, { models } from "@next-auth/sequelize-adapter"
|
||||
* import SequelizeAdapter, { models } from "@auth/sequelize-adapter"
|
||||
* import Sequelize, { DataTypes } from "sequelize"
|
||||
*
|
||||
* const sequelize = new Sequelize("sqlite::memory:")
|
||||
@@ -218,6 +219,7 @@ export default function SequelizeAdapter(
|
||||
await sync()
|
||||
|
||||
const accountInstance = await Account.findOne({
|
||||
// @ts-expect-error
|
||||
where: { provider, providerAccountId },
|
||||
})
|
||||
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"extends": "@next-auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"exclude": ["tests", "dist", "jest.config.js"]
|
||||
}
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
1
packages/adapter-supabase/.npmrc
Normal file
1
packages/adapter-supabase/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
<h3 align="center"><b>Supabase Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@next-auth/supabase-adapter">
|
||||
<a href="https://npm.im/@auth/supabase-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@next-auth/supabase-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@next-auth/supabase-adapter?color=green&label=@next-auth/supabase-adapter&style=flat-square">
|
||||
<a href="https://npm.im/@auth/supabase-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/supabase-adapter?color=green&label=@auth/supabase-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@next-auth/supabase-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@next-auth/supabase-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
<a href="https://www.npmtrends.com/@auth/supabase-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/supabase-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
{
|
||||
"name": "@next-auth/supabase-adapter",
|
||||
"version": "0.2.1",
|
||||
"description": "Supabase adapter for next-auth.",
|
||||
"name": "@auth/supabase-adapter",
|
||||
"version": "0.1.2",
|
||||
"description": "Supabase adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Martin Sonnberger <martin.sonnberger@icloud.com>",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
"next.js",
|
||||
@@ -23,18 +35,19 @@
|
||||
"build": "tsc",
|
||||
"test": "./tests/test.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@supabase/supabase-js": "^2.0.5",
|
||||
"next-auth": "^4.18.7"
|
||||
"@supabase/supabase-js": "^2.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:^0.0.0",
|
||||
"@next-auth/tsconfig": "workspace:^0.0.0",
|
||||
"@supabase/supabase-js": "^2.0.5",
|
||||
"jest": "^27.4.3",
|
||||
"next-auth": "workspace:*"
|
||||
"jest": "^27.4.3"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@next-auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
export type Json =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| { [key: string]: Json }
|
||||
| Json[]
|
||||
|
||||
export interface Database {
|
||||
next_auth: {
|
||||
Tables: {
|
||||
accounts: {
|
||||
Row: {
|
||||
id: string
|
||||
type: string | null
|
||||
provider: string | null
|
||||
providerAccountId: string | null
|
||||
refresh_token: string | null
|
||||
access_token: string | null
|
||||
expires_at: number | null
|
||||
token_type: string | null
|
||||
scope: string | null
|
||||
id_token: string | null
|
||||
session_state: string | null
|
||||
oauth_token_secret: string | null
|
||||
oauth_token: string | null
|
||||
userId: string | null
|
||||
}
|
||||
Insert: {
|
||||
id?: string
|
||||
type?: string | null
|
||||
provider?: string | null
|
||||
providerAccountId?: string | null
|
||||
refresh_token?: string | null
|
||||
access_token?: string | null
|
||||
expires_at?: number | null
|
||||
token_type?: string | null
|
||||
scope?: string | null
|
||||
id_token?: string | null
|
||||
session_state?: string | null
|
||||
oauth_token_secret?: string | null
|
||||
oauth_token?: string | null
|
||||
userId?: string | null
|
||||
}
|
||||
Update: {
|
||||
id?: string
|
||||
type?: string | null
|
||||
provider?: string | null
|
||||
providerAccountId?: string | null
|
||||
refresh_token?: string | null
|
||||
access_token?: string | null
|
||||
expires_at?: number | null
|
||||
token_type?: string | null
|
||||
scope?: string | null
|
||||
id_token?: string | null
|
||||
session_state?: string | null
|
||||
oauth_token_secret?: string | null
|
||||
oauth_token?: string | null
|
||||
userId?: string | null
|
||||
}
|
||||
}
|
||||
sessions: {
|
||||
Row: {
|
||||
expires: string | null
|
||||
sessionToken: string | null
|
||||
userId: string | null
|
||||
id: string
|
||||
}
|
||||
Insert: {
|
||||
expires?: string | null
|
||||
sessionToken?: string | null
|
||||
userId?: string | null
|
||||
id?: string
|
||||
}
|
||||
Update: {
|
||||
expires?: string | null
|
||||
sessionToken?: string | null
|
||||
userId?: string | null
|
||||
id?: string
|
||||
}
|
||||
}
|
||||
users: {
|
||||
Row: {
|
||||
name: string | null
|
||||
email: string | null
|
||||
emailVerified: string | null
|
||||
image: string | null
|
||||
id: string
|
||||
}
|
||||
Insert: {
|
||||
name?: string | null
|
||||
email?: string | null
|
||||
emailVerified?: string | null
|
||||
image?: string | null
|
||||
id?: string
|
||||
}
|
||||
Update: {
|
||||
name?: string | null
|
||||
email?: string | null
|
||||
emailVerified?: string | null
|
||||
image?: string | null
|
||||
id?: string
|
||||
}
|
||||
}
|
||||
verification_tokens: {
|
||||
Row: {
|
||||
id: number
|
||||
identifier: string | null
|
||||
token: string | null
|
||||
expires: string | null
|
||||
}
|
||||
Insert: {
|
||||
id?: number
|
||||
identifier?: string | null
|
||||
token?: string | null
|
||||
expires?: string | null
|
||||
}
|
||||
Update: {
|
||||
id?: number
|
||||
identifier?: string | null
|
||||
token?: string | null
|
||||
expires?: string | null
|
||||
}
|
||||
}
|
||||
}
|
||||
Views: {
|
||||
[_ in never]: never
|
||||
}
|
||||
Functions: {
|
||||
uid: {
|
||||
Args: Record<PropertyKey, never>
|
||||
Returns: string
|
||||
}
|
||||
}
|
||||
Enums: {
|
||||
[_ in never]: never
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,19 +9,18 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install @supabase/supabase-js next-auth @next-auth/supabase-adapter
|
||||
* npm install @supabase/supabase-js @auth/supabase-adapter
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/supabase-adapter
|
||||
* @module @auth/supabase-adapter
|
||||
*/
|
||||
import { createClient } from "@supabase/supabase-js"
|
||||
import { Database } from "./database.types"
|
||||
import {
|
||||
Adapter,
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
} from "@auth/core/adapters"
|
||||
|
||||
function isDate(date: any) {
|
||||
return (
|
||||
@@ -61,7 +60,7 @@ export interface SupabaseAdapterOptions {
|
||||
* :::note
|
||||
* This adapter is developed by the community and not officially maintained or supported by Supabase. It uses the Supabase Database to store user and session data in a separate `next_auth` schema. It is a standalone Auth server that does not interface with Supabase Auth and therefore provides a different feature set.
|
||||
*
|
||||
* If you’re looking for an officially maintained Auth server with additional features like [built-in email server](https://supabase.com/docs/guides/auth/auth-email#configure-email-settings?utm_source=authjs-docs&medium=referral&campaign=authjs), [phone auth](https://supabase.com/docs/guides/auth/auth-twilio?utm_source=authjs-docs&medium=referral&campaign=authjs), and [Multi Factor Authentication (MFA / 2FA)](https://supabase.com/contact/mfa?utm_source=authjs-docs&medium=referral&campaign=authjs), please use [Supabase Auth](https://supabase.com/auth) with the [Auth Helpers for Next.js](https://supabase.com/docs/guides/auth/auth-helpers/nextjs?utm_source=authjs-docs&medium=referral&campaign=authjs).
|
||||
* If you're looking for an officially maintained Auth server with additional features like [built-in email server](https://supabase.com/docs/guides/auth/auth-email#configure-email-settings?utm_source=authjs-docs&medium=referral&campaign=authjs), [phone auth](https://supabase.com/docs/guides/auth/auth-twilio?utm_source=authjs-docs&medium=referral&campaign=authjs), and [Multi Factor Authentication (MFA / 2FA)](https://supabase.com/contact/mfa?utm_source=authjs-docs&medium=referral&campaign=authjs), please use [Supabase Auth](https://supabase.com/auth) with the [Auth Helpers for Next.js](https://supabase.com/docs/guides/auth/auth-helpers/nextjs?utm_source=authjs-docs&medium=referral&campaign=authjs).
|
||||
* :::
|
||||
*
|
||||
* ## Setup
|
||||
@@ -72,7 +71,7 @@ export interface SupabaseAdapterOptions {
|
||||
*
|
||||
* ```js title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { SupabaseAdapter } from "@next-auth/supabase-adapter"
|
||||
* import { SupabaseAdapter } from "@auth/supabase-adapter"
|
||||
*
|
||||
* // For more information on each option (and a full list of options) go to
|
||||
* // https://authjs.dev/reference/configuration/auth-config
|
||||
@@ -224,7 +223,7 @@ export interface SupabaseAdapterOptions {
|
||||
*
|
||||
* ```js title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { SupabaseAdapter } from "@next-auth/supabase-adapter"
|
||||
* import { SupabaseAdapter } from "@auth/supabase-adapter"
|
||||
* import jwt from "jsonwebtoken"
|
||||
*
|
||||
* // For more information on each option (and a full list of options) go to
|
||||
@@ -350,9 +349,7 @@ export function SupabaseAdapter(options: SupabaseAdapterOptions): Adapter {
|
||||
const { url, secret } = options
|
||||
const supabase = createClient<Database, "next_auth">(url, secret, {
|
||||
db: { schema: "next_auth" },
|
||||
global: {
|
||||
headers: { "X-Client-Info": "@next-auth/supabase-adapter@0.1.0" },
|
||||
},
|
||||
global: { headers: { "X-Client-Info": "@auth/supabase-adapter" } },
|
||||
})
|
||||
return {
|
||||
async createUser(user) {
|
||||
@@ -463,7 +460,7 @@ export function SupabaseAdapter(options: SupabaseAdapterOptions): Adapter {
|
||||
|
||||
return {
|
||||
user: format<AdapterUser>(
|
||||
user as Database["next_auth"]["Tables"]["users"]["Row"]
|
||||
user as Database["next_auth"]["Tables"]["users"]["Row"][]
|
||||
),
|
||||
session: format<AdapterSession>(session),
|
||||
}
|
||||
@@ -524,3 +521,135 @@ export function SupabaseAdapter(options: SupabaseAdapterOptions): Adapter {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
interface Database {
|
||||
next_auth: {
|
||||
Tables: {
|
||||
accounts: {
|
||||
Row: {
|
||||
id: string
|
||||
type: string | null
|
||||
provider: string | null
|
||||
providerAccountId: string | null
|
||||
refresh_token: string | null
|
||||
access_token: string | null
|
||||
expires_at: number | null
|
||||
token_type: string | null
|
||||
scope: string | null
|
||||
id_token: string | null
|
||||
session_state: string | null
|
||||
oauth_token_secret: string | null
|
||||
oauth_token: string | null
|
||||
userId: string | null
|
||||
}
|
||||
Insert: {
|
||||
id?: string
|
||||
type?: string | null
|
||||
provider?: string | null
|
||||
providerAccountId?: string | null
|
||||
refresh_token?: string | null
|
||||
access_token?: string | null
|
||||
expires_at?: number | null
|
||||
token_type?: string | null
|
||||
scope?: string | null
|
||||
id_token?: string | null
|
||||
session_state?: string | null
|
||||
oauth_token_secret?: string | null
|
||||
oauth_token?: string | null
|
||||
userId?: string | null
|
||||
}
|
||||
Update: {
|
||||
id?: string
|
||||
type?: string | null
|
||||
provider?: string | null
|
||||
providerAccountId?: string | null
|
||||
refresh_token?: string | null
|
||||
access_token?: string | null
|
||||
expires_at?: number | null
|
||||
token_type?: string | null
|
||||
scope?: string | null
|
||||
id_token?: string | null
|
||||
session_state?: string | null
|
||||
oauth_token_secret?: string | null
|
||||
oauth_token?: string | null
|
||||
userId?: string | null
|
||||
}
|
||||
}
|
||||
sessions: {
|
||||
Row: {
|
||||
expires: string | null
|
||||
sessionToken: string | null
|
||||
userId: string | null
|
||||
id: string
|
||||
}
|
||||
Insert: {
|
||||
expires?: string | null
|
||||
sessionToken?: string | null
|
||||
userId?: string | null
|
||||
id?: string
|
||||
}
|
||||
Update: {
|
||||
expires?: string | null
|
||||
sessionToken?: string | null
|
||||
userId?: string | null
|
||||
id?: string
|
||||
}
|
||||
}
|
||||
users: {
|
||||
Row: {
|
||||
name: string | null
|
||||
email: string | null
|
||||
emailVerified: string | null
|
||||
image: string | null
|
||||
id: string
|
||||
}
|
||||
Insert: {
|
||||
name?: string | null
|
||||
email?: string | null
|
||||
emailVerified?: string | null
|
||||
image?: string | null
|
||||
id?: string
|
||||
}
|
||||
Update: {
|
||||
name?: string | null
|
||||
email?: string | null
|
||||
emailVerified?: string | null
|
||||
image?: string | null
|
||||
id?: string
|
||||
}
|
||||
}
|
||||
verification_tokens: {
|
||||
Row: {
|
||||
id: number
|
||||
identifier: string | null
|
||||
token: string | null
|
||||
expires: string | null
|
||||
}
|
||||
Insert: {
|
||||
id?: number
|
||||
identifier?: string | null
|
||||
token?: string | null
|
||||
expires?: string | null
|
||||
}
|
||||
Update: {
|
||||
id?: number
|
||||
identifier?: string | null
|
||||
token?: string | null
|
||||
expires?: string | null
|
||||
}
|
||||
}
|
||||
}
|
||||
Views: {
|
||||
[_ in never]: never
|
||||
}
|
||||
Functions: {
|
||||
uid: {
|
||||
Args: Record<PropertyKey, never>
|
||||
Returns: string
|
||||
}
|
||||
}
|
||||
Enums: {
|
||||
[_ in never]: never
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import type {
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
import type { Account } from "next-auth"
|
||||
} from "@auth/core/adapters"
|
||||
import type { Account } from "@auth/core/types"
|
||||
|
||||
const url = process.env.SUPABASE_URL ?? "http://localhost:54321"
|
||||
const secret =
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"extends": "@next-auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"exclude": ["tests", "dist", "jest.config.js"]
|
||||
}
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import("@swc/core").Config} */
|
||||
const swcConfig = {
|
||||
jsc: {
|
||||
parser: { syntax: "typescript", decorators: true },
|
||||
transform: { legacyDecorator: true, decoratorMetadata: true },
|
||||
},
|
||||
}
|
||||
|
||||
/** @type {import("jest").Config} */
|
||||
module.exports = {
|
||||
transform: {
|
||||
".(ts|tsx)$": ["@swc/jest", swcConfig],
|
||||
@@ -16,4 +21,7 @@ module.exports = {
|
||||
// collectCoverageFrom: ["<rootDir>/packages/*/src/**/*.{ts,tsx}"],
|
||||
testURL: "http://localhost/",
|
||||
moduleDirectories: ["node_modules"],
|
||||
moduleNameMapper: {
|
||||
'^(\\.{1,2}/.*)\\.js$': '$1',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
"@babel/cli": "^7.14.3",
|
||||
"@babel/plugin-transform-runtime": "^7.14.3",
|
||||
"@babel/preset-env": "^7.14.2",
|
||||
"@types/jest": "^26.0.23",
|
||||
"@swc/core": "^1.2.198",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/nodemailer": "^6.4.4",
|
||||
"jest": "^27.0.3",
|
||||
"jest": "^29.5.0",
|
||||
"ts-jest": "^27.0.3",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/typeorm-adapter",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "TypeORM adapter for Auth.js.",
|
||||
"homepage": "https://authjs.dev/reference/adapter/typeorm",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
|
||||
@@ -21,8 +21,8 @@ import type {
|
||||
AdapterSession,
|
||||
} from "@auth/core/adapters"
|
||||
import { DataSourceOptions, DataSource, EntityManager } from "typeorm"
|
||||
import * as defaultEntities from "./entities"
|
||||
import { parseDataSourceConfig, updateConnectionEntities } from "./utils"
|
||||
import * as defaultEntities from "./entities.js"
|
||||
import { parseDataSourceConfig, updateConnectionEntities } from "./utils.js"
|
||||
|
||||
export const entities = defaultEntities
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { DataSource, DataSourceOptions } from "typeorm"
|
||||
import * as defaultEntities from "./entities"
|
||||
import * as defaultEntities from "./entities.js"
|
||||
|
||||
/** Ensure configOrString is normalized to an object. */
|
||||
export function parseDataSourceConfig(
|
||||
|
||||
1
packages/adapter-xata/.npmrc
Normal file
1
packages/adapter-xata/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
||||
@@ -8,14 +8,14 @@
|
||||
</a>
|
||||
<h3 align="center"><b>Xata Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@next-auth/xata-adapter">
|
||||
<a href="https://npm.im/@auth/xata-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@next-auth/xata-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@next-auth/xata-adapter?color=green&label=@next-auth/xata-adapter&style=flat-square">
|
||||
<a href="https://npm.im/@auth/xata-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/xata-adapter?color=green&label=@auth/xata-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@next-auth/xata-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@next-auth/xata-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
<a href="https://www.npmtrends.com/@auth/xata-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/xata-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
{
|
||||
"name": "@next-auth/xata-adapter",
|
||||
"version": "0.2.2",
|
||||
"description": "Xata adapter for next-auth.",
|
||||
"name": "@auth/xata-adapter",
|
||||
"version": "0.1.0",
|
||||
"description": "Xata adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Tejas Kumar",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
@@ -24,19 +36,16 @@
|
||||
"build": "tsc",
|
||||
"test": "jest"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@xata.io/client": ">=0.13.0",
|
||||
"next-auth": "^4"
|
||||
"@xata.io/client": ">=0.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:^0.0.0",
|
||||
"@next-auth/tsconfig": "workspace:^0.0.0",
|
||||
"jest": "^27.4.3",
|
||||
"next-auth": "workspace:*",
|
||||
"@xata.io/client": "^0.13.0",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* # Install Auth.js and the Xata adapter
|
||||
* npm install next-auth @next-auth/xata-adapter
|
||||
* npm install @auth/xata-adapter
|
||||
*
|
||||
* # Install the Xata CLI globally if you don't already have it
|
||||
* npm install --location=global @xata.io/cli
|
||||
@@ -19,9 +19,9 @@
|
||||
* xata auth login
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/xata-adapter
|
||||
* @module @auth/xata-adapter
|
||||
*/
|
||||
import type { Adapter } from "next-auth/adapters"
|
||||
import type { Adapter } from "@auth/core/adapters"
|
||||
|
||||
import type { XataClient } from "./xata"
|
||||
|
||||
@@ -220,7 +220,7 @@ import type { XataClient } from "./xata"
|
||||
* ```diff
|
||||
* import NextAuth from "next-auth"
|
||||
* import GoogleProvider from "next-auth/providers/google"
|
||||
* +import { XataAdapter } from "@next-auth/xata-adapter"
|
||||
* +import { XataAdapter } from "@auth/xata-adapter"
|
||||
* +import { XataClient } from "../../../xata" // or wherever you've chosen to create the client
|
||||
*
|
||||
* +const client = new XataClient()
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"extends": "@next-auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["."],
|
||||
"exclude": ["tests", "dist", "jest.config.js"]
|
||||
}
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/core",
|
||||
"version": "0.8.2",
|
||||
"version": "0.10.0",
|
||||
"description": "Authentication for the Web.",
|
||||
"keywords": [
|
||||
"authentication",
|
||||
|
||||
@@ -223,7 +223,7 @@ export interface Adapter {
|
||||
getUserByAccount?(
|
||||
providerAccountId: Pick<AdapterAccount, "provider" | "providerAccountId">
|
||||
): Awaitable<AdapterUser | null>
|
||||
updateUser?(user: Partial<AdapterUser>): Awaitable<AdapterUser>
|
||||
updateUser?(user: Partial<AdapterUser> & Pick<AdapterUser, 'id'>): Awaitable<AdapterUser>
|
||||
/** @todo This method is currently not invoked yet. */
|
||||
deleteUser?(
|
||||
userId: string
|
||||
|
||||
@@ -88,7 +88,7 @@ export function assertConfig(
|
||||
}
|
||||
|
||||
const { callbackUrl: defaultCallbackUrl } = defaultCookies(
|
||||
options.useSecureCookies ?? url.protocol === "https://"
|
||||
options.useSecureCookies ?? url.protocol === "https:"
|
||||
)
|
||||
const callbackUrlCookie =
|
||||
request.cookies?.[
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { createHash, randomString } from "../web.js"
|
||||
import { createHash, randomString, toRequest } from "../web.js"
|
||||
|
||||
import type { InternalOptions } from "../../types.js"
|
||||
import type { InternalOptions, RequestInternal } from "../../types.js"
|
||||
/**
|
||||
* Starts an e-mail login flow, by generating a token,
|
||||
* and sending it to the user's e-mail (with the help of a DB adapter)
|
||||
*/
|
||||
export default async function email(
|
||||
identifier: string,
|
||||
options: InternalOptions<"email">
|
||||
options: InternalOptions<"email">,
|
||||
request: RequestInternal
|
||||
): Promise<string> {
|
||||
const { url, adapter, provider, callbackUrl, theme } = options
|
||||
const token =
|
||||
@@ -31,6 +32,7 @@ export default async function email(
|
||||
url: _url,
|
||||
provider,
|
||||
theme,
|
||||
request: toRequest(request),
|
||||
}),
|
||||
// @ts-expect-error -- Verified in `assertConfig`.
|
||||
adapter.createVerificationToken?.({
|
||||
|
||||
@@ -137,8 +137,7 @@ export async function AuthInternal<
|
||||
case "signin":
|
||||
if ((csrfDisabled || options.csrfTokenVerified) && options.provider) {
|
||||
const signin = await routes.signin(
|
||||
request.query,
|
||||
request.body,
|
||||
request,
|
||||
options
|
||||
)
|
||||
if (signin.cookies) cookies.push(...signin.cookies)
|
||||
|
||||
@@ -16,10 +16,10 @@ import type {
|
||||
* For Email, sends an email with a sign in link.
|
||||
*/
|
||||
export async function signin(
|
||||
query: RequestInternal["query"],
|
||||
body: RequestInternal["body"],
|
||||
request: RequestInternal,
|
||||
options: InternalOptions<"oauth" | "oidc" | "email">
|
||||
): Promise<ResponseInternal> {
|
||||
const { query, body } = request
|
||||
const { url, logger, provider } = options
|
||||
try {
|
||||
if (provider.type === "oauth" || provider.type === "oidc") {
|
||||
@@ -48,7 +48,7 @@ export async function signin(
|
||||
|
||||
if (unauthorizedOrError) return unauthorizedOrError
|
||||
|
||||
const redirect = await emailSignin(email, options)
|
||||
const redirect = await emailSignin(email, options, request)
|
||||
return { redirect }
|
||||
}
|
||||
return { redirect: `${url}/signin` }
|
||||
|
||||
@@ -72,6 +72,17 @@ export async function toInternalRequest(
|
||||
}
|
||||
}
|
||||
|
||||
export function toRequest(request: RequestInternal): Request {
|
||||
return new Request(request.url, {
|
||||
headers: request.headers,
|
||||
method: request.method,
|
||||
body:
|
||||
request.method === "POST"
|
||||
? JSON.stringify(request.body ?? {})
|
||||
: undefined,
|
||||
})
|
||||
}
|
||||
|
||||
export function toResponse(res: ResponseInternal): Response {
|
||||
const headers = new Headers(res.headers)
|
||||
|
||||
|
||||
@@ -131,6 +131,11 @@ export default function AzureAD<P extends AzureADProfile>(
|
||||
name: "Azure Active Directory",
|
||||
type: "oidc",
|
||||
wellKnown: `${rest.issuer}}/.well-known/openid-configuration?appid=${options.clientId}`,
|
||||
authorization: {
|
||||
params: {
|
||||
scope: 'openid profile email User.Read',
|
||||
},
|
||||
},
|
||||
async profile(profile, tokens) {
|
||||
// https://docs.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0#examples
|
||||
const response = await fetch(
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface BoxyHQSAMLProfile extends Record<string, any> {
|
||||
/**
|
||||
* Add BoxyHQ SAML login to your page.
|
||||
*
|
||||
* BoxyHQ SAML is an open source service that handles the SAML login flow as an OAuth 2.0 flow, abstracting away all the complexities of the SAML protocol.
|
||||
* BoxyHQ SAML is an open source service that handles the SAML SSO login flow as an OAuth 2.0 flow, abstracting away all the complexities of the SAML protocol. Enable Enterprise single-sign-on in your app with ease.
|
||||
*
|
||||
* You can deploy BoxyHQ SAML as a separate service or embed it into your app using our NPM library. [Check out the documentation for more details](https://boxyhq.com/docs/jackson/deploy)
|
||||
*
|
||||
@@ -32,13 +32,38 @@ export interface BoxyHQSAMLProfile extends Record<string, any> {
|
||||
* ```
|
||||
*
|
||||
* #### Configuration
|
||||
*
|
||||
* For OAuth 2.0 Flow:
|
||||
*```js
|
||||
* import Auth from "@auth/core"
|
||||
* import BoxyHQ from "@auth/core/providers/boxyhq-saml"
|
||||
*
|
||||
* const request = new Request(origin)
|
||||
* const response = await Auth(request, {
|
||||
* providers: [BoxyHQ({ clientId: BOXYHQ_SAML_CLIENT_ID, clientSecret: BOXYHQ_SAML_CLIENT_SECRET. issuer: BOXYHQ_SAML_ISSUER })],
|
||||
* providers: [BoxyHQ({
|
||||
* authorization: { params: { scope: "" } }, // This is needed for OAuth 2.0 flow, otherwise default to openid
|
||||
* clientId: BOXYHQ_SAML_CLIENT_ID,
|
||||
* clientSecret: BOXYHQ_SAML_CLIENT_SECRET,
|
||||
* issuer: BOXYHQ_SAML_ISSUER
|
||||
* })],
|
||||
* })
|
||||
* ```
|
||||
* For OIDC Flow:
|
||||
*
|
||||
*```js
|
||||
* import Auth from "@auth/core"
|
||||
* import BoxyHQ from "@auth/core/providers/boxyhq-saml"
|
||||
*
|
||||
* const request = new Request(origin)
|
||||
* const response = await Auth(request, {
|
||||
* providers: [BoxyHQ({
|
||||
* id: "boxyhq-saml-oidc",
|
||||
* wellKnown: `http://localhost:5225/.well-known/openid-configuration`,
|
||||
* authorization: { params: { scope: "openid email" } },
|
||||
* clientId: BOXYHQ_SAML_CLIENT_ID,
|
||||
* clientSecret: BOXYHQ_SAML_CLIENT_SECRET,
|
||||
* issuer: BOXYHQ_SAML_ISSUER
|
||||
* })],
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
|
||||
119
packages/core/src/providers/descope.ts
Normal file
119
packages/core/src/providers/descope.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
|
||||
* <span style={{fontSize: "1.35rem" }}>
|
||||
* Built-in sign in with <b>Descope</b> integration.
|
||||
* </span>
|
||||
* <a href="https://descope.com" style={{backgroundColor: "#000000", padding: "12px", borderRadius: "100%" }}>
|
||||
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/descope.svg" width="24"/>
|
||||
* </a>
|
||||
* </div>
|
||||
*
|
||||
* @module providers/descope
|
||||
*/
|
||||
|
||||
import type { OIDCConfig, OIDCUserConfig } from "./index.js"
|
||||
|
||||
/** The returned user profile from Descope when using the profile callback.
|
||||
* [See Load User](https://docs.descope.com/api/openapi/usermanagement/operation/LoadUser/)
|
||||
*/
|
||||
export interface DescopeProfile {
|
||||
/** The user's unique Descope ID */
|
||||
sub: string
|
||||
/** The user's name */
|
||||
name: string
|
||||
/** The user's email */
|
||||
email: string
|
||||
/** A boolean indicating if the user's email is verified */
|
||||
email_verified: boolean
|
||||
/** The user's phone number */
|
||||
phone_number: string
|
||||
/** A boolean indicating if the user's phone number is verified */
|
||||
phone_number_verified: boolean
|
||||
/** The user's picture */
|
||||
picture: string
|
||||
/** The user's custom attributes */
|
||||
[claim: string]: unknown
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ### Setup
|
||||
*
|
||||
* #### Callback URL
|
||||
* ```
|
||||
* https://example.com/api/auth/callback/descope
|
||||
* ```
|
||||
*
|
||||
* #### Configuration
|
||||
*
|
||||
* Import the provider and configure it in your **Auth.js** initialization file:
|
||||
*
|
||||
* ```ts title="pages/api/auth/[...nextauth].ts"
|
||||
* import NextAuth from "next-auth"
|
||||
* import DescopeProvider from "next-auth/providers/descope";
|
||||
*
|
||||
* export default NextAuth({
|
||||
* providers: [
|
||||
* DescopeProvider({
|
||||
* clientId: process.env.DESCOPE_ID,
|
||||
* clientSecret: process.env.DESCOPE_SECRET,
|
||||
* }),
|
||||
* ],
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* ### Configuring Descope
|
||||
*
|
||||
* Follow these steps:
|
||||
*
|
||||
* 1. Log into the [Descope console](https://app.descope.com)
|
||||
* 2. Follow the [OIDC instructions](https://docs.descope.com/customize/auth/oidc)
|
||||
*
|
||||
* Then, create a `.env.local` file in the project root add the following entries:
|
||||
*
|
||||
* Get the following from the Descope's console:
|
||||
* ```
|
||||
* DESCOPE_ID="<Descope Issuer's last url segment>" # Descope's Issuer can be found in "Authentication Methods > SSO > Identity Provider" (Can also be taken from "Project > Project ID")
|
||||
* DESCOPE_SECRET="<Descope Access Key>" # Manage > Access Keys
|
||||
* ```
|
||||
*
|
||||
* ### Resources
|
||||
*
|
||||
* - [Descope OIDC](https://docs.descope.com/customize/auth/oidc)
|
||||
* - [Descope Flows](https://docs.descope.com/customize/flows)
|
||||
*
|
||||
* ### Notes
|
||||
*
|
||||
* The Descope provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/descope.ts). To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
|
||||
*
|
||||
* :::info
|
||||
* By default, Auth.js assumes that the Descope provider is based on the [OIDC](https://openid.net/specs/openid-connect-core-1_0.html) spec
|
||||
* :::
|
||||
*
|
||||
* ## Help
|
||||
*
|
||||
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
|
||||
*
|
||||
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
|
||||
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
|
||||
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
|
||||
*/
|
||||
export default function Descope(
|
||||
config: OIDCUserConfig<DescopeProfile>
|
||||
): OIDCConfig<DescopeProfile> {
|
||||
return {
|
||||
id: "descope",
|
||||
name: "Descope",
|
||||
type: "oidc",
|
||||
issuer: `https://api.descope.com/${config.clientId}`,
|
||||
style: {
|
||||
logo: "/descope.svg",
|
||||
logoDark: "/descope.svg",
|
||||
bg: "#1C1C23",
|
||||
text: "#ffffff",
|
||||
bgDark: "#1C1C23",
|
||||
textDark: "#ffffff",
|
||||
},
|
||||
options: config,
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,17 @@
|
||||
import { createTransport } from "nodemailer"
|
||||
|
||||
import type { CommonProviderOptions } from "./index.js"
|
||||
import type { Options as SMTPTransportOptions } from "nodemailer/lib/smtp-transport"
|
||||
import type { Awaitable, Theme } from "../types.js"
|
||||
|
||||
import { Transport, TransportOptions, createTransport } from "nodemailer"
|
||||
import * as JSONTransport from "nodemailer/lib/json-transport/index.js"
|
||||
import * as SendmailTransport from "nodemailer/lib/sendmail-transport/index.js"
|
||||
import * as SESTransport from "nodemailer/lib/ses-transport/index.js"
|
||||
import * as SMTPTransport from "nodemailer/lib/smtp-transport/index.js"
|
||||
import * as SMTPPool from "nodemailer/lib/smtp-pool/index.js"
|
||||
import * as StreamTransport from "nodemailer/lib/stream-transport/index.js"
|
||||
|
||||
// TODO: Make use of https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html for the string
|
||||
type AllTransportOptions = string | SMTPTransport | SMTPTransport.Options | SMTPPool | SMTPPool.Options | SendmailTransport | SendmailTransport.Options | StreamTransport | StreamTransport.Options | JSONTransport | JSONTransport.Options | SESTransport | SESTransport.Options | Transport<any> | TransportOptions
|
||||
|
||||
export interface SendVerificationRequestParams {
|
||||
identifier: string
|
||||
url: string
|
||||
@@ -11,6 +19,7 @@ export interface SendVerificationRequestParams {
|
||||
provider: EmailConfig
|
||||
token: string
|
||||
theme: Theme
|
||||
request: Request
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,10 +35,9 @@ export interface SendVerificationRequestParams {
|
||||
*
|
||||
* [Custom email service with Auth.js](https://authjs.dev/guides/providers/email#custom-email-service)
|
||||
*/
|
||||
export interface EmailConfig extends CommonProviderOptions {
|
||||
type: "email"
|
||||
// TODO: Make use of https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html
|
||||
server?: string | SMTPTransportOptions
|
||||
export interface EmailUserConfig {
|
||||
server?: AllTransportOptions
|
||||
type?: "email"
|
||||
/** @default `"Auth.js <no-reply@authjs.dev>"` */
|
||||
from?: string
|
||||
/**
|
||||
@@ -40,7 +48,7 @@ export interface EmailConfig extends CommonProviderOptions {
|
||||
*/
|
||||
maxAge?: number
|
||||
/** [Documentation](https://authjs.dev/guides/providers/email#customizing-emails) */
|
||||
sendVerificationRequest: (
|
||||
sendVerificationRequest?: (
|
||||
params: SendVerificationRequestParams
|
||||
) => Awaitable<void>
|
||||
/**
|
||||
@@ -77,24 +85,49 @@ export interface EmailConfig extends CommonProviderOptions {
|
||||
normalizeIdentifier?: (identifier: string) => string
|
||||
}
|
||||
|
||||
export interface EmailConfig extends CommonProviderOptions {
|
||||
// defaults
|
||||
id: "email"
|
||||
type: "email"
|
||||
name: "Email"
|
||||
server: AllTransportOptions
|
||||
from: string
|
||||
maxAge: number
|
||||
sendVerificationRequest: (
|
||||
params: SendVerificationRequestParams
|
||||
) => Awaitable<void>
|
||||
|
||||
/**
|
||||
* This is copied into EmailConfig in parseProviders() don't use elsewhere
|
||||
*/
|
||||
options: EmailUserConfig
|
||||
|
||||
// user options
|
||||
// TODO figure out a better way than copying from EmailUserConfig
|
||||
secret?: string
|
||||
generateVerificationToken?: () => Awaitable<string>
|
||||
normalizeIdentifier?: (identifier: string) => string
|
||||
}
|
||||
|
||||
|
||||
// TODO: Rename to Token provider
|
||||
// when started working on https://github.com/nextauthjs/next-auth/discussions/1465
|
||||
export type EmailProviderType = "email"
|
||||
|
||||
/**
|
||||
/**
|
||||
* ## Overview
|
||||
* The Email provider uses email to send "magic links" that can be used to sign in, you will likely have seen these if you have used services like Slack before.
|
||||
*
|
||||
*
|
||||
* Adding support for signing in via email in addition to one or more OAuth services provides a way for users to sign in if they lose access to their OAuth account (e.g. if it is locked or deleted).
|
||||
*
|
||||
*
|
||||
* The Email provider can be used in conjunction with (or instead of) one or more OAuth providers.
|
||||
* ### How it works
|
||||
*
|
||||
*
|
||||
* On initial sign in, a **Verification Token** is sent to the email address provided. By default this token is valid for 24 hours. If the Verification Token is used within that time (i.e. by clicking on the link in the email) an account is created for the user and they are signed in.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* If someone provides the email address of an _existing account_ when signing in, an email is sent and they are signed into the account associated with that email address when they follow the link in the email.
|
||||
*
|
||||
*
|
||||
* :::tip
|
||||
* The Email Provider can be used with both JSON Web Tokens and database sessions, but you **must** configure a database to use it. It is not possible to enable email sign in without using a database.
|
||||
* :::
|
||||
@@ -103,20 +136,20 @@ export type EmailProviderType = "email"
|
||||
* 1. NextAuth.js does not include `nodemailer` as a dependency, so you'll need to install it yourself if you want to use the Email Provider. Run `npm install nodemailer` or `yarn add nodemailer`.
|
||||
* 2. You will need an SMTP account; ideally for one of the [services known to work with `nodemailer`](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/).
|
||||
* 3. There are two ways to configure the SMTP server connection.
|
||||
*
|
||||
*
|
||||
* You can either use a connection string or a `nodemailer` configuration object.
|
||||
*
|
||||
*
|
||||
* 3.1 **Using a connection string**
|
||||
*
|
||||
*
|
||||
* Create an `.env` file to the root of your project and add the connection string and email address.
|
||||
*
|
||||
*
|
||||
* ```js title=".env" {1}
|
||||
* EMAIL_SERVER=smtp://username:password@smtp.example.com:587
|
||||
* EMAIL_FROM=noreply@example.com
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* Now you can add the email provider like this:
|
||||
*
|
||||
*
|
||||
* ```js {3} title="pages/api/auth/[...nextauth].js"
|
||||
* import EmailProvider from "next-auth/providers/email";
|
||||
* ...
|
||||
@@ -127,11 +160,11 @@ export type EmailProviderType = "email"
|
||||
* }),
|
||||
* ],
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* 3.2 **Using a configuration object**
|
||||
*
|
||||
*
|
||||
* In your `.env` file in the root of your project simply add the configuration object options individually:
|
||||
*
|
||||
*
|
||||
* ```js title=".env"
|
||||
* EMAIL_SERVER_USER=username
|
||||
* EMAIL_SERVER_PASSWORD=password
|
||||
@@ -139,9 +172,9 @@ export type EmailProviderType = "email"
|
||||
* EMAIL_SERVER_PORT=587
|
||||
* EMAIL_FROM=noreply@example.com
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* Now you can add the provider settings to the NextAuth.js options object in the Email Provider.
|
||||
*
|
||||
*
|
||||
* ```js title="pages/api/auth/[...nextauth].js"
|
||||
* import EmailProvider from "next-auth/providers/email";
|
||||
* ...
|
||||
@@ -159,19 +192,19 @@ export type EmailProviderType = "email"
|
||||
* }),
|
||||
* ],
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/adapters) for storing the Email verification token.
|
||||
*
|
||||
*
|
||||
* 5. You can now sign in with an email address at `/api/auth/signin`.
|
||||
*
|
||||
*
|
||||
* A user account (i.e. an entry in the Users table) will not be created for the user until the first time they verify their email address. If an email address is already associated with an account, the user will be signed in to that account when they use the link in the email.
|
||||
*
|
||||
*
|
||||
* ## Customizing emails
|
||||
*
|
||||
*
|
||||
* You can fully customize the sign in email that is sent by passing a custom function as the `sendVerificationRequest` option to `EmailProvider()`.
|
||||
*
|
||||
*
|
||||
* e.g.
|
||||
*
|
||||
*
|
||||
* ```js {3} title="pages/api/auth/[...nextauth].js"
|
||||
* import EmailProvider from "next-auth/providers/email";
|
||||
* ...
|
||||
@@ -189,12 +222,12 @@ export type EmailProviderType = "email"
|
||||
* }),
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* The following code shows the complete source for the built-in `sendVerificationRequest()` method:
|
||||
*
|
||||
*
|
||||
* ```js
|
||||
* import { createTransport } from "nodemailer"
|
||||
*
|
||||
*
|
||||
* async function sendVerificationRequest(params) {
|
||||
* const { identifier, url, provider, theme } = params
|
||||
* const { host } = new URL(url)
|
||||
@@ -212,12 +245,12 @@ export type EmailProviderType = "email"
|
||||
* throw new Error(`Email(s) (${failed.join(", ")}) could not be sent`)
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*
|
||||
* function html(params: { url: string; host: string; theme: Theme }) {
|
||||
* const { url, host, theme } = params
|
||||
*
|
||||
*
|
||||
* const escapedHost = host.replace(/\./g, "​.")
|
||||
*
|
||||
*
|
||||
* const brandColor = theme.brandColor || "#346df1"
|
||||
* const color = {
|
||||
* background: "#f9f9f9",
|
||||
@@ -227,7 +260,7 @@ export type EmailProviderType = "email"
|
||||
* buttonBorder: brandColor,
|
||||
* buttonText: theme.buttonText || "#fff",
|
||||
* }
|
||||
*
|
||||
*
|
||||
* return `
|
||||
* <body style="background: ${color.background};">
|
||||
* <table width="100%" border="0" cellspacing="20" cellpadding="0"
|
||||
@@ -260,21 +293,21 @@ export type EmailProviderType = "email"
|
||||
* </body>
|
||||
* `
|
||||
* }
|
||||
*
|
||||
*
|
||||
* // Email Text body (fallback for email clients that don't render HTML, e.g. feature phones)
|
||||
* function text({ url, host }: { url: string; host: string }) {
|
||||
* return `Sign in to ${host}\n${url}\n\n`
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* :::tip
|
||||
* If you want to generate great looking email client compatible HTML with React, check out https://mjml.io
|
||||
* :::
|
||||
*
|
||||
*
|
||||
* ## Customizing the Verification Token
|
||||
*
|
||||
*
|
||||
* By default, we are generating a random verification token. You can define a `generateVerificationToken` method in your provider options if you want to override it:
|
||||
*
|
||||
*
|
||||
* ```js title="pages/api/auth/[...nextauth].js"
|
||||
* providers: [
|
||||
* EmailProvider({
|
||||
@@ -284,9 +317,9 @@ export type EmailProviderType = "email"
|
||||
* })
|
||||
* ],
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* ## Normalizing the email address
|
||||
*
|
||||
*
|
||||
* By default, Auth.js will normalize the email address. It treats values as case-insensitive (which is technically not compliant to the [RFC 2821 spec](https://datatracker.ietf.org/doc/html/rfc2821), but in practice this causes more problems than it solves, eg. when looking up users by e-mail from databases.) and also removes any secondary email address that was passed in as a comma-separated list. You can apply your own normalization via the `normalizeIdentifier` method on the `EmailProvider`. The following example shows the default behavior:
|
||||
* ```ts
|
||||
* EmailProvider({
|
||||
@@ -299,7 +332,7 @@ export type EmailProviderType = "email"
|
||||
* // but we remove it on the domain part
|
||||
* domain = domain.split(",")[0]
|
||||
* return `${local}@${domain}`
|
||||
*
|
||||
*
|
||||
* // You can also throw an error, which will redirect the user
|
||||
* // to the sign-in page with error=EmailSignin in the URL
|
||||
* // if (identifier.split("@").length > 2) {
|
||||
@@ -308,12 +341,12 @@ export type EmailProviderType = "email"
|
||||
* },
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* :::warning
|
||||
* Always make sure this returns a single e-mail address, even if multiple ones were passed in.
|
||||
* :::
|
||||
*/
|
||||
export default function Email(config: EmailConfig): EmailConfig {
|
||||
export default function Email(config: EmailUserConfig): EmailConfig {
|
||||
return {
|
||||
id: "email",
|
||||
type: "email",
|
||||
@@ -337,7 +370,6 @@ export default function Email(config: EmailConfig): EmailConfig {
|
||||
throw new Error(`Email (${failed.join(", ")}) could not be sent`)
|
||||
}
|
||||
},
|
||||
// @ts-expect-error
|
||||
options: config,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ interface InternalProviderOptions {
|
||||
* @see [Email (Passwordless) guide](https://authjs.dev/guides/providers/email)
|
||||
* @see [Credentials guide](https://authjs.dev/guides/providers/credentials)
|
||||
*/
|
||||
export type Provider<P extends Profile = Profile> = (
|
||||
export type Provider<P extends Profile = any> = (
|
||||
| ((OIDCConfig<P> | OAuth2Config<P> | EmailConfig | CredentialsConfig) &
|
||||
InternalProviderOptions)
|
||||
| ((
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/sveltekit",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.6",
|
||||
"description": "Authentication for SvelteKit.",
|
||||
"keywords": [
|
||||
"authentication",
|
||||
@@ -48,7 +48,7 @@
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^3.54.0",
|
||||
"svelte": "^3.54.0 || ^4.0.0",
|
||||
"@sveltejs/kit": "^1.0.0"
|
||||
},
|
||||
"type": "module",
|
||||
|
||||
@@ -61,7 +61,6 @@ export async function signIn<
|
||||
})
|
||||
|
||||
const data = await res.clone().json()
|
||||
const error = new URL(data.url).searchParams.get("error")
|
||||
|
||||
if (redirect || !isSupportingReturn) {
|
||||
// TODO: Do not redirect for Credentials and Email providers by default in next major
|
||||
|
||||
@@ -211,12 +211,13 @@ import type { AuthAction, AuthConfig, Session } from "@auth/core/types"
|
||||
|
||||
export async function getSession(
|
||||
req: Request,
|
||||
config: AuthConfig
|
||||
config: SvelteKitAuthConfig
|
||||
): ReturnType<App.Locals["getSession"]> {
|
||||
config.secret ??= env.AUTH_SECRET
|
||||
config.trustHost ??= true
|
||||
|
||||
const url = new URL("/api/auth/session", req.url)
|
||||
const prefix = config.prefix ?? "/auth"
|
||||
const url = new URL(prefix + "/session", req.url)
|
||||
const request = new Request(url, { headers: req.headers })
|
||||
const response = await Auth(request, config)
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ export type WithAuthArgs =
|
||||
|
||||
/**
|
||||
* Middleware that checks if the user is authenticated/authorized.
|
||||
* If if they aren't, they will be redirected to the login page.
|
||||
* If they aren't, they will be redirected to the login page.
|
||||
* Otherwise, continue.
|
||||
*
|
||||
* @example
|
||||
|
||||
1065
pnpm-lock.yaml
generated
1065
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
28
turbo.json
28
turbo.json
@@ -57,17 +57,17 @@
|
||||
"@auth/sveltekit#build",
|
||||
"@auth/dgraph-adapter#build",
|
||||
"@auth/dynamodb-adapter#build",
|
||||
"@next-auth/fauna-adapter#build",
|
||||
"@next-auth/firebase-adapter#build",
|
||||
"@auth/fauna-adapter#build",
|
||||
"@auth/firebase-adapter#build",
|
||||
"@auth/mikro-orm-adapter#build",
|
||||
"@auth/mongodb-adapter#build",
|
||||
"@next-auth/neo4j-adapter#build",
|
||||
"@next-auth/pouchdb-adapter#build",
|
||||
"@next-auth/sequelize-adapter#build",
|
||||
"@next-auth/supabase-adapter#build",
|
||||
"@auth/neo4j-adapter#build",
|
||||
"@auth/pouchdb-adapter#build",
|
||||
"@auth/sequelize-adapter#build",
|
||||
"@auth/supabase-adapter#build",
|
||||
"@auth/typeorm-adapter#build",
|
||||
"@auth/upstash-redis-adapter#build",
|
||||
"@next-auth/xata-adapter#build",
|
||||
"@auth/xata-adapter#build",
|
||||
"^build",
|
||||
"next-auth#build"
|
||||
],
|
||||
@@ -80,17 +80,17 @@
|
||||
"@auth/sveltekit#build",
|
||||
"@auth/dgraph-adapter#build",
|
||||
"@auth/dynamodb-adapter#build",
|
||||
"@next-auth/fauna-adapter#build",
|
||||
"@next-auth/firebase-adapter#build",
|
||||
"@auth/fauna-adapter#build",
|
||||
"@auth/firebase-adapter#build",
|
||||
"@auth/mikro-orm-adapter#build",
|
||||
"@auth/mongodb-adapter#build",
|
||||
"@next-auth/neo4j-adapter#build",
|
||||
"@next-auth/pouchdb-adapter#build",
|
||||
"@next-auth/sequelize-adapter#build",
|
||||
"@next-auth/supabase-adapter#build",
|
||||
"@auth/neo4j-adapter#build",
|
||||
"@auth/pouchdb-adapter#build",
|
||||
"@auth/sequelize-adapter#build",
|
||||
"@auth/supabase-adapter#build",
|
||||
"@auth/typeorm-adapter#build",
|
||||
"@auth/upstash-redis-adapter#build",
|
||||
"@next-auth/xata-adapter#build",
|
||||
"@auth/xata-adapter#build",
|
||||
"^build",
|
||||
"next-auth#build"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user