@opensaas/keystone-nextjs-auth 25.0.0 → 27.0.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/CHANGELOG.md +27 -0
- package/README.md +15 -13
- package/dist/declarations/src/pages/NextAuthPage.d.ts +3 -3
- package/dist/declarations/src/types/index.d.ts +15 -23
- package/dist/opensaas-keystone-nextjs-auth.cjs.dev.js +74 -161
- package/dist/opensaas-keystone-nextjs-auth.cjs.prod.js +75 -156
- package/dist/opensaas-keystone-nextjs-auth.esm.js +73 -160
- package/package.json +7 -7
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.dev.js +9 -30
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.prod.js +9 -30
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.esm.js +9 -30
- package/src/index.ts +49 -56
- package/src/pages/NextAuthPage.tsx +8 -5
- package/src/templates/next-config.ts +5 -54
- package/src/types/index.ts +4 -19
- package/src/types/next-auth.d.ts +13 -6
package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.prod.js
CHANGED
@@ -14,21 +14,18 @@ async function findMatchingIdentity(identityField, identity, queryAPI) {
|
|
14
14
|
where: {
|
15
15
|
[identityField]: identity
|
16
16
|
}
|
17
|
-
});
|
18
|
-
|
17
|
+
});
|
18
|
+
// Identity failures with helpful errors
|
19
19
|
let code;
|
20
|
-
|
21
20
|
if (!item) {
|
22
21
|
code = 'IDENTITY_NOT_FOUND';
|
23
22
|
}
|
24
|
-
|
25
23
|
if (code) {
|
26
24
|
return {
|
27
25
|
success: false,
|
28
26
|
code
|
29
27
|
};
|
30
28
|
}
|
31
|
-
|
32
29
|
return {
|
33
30
|
success: true,
|
34
31
|
item
|
@@ -40,14 +37,12 @@ async function validateNextAuth(identityField, identity, protectIdentities, item
|
|
40
37
|
const {
|
41
38
|
item
|
42
39
|
} = match;
|
43
|
-
|
44
40
|
if (item) {
|
45
41
|
return {
|
46
42
|
success: true,
|
47
43
|
item
|
48
44
|
};
|
49
45
|
}
|
50
|
-
|
51
46
|
return {
|
52
47
|
success: false,
|
53
48
|
code: protectIdentities ? 'FAILURE' : 'SUBJECT_NOT_FOUND'
|
@@ -69,17 +64,14 @@ function NextAuthPage(props) {
|
|
69
64
|
sessionData,
|
70
65
|
sessionSecret
|
71
66
|
} = props;
|
72
|
-
|
73
67
|
if (!query) {
|
74
68
|
console.error('NextAuthPage got no query.');
|
75
69
|
return null;
|
76
70
|
}
|
77
|
-
|
78
71
|
if (!providers || !providers.length) {
|
79
72
|
console.error('You need to provide at least one provider.');
|
80
73
|
return null;
|
81
74
|
}
|
82
|
-
|
83
75
|
const list = query[listKey];
|
84
76
|
const protectIdentities = true;
|
85
77
|
return NextAuth__default["default"]({
|
@@ -97,7 +89,6 @@ function NextAuthPage(props) {
|
|
97
89
|
profile
|
98
90
|
} = _ref;
|
99
91
|
let identity;
|
100
|
-
|
101
92
|
if (typeof user.id === 'string') {
|
102
93
|
identity = user.id;
|
103
94
|
} else if (typeof user.id === 'number') {
|
@@ -105,23 +96,20 @@ function NextAuthPage(props) {
|
|
105
96
|
} else {
|
106
97
|
identity = 0;
|
107
98
|
}
|
108
|
-
|
109
99
|
const userInput = resolver ? await resolver({
|
110
100
|
user,
|
111
101
|
account,
|
112
102
|
profile
|
113
103
|
}) : {};
|
114
|
-
const result = await validateNextAuth(identityField, identity, protectIdentities, list);
|
115
|
-
|
104
|
+
const result = await validateNextAuth(identityField, identity, protectIdentities, list);
|
105
|
+
// ID
|
116
106
|
const data = _objectSpread({
|
117
107
|
[identityField]: identity
|
118
108
|
}, userInput);
|
119
|
-
|
120
109
|
if (!result.success) {
|
121
110
|
if (!autoCreate) {
|
122
111
|
return false;
|
123
112
|
}
|
124
|
-
|
125
113
|
const createUser = await list.createOne({
|
126
114
|
data
|
127
115
|
}).then(returned => {
|
@@ -135,7 +123,6 @@ function NextAuthPage(props) {
|
|
135
123
|
});
|
136
124
|
return createUser.success;
|
137
125
|
}
|
138
|
-
|
139
126
|
const updateUser = await list.updateOne({
|
140
127
|
where: {
|
141
128
|
id: result.item.id
|
@@ -152,25 +139,20 @@ function NextAuthPage(props) {
|
|
152
139
|
});
|
153
140
|
return updateUser.success;
|
154
141
|
},
|
155
|
-
|
156
142
|
async redirect(_ref2) {
|
157
143
|
let {
|
158
144
|
url
|
159
145
|
} = _ref2;
|
160
146
|
return url;
|
161
147
|
},
|
162
|
-
|
163
148
|
async session(_ref3) {
|
164
149
|
let {
|
165
150
|
session,
|
166
151
|
token
|
167
152
|
} = _ref3;
|
168
153
|
let returnSession = session;
|
169
|
-
|
170
154
|
if (!token.itemId) {
|
171
|
-
return
|
172
|
-
expires: '0'
|
173
|
-
};
|
155
|
+
return session;
|
174
156
|
} else {
|
175
157
|
returnSession = _objectSpread(_objectSpread({}, session), {}, {
|
176
158
|
data: token.data,
|
@@ -179,19 +161,19 @@ function NextAuthPage(props) {
|
|
179
161
|
itemId: token.itemId
|
180
162
|
});
|
181
163
|
}
|
182
|
-
|
183
164
|
return returnSession;
|
184
165
|
},
|
185
|
-
|
186
166
|
async jwt(_ref4) {
|
187
167
|
let {
|
188
168
|
token
|
189
169
|
} = _ref4;
|
190
170
|
const identity = token.sub;
|
171
|
+
if (!identity) {
|
172
|
+
return token;
|
173
|
+
}
|
191
174
|
const result = await validateNextAuth(identityField, identity, protectIdentities, list);
|
192
|
-
|
193
175
|
if (!result.success) {
|
194
|
-
token.itemId =
|
176
|
+
token.itemId = undefined;
|
195
177
|
} else {
|
196
178
|
token.itemId = result.item.id;
|
197
179
|
const data = await query[listKey].findOne({
|
@@ -202,15 +184,12 @@ function NextAuthPage(props) {
|
|
202
184
|
});
|
203
185
|
token.data = data;
|
204
186
|
}
|
205
|
-
|
206
187
|
const returnToken = _objectSpread(_objectSpread({}, token), {}, {
|
207
188
|
subject: token.sub,
|
208
189
|
listKey
|
209
190
|
});
|
210
|
-
|
211
191
|
return returnToken;
|
212
192
|
}
|
213
|
-
|
214
193
|
}
|
215
194
|
});
|
216
195
|
}
|
@@ -6,21 +6,18 @@ async function findMatchingIdentity(identityField, identity, queryAPI) {
|
|
6
6
|
where: {
|
7
7
|
[identityField]: identity
|
8
8
|
}
|
9
|
-
});
|
10
|
-
|
9
|
+
});
|
10
|
+
// Identity failures with helpful errors
|
11
11
|
let code;
|
12
|
-
|
13
12
|
if (!item) {
|
14
13
|
code = 'IDENTITY_NOT_FOUND';
|
15
14
|
}
|
16
|
-
|
17
15
|
if (code) {
|
18
16
|
return {
|
19
17
|
success: false,
|
20
18
|
code
|
21
19
|
};
|
22
20
|
}
|
23
|
-
|
24
21
|
return {
|
25
22
|
success: true,
|
26
23
|
item
|
@@ -32,14 +29,12 @@ async function validateNextAuth(identityField, identity, protectIdentities, item
|
|
32
29
|
const {
|
33
30
|
item
|
34
31
|
} = match;
|
35
|
-
|
36
32
|
if (item) {
|
37
33
|
return {
|
38
34
|
success: true,
|
39
35
|
item
|
40
36
|
};
|
41
37
|
}
|
42
|
-
|
43
38
|
return {
|
44
39
|
success: false,
|
45
40
|
code: protectIdentities ? 'FAILURE' : 'SUBJECT_NOT_FOUND'
|
@@ -61,17 +56,14 @@ function NextAuthPage(props) {
|
|
61
56
|
sessionData,
|
62
57
|
sessionSecret
|
63
58
|
} = props;
|
64
|
-
|
65
59
|
if (!query) {
|
66
60
|
console.error('NextAuthPage got no query.');
|
67
61
|
return null;
|
68
62
|
}
|
69
|
-
|
70
63
|
if (!providers || !providers.length) {
|
71
64
|
console.error('You need to provide at least one provider.');
|
72
65
|
return null;
|
73
66
|
}
|
74
|
-
|
75
67
|
const list = query[listKey];
|
76
68
|
const protectIdentities = true;
|
77
69
|
return NextAuth({
|
@@ -89,7 +81,6 @@ function NextAuthPage(props) {
|
|
89
81
|
profile
|
90
82
|
} = _ref;
|
91
83
|
let identity;
|
92
|
-
|
93
84
|
if (typeof user.id === 'string') {
|
94
85
|
identity = user.id;
|
95
86
|
} else if (typeof user.id === 'number') {
|
@@ -97,23 +88,20 @@ function NextAuthPage(props) {
|
|
97
88
|
} else {
|
98
89
|
identity = 0;
|
99
90
|
}
|
100
|
-
|
101
91
|
const userInput = resolver ? await resolver({
|
102
92
|
user,
|
103
93
|
account,
|
104
94
|
profile
|
105
95
|
}) : {};
|
106
|
-
const result = await validateNextAuth(identityField, identity, protectIdentities, list);
|
107
|
-
|
96
|
+
const result = await validateNextAuth(identityField, identity, protectIdentities, list);
|
97
|
+
// ID
|
108
98
|
const data = _objectSpread({
|
109
99
|
[identityField]: identity
|
110
100
|
}, userInput);
|
111
|
-
|
112
101
|
if (!result.success) {
|
113
102
|
if (!autoCreate) {
|
114
103
|
return false;
|
115
104
|
}
|
116
|
-
|
117
105
|
const createUser = await list.createOne({
|
118
106
|
data
|
119
107
|
}).then(returned => {
|
@@ -127,7 +115,6 @@ function NextAuthPage(props) {
|
|
127
115
|
});
|
128
116
|
return createUser.success;
|
129
117
|
}
|
130
|
-
|
131
118
|
const updateUser = await list.updateOne({
|
132
119
|
where: {
|
133
120
|
id: result.item.id
|
@@ -144,25 +131,20 @@ function NextAuthPage(props) {
|
|
144
131
|
});
|
145
132
|
return updateUser.success;
|
146
133
|
},
|
147
|
-
|
148
134
|
async redirect(_ref2) {
|
149
135
|
let {
|
150
136
|
url
|
151
137
|
} = _ref2;
|
152
138
|
return url;
|
153
139
|
},
|
154
|
-
|
155
140
|
async session(_ref3) {
|
156
141
|
let {
|
157
142
|
session,
|
158
143
|
token
|
159
144
|
} = _ref3;
|
160
145
|
let returnSession = session;
|
161
|
-
|
162
146
|
if (!token.itemId) {
|
163
|
-
return
|
164
|
-
expires: '0'
|
165
|
-
};
|
147
|
+
return session;
|
166
148
|
} else {
|
167
149
|
returnSession = _objectSpread(_objectSpread({}, session), {}, {
|
168
150
|
data: token.data,
|
@@ -171,19 +153,19 @@ function NextAuthPage(props) {
|
|
171
153
|
itemId: token.itemId
|
172
154
|
});
|
173
155
|
}
|
174
|
-
|
175
156
|
return returnSession;
|
176
157
|
},
|
177
|
-
|
178
158
|
async jwt(_ref4) {
|
179
159
|
let {
|
180
160
|
token
|
181
161
|
} = _ref4;
|
182
162
|
const identity = token.sub;
|
163
|
+
if (!identity) {
|
164
|
+
return token;
|
165
|
+
}
|
183
166
|
const result = await validateNextAuth(identityField, identity, protectIdentities, list);
|
184
|
-
|
185
167
|
if (!result.success) {
|
186
|
-
token.itemId =
|
168
|
+
token.itemId = undefined;
|
187
169
|
} else {
|
188
170
|
token.itemId = result.item.id;
|
189
171
|
const data = await query[listKey].findOne({
|
@@ -194,15 +176,12 @@ function NextAuthPage(props) {
|
|
194
176
|
});
|
195
177
|
token.data = data;
|
196
178
|
}
|
197
|
-
|
198
179
|
const returnToken = _objectSpread(_objectSpread({}, token), {}, {
|
199
180
|
subject: token.sub,
|
200
181
|
listKey
|
201
182
|
});
|
202
|
-
|
203
183
|
return returnToken;
|
204
184
|
}
|
205
|
-
|
206
185
|
}
|
207
186
|
});
|
208
187
|
}
|
package/src/index.ts
CHANGED
@@ -3,18 +3,20 @@ import {
|
|
3
3
|
AdminFileToWrite,
|
4
4
|
BaseListTypeInfo,
|
5
5
|
KeystoneConfig,
|
6
|
-
KeystoneContext,
|
7
6
|
AdminUIConfig,
|
8
7
|
BaseKeystoneTypeInfo,
|
9
8
|
SessionStrategy,
|
9
|
+
KeystoneContext,
|
10
10
|
} from '@keystone-6/core/types';
|
11
|
+
import type { NextApiRequest } from 'next';
|
12
|
+
|
11
13
|
import { getSession } from 'next-auth/react';
|
12
14
|
import { getToken } from 'next-auth/jwt';
|
13
15
|
import { Provider } from 'next-auth/providers';
|
14
16
|
|
15
17
|
import * as cookie from 'cookie';
|
16
|
-
|
17
|
-
import {
|
18
|
+
import { JWT } from 'next-auth/jwt';
|
19
|
+
import { Session } from 'next-auth';
|
18
20
|
import { nextConfigTemplate } from './templates/next-config';
|
19
21
|
// import * as Path from 'path';
|
20
22
|
|
@@ -57,34 +59,19 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
57
59
|
* - to the init page when initFirstItem is configured, and there are no user in the database
|
58
60
|
* - to the signin page when no valid session is present
|
59
61
|
*/
|
60
|
-
const
|
62
|
+
const authMiddleware: AdminUIConfig<BaseKeystoneTypeInfo>['pageMiddleware'] = async ({
|
61
63
|
context,
|
62
|
-
|
64
|
+
wasAccessAllowed,
|
63
65
|
}) => {
|
64
66
|
const { req, session } = context;
|
65
67
|
const pathname = url.parse(req?.url!).pathname!;
|
66
68
|
|
67
|
-
if (
|
68
|
-
if (
|
69
|
-
pathname === `${customPath}/api/auth/signin` ||
|
70
|
-
(pages?.signIn && pathname.includes(pages?.signIn))
|
71
|
-
) {
|
72
|
-
return { kind: 'redirect', to: `${customPath}` };
|
73
|
-
}
|
69
|
+
if (wasAccessAllowed) {
|
74
70
|
if (customPath !== '' && pathname === '/') {
|
75
71
|
return { kind: 'redirect', to: `${customPath}` };
|
76
72
|
}
|
77
73
|
return;
|
78
74
|
}
|
79
|
-
if (
|
80
|
-
pathname.includes('/_next/') ||
|
81
|
-
pathname.includes('/api/auth/') ||
|
82
|
-
(pages?.signIn && pathname.includes(pages?.signIn)) ||
|
83
|
-
(pages?.error && pathname.includes(pages?.error)) ||
|
84
|
-
(pages?.signOut && pathname.includes(pages?.signOut))
|
85
|
-
) {
|
86
|
-
return;
|
87
|
-
}
|
88
75
|
if (!session && !pathname.includes(`${customPath}/api/auth/`)) {
|
89
76
|
return {
|
90
77
|
kind: 'redirect',
|
@@ -94,14 +81,14 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
94
81
|
};
|
95
82
|
|
96
83
|
/**
|
97
|
-
*
|
84
|
+
* authGetAdditionalFiles
|
98
85
|
*
|
99
86
|
* This function adds files to be generated into the Admin UI build. Must be added to the
|
100
87
|
* ui.getAdditionalFiles config.
|
101
88
|
*
|
102
89
|
* The signin page is always included, and the init page is included when initFirstItem is set
|
103
90
|
*/
|
104
|
-
const
|
91
|
+
const authGetAdditionalFiles = () => {
|
105
92
|
const filesToWrite: AdminFileToWrite[] = [
|
106
93
|
{
|
107
94
|
mode: 'write',
|
@@ -128,8 +115,7 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
128
115
|
*
|
129
116
|
* Must be added to the ui.publicPages config
|
130
117
|
*/
|
131
|
-
const
|
132
|
-
`${customPath}/api/__keystone_api_build`,
|
118
|
+
const authPublicPages = [
|
133
119
|
`${customPath}/api/auth/csrf`,
|
134
120
|
`${customPath}/api/auth/signin`,
|
135
121
|
`${customPath}/api/auth/callback`,
|
@@ -142,8 +128,8 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
142
128
|
// @ts-ignore
|
143
129
|
function addPages(provider: Provider) {
|
144
130
|
const name = provider.id;
|
145
|
-
|
146
|
-
|
131
|
+
authPublicPages.push(`${customPath}/api/auth/signin/${name}`);
|
132
|
+
authPublicPages.push(`${customPath}/api/auth/callback/${name}`);
|
147
133
|
}
|
148
134
|
providers.map(addPages);
|
149
135
|
|
@@ -197,17 +183,19 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
197
183
|
const { get, end, ...sessionStrategy } = _sessionStrategy;
|
198
184
|
return {
|
199
185
|
...sessionStrategy,
|
200
|
-
get: async ({
|
186
|
+
get: async ({ context }) => {
|
187
|
+
const { req } = context;
|
201
188
|
const pathname = url.parse(req?.url!).pathname!;
|
202
189
|
let nextSession: Session | JWT | null;
|
190
|
+
if (!req) return;
|
203
191
|
if (pathname.includes('/api/auth')) {
|
204
192
|
return;
|
205
193
|
}
|
206
|
-
const sudoContext =
|
194
|
+
const sudoContext = context.sudo();
|
207
195
|
|
208
196
|
if (req.headers?.authorization?.split(' ')[0] === 'Bearer') {
|
209
197
|
nextSession = await getToken({
|
210
|
-
req,
|
198
|
+
req: req as NextApiRequest,
|
211
199
|
secret: sessionSecret,
|
212
200
|
});
|
213
201
|
} else {
|
@@ -231,7 +219,7 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
231
219
|
data: nextSession.data,
|
232
220
|
};
|
233
221
|
|
234
|
-
const userSession = await get({
|
222
|
+
const userSession = await get({ context });
|
235
223
|
|
236
224
|
return {
|
237
225
|
...userSession,
|
@@ -241,12 +229,14 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
241
229
|
itemId: nextSession.itemId,
|
242
230
|
};
|
243
231
|
},
|
244
|
-
end: async ({
|
245
|
-
await end({
|
232
|
+
end: async ({ context }) => {
|
233
|
+
await end({ context });
|
246
234
|
const TOKEN_NAME =
|
247
235
|
process.env.NODE_ENV === 'production'
|
248
236
|
? '__Secure-next-auth.session-token'
|
249
237
|
: 'next-auth.session-token';
|
238
|
+
const { req, res } = context;
|
239
|
+
if (!req || !res) return;
|
250
240
|
res.setHeader(
|
251
241
|
'Set-Cookie',
|
252
242
|
cookie.serialize(TOKEN_NAME, '', {
|
@@ -264,6 +254,9 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
264
254
|
};
|
265
255
|
};
|
266
256
|
|
257
|
+
function defaultIsAccessAllowed({ session }: KeystoneContext) {
|
258
|
+
return session !== undefined;
|
259
|
+
}
|
267
260
|
/**
|
268
261
|
* withAuth
|
269
262
|
*
|
@@ -277,35 +270,35 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
|
|
277
270
|
const withAuth = (keystoneConfig: KeystoneConfig): KeystoneOAuthConfig => {
|
278
271
|
validateConfig(keystoneConfig);
|
279
272
|
let { ui } = keystoneConfig;
|
280
|
-
if (
|
273
|
+
if (!ui?.isDisabled) {
|
274
|
+
const {
|
275
|
+
getAdditionalFiles = [],
|
276
|
+
isAccessAllowed = defaultIsAccessAllowed,
|
277
|
+
pageMiddleware,
|
278
|
+
publicPages = [],
|
279
|
+
} = ui || {};
|
281
280
|
ui = {
|
282
|
-
...
|
283
|
-
publicPages: [...
|
284
|
-
getAdditionalFiles: [...(keystoneConfig.ui?.getAdditionalFiles || []), getAdditionalFiles],
|
285
|
-
pageMiddleware: async args =>
|
286
|
-
(await pageMiddleware(args)) ?? keystoneConfig?.ui?.pageMiddleware?.(args),
|
281
|
+
...ui,
|
282
|
+
publicPages: [...publicPages, ...authPublicPages],
|
287
283
|
isAccessAllowed: async (context: KeystoneContext) => {
|
288
|
-
const
|
289
|
-
const pathname = url.parse(req?.url!).pathname!;
|
290
|
-
|
291
|
-
// Allow nextjs scripts and static files to be accessed without auth
|
292
|
-
if (pathname.includes('/_next/')) {
|
293
|
-
return true;
|
294
|
-
}
|
295
|
-
|
296
|
-
// Allow keystone to access /api/__keystone_api_build for hot reloading
|
284
|
+
const pathname = url.parse(context.req?.url!).pathname!;
|
297
285
|
if (
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
286
|
+
pathname.startsWith(`${customPath}/_next`) ||
|
287
|
+
pathname.startsWith(`${customPath}/__next`) ||
|
288
|
+
pathname.startsWith(`${customPath}/api/auth/`) ||
|
289
|
+
(pages?.signIn && pathname.includes(pages?.signIn)) ||
|
290
|
+
(pages?.error && pathname.includes(pages?.error)) ||
|
291
|
+
(pages?.signOut && pathname.includes(pages?.signOut))
|
302
292
|
) {
|
303
293
|
return true;
|
304
294
|
}
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
295
|
+
return await isAccessAllowed(context);
|
296
|
+
},
|
297
|
+
getAdditionalFiles: [...getAdditionalFiles, authGetAdditionalFiles],
|
298
|
+
pageMiddleware: async args => {
|
299
|
+
const shouldRedirect = await authMiddleware(args);
|
300
|
+
if (shouldRedirect) return shouldRedirect;
|
301
|
+
return pageMiddleware?.(args);
|
309
302
|
},
|
310
303
|
};
|
311
304
|
}
|
@@ -116,25 +116,28 @@ export default function NextAuthPage(props: NextAuthPageProps) {
|
|
116
116
|
async session({ session, token }) {
|
117
117
|
let returnSession = session;
|
118
118
|
if (!token.itemId) {
|
119
|
-
return
|
119
|
+
return session;
|
120
120
|
} else {
|
121
121
|
returnSession = {
|
122
122
|
...session,
|
123
123
|
data: token.data,
|
124
124
|
subject: token.sub,
|
125
|
-
listKey: token.listKey
|
126
|
-
itemId: token.itemId
|
125
|
+
listKey: token.listKey,
|
126
|
+
itemId: token.itemId,
|
127
127
|
};
|
128
128
|
}
|
129
129
|
|
130
130
|
return returnSession;
|
131
131
|
},
|
132
132
|
async jwt({ token }) {
|
133
|
-
const identity = token.sub
|
133
|
+
const identity = token.sub;
|
134
|
+
if (!identity) {
|
135
|
+
return token;
|
136
|
+
}
|
134
137
|
const result = await validateNextAuth(identityField, identity, protectIdentities, list);
|
135
138
|
|
136
139
|
if (!result.success) {
|
137
|
-
token.itemId =
|
140
|
+
token.itemId = undefined;
|
138
141
|
} else {
|
139
142
|
token.itemId = result.item.id;
|
140
143
|
const data = await query[listKey].findOne({
|
@@ -1,61 +1,12 @@
|
|
1
1
|
import ejs from 'ejs';
|
2
2
|
|
3
3
|
const template = `
|
4
|
-
const
|
5
|
-
// @ts-ignore
|
6
|
-
const withPreconstruct = require('@preconstruct/next');
|
4
|
+
const keystoneConfig = require('@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/next-config').config;
|
7
5
|
|
8
|
-
module.exports =
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
env: {
|
13
|
-
NEXTAUTH_URL: process.env.NEXTAUTH_URL || 'http://localhost:<%= process.env.PORT || 3000 %><%= keystonePath || '' %>/api/auth',
|
14
|
-
},
|
15
|
-
eslint: {
|
16
|
-
ignoreDuringBuilds: true,
|
17
|
-
},
|
18
|
-
webpack(config, { isServer }) {
|
19
|
-
config.resolve.alias = {
|
20
|
-
...config.resolve.alias,
|
21
|
-
react: Path.dirname(require.resolve('react/package.json')),
|
22
|
-
'react-dom': Path.dirname(require.resolve('react-dom/package.json')),
|
23
|
-
'@keystone-6/core': Path.dirname(
|
24
|
-
require.resolve('@keystone-6/core/package.json')
|
25
|
-
),
|
26
|
-
};
|
27
|
-
if (isServer) {
|
28
|
-
config.externals = [
|
29
|
-
...config.externals,
|
30
|
-
/@keystone-6\\/core(?!\\/___internal-do-not-use-will-break-in-patch\\/admin-ui\\/id-field-view|\\/fields\\/types\\/[^\\/]+\\/views)/,
|
31
|
-
/.prisma\\/client/
|
32
|
-
];
|
33
|
-
// we need to set these to true so that when __dirname/__filename is used
|
34
|
-
// to resolve the location of field views, we will get a path that we can use
|
35
|
-
// rather than just the __dirname/__filename of the generated file.
|
36
|
-
// https://webpack.js.org/configuration/node/#node__filename
|
37
|
-
(_config$node = config.node) !== null && _config$node !== void 0 ? _config$node : config.node = {};
|
38
|
-
config.node.__dirname = true;
|
39
|
-
config.node.__filename = true;
|
40
|
-
}
|
41
|
-
return config;
|
42
|
-
},
|
43
|
-
<% if (keystonePath) { %>
|
44
|
-
<% if (process.env.NODE_ENV != 'production') { %>
|
45
|
-
async rewrites() {
|
46
|
-
return [
|
47
|
-
{
|
48
|
-
source: '/api/__keystone_api_build',
|
49
|
-
destination: 'http://localhost:<%= process.env.PORT || 3000 %><%= keystonePath || '' %>/api/__keystone_api_build',
|
50
|
-
basePath: false
|
51
|
-
}
|
52
|
-
];
|
53
|
-
},
|
54
|
-
<% }%>
|
55
|
-
basePath: '<%= keystonePath || '' %>'
|
56
|
-
<% } %>
|
57
|
-
});
|
58
|
-
`;
|
6
|
+
module.exports = {
|
7
|
+
...keystoneConfig,
|
8
|
+
basePath: '<%= keystonePath || '' %>'
|
9
|
+
};`;
|
59
10
|
export const nextConfigTemplate = ({ keystonePath }: { keystonePath: string }) => {
|
60
11
|
const nextConfigOut = ejs.render(template, { keystonePath });
|
61
12
|
|
package/src/types/index.ts
CHANGED
@@ -1,26 +1,11 @@
|
|
1
|
-
import type { ServerResponse, IncomingMessage } from 'http';
|
2
|
-
import type { NextRequest } from 'next/server';
|
3
1
|
import { Provider } from 'next-auth/providers';
|
4
2
|
import { CookiesOptions, PagesOptions } from 'next-auth';
|
5
|
-
import { BaseListTypeInfo, KeystoneConfig,
|
6
|
-
|
7
|
-
type NextAuthResponse = IncomingMessage & NextRequest;
|
3
|
+
import { BaseListTypeInfo, KeystoneConfig, KeystoneContext } from '@keystone-6/core/types';
|
8
4
|
|
9
5
|
export declare type AuthSessionStrategy<StoredSessionData> = {
|
10
|
-
start: (args: {
|
11
|
-
|
12
|
-
|
13
|
-
createContext: CreateContext;
|
14
|
-
}) => Promise<string>;
|
15
|
-
end: (args: {
|
16
|
-
req: IncomingMessage;
|
17
|
-
res: ServerResponse;
|
18
|
-
createContext: CreateContext;
|
19
|
-
}) => Promise<void>;
|
20
|
-
get: (args: {
|
21
|
-
req: NextAuthResponse;
|
22
|
-
createContext: CreateContext;
|
23
|
-
}) => Promise<StoredSessionData | undefined>;
|
6
|
+
start: (args: { data: any; context: KeystoneContext }) => Promise<unknown>;
|
7
|
+
end: (args: { context: KeystoneContext }) => Promise<unknown>;
|
8
|
+
get: (args: { context: KeystoneContext }) => Promise<StoredSessionData | undefined>;
|
24
9
|
};
|
25
10
|
|
26
11
|
export type NextAuthProviders = Provider[];
|