@auth/fauna-adapter 2.2.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/index.d.ts +3 -177
- package/index.d.ts.map +1 -1
- package/index.js +7 -179
- package/package.json +2 -2
- package/src/index.ts +41 -193
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<br/>
|
|
3
3
|
<a href="https://authjs.dev" target="_blank">
|
|
4
|
-
<img height="64px" src="https://authjs.dev/img/logo
|
|
4
|
+
<img height="64px" src="https://authjs.dev/img/logo-sm.png" />
|
|
5
5
|
</a>
|
|
6
6
|
<a href="https://fauna.com" target="_blank">
|
|
7
7
|
<img height="64px" src="https://authjs.dev/img/adapters/fauna.svg"/>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<img src="https://img.shields.io/npm/dm/@auth/fauna-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
|
19
19
|
</a>
|
|
20
20
|
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
|
21
|
-
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="
|
|
21
|
+
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="GitHub Stars" />
|
|
22
22
|
</a>
|
|
23
23
|
</p>
|
|
24
24
|
</p>
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding:
|
|
3
|
-
* <p
|
|
2
|
+
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px"}}>
|
|
3
|
+
* <p>Official <a href="https://docs.fauna.com/fauna/current/">Fauna</a> adapter for Auth.js / NextAuth.js.</p>
|
|
4
4
|
* <a href="https://fauna.com/features">
|
|
5
|
-
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/fauna.svg"
|
|
5
|
+
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/fauna.svg" width="64" />
|
|
6
6
|
* </a>
|
|
7
7
|
* </div>
|
|
8
8
|
*
|
|
@@ -33,180 +33,6 @@ type AdapterConfig = {
|
|
|
33
33
|
verificationToken: string;
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* ## Setup
|
|
39
|
-
*
|
|
40
|
-
* This is the Fauna Adapter for [Auth.js](https://authjs.dev). This package can only be used in conjunction with the primary `next-auth` and other framework packages. It is not a standalone package.
|
|
41
|
-
*
|
|
42
|
-
* You can find the Fauna schema and seed information in the docs at [authjs.dev/reference/adapter/fauna](https://authjs.dev/reference/adapter/fauna).
|
|
43
|
-
*
|
|
44
|
-
* ### Configure Auth.js
|
|
45
|
-
*
|
|
46
|
-
* ```javascript title="pages/api/auth/[...nextauth].js"
|
|
47
|
-
* import NextAuth from "next-auth"
|
|
48
|
-
* import { Client } from "fauna"
|
|
49
|
-
* import { FaunaAdapter } from "@auth/fauna-adapter"
|
|
50
|
-
*
|
|
51
|
-
* const client = new Client({
|
|
52
|
-
* secret: "secret",
|
|
53
|
-
* endpoint: new URL('http://localhost:8443')
|
|
54
|
-
* })
|
|
55
|
-
*
|
|
56
|
-
* // For more information on each option (and a full list of options) go to
|
|
57
|
-
* // https://authjs.dev/reference/configuration/auth-options
|
|
58
|
-
* export default NextAuth({
|
|
59
|
-
* // https://authjs.dev/reference/providers/
|
|
60
|
-
* providers: [],
|
|
61
|
-
* adapter: FaunaAdapter(client)
|
|
62
|
-
* ...
|
|
63
|
-
* })
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* ### Schema
|
|
67
|
-
*
|
|
68
|
-
* Run the following FQL code inside the `Shell` tab in the Fauna dashboard to set up the appropriate collections and indexes.
|
|
69
|
-
*
|
|
70
|
-
* ```javascript
|
|
71
|
-
* Collection.create({
|
|
72
|
-
* name: "Account",
|
|
73
|
-
* indexes: {
|
|
74
|
-
* byUserId: {
|
|
75
|
-
* terms: [
|
|
76
|
-
* { field: "userId" }
|
|
77
|
-
* ]
|
|
78
|
-
* },
|
|
79
|
-
* byProviderAndProviderAccountId: {
|
|
80
|
-
* terms [
|
|
81
|
-
* { field: "provider" },
|
|
82
|
-
* { field: "providerAccountId" }
|
|
83
|
-
* ]
|
|
84
|
-
* },
|
|
85
|
-
* }
|
|
86
|
-
* })
|
|
87
|
-
* Collection.create({
|
|
88
|
-
* name: "Session",
|
|
89
|
-
* constraints: [
|
|
90
|
-
* {
|
|
91
|
-
* unique: ["sessionToken"],
|
|
92
|
-
* status: "active",
|
|
93
|
-
* }
|
|
94
|
-
* ],
|
|
95
|
-
* indexes: {
|
|
96
|
-
* bySessionToken: {
|
|
97
|
-
* terms: [
|
|
98
|
-
* { field: "sessionToken" }
|
|
99
|
-
* ]
|
|
100
|
-
* },
|
|
101
|
-
* byUserId: {
|
|
102
|
-
* terms [
|
|
103
|
-
* { field: "userId" }
|
|
104
|
-
* ]
|
|
105
|
-
* },
|
|
106
|
-
* }
|
|
107
|
-
* })
|
|
108
|
-
* Collection.create({
|
|
109
|
-
* name: "User",
|
|
110
|
-
* constraints: [
|
|
111
|
-
* {
|
|
112
|
-
* unique: ["email"],
|
|
113
|
-
* status: "active",
|
|
114
|
-
* }
|
|
115
|
-
* ],
|
|
116
|
-
* indexes: {
|
|
117
|
-
* byEmail: {
|
|
118
|
-
* terms [
|
|
119
|
-
* { field: "email" }
|
|
120
|
-
* ]
|
|
121
|
-
* },
|
|
122
|
-
* }
|
|
123
|
-
* })
|
|
124
|
-
* Collection.create({
|
|
125
|
-
* name: "VerificationToken",
|
|
126
|
-
* indexes: {
|
|
127
|
-
* byIdentifierAndToken: {
|
|
128
|
-
* terms [
|
|
129
|
-
* { field: "identifier" },
|
|
130
|
-
* { field: "token" }
|
|
131
|
-
* ]
|
|
132
|
-
* },
|
|
133
|
-
* }
|
|
134
|
-
* })
|
|
135
|
-
* ```
|
|
136
|
-
*
|
|
137
|
-
* > This schema is adapted for use in Fauna and based upon our main [schema](https://authjs.dev/reference/core/adapters#models)
|
|
138
|
-
*
|
|
139
|
-
* #### Custom collection names
|
|
140
|
-
* If you want to use custom collection names, you can pass them as an option to the adapter, like this:
|
|
141
|
-
*
|
|
142
|
-
* ```javascript
|
|
143
|
-
* FaunaAdapter(client, {
|
|
144
|
-
* collectionNames: {
|
|
145
|
-
* user: "CustomUser",
|
|
146
|
-
* account: "CustomAccount",
|
|
147
|
-
* session: "CustomSession",
|
|
148
|
-
* verificationToken: "CustomVerificationToken",
|
|
149
|
-
* }
|
|
150
|
-
* })
|
|
151
|
-
* ```
|
|
152
|
-
*
|
|
153
|
-
* Make sure the collection names you pass to the provider match the collection names of your Fauna database.
|
|
154
|
-
*
|
|
155
|
-
* ### Migrating from v1
|
|
156
|
-
* In v2, we've renamed the collections to use uppercase naming, in accordance with Fauna best practices. If you're migrating from v1, you'll need to rename your collections to match the new naming scheme.
|
|
157
|
-
* Additionally, we've renamed the indexes to match the new method-like index names.
|
|
158
|
-
*
|
|
159
|
-
* #### Migration script
|
|
160
|
-
* Run this FQL script inside a Fauna shell for the database you're migrating from v1 to v2 (it will rename your collections and indexes to match):
|
|
161
|
-
*
|
|
162
|
-
* ```javascript
|
|
163
|
-
* Collection.byName("accounts")!.update({
|
|
164
|
-
* name: "Account"
|
|
165
|
-
* indexes: {
|
|
166
|
-
* byUserId: {
|
|
167
|
-
* terms: [{ field: "userId" }]
|
|
168
|
-
* },
|
|
169
|
-
* byProviderAndProviderAccountId: {
|
|
170
|
-
* terms: [{ field: "provider" }, { field: "providerAccountId" }]
|
|
171
|
-
* },
|
|
172
|
-
* account_by_provider_and_provider_account_id: null,
|
|
173
|
-
* accounts_by_user_id: null
|
|
174
|
-
* }
|
|
175
|
-
* })
|
|
176
|
-
* Collection.byName("sessions")!.update({
|
|
177
|
-
* name: "Session",
|
|
178
|
-
* indexes: {
|
|
179
|
-
* bySessionToken: {
|
|
180
|
-
* terms: [{ field: "sessionToken" }]
|
|
181
|
-
* },
|
|
182
|
-
* byUserId: {
|
|
183
|
-
* terms: [{ field: "userId" }]
|
|
184
|
-
* },
|
|
185
|
-
* session_by_session_token: null,
|
|
186
|
-
* sessions_by_user_id: null
|
|
187
|
-
* }
|
|
188
|
-
* })
|
|
189
|
-
* Collection.byName("users")!.update({
|
|
190
|
-
* name: "User",
|
|
191
|
-
* indexes: {
|
|
192
|
-
* byEmail: {
|
|
193
|
-
* terms: [{ field: "email" }]
|
|
194
|
-
* },
|
|
195
|
-
* user_by_email: null
|
|
196
|
-
* }
|
|
197
|
-
* })
|
|
198
|
-
* Collection.byName("verification_tokens")!.update({
|
|
199
|
-
* name: "VerificationToken",
|
|
200
|
-
* indexes: {
|
|
201
|
-
* byIdentifierAndToken: {
|
|
202
|
-
* terms: [{ field: "identifier" }, { field: "token" }]
|
|
203
|
-
* },
|
|
204
|
-
* verification_token_by_identifier_and_token: null
|
|
205
|
-
* }
|
|
206
|
-
* })
|
|
207
|
-
* ```
|
|
208
|
-
*
|
|
209
|
-
**/
|
|
210
36
|
export declare function FaunaAdapter(client: Client, config?: AdapterConfig): Adapter;
|
|
211
37
|
export declare const format: {
|
|
212
38
|
/** Takes an object that's coming from the database and converts it to plain JavaScript. */
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,MAAM,EACN,QAAQ,EAGR,UAAU,EACV,gBAAgB,EAEjB,MAAM,OAAO,CAAA;AAEd,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,qBAAqB,CAAA;AAE5B,KAAK,OAAO,CAAC,CAAC,IAAI;KACf,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,GACpC,QAAQ,GAAG,IAAI,GACf,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,GACpB,IAAI,GACJ,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,GACrB,CAAC,CAAC,CAAC,CAAC,GACJ,gBAAgB;CACzB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AAC5C,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;AAClD,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAChF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;AAElD,KAAK,aAAa,GAAG;IACnB,eAAe,EAAE;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,iBAAiB,EAAE,MAAM,CAAA;KAC1B,CAAA;CACF,CAAA;AASD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAsI5E;AAED,eAAO,MAAM,MAAM;IACjB,2FAA2F;qBAC3E,OAAO,MAAM,EAAE,GAAG,CAAC;IASnC,gGAAgG;oBAClF,OAAO,MAAM,EAAE,GAAG,CAAC;CAUlC,CAAA"}
|
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding:
|
|
3
|
-
* <p
|
|
2
|
+
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px"}}>
|
|
3
|
+
* <p>Official <a href="https://docs.fauna.com/fauna/current/">Fauna</a> adapter for Auth.js / NextAuth.js.</p>
|
|
4
4
|
* <a href="https://fauna.com/features">
|
|
5
|
-
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/fauna.svg"
|
|
5
|
+
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/fauna.svg" width="64" />
|
|
6
6
|
* </a>
|
|
7
7
|
* </div>
|
|
8
8
|
*
|
|
@@ -14,187 +14,13 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @module @auth/fauna-adapter
|
|
16
16
|
*/
|
|
17
|
-
import { TimeStub, fql, NullDocument } from "fauna";
|
|
17
|
+
import { TimeStub, fql, NullDocument, } from "fauna";
|
|
18
18
|
const defaultCollectionNames = {
|
|
19
19
|
user: "User",
|
|
20
20
|
session: "Session",
|
|
21
21
|
account: "Account",
|
|
22
22
|
verificationToken: "VerificationToken",
|
|
23
23
|
};
|
|
24
|
-
/**
|
|
25
|
-
*
|
|
26
|
-
* ## Setup
|
|
27
|
-
*
|
|
28
|
-
* This is the Fauna Adapter for [Auth.js](https://authjs.dev). This package can only be used in conjunction with the primary `next-auth` and other framework packages. It is not a standalone package.
|
|
29
|
-
*
|
|
30
|
-
* You can find the Fauna schema and seed information in the docs at [authjs.dev/reference/adapter/fauna](https://authjs.dev/reference/adapter/fauna).
|
|
31
|
-
*
|
|
32
|
-
* ### Configure Auth.js
|
|
33
|
-
*
|
|
34
|
-
* ```javascript title="pages/api/auth/[...nextauth].js"
|
|
35
|
-
* import NextAuth from "next-auth"
|
|
36
|
-
* import { Client } from "fauna"
|
|
37
|
-
* import { FaunaAdapter } from "@auth/fauna-adapter"
|
|
38
|
-
*
|
|
39
|
-
* const client = new Client({
|
|
40
|
-
* secret: "secret",
|
|
41
|
-
* endpoint: new URL('http://localhost:8443')
|
|
42
|
-
* })
|
|
43
|
-
*
|
|
44
|
-
* // For more information on each option (and a full list of options) go to
|
|
45
|
-
* // https://authjs.dev/reference/configuration/auth-options
|
|
46
|
-
* export default NextAuth({
|
|
47
|
-
* // https://authjs.dev/reference/providers/
|
|
48
|
-
* providers: [],
|
|
49
|
-
* adapter: FaunaAdapter(client)
|
|
50
|
-
* ...
|
|
51
|
-
* })
|
|
52
|
-
* ```
|
|
53
|
-
*
|
|
54
|
-
* ### Schema
|
|
55
|
-
*
|
|
56
|
-
* Run the following FQL code inside the `Shell` tab in the Fauna dashboard to set up the appropriate collections and indexes.
|
|
57
|
-
*
|
|
58
|
-
* ```javascript
|
|
59
|
-
* Collection.create({
|
|
60
|
-
* name: "Account",
|
|
61
|
-
* indexes: {
|
|
62
|
-
* byUserId: {
|
|
63
|
-
* terms: [
|
|
64
|
-
* { field: "userId" }
|
|
65
|
-
* ]
|
|
66
|
-
* },
|
|
67
|
-
* byProviderAndProviderAccountId: {
|
|
68
|
-
* terms [
|
|
69
|
-
* { field: "provider" },
|
|
70
|
-
* { field: "providerAccountId" }
|
|
71
|
-
* ]
|
|
72
|
-
* },
|
|
73
|
-
* }
|
|
74
|
-
* })
|
|
75
|
-
* Collection.create({
|
|
76
|
-
* name: "Session",
|
|
77
|
-
* constraints: [
|
|
78
|
-
* {
|
|
79
|
-
* unique: ["sessionToken"],
|
|
80
|
-
* status: "active",
|
|
81
|
-
* }
|
|
82
|
-
* ],
|
|
83
|
-
* indexes: {
|
|
84
|
-
* bySessionToken: {
|
|
85
|
-
* terms: [
|
|
86
|
-
* { field: "sessionToken" }
|
|
87
|
-
* ]
|
|
88
|
-
* },
|
|
89
|
-
* byUserId: {
|
|
90
|
-
* terms [
|
|
91
|
-
* { field: "userId" }
|
|
92
|
-
* ]
|
|
93
|
-
* },
|
|
94
|
-
* }
|
|
95
|
-
* })
|
|
96
|
-
* Collection.create({
|
|
97
|
-
* name: "User",
|
|
98
|
-
* constraints: [
|
|
99
|
-
* {
|
|
100
|
-
* unique: ["email"],
|
|
101
|
-
* status: "active",
|
|
102
|
-
* }
|
|
103
|
-
* ],
|
|
104
|
-
* indexes: {
|
|
105
|
-
* byEmail: {
|
|
106
|
-
* terms [
|
|
107
|
-
* { field: "email" }
|
|
108
|
-
* ]
|
|
109
|
-
* },
|
|
110
|
-
* }
|
|
111
|
-
* })
|
|
112
|
-
* Collection.create({
|
|
113
|
-
* name: "VerificationToken",
|
|
114
|
-
* indexes: {
|
|
115
|
-
* byIdentifierAndToken: {
|
|
116
|
-
* terms [
|
|
117
|
-
* { field: "identifier" },
|
|
118
|
-
* { field: "token" }
|
|
119
|
-
* ]
|
|
120
|
-
* },
|
|
121
|
-
* }
|
|
122
|
-
* })
|
|
123
|
-
* ```
|
|
124
|
-
*
|
|
125
|
-
* > This schema is adapted for use in Fauna and based upon our main [schema](https://authjs.dev/reference/core/adapters#models)
|
|
126
|
-
*
|
|
127
|
-
* #### Custom collection names
|
|
128
|
-
* If you want to use custom collection names, you can pass them as an option to the adapter, like this:
|
|
129
|
-
*
|
|
130
|
-
* ```javascript
|
|
131
|
-
* FaunaAdapter(client, {
|
|
132
|
-
* collectionNames: {
|
|
133
|
-
* user: "CustomUser",
|
|
134
|
-
* account: "CustomAccount",
|
|
135
|
-
* session: "CustomSession",
|
|
136
|
-
* verificationToken: "CustomVerificationToken",
|
|
137
|
-
* }
|
|
138
|
-
* })
|
|
139
|
-
* ```
|
|
140
|
-
*
|
|
141
|
-
* Make sure the collection names you pass to the provider match the collection names of your Fauna database.
|
|
142
|
-
*
|
|
143
|
-
* ### Migrating from v1
|
|
144
|
-
* In v2, we've renamed the collections to use uppercase naming, in accordance with Fauna best practices. If you're migrating from v1, you'll need to rename your collections to match the new naming scheme.
|
|
145
|
-
* Additionally, we've renamed the indexes to match the new method-like index names.
|
|
146
|
-
*
|
|
147
|
-
* #### Migration script
|
|
148
|
-
* Run this FQL script inside a Fauna shell for the database you're migrating from v1 to v2 (it will rename your collections and indexes to match):
|
|
149
|
-
*
|
|
150
|
-
* ```javascript
|
|
151
|
-
* Collection.byName("accounts")!.update({
|
|
152
|
-
* name: "Account"
|
|
153
|
-
* indexes: {
|
|
154
|
-
* byUserId: {
|
|
155
|
-
* terms: [{ field: "userId" }]
|
|
156
|
-
* },
|
|
157
|
-
* byProviderAndProviderAccountId: {
|
|
158
|
-
* terms: [{ field: "provider" }, { field: "providerAccountId" }]
|
|
159
|
-
* },
|
|
160
|
-
* account_by_provider_and_provider_account_id: null,
|
|
161
|
-
* accounts_by_user_id: null
|
|
162
|
-
* }
|
|
163
|
-
* })
|
|
164
|
-
* Collection.byName("sessions")!.update({
|
|
165
|
-
* name: "Session",
|
|
166
|
-
* indexes: {
|
|
167
|
-
* bySessionToken: {
|
|
168
|
-
* terms: [{ field: "sessionToken" }]
|
|
169
|
-
* },
|
|
170
|
-
* byUserId: {
|
|
171
|
-
* terms: [{ field: "userId" }]
|
|
172
|
-
* },
|
|
173
|
-
* session_by_session_token: null,
|
|
174
|
-
* sessions_by_user_id: null
|
|
175
|
-
* }
|
|
176
|
-
* })
|
|
177
|
-
* Collection.byName("users")!.update({
|
|
178
|
-
* name: "User",
|
|
179
|
-
* indexes: {
|
|
180
|
-
* byEmail: {
|
|
181
|
-
* terms: [{ field: "email" }]
|
|
182
|
-
* },
|
|
183
|
-
* user_by_email: null
|
|
184
|
-
* }
|
|
185
|
-
* })
|
|
186
|
-
* Collection.byName("verification_tokens")!.update({
|
|
187
|
-
* name: "VerificationToken",
|
|
188
|
-
* indexes: {
|
|
189
|
-
* byIdentifierAndToken: {
|
|
190
|
-
* terms: [{ field: "identifier" }, { field: "token" }]
|
|
191
|
-
* },
|
|
192
|
-
* verification_token_by_identifier_and_token: null
|
|
193
|
-
* }
|
|
194
|
-
* })
|
|
195
|
-
* ```
|
|
196
|
-
*
|
|
197
|
-
**/
|
|
198
24
|
export function FaunaAdapter(client, config) {
|
|
199
25
|
const { collectionNames = defaultCollectionNames } = config || {};
|
|
200
26
|
return {
|
|
@@ -291,7 +117,9 @@ export function FaunaAdapter(client, config) {
|
|
|
291
117
|
return null;
|
|
292
118
|
// Delete the verification token so it can only be used once
|
|
293
119
|
await client.query(fql `Collection(${collectionNames.verificationToken}).byId(${response.data.id}).delete()`);
|
|
294
|
-
const _verificationToken = {
|
|
120
|
+
const _verificationToken = {
|
|
121
|
+
...response.data,
|
|
122
|
+
};
|
|
295
123
|
delete _verificationToken.id;
|
|
296
124
|
return format.from(_verificationToken);
|
|
297
125
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auth/fauna-adapter",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Fauna Adapter for Auth.js",
|
|
5
5
|
"homepage": "https://authjs.dev",
|
|
6
6
|
"repository": "https://github.com/nextauthjs/next-auth",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@auth/core": "0.
|
|
41
|
+
"@auth/core": "0.31.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"fauna": "^1.3.1"
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding:
|
|
3
|
-
* <p
|
|
2
|
+
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px"}}>
|
|
3
|
+
* <p>Official <a href="https://docs.fauna.com/fauna/current/">Fauna</a> adapter for Auth.js / NextAuth.js.</p>
|
|
4
4
|
* <a href="https://fauna.com/features">
|
|
5
|
-
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/fauna.svg"
|
|
5
|
+
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/fauna.svg" width="64" />
|
|
6
6
|
* </a>
|
|
7
7
|
* </div>
|
|
8
8
|
*
|
|
@@ -14,7 +14,15 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @module @auth/fauna-adapter
|
|
16
16
|
*/
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
Client,
|
|
19
|
+
TimeStub,
|
|
20
|
+
fql,
|
|
21
|
+
NullDocument,
|
|
22
|
+
QueryValue,
|
|
23
|
+
QueryValueObject,
|
|
24
|
+
Module,
|
|
25
|
+
} from "fauna"
|
|
18
26
|
|
|
19
27
|
import type {
|
|
20
28
|
Adapter,
|
|
@@ -25,7 +33,13 @@ import type {
|
|
|
25
33
|
} from "@auth/core/adapters"
|
|
26
34
|
|
|
27
35
|
type ToFauna<T> = {
|
|
28
|
-
[P in keyof T]: T[P] extends Date | null
|
|
36
|
+
[P in keyof T]: T[P] extends Date | null
|
|
37
|
+
? TimeStub | null
|
|
38
|
+
: T[P] extends undefined
|
|
39
|
+
? null
|
|
40
|
+
: T[P] extends QueryValue
|
|
41
|
+
? T[P]
|
|
42
|
+
: QueryValueObject
|
|
29
43
|
}
|
|
30
44
|
|
|
31
45
|
export type FaunaUser = ToFauna<AdapterUser>
|
|
@@ -49,200 +63,26 @@ const defaultCollectionNames = {
|
|
|
49
63
|
verificationToken: "VerificationToken",
|
|
50
64
|
}
|
|
51
65
|
|
|
52
|
-
/**
|
|
53
|
-
*
|
|
54
|
-
* ## Setup
|
|
55
|
-
*
|
|
56
|
-
* This is the Fauna Adapter for [Auth.js](https://authjs.dev). This package can only be used in conjunction with the primary `next-auth` and other framework packages. It is not a standalone package.
|
|
57
|
-
*
|
|
58
|
-
* You can find the Fauna schema and seed information in the docs at [authjs.dev/reference/adapter/fauna](https://authjs.dev/reference/adapter/fauna).
|
|
59
|
-
*
|
|
60
|
-
* ### Configure Auth.js
|
|
61
|
-
*
|
|
62
|
-
* ```javascript title="pages/api/auth/[...nextauth].js"
|
|
63
|
-
* import NextAuth from "next-auth"
|
|
64
|
-
* import { Client } from "fauna"
|
|
65
|
-
* import { FaunaAdapter } from "@auth/fauna-adapter"
|
|
66
|
-
*
|
|
67
|
-
* const client = new Client({
|
|
68
|
-
* secret: "secret",
|
|
69
|
-
* endpoint: new URL('http://localhost:8443')
|
|
70
|
-
* })
|
|
71
|
-
*
|
|
72
|
-
* // For more information on each option (and a full list of options) go to
|
|
73
|
-
* // https://authjs.dev/reference/configuration/auth-options
|
|
74
|
-
* export default NextAuth({
|
|
75
|
-
* // https://authjs.dev/reference/providers/
|
|
76
|
-
* providers: [],
|
|
77
|
-
* adapter: FaunaAdapter(client)
|
|
78
|
-
* ...
|
|
79
|
-
* })
|
|
80
|
-
* ```
|
|
81
|
-
*
|
|
82
|
-
* ### Schema
|
|
83
|
-
*
|
|
84
|
-
* Run the following FQL code inside the `Shell` tab in the Fauna dashboard to set up the appropriate collections and indexes.
|
|
85
|
-
*
|
|
86
|
-
* ```javascript
|
|
87
|
-
* Collection.create({
|
|
88
|
-
* name: "Account",
|
|
89
|
-
* indexes: {
|
|
90
|
-
* byUserId: {
|
|
91
|
-
* terms: [
|
|
92
|
-
* { field: "userId" }
|
|
93
|
-
* ]
|
|
94
|
-
* },
|
|
95
|
-
* byProviderAndProviderAccountId: {
|
|
96
|
-
* terms [
|
|
97
|
-
* { field: "provider" },
|
|
98
|
-
* { field: "providerAccountId" }
|
|
99
|
-
* ]
|
|
100
|
-
* },
|
|
101
|
-
* }
|
|
102
|
-
* })
|
|
103
|
-
* Collection.create({
|
|
104
|
-
* name: "Session",
|
|
105
|
-
* constraints: [
|
|
106
|
-
* {
|
|
107
|
-
* unique: ["sessionToken"],
|
|
108
|
-
* status: "active",
|
|
109
|
-
* }
|
|
110
|
-
* ],
|
|
111
|
-
* indexes: {
|
|
112
|
-
* bySessionToken: {
|
|
113
|
-
* terms: [
|
|
114
|
-
* { field: "sessionToken" }
|
|
115
|
-
* ]
|
|
116
|
-
* },
|
|
117
|
-
* byUserId: {
|
|
118
|
-
* terms [
|
|
119
|
-
* { field: "userId" }
|
|
120
|
-
* ]
|
|
121
|
-
* },
|
|
122
|
-
* }
|
|
123
|
-
* })
|
|
124
|
-
* Collection.create({
|
|
125
|
-
* name: "User",
|
|
126
|
-
* constraints: [
|
|
127
|
-
* {
|
|
128
|
-
* unique: ["email"],
|
|
129
|
-
* status: "active",
|
|
130
|
-
* }
|
|
131
|
-
* ],
|
|
132
|
-
* indexes: {
|
|
133
|
-
* byEmail: {
|
|
134
|
-
* terms [
|
|
135
|
-
* { field: "email" }
|
|
136
|
-
* ]
|
|
137
|
-
* },
|
|
138
|
-
* }
|
|
139
|
-
* })
|
|
140
|
-
* Collection.create({
|
|
141
|
-
* name: "VerificationToken",
|
|
142
|
-
* indexes: {
|
|
143
|
-
* byIdentifierAndToken: {
|
|
144
|
-
* terms [
|
|
145
|
-
* { field: "identifier" },
|
|
146
|
-
* { field: "token" }
|
|
147
|
-
* ]
|
|
148
|
-
* },
|
|
149
|
-
* }
|
|
150
|
-
* })
|
|
151
|
-
* ```
|
|
152
|
-
*
|
|
153
|
-
* > This schema is adapted for use in Fauna and based upon our main [schema](https://authjs.dev/reference/core/adapters#models)
|
|
154
|
-
*
|
|
155
|
-
* #### Custom collection names
|
|
156
|
-
* If you want to use custom collection names, you can pass them as an option to the adapter, like this:
|
|
157
|
-
*
|
|
158
|
-
* ```javascript
|
|
159
|
-
* FaunaAdapter(client, {
|
|
160
|
-
* collectionNames: {
|
|
161
|
-
* user: "CustomUser",
|
|
162
|
-
* account: "CustomAccount",
|
|
163
|
-
* session: "CustomSession",
|
|
164
|
-
* verificationToken: "CustomVerificationToken",
|
|
165
|
-
* }
|
|
166
|
-
* })
|
|
167
|
-
* ```
|
|
168
|
-
*
|
|
169
|
-
* Make sure the collection names you pass to the provider match the collection names of your Fauna database.
|
|
170
|
-
*
|
|
171
|
-
* ### Migrating from v1
|
|
172
|
-
* In v2, we've renamed the collections to use uppercase naming, in accordance with Fauna best practices. If you're migrating from v1, you'll need to rename your collections to match the new naming scheme.
|
|
173
|
-
* Additionally, we've renamed the indexes to match the new method-like index names.
|
|
174
|
-
*
|
|
175
|
-
* #### Migration script
|
|
176
|
-
* Run this FQL script inside a Fauna shell for the database you're migrating from v1 to v2 (it will rename your collections and indexes to match):
|
|
177
|
-
*
|
|
178
|
-
* ```javascript
|
|
179
|
-
* Collection.byName("accounts")!.update({
|
|
180
|
-
* name: "Account"
|
|
181
|
-
* indexes: {
|
|
182
|
-
* byUserId: {
|
|
183
|
-
* terms: [{ field: "userId" }]
|
|
184
|
-
* },
|
|
185
|
-
* byProviderAndProviderAccountId: {
|
|
186
|
-
* terms: [{ field: "provider" }, { field: "providerAccountId" }]
|
|
187
|
-
* },
|
|
188
|
-
* account_by_provider_and_provider_account_id: null,
|
|
189
|
-
* accounts_by_user_id: null
|
|
190
|
-
* }
|
|
191
|
-
* })
|
|
192
|
-
* Collection.byName("sessions")!.update({
|
|
193
|
-
* name: "Session",
|
|
194
|
-
* indexes: {
|
|
195
|
-
* bySessionToken: {
|
|
196
|
-
* terms: [{ field: "sessionToken" }]
|
|
197
|
-
* },
|
|
198
|
-
* byUserId: {
|
|
199
|
-
* terms: [{ field: "userId" }]
|
|
200
|
-
* },
|
|
201
|
-
* session_by_session_token: null,
|
|
202
|
-
* sessions_by_user_id: null
|
|
203
|
-
* }
|
|
204
|
-
* })
|
|
205
|
-
* Collection.byName("users")!.update({
|
|
206
|
-
* name: "User",
|
|
207
|
-
* indexes: {
|
|
208
|
-
* byEmail: {
|
|
209
|
-
* terms: [{ field: "email" }]
|
|
210
|
-
* },
|
|
211
|
-
* user_by_email: null
|
|
212
|
-
* }
|
|
213
|
-
* })
|
|
214
|
-
* Collection.byName("verification_tokens")!.update({
|
|
215
|
-
* name: "VerificationToken",
|
|
216
|
-
* indexes: {
|
|
217
|
-
* byIdentifierAndToken: {
|
|
218
|
-
* terms: [{ field: "identifier" }, { field: "token" }]
|
|
219
|
-
* },
|
|
220
|
-
* verification_token_by_identifier_and_token: null
|
|
221
|
-
* }
|
|
222
|
-
* })
|
|
223
|
-
* ```
|
|
224
|
-
*
|
|
225
|
-
**/
|
|
226
66
|
export function FaunaAdapter(client: Client, config?: AdapterConfig): Adapter {
|
|
227
67
|
const { collectionNames = defaultCollectionNames } = config || {}
|
|
228
68
|
|
|
229
69
|
return {
|
|
230
70
|
async createUser(user) {
|
|
231
71
|
const response = await client.query<FaunaUser>(
|
|
232
|
-
fql`Collection(${collectionNames.user}).create(${format.to(user)})
|
|
72
|
+
fql`Collection(${collectionNames.user}).create(${format.to(user)})`
|
|
233
73
|
)
|
|
234
74
|
return format.from(response.data)
|
|
235
75
|
},
|
|
236
76
|
async getUser(id) {
|
|
237
77
|
const response = await client.query<FaunaUser | NullDocument>(
|
|
238
|
-
fql`Collection(${collectionNames.user}).byId(${id})
|
|
78
|
+
fql`Collection(${collectionNames.user}).byId(${id})`
|
|
239
79
|
)
|
|
240
80
|
if (response.data instanceof NullDocument) return null
|
|
241
81
|
return format.from(response.data)
|
|
242
82
|
},
|
|
243
83
|
async getUserByEmail(email) {
|
|
244
84
|
const response = await client.query<FaunaUser>(
|
|
245
|
-
fql`Collection(${collectionNames.user}).byEmail(${email}).first()
|
|
85
|
+
fql`Collection(${collectionNames.user}).byEmail(${email}).first()`
|
|
246
86
|
)
|
|
247
87
|
if (response.data === null) return null
|
|
248
88
|
return format.from(response.data)
|
|
@@ -262,7 +102,9 @@ export function FaunaAdapter(client: Client, config?: AdapterConfig): Adapter {
|
|
|
262
102
|
const _user: Partial<AdapterUser> = { ...user }
|
|
263
103
|
delete _user.id
|
|
264
104
|
const response = await client.query<FaunaUser>(
|
|
265
|
-
fql`Collection(${collectionNames.user}).byId(${
|
|
105
|
+
fql`Collection(${collectionNames.user}).byId(${
|
|
106
|
+
user.id
|
|
107
|
+
}).update(${format.to(_user)})`
|
|
266
108
|
)
|
|
267
109
|
return format.from(response.data)
|
|
268
110
|
},
|
|
@@ -280,13 +122,15 @@ export function FaunaAdapter(client: Client, config?: AdapterConfig): Adapter {
|
|
|
280
122
|
},
|
|
281
123
|
async linkAccount(account) {
|
|
282
124
|
await client.query<FaunaAccount>(
|
|
283
|
-
fql`Collection(${collectionNames.account}).create(${format.to(
|
|
125
|
+
fql`Collection(${collectionNames.account}).create(${format.to(
|
|
126
|
+
account
|
|
127
|
+
)})`
|
|
284
128
|
)
|
|
285
129
|
return account
|
|
286
130
|
},
|
|
287
131
|
async unlinkAccount({ provider, providerAccountId }) {
|
|
288
132
|
const response = await client.query<FaunaAccount>(
|
|
289
|
-
fql`Collection(${collectionNames.account}).byProviderAndProviderAccountId(${provider}, ${providerAccountId}).first().delete()
|
|
133
|
+
fql`Collection(${collectionNames.account}).byProviderAndProviderAccountId(${provider}, ${providerAccountId}).first().delete()`
|
|
290
134
|
)
|
|
291
135
|
return format.from<AdapterAccount>(response.data)
|
|
292
136
|
},
|
|
@@ -310,7 +154,9 @@ export function FaunaAdapter(client: Client, config?: AdapterConfig): Adapter {
|
|
|
310
154
|
},
|
|
311
155
|
async createSession(session) {
|
|
312
156
|
await client.query<FaunaSession>(
|
|
313
|
-
fql`Collection(${collectionNames.session}).create(${format.to(
|
|
157
|
+
fql`Collection(${collectionNames.session}).create(${format.to(
|
|
158
|
+
session
|
|
159
|
+
)})`
|
|
314
160
|
)
|
|
315
161
|
return session
|
|
316
162
|
},
|
|
@@ -318,33 +164,35 @@ export function FaunaAdapter(client: Client, config?: AdapterConfig): Adapter {
|
|
|
318
164
|
const response = await client.query<FaunaSession>(
|
|
319
165
|
fql`Collection(${collectionNames.session}).bySessionToken(${
|
|
320
166
|
session.sessionToken
|
|
321
|
-
}).first().update(${format.to(session)})
|
|
167
|
+
}).first().update(${format.to(session)})`
|
|
322
168
|
)
|
|
323
169
|
return format.from(response.data)
|
|
324
170
|
},
|
|
325
171
|
async deleteSession(sessionToken) {
|
|
326
172
|
await client.query(
|
|
327
|
-
fql`Collection(${collectionNames.session}).bySessionToken(${sessionToken}).first().delete()
|
|
173
|
+
fql`Collection(${collectionNames.session}).bySessionToken(${sessionToken}).first().delete()`
|
|
328
174
|
)
|
|
329
175
|
},
|
|
330
176
|
async createVerificationToken(verificationToken) {
|
|
331
177
|
await client.query<FaunaVerificationToken>(
|
|
332
178
|
fql`Collection(${collectionNames.verificationToken}).create(${format.to(
|
|
333
|
-
verificationToken
|
|
334
|
-
)})
|
|
179
|
+
verificationToken
|
|
180
|
+
)})`
|
|
335
181
|
)
|
|
336
182
|
return verificationToken
|
|
337
183
|
},
|
|
338
184
|
async useVerificationToken({ identifier, token }) {
|
|
339
185
|
const response = await client.query<FaunaVerificationToken>(
|
|
340
|
-
fql`Collection(${collectionNames.verificationToken}).byIdentifierAndToken(${identifier}, ${token}).first()
|
|
186
|
+
fql`Collection(${collectionNames.verificationToken}).byIdentifierAndToken(${identifier}, ${token}).first()`
|
|
341
187
|
)
|
|
342
188
|
if (response.data === null) return null
|
|
343
189
|
// Delete the verification token so it can only be used once
|
|
344
190
|
await client.query(
|
|
345
|
-
fql`Collection(${collectionNames.verificationToken}).byId(${response.data.id}).delete()
|
|
191
|
+
fql`Collection(${collectionNames.verificationToken}).byId(${response.data.id}).delete()`
|
|
346
192
|
)
|
|
347
|
-
const _verificationToken: Partial<FaunaVerificationToken> = {
|
|
193
|
+
const _verificationToken: Partial<FaunaVerificationToken> = {
|
|
194
|
+
...response.data,
|
|
195
|
+
}
|
|
348
196
|
delete _verificationToken.id
|
|
349
197
|
return format.from(_verificationToken)
|
|
350
198
|
},
|