@auth/dynamodb-adapter 2.0.0 → 2.2.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 CHANGED
@@ -18,7 +18,7 @@
18
18
  <img src="https://img.shields.io/npm/dm/@auth/dynamodb-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="Github Stars" />
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,6 +1,6 @@
1
1
  /**
2
2
  * <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px"}}>
3
- * <p style={{fontWeight: "300"}}>Official <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html">DynamoDB</a> adapter for Auth.js / NextAuth.js.</p>
3
+ * <p>Official <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html">DynamoDB</a> adapter for Auth.js / NextAuth.js.</p>
4
4
  * <a href="https://docs.aws.amazon.com/dynamodb/index.html">
5
5
  * <img style={{display: "block"}} src="https://authjs.dev/img/adapters/dynamodb.png" width="48"/>
6
6
  * </a>
@@ -15,7 +15,7 @@
15
15
  * @module @auth/dynamodb-adapter
16
16
  */
17
17
  import type { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";
18
- import type { Adapter } from "@auth/core/adapters";
18
+ import { type Adapter } from "@auth/core/adapters";
19
19
  export interface DynamoDBAdapterOptions {
20
20
  tableName?: string;
21
21
  partitionKey?: string;
@@ -24,185 +24,9 @@ export interface DynamoDBAdapterOptions {
24
24
  indexPartitionKey?: string;
25
25
  indexSortKey?: string;
26
26
  }
27
- /**
28
- * ## Setup
29
- *
30
- * By default, the adapter expects a table with a partition key `pk` and a sort key `sk`, as well as a global secondary index named `GSI1` with `GSI1PK` as partition key and `GSI1SK` as sorting key. To automatically delete sessions and verification requests after they expire using [dynamodb TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) you should [enable the TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-how-to.html) with attribute name 'expires'. You can set whatever you want as the table name and the billing method.
31
- * You can find the full schema in the table structure section below.
32
- *
33
- * ### Configuring Auth.js
34
- *
35
- * You need to pass `DynamoDBDocument` client from the modular [`aws-sdk`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html) v3 to the adapter.
36
- * The default table name is `next-auth`, but you can customise that by passing `{ tableName: 'your-table-name' }` as the second parameter in the adapter.
37
- *
38
- * ```js title="pages/api/auth/[...nextauth].js"
39
- * import { DynamoDB, DynamoDBClientConfig } from "@aws-sdk/client-dynamodb"
40
- * import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"
41
- * import NextAuth from "next-auth";
42
- * import Providers from "next-auth/providers";
43
- * import { DynamoDBAdapter } from "@auth/dynamodb-adapter"
44
- *
45
- * const config: DynamoDBClientConfig = {
46
- * credentials: {
47
- * accessKeyId: process.env.NEXT_AUTH_AWS_ACCESS_KEY,
48
- * secretAccessKey: process.env.NEXT_AUTH_AWS_SECRET_KEY,
49
- * },
50
- * region: process.env.NEXT_AUTH_AWS_REGION,
51
- * };
52
- *
53
- * const client = DynamoDBDocument.from(new DynamoDB(config), {
54
- * marshallOptions: {
55
- * convertEmptyValues: true,
56
- * removeUndefinedValues: true,
57
- * convertClassInstanceToMap: true,
58
- * },
59
- * })
60
- *
61
- * export default NextAuth({
62
- * // Configure one or more authentication providers
63
- * providers: [
64
- * Providers.GitHub({
65
- * clientId: process.env.GITHUB_ID,
66
- * clientSecret: process.env.GITHUB_SECRET,
67
- * }),
68
- * Providers.Email({
69
- * server: process.env.EMAIL_SERVER,
70
- * from: process.env.EMAIL_FROM,
71
- * }),
72
- * // ...add more providers here
73
- * ],
74
- * adapter: DynamoDBAdapter(
75
- * client
76
- * ),
77
- * });
78
- * ```
79
- *
80
- * (AWS secrets start with `NEXT_AUTH_` in order to not conflict with [Vercel's reserved environment variables](https://vercel.com/docs/environment-variables#reserved-environment-variables).)
81
- *
82
- * ## AWS Credentials
83
- *
84
- * :::note
85
- * Always follow the **principle of least privilege** when giving access to AWS
86
- * services/resources -> identities should only be permitted to perform the
87
- * smallest set of actions necessary to fulfill a specific task.
88
- * :::
89
- *
90
- * 1. Open the [AWS console](https://console.aws.amazon.com/) and go to "IAM", then "Users".
91
- * 2. Create a new user. The purpose of this user is to give programmatic access to DynamoDB.
92
- * 3. Create an Access Key and then copy Key ID and Secret to your `.env`/`.env.local` file.
93
- * 4. Select "Add Permission" and "Create Inline Policy".
94
- * 5. Copy the JSON below into the JSON input and replace `region`, `account_id` and `table_name` with your values.
95
- *
96
- * ```json
97
- * {
98
- * "Version": "2012-10-17",
99
- * "Statement": [
100
- * {
101
- * "Sid": "DynamoDBAccess",
102
- * "Effect": "Allow",
103
- * "Action": [
104
- * "dynamodb:BatchGetItem",
105
- * "dynamodb:BatchWriteItem",
106
- * "dynamodb:Describe*",
107
- * "dynamodb:List*",
108
- * "dynamodb:PutItem",
109
- * "dynamodb:DeleteItem",
110
- * "dynamodb:GetItem",
111
- * "dynamodb:Scan",
112
- * "dynamodb:Query",
113
- * "dynamodb:UpdateItem"
114
- * ],
115
- * "Resource": [
116
- * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}",
117
- * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}/index/GSI1"
118
- * ]
119
- * }
120
- * ]
121
- * }
122
- * ```
123
- *
124
- * ## Advanced usage
125
- *
126
- * ### Default schema
127
- *
128
- * The table respects the single table design pattern. This has many advantages:
129
- *
130
- * - Only one table to manage, monitor and provision.
131
- * - Querying relations is faster than with multi-table schemas (for eg. retrieving all sessions for a user).
132
- * - Only one table needs to be replicated if you want to go multi-region.
133
- *
134
- * > This schema is adapted for use in DynamoDB and based upon our main [schema](https://authjs.dev/reference/core/adapters#models)
135
- *
136
- * ![DynamoDB Table](https://i.imgur.com/hGZtWDq.png)
137
- *
138
- * You can create this table with infrastructure as code using [`aws-cdk`](https://github.com/aws/aws-cdk) with the following table definition:
139
- *
140
- * ```js title="stack.ts"
141
- * new dynamodb.Table(this, `NextAuthTable`, {
142
- * tableName: "next-auth",
143
- * partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
144
- * sortKey: { name: "sk", type: dynamodb.AttributeType.STRING },
145
- * timeToLiveAttribute: "expires",
146
- * }).addGlobalSecondaryIndex({
147
- * indexName: "GSI1",
148
- * partitionKey: { name: "GSI1PK", type: dynamodb.AttributeType.STRING },
149
- * sortKey: { name: "GSI1SK", type: dynamodb.AttributeType.STRING },
150
- * })
151
- * ```
152
- *
153
- * Alternatively, you can use this cloudformation template:
154
- *
155
- * ```yaml title=cloudformation.yaml
156
- * NextAuthTable:
157
- * Type: "AWS::DynamoDB::Table"
158
- * Properties:
159
- * TableName: next-auth
160
- * AttributeDefinitions:
161
- * - AttributeName: pk
162
- * AttributeType: S
163
- * - AttributeName: sk
164
- * AttributeType: S
165
- * - AttributeName: GSI1PK
166
- * AttributeType: S
167
- * - AttributeName: GSI1SK
168
- * AttributeType: S
169
- * KeySchema:
170
- * - AttributeName: pk
171
- * KeyType: HASH
172
- * - AttributeName: sk
173
- * KeyType: RANGE
174
- * GlobalSecondaryIndexes:
175
- * - IndexName: GSI1
176
- * Projection:
177
- * ProjectionType: ALL
178
- * KeySchema:
179
- * - AttributeName: GSI1PK
180
- * KeyType: HASH
181
- * - AttributeName: GSI1SK
182
- * KeyType: RANGE
183
- * TimeToLiveSpecification:
184
- * AttributeName: expires
185
- * Enabled: true
186
- * ```
187
- *
188
- * ### Using a custom schema
189
- *
190
- * You can configure your custom table schema by passing the `options` key to the adapter constructor:
191
- *
192
- * ```js
193
- * const adapter = DynamoDBAdapter(client, {
194
- * tableName: "custom-table-name",
195
- * partitionKey: "custom-pk",
196
- * sortKey: "custom-sk",
197
- * indexName: "custom-index-name",
198
- * indexPartitionKey: "custom-index-pk",
199
- * indexSortKey: "custom-index-sk",
200
- * })
201
- * ```
202
- **/
203
27
  export declare function DynamoDBAdapter(client: DynamoDBDocument, options?: DynamoDBAdapterOptions): Adapter;
204
28
  declare const format: {
205
- /** Takes a plain old JavaScript object and turns it into a Dynamodb object */
29
+ /** Takes a plain old JavaScript object and turns it into a DynamoDB object */
206
30
  to(object: Record<string, any>): Record<string, unknown>;
207
31
  /** Takes a Dynamo object and returns a plain old JavaScript object */
208
32
  from<T = Record<string, unknown>>(object?: Record<string, any>): T | null;
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EACV,OAAO,EAKR,MAAM,qBAAqB,CAAA;AAE5B,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+KI;AACJ,wBAAgB,eAAe,CAC7B,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CA+ST;AASD,QAAA,MAAM,MAAM;IACV,8EAA8E;eACnE,OAAO,MAAM,EAAE,GAAG,CAAC;IAY9B,sEAAsE;+CAC3B,OAAO,MAAM,EAAE,GAAG,CAAC;CAsB/D,CAAA;AAED,iBAAS,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAC9D,gBAAgB,EAAE,MAAM,CAAA;IACxB,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChD,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnD,CAgBA;AAED,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,KAAK,OAAO,EAMb,MAAM,qBAAqB,CAAA;AAE5B,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CA+ST;AAED,QAAA,MAAM,MAAM;IACV,8EAA8E;eACnE,OAAO,MAAM,EAAE,GAAG,CAAC;IAY9B,sEAAsE;+CAC3B,OAAO,MAAM,EAAE,GAAG,CAAC;CAsB/D,CAAA;AAED,iBAAS,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAC9D,gBAAgB,EAAE,MAAM,CAAA;IACxB,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChD,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnD,CAgBA;AAED,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAA"}
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px"}}>
3
- * <p style={{fontWeight: "300"}}>Official <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html">DynamoDB</a> adapter for Auth.js / NextAuth.js.</p>
3
+ * <p>Official <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html">DynamoDB</a> adapter for Auth.js / NextAuth.js.</p>
4
4
  * <a href="https://docs.aws.amazon.com/dynamodb/index.html">
5
5
  * <img style={{display: "block"}} src="https://authjs.dev/img/adapters/dynamodb.png" width="48"/>
6
6
  * </a>
@@ -14,182 +14,7 @@
14
14
  *
15
15
  * @module @auth/dynamodb-adapter
16
16
  */
17
- /**
18
- * ## Setup
19
- *
20
- * By default, the adapter expects a table with a partition key `pk` and a sort key `sk`, as well as a global secondary index named `GSI1` with `GSI1PK` as partition key and `GSI1SK` as sorting key. To automatically delete sessions and verification requests after they expire using [dynamodb TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) you should [enable the TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-how-to.html) with attribute name 'expires'. You can set whatever you want as the table name and the billing method.
21
- * You can find the full schema in the table structure section below.
22
- *
23
- * ### Configuring Auth.js
24
- *
25
- * You need to pass `DynamoDBDocument` client from the modular [`aws-sdk`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html) v3 to the adapter.
26
- * The default table name is `next-auth`, but you can customise that by passing `{ tableName: 'your-table-name' }` as the second parameter in the adapter.
27
- *
28
- * ```js title="pages/api/auth/[...nextauth].js"
29
- * import { DynamoDB, DynamoDBClientConfig } from "@aws-sdk/client-dynamodb"
30
- * import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"
31
- * import NextAuth from "next-auth";
32
- * import Providers from "next-auth/providers";
33
- * import { DynamoDBAdapter } from "@auth/dynamodb-adapter"
34
- *
35
- * const config: DynamoDBClientConfig = {
36
- * credentials: {
37
- * accessKeyId: process.env.NEXT_AUTH_AWS_ACCESS_KEY,
38
- * secretAccessKey: process.env.NEXT_AUTH_AWS_SECRET_KEY,
39
- * },
40
- * region: process.env.NEXT_AUTH_AWS_REGION,
41
- * };
42
- *
43
- * const client = DynamoDBDocument.from(new DynamoDB(config), {
44
- * marshallOptions: {
45
- * convertEmptyValues: true,
46
- * removeUndefinedValues: true,
47
- * convertClassInstanceToMap: true,
48
- * },
49
- * })
50
- *
51
- * export default NextAuth({
52
- * // Configure one or more authentication providers
53
- * providers: [
54
- * Providers.GitHub({
55
- * clientId: process.env.GITHUB_ID,
56
- * clientSecret: process.env.GITHUB_SECRET,
57
- * }),
58
- * Providers.Email({
59
- * server: process.env.EMAIL_SERVER,
60
- * from: process.env.EMAIL_FROM,
61
- * }),
62
- * // ...add more providers here
63
- * ],
64
- * adapter: DynamoDBAdapter(
65
- * client
66
- * ),
67
- * });
68
- * ```
69
- *
70
- * (AWS secrets start with `NEXT_AUTH_` in order to not conflict with [Vercel's reserved environment variables](https://vercel.com/docs/environment-variables#reserved-environment-variables).)
71
- *
72
- * ## AWS Credentials
73
- *
74
- * :::note
75
- * Always follow the **principle of least privilege** when giving access to AWS
76
- * services/resources -> identities should only be permitted to perform the
77
- * smallest set of actions necessary to fulfill a specific task.
78
- * :::
79
- *
80
- * 1. Open the [AWS console](https://console.aws.amazon.com/) and go to "IAM", then "Users".
81
- * 2. Create a new user. The purpose of this user is to give programmatic access to DynamoDB.
82
- * 3. Create an Access Key and then copy Key ID and Secret to your `.env`/`.env.local` file.
83
- * 4. Select "Add Permission" and "Create Inline Policy".
84
- * 5. Copy the JSON below into the JSON input and replace `region`, `account_id` and `table_name` with your values.
85
- *
86
- * ```json
87
- * {
88
- * "Version": "2012-10-17",
89
- * "Statement": [
90
- * {
91
- * "Sid": "DynamoDBAccess",
92
- * "Effect": "Allow",
93
- * "Action": [
94
- * "dynamodb:BatchGetItem",
95
- * "dynamodb:BatchWriteItem",
96
- * "dynamodb:Describe*",
97
- * "dynamodb:List*",
98
- * "dynamodb:PutItem",
99
- * "dynamodb:DeleteItem",
100
- * "dynamodb:GetItem",
101
- * "dynamodb:Scan",
102
- * "dynamodb:Query",
103
- * "dynamodb:UpdateItem"
104
- * ],
105
- * "Resource": [
106
- * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}",
107
- * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}/index/GSI1"
108
- * ]
109
- * }
110
- * ]
111
- * }
112
- * ```
113
- *
114
- * ## Advanced usage
115
- *
116
- * ### Default schema
117
- *
118
- * The table respects the single table design pattern. This has many advantages:
119
- *
120
- * - Only one table to manage, monitor and provision.
121
- * - Querying relations is faster than with multi-table schemas (for eg. retrieving all sessions for a user).
122
- * - Only one table needs to be replicated if you want to go multi-region.
123
- *
124
- * > This schema is adapted for use in DynamoDB and based upon our main [schema](https://authjs.dev/reference/core/adapters#models)
125
- *
126
- * ![DynamoDB Table](https://i.imgur.com/hGZtWDq.png)
127
- *
128
- * You can create this table with infrastructure as code using [`aws-cdk`](https://github.com/aws/aws-cdk) with the following table definition:
129
- *
130
- * ```js title="stack.ts"
131
- * new dynamodb.Table(this, `NextAuthTable`, {
132
- * tableName: "next-auth",
133
- * partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
134
- * sortKey: { name: "sk", type: dynamodb.AttributeType.STRING },
135
- * timeToLiveAttribute: "expires",
136
- * }).addGlobalSecondaryIndex({
137
- * indexName: "GSI1",
138
- * partitionKey: { name: "GSI1PK", type: dynamodb.AttributeType.STRING },
139
- * sortKey: { name: "GSI1SK", type: dynamodb.AttributeType.STRING },
140
- * })
141
- * ```
142
- *
143
- * Alternatively, you can use this cloudformation template:
144
- *
145
- * ```yaml title=cloudformation.yaml
146
- * NextAuthTable:
147
- * Type: "AWS::DynamoDB::Table"
148
- * Properties:
149
- * TableName: next-auth
150
- * AttributeDefinitions:
151
- * - AttributeName: pk
152
- * AttributeType: S
153
- * - AttributeName: sk
154
- * AttributeType: S
155
- * - AttributeName: GSI1PK
156
- * AttributeType: S
157
- * - AttributeName: GSI1SK
158
- * AttributeType: S
159
- * KeySchema:
160
- * - AttributeName: pk
161
- * KeyType: HASH
162
- * - AttributeName: sk
163
- * KeyType: RANGE
164
- * GlobalSecondaryIndexes:
165
- * - IndexName: GSI1
166
- * Projection:
167
- * ProjectionType: ALL
168
- * KeySchema:
169
- * - AttributeName: GSI1PK
170
- * KeyType: HASH
171
- * - AttributeName: GSI1SK
172
- * KeyType: RANGE
173
- * TimeToLiveSpecification:
174
- * AttributeName: expires
175
- * Enabled: true
176
- * ```
177
- *
178
- * ### Using a custom schema
179
- *
180
- * You can configure your custom table schema by passing the `options` key to the adapter constructor:
181
- *
182
- * ```js
183
- * const adapter = DynamoDBAdapter(client, {
184
- * tableName: "custom-table-name",
185
- * partitionKey: "custom-pk",
186
- * sortKey: "custom-sk",
187
- * indexName: "custom-index-name",
188
- * indexPartitionKey: "custom-index-pk",
189
- * indexSortKey: "custom-index-sk",
190
- * })
191
- * ```
192
- **/
17
+ import { isDate, } from "@auth/core/adapters";
193
18
  export function DynamoDBAdapter(client, options) {
194
19
  const TableName = options?.tableName ?? "next-auth";
195
20
  const pk = options?.partitionKey ?? "pk";
@@ -485,13 +310,8 @@ export function DynamoDBAdapter(client, options) {
485
310
  },
486
311
  };
487
312
  }
488
- // https://github.com/honeinc/is-iso-date/blob/master/index.js
489
- 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))/;
490
- function isDate(value) {
491
- return value && isoDateRE.test(value) && !isNaN(Date.parse(value));
492
- }
493
313
  const format = {
494
- /** Takes a plain old JavaScript object and turns it into a Dynamodb object */
314
+ /** Takes a plain old JavaScript object and turns it into a DynamoDB object */
495
315
  to(object) {
496
316
  const newObject = {};
497
317
  for (const key in object) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@auth/dynamodb-adapter",
3
3
  "repository": "https://github.com/nextauthjs/next-auth",
4
- "version": "2.0.0",
4
+ "version": "2.2.0",
5
5
  "description": "AWS DynamoDB adapter for next-auth.",
6
6
  "keywords": [
7
7
  "next-auth",
@@ -44,7 +44,7 @@
44
44
  "@aws-sdk/lib-dynamodb": "^3.36.1"
45
45
  },
46
46
  "dependencies": {
47
- "@auth/core": "0.30.0"
47
+ "@auth/core": "0.32.0"
48
48
  },
49
49
  "scripts": {
50
50
  "test:default": "vitest -c ../utils/vitest.config.ts",
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px"}}>
3
- * <p style={{fontWeight: "300"}}>Official <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html">DynamoDB</a> adapter for Auth.js / NextAuth.js.</p>
3
+ * <p>Official <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html">DynamoDB</a> adapter for Auth.js / NextAuth.js.</p>
4
4
  * <a href="https://docs.aws.amazon.com/dynamodb/index.html">
5
5
  * <img style={{display: "block"}} src="https://authjs.dev/img/adapters/dynamodb.png" width="48"/>
6
6
  * </a>
@@ -19,12 +19,13 @@ import type {
19
19
  BatchWriteCommandInput,
20
20
  DynamoDBDocument,
21
21
  } from "@aws-sdk/lib-dynamodb"
22
- import type {
23
- Adapter,
24
- AdapterSession,
25
- AdapterAccount,
26
- AdapterUser,
27
- VerificationToken,
22
+ import {
23
+ type Adapter,
24
+ type AdapterSession,
25
+ type AdapterAccount,
26
+ type AdapterUser,
27
+ type VerificationToken,
28
+ isDate,
28
29
  } from "@auth/core/adapters"
29
30
 
30
31
  export interface DynamoDBAdapterOptions {
@@ -36,182 +37,6 @@ export interface DynamoDBAdapterOptions {
36
37
  indexSortKey?: string
37
38
  }
38
39
 
39
- /**
40
- * ## Setup
41
- *
42
- * By default, the adapter expects a table with a partition key `pk` and a sort key `sk`, as well as a global secondary index named `GSI1` with `GSI1PK` as partition key and `GSI1SK` as sorting key. To automatically delete sessions and verification requests after they expire using [dynamodb TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) you should [enable the TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-how-to.html) with attribute name 'expires'. You can set whatever you want as the table name and the billing method.
43
- * You can find the full schema in the table structure section below.
44
- *
45
- * ### Configuring Auth.js
46
- *
47
- * You need to pass `DynamoDBDocument` client from the modular [`aws-sdk`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html) v3 to the adapter.
48
- * The default table name is `next-auth`, but you can customise that by passing `{ tableName: 'your-table-name' }` as the second parameter in the adapter.
49
- *
50
- * ```js title="pages/api/auth/[...nextauth].js"
51
- * import { DynamoDB, DynamoDBClientConfig } from "@aws-sdk/client-dynamodb"
52
- * import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"
53
- * import NextAuth from "next-auth";
54
- * import Providers from "next-auth/providers";
55
- * import { DynamoDBAdapter } from "@auth/dynamodb-adapter"
56
- *
57
- * const config: DynamoDBClientConfig = {
58
- * credentials: {
59
- * accessKeyId: process.env.NEXT_AUTH_AWS_ACCESS_KEY,
60
- * secretAccessKey: process.env.NEXT_AUTH_AWS_SECRET_KEY,
61
- * },
62
- * region: process.env.NEXT_AUTH_AWS_REGION,
63
- * };
64
- *
65
- * const client = DynamoDBDocument.from(new DynamoDB(config), {
66
- * marshallOptions: {
67
- * convertEmptyValues: true,
68
- * removeUndefinedValues: true,
69
- * convertClassInstanceToMap: true,
70
- * },
71
- * })
72
- *
73
- * export default NextAuth({
74
- * // Configure one or more authentication providers
75
- * providers: [
76
- * Providers.GitHub({
77
- * clientId: process.env.GITHUB_ID,
78
- * clientSecret: process.env.GITHUB_SECRET,
79
- * }),
80
- * Providers.Email({
81
- * server: process.env.EMAIL_SERVER,
82
- * from: process.env.EMAIL_FROM,
83
- * }),
84
- * // ...add more providers here
85
- * ],
86
- * adapter: DynamoDBAdapter(
87
- * client
88
- * ),
89
- * });
90
- * ```
91
- *
92
- * (AWS secrets start with `NEXT_AUTH_` in order to not conflict with [Vercel's reserved environment variables](https://vercel.com/docs/environment-variables#reserved-environment-variables).)
93
- *
94
- * ## AWS Credentials
95
- *
96
- * :::note
97
- * Always follow the **principle of least privilege** when giving access to AWS
98
- * services/resources -> identities should only be permitted to perform the
99
- * smallest set of actions necessary to fulfill a specific task.
100
- * :::
101
- *
102
- * 1. Open the [AWS console](https://console.aws.amazon.com/) and go to "IAM", then "Users".
103
- * 2. Create a new user. The purpose of this user is to give programmatic access to DynamoDB.
104
- * 3. Create an Access Key and then copy Key ID and Secret to your `.env`/`.env.local` file.
105
- * 4. Select "Add Permission" and "Create Inline Policy".
106
- * 5. Copy the JSON below into the JSON input and replace `region`, `account_id` and `table_name` with your values.
107
- *
108
- * ```json
109
- * {
110
- * "Version": "2012-10-17",
111
- * "Statement": [
112
- * {
113
- * "Sid": "DynamoDBAccess",
114
- * "Effect": "Allow",
115
- * "Action": [
116
- * "dynamodb:BatchGetItem",
117
- * "dynamodb:BatchWriteItem",
118
- * "dynamodb:Describe*",
119
- * "dynamodb:List*",
120
- * "dynamodb:PutItem",
121
- * "dynamodb:DeleteItem",
122
- * "dynamodb:GetItem",
123
- * "dynamodb:Scan",
124
- * "dynamodb:Query",
125
- * "dynamodb:UpdateItem"
126
- * ],
127
- * "Resource": [
128
- * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}",
129
- * "arn:aws:dynamodb:{region}:{account_id}:table/{table_name}/index/GSI1"
130
- * ]
131
- * }
132
- * ]
133
- * }
134
- * ```
135
- *
136
- * ## Advanced usage
137
- *
138
- * ### Default schema
139
- *
140
- * The table respects the single table design pattern. This has many advantages:
141
- *
142
- * - Only one table to manage, monitor and provision.
143
- * - Querying relations is faster than with multi-table schemas (for eg. retrieving all sessions for a user).
144
- * - Only one table needs to be replicated if you want to go multi-region.
145
- *
146
- * > This schema is adapted for use in DynamoDB and based upon our main [schema](https://authjs.dev/reference/core/adapters#models)
147
- *
148
- * ![DynamoDB Table](https://i.imgur.com/hGZtWDq.png)
149
- *
150
- * You can create this table with infrastructure as code using [`aws-cdk`](https://github.com/aws/aws-cdk) with the following table definition:
151
- *
152
- * ```js title="stack.ts"
153
- * new dynamodb.Table(this, `NextAuthTable`, {
154
- * tableName: "next-auth",
155
- * partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
156
- * sortKey: { name: "sk", type: dynamodb.AttributeType.STRING },
157
- * timeToLiveAttribute: "expires",
158
- * }).addGlobalSecondaryIndex({
159
- * indexName: "GSI1",
160
- * partitionKey: { name: "GSI1PK", type: dynamodb.AttributeType.STRING },
161
- * sortKey: { name: "GSI1SK", type: dynamodb.AttributeType.STRING },
162
- * })
163
- * ```
164
- *
165
- * Alternatively, you can use this cloudformation template:
166
- *
167
- * ```yaml title=cloudformation.yaml
168
- * NextAuthTable:
169
- * Type: "AWS::DynamoDB::Table"
170
- * Properties:
171
- * TableName: next-auth
172
- * AttributeDefinitions:
173
- * - AttributeName: pk
174
- * AttributeType: S
175
- * - AttributeName: sk
176
- * AttributeType: S
177
- * - AttributeName: GSI1PK
178
- * AttributeType: S
179
- * - AttributeName: GSI1SK
180
- * AttributeType: S
181
- * KeySchema:
182
- * - AttributeName: pk
183
- * KeyType: HASH
184
- * - AttributeName: sk
185
- * KeyType: RANGE
186
- * GlobalSecondaryIndexes:
187
- * - IndexName: GSI1
188
- * Projection:
189
- * ProjectionType: ALL
190
- * KeySchema:
191
- * - AttributeName: GSI1PK
192
- * KeyType: HASH
193
- * - AttributeName: GSI1SK
194
- * KeyType: RANGE
195
- * TimeToLiveSpecification:
196
- * AttributeName: expires
197
- * Enabled: true
198
- * ```
199
- *
200
- * ### Using a custom schema
201
- *
202
- * You can configure your custom table schema by passing the `options` key to the adapter constructor:
203
- *
204
- * ```js
205
- * const adapter = DynamoDBAdapter(client, {
206
- * tableName: "custom-table-name",
207
- * partitionKey: "custom-pk",
208
- * sortKey: "custom-sk",
209
- * indexName: "custom-index-name",
210
- * indexPartitionKey: "custom-index-pk",
211
- * indexSortKey: "custom-index-sk",
212
- * })
213
- * ```
214
- **/
215
40
  export function DynamoDBAdapter(
216
41
  client: DynamoDBDocument,
217
42
  options?: DynamoDBAdapterOptions
@@ -520,15 +345,8 @@ export function DynamoDBAdapter(
520
345
  }
521
346
  }
522
347
 
523
- // https://github.com/honeinc/is-iso-date/blob/master/index.js
524
- const isoDateRE =
525
- /(\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))/
526
- function isDate(value: any) {
527
- return value && isoDateRE.test(value) && !isNaN(Date.parse(value))
528
- }
529
-
530
348
  const format = {
531
- /** Takes a plain old JavaScript object and turns it into a Dynamodb object */
349
+ /** Takes a plain old JavaScript object and turns it into a DynamoDB object */
532
350
  to(object: Record<string, any>) {
533
351
  const newObject: Record<string, unknown> = {}
534
352
  for (const key in object) {