@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
@@ -3,7 +3,7 @@ import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutPr
|
|
3
3
|
import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes';
|
4
4
|
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
|
5
5
|
import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringify';
|
6
|
-
import
|
6
|
+
import _startsWithInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/starts-with';
|
7
7
|
import url from 'url';
|
8
8
|
import { getSession } from 'next-auth/react';
|
9
9
|
import { getToken } from 'next-auth/jwt';
|
@@ -13,61 +13,12 @@ import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/insta
|
|
13
13
|
import { graphql } from '@keystone-6/core';
|
14
14
|
|
15
15
|
const template$1 = `
|
16
|
-
const
|
17
|
-
// @ts-ignore
|
18
|
-
const withPreconstruct = require('@preconstruct/next');
|
16
|
+
const keystoneConfig = require('@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/next-config').config;
|
19
17
|
|
20
|
-
module.exports =
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
env: {
|
25
|
-
NEXTAUTH_URL: process.env.NEXTAUTH_URL || 'http://localhost:<%= process.env.PORT || 3000 %><%= keystonePath || '' %>/api/auth',
|
26
|
-
},
|
27
|
-
eslint: {
|
28
|
-
ignoreDuringBuilds: true,
|
29
|
-
},
|
30
|
-
webpack(config, { isServer }) {
|
31
|
-
config.resolve.alias = {
|
32
|
-
...config.resolve.alias,
|
33
|
-
react: Path.dirname(require.resolve('react/package.json')),
|
34
|
-
'react-dom': Path.dirname(require.resolve('react-dom/package.json')),
|
35
|
-
'@keystone-6/core': Path.dirname(
|
36
|
-
require.resolve('@keystone-6/core/package.json')
|
37
|
-
),
|
38
|
-
};
|
39
|
-
if (isServer) {
|
40
|
-
config.externals = [
|
41
|
-
...config.externals,
|
42
|
-
/@keystone-6\\/core(?!\\/___internal-do-not-use-will-break-in-patch\\/admin-ui\\/id-field-view|\\/fields\\/types\\/[^\\/]+\\/views)/,
|
43
|
-
/.prisma\\/client/
|
44
|
-
];
|
45
|
-
// we need to set these to true so that when __dirname/__filename is used
|
46
|
-
// to resolve the location of field views, we will get a path that we can use
|
47
|
-
// rather than just the __dirname/__filename of the generated file.
|
48
|
-
// https://webpack.js.org/configuration/node/#node__filename
|
49
|
-
(_config$node = config.node) !== null && _config$node !== void 0 ? _config$node : config.node = {};
|
50
|
-
config.node.__dirname = true;
|
51
|
-
config.node.__filename = true;
|
52
|
-
}
|
53
|
-
return config;
|
54
|
-
},
|
55
|
-
<% if (keystonePath) { %>
|
56
|
-
<% if (process.env.NODE_ENV != 'production') { %>
|
57
|
-
async rewrites() {
|
58
|
-
return [
|
59
|
-
{
|
60
|
-
source: '/api/__keystone_api_build',
|
61
|
-
destination: 'http://localhost:<%= process.env.PORT || 3000 %><%= keystonePath || '' %>/api/__keystone_api_build',
|
62
|
-
basePath: false
|
63
|
-
}
|
64
|
-
];
|
65
|
-
},
|
66
|
-
<% }%>
|
67
|
-
basePath: '<%= keystonePath || '' %>'
|
68
|
-
<% } %>
|
69
|
-
});
|
70
|
-
`;
|
18
|
+
module.exports = {
|
19
|
+
...keystoneConfig,
|
20
|
+
basePath: '<%= keystonePath || '' %>'
|
21
|
+
};`;
|
71
22
|
const nextConfigTemplate = _ref => {
|
72
23
|
let {
|
73
24
|
keystonePath
|
@@ -91,17 +42,14 @@ function getBaseAuthSchema(_ref) {
|
|
91
42
|
types: [base.object(listKey)],
|
92
43
|
resolveType: (root, context) => {
|
93
44
|
var _context$session;
|
94
|
-
|
95
45
|
return (_context$session = context.session) === null || _context$session === void 0 ? void 0 : _context$session.listKey;
|
96
46
|
}
|
97
47
|
}),
|
98
|
-
|
99
48
|
resolve(root, args, _ref2) {
|
100
49
|
let {
|
101
50
|
session,
|
102
51
|
db
|
103
52
|
} = _ref2;
|
104
|
-
|
105
53
|
if (typeof (session === null || session === void 0 ? void 0 : session.itemId) === 'string' && typeof session.listKey === 'string') {
|
106
54
|
return db[session.listKey].findOne({
|
107
55
|
where: {
|
@@ -109,10 +57,8 @@ function getBaseAuthSchema(_ref) {
|
|
109
57
|
}
|
110
58
|
});
|
111
59
|
}
|
112
|
-
|
113
60
|
return null;
|
114
61
|
}
|
115
|
-
|
116
62
|
})
|
117
63
|
}
|
118
64
|
};
|
@@ -127,7 +73,6 @@ const getSchemaExtension = _ref => {
|
|
127
73
|
} = _ref;
|
128
74
|
return graphql.extend(base => {
|
129
75
|
var _context;
|
130
|
-
|
131
76
|
const baseSchema = getBaseAuthSchema({
|
132
77
|
listKey,
|
133
78
|
base
|
@@ -177,6 +122,7 @@ const authTemplate = _ref => {
|
|
177
122
|
};
|
178
123
|
|
179
124
|
const _excluded = ["get", "end"];
|
125
|
+
|
180
126
|
/**
|
181
127
|
* createAuth function
|
182
128
|
*
|
@@ -200,6 +146,7 @@ function createAuth(_ref) {
|
|
200
146
|
// part of the createAuth API (in which case its use cases need to be documented and tested)
|
201
147
|
// or whether always being true is what we want, in which case we can refactor our code
|
202
148
|
// to match this. -TL
|
149
|
+
|
203
150
|
const customPath = !keystonePath || keystonePath === '/' ? '' : keystonePath;
|
204
151
|
/**
|
205
152
|
* pageMiddleware
|
@@ -211,40 +158,25 @@ function createAuth(_ref) {
|
|
211
158
|
* - to the init page when initFirstItem is configured, and there are no user in the database
|
212
159
|
* - to the signin page when no valid session is present
|
213
160
|
*/
|
214
|
-
|
215
|
-
const pageMiddleware = async _ref2 => {
|
161
|
+
const authMiddleware = async _ref2 => {
|
216
162
|
let {
|
217
163
|
context,
|
218
|
-
|
164
|
+
wasAccessAllowed
|
219
165
|
} = _ref2;
|
220
166
|
const {
|
221
167
|
req,
|
222
168
|
session
|
223
169
|
} = context;
|
224
170
|
const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
225
|
-
|
226
|
-
if (isValidSession) {
|
227
|
-
if (pathname === `${customPath}/api/auth/signin` || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn)) {
|
228
|
-
return {
|
229
|
-
kind: 'redirect',
|
230
|
-
to: `${customPath}`
|
231
|
-
};
|
232
|
-
}
|
233
|
-
|
171
|
+
if (wasAccessAllowed) {
|
234
172
|
if (customPath !== '' && pathname === '/') {
|
235
173
|
return {
|
236
174
|
kind: 'redirect',
|
237
175
|
to: `${customPath}`
|
238
176
|
};
|
239
177
|
}
|
240
|
-
|
241
178
|
return;
|
242
179
|
}
|
243
|
-
|
244
|
-
if (_includesInstanceProperty(pathname).call(pathname, '/_next/') || _includesInstanceProperty(pathname).call(pathname, '/api/auth/') || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn) || pages !== null && pages !== void 0 && pages.error && _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.error) || pages !== null && pages !== void 0 && pages.signOut && _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signOut)) {
|
245
|
-
return;
|
246
|
-
}
|
247
|
-
|
248
180
|
if (!session && !_includesInstanceProperty(pathname).call(pathname, `${customPath}/api/auth/`)) {
|
249
181
|
return {
|
250
182
|
kind: 'redirect',
|
@@ -252,17 +184,16 @@ function createAuth(_ref) {
|
|
252
184
|
};
|
253
185
|
}
|
254
186
|
};
|
187
|
+
|
255
188
|
/**
|
256
|
-
*
|
189
|
+
* authGetAdditionalFiles
|
257
190
|
*
|
258
191
|
* This function adds files to be generated into the Admin UI build. Must be added to the
|
259
192
|
* ui.getAdditionalFiles config.
|
260
193
|
*
|
261
194
|
* The signin page is always included, and the init page is included when initFirstItem is set
|
262
195
|
*/
|
263
|
-
|
264
|
-
|
265
|
-
const getAdditionalFiles = () => {
|
196
|
+
const authGetAdditionalFiles = () => {
|
266
197
|
const filesToWrite = [{
|
267
198
|
mode: 'write',
|
268
199
|
outputPath: 'pages/api/auth/[...nextauth].js',
|
@@ -282,102 +213,91 @@ function createAuth(_ref) {
|
|
282
213
|
}];
|
283
214
|
return filesToWrite;
|
284
215
|
};
|
216
|
+
|
285
217
|
/**
|
286
218
|
* publicAuthPages
|
287
219
|
*
|
288
220
|
* Must be added to the ui.publicPages config
|
289
221
|
*/
|
290
|
-
|
291
|
-
|
292
|
-
const publicPages = [`${customPath}/api/__keystone_api_build`, `${customPath}/api/auth/csrf`, `${customPath}/api/auth/signin`, `${customPath}/api/auth/callback`, `${customPath}/api/auth/session`, `${customPath}/api/auth/providers`, `${customPath}/api/auth/signout`, `${customPath}/api/auth/error`]; // TODO: Add Provider Types
|
222
|
+
const authPublicPages = [`${customPath}/api/auth/csrf`, `${customPath}/api/auth/signin`, `${customPath}/api/auth/callback`, `${customPath}/api/auth/session`, `${customPath}/api/auth/providers`, `${customPath}/api/auth/signout`, `${customPath}/api/auth/error`];
|
223
|
+
// TODO: Add Provider Types
|
293
224
|
// @ts-ignore
|
294
|
-
|
295
225
|
function addPages(provider) {
|
296
226
|
const name = provider.id;
|
297
|
-
|
298
|
-
|
227
|
+
authPublicPages.push(`${customPath}/api/auth/signin/${name}`);
|
228
|
+
authPublicPages.push(`${customPath}/api/auth/callback/${name}`);
|
299
229
|
}
|
300
|
-
|
301
230
|
_mapInstanceProperty(providers).call(providers, addPages);
|
231
|
+
|
302
232
|
/**
|
303
233
|
* extendGraphqlSchema
|
304
234
|
*
|
305
235
|
* Must be added to the extendGraphqlSchema config. Can be composed.
|
306
236
|
*/
|
307
|
-
|
308
|
-
|
309
237
|
const extendGraphqlSchema = getSchemaExtension({
|
310
238
|
identityField,
|
311
239
|
listKey
|
312
240
|
});
|
241
|
+
|
313
242
|
/**
|
314
243
|
* validateConfig
|
315
244
|
*
|
316
245
|
* Validates the provided auth config; optional step when integrating auth
|
317
246
|
*/
|
318
|
-
|
319
247
|
const validateConfig = keystoneConfig => {
|
320
248
|
const listConfig = keystoneConfig.lists[listKey];
|
321
|
-
|
322
249
|
if (listConfig === undefined) {
|
323
250
|
const msg = `A createAuth() invocation specifies the list "${listKey}" but no list with that key has been defined.`;
|
324
251
|
throw new Error(msg);
|
325
|
-
}
|
252
|
+
}
|
253
|
+
|
254
|
+
// TODO: Check if providers
|
326
255
|
// TODO: Check other required commands/data
|
256
|
+
|
327
257
|
// TODO: Check for String-like typing for identityField? How?
|
328
258
|
// TODO: Validate that the identifyField is unique.
|
329
259
|
// TODO: If this field isn't required, what happens if I try to log in as `null`?
|
330
|
-
|
331
|
-
|
332
260
|
const identityFieldConfig = listConfig.fields[identityField];
|
333
|
-
|
334
261
|
if (identityFieldConfig === undefined) {
|
335
262
|
const identityFieldName = _JSON$stringify(identityField);
|
336
|
-
|
337
263
|
const msg = `A createAuth() invocation for the "${listKey}" list specifies ${identityFieldName} as its identityField but no field with that key exists on the list.`;
|
338
264
|
throw new Error(msg);
|
339
265
|
}
|
340
266
|
};
|
267
|
+
|
341
268
|
/**
|
342
269
|
* withItemData
|
343
270
|
*
|
344
271
|
* Automatically injects a session.data value with the authenticated item
|
345
272
|
*/
|
346
|
-
|
347
273
|
/* TODO:
|
348
274
|
- [ ] We could support additional where input to validate item sessions (e.g an isEnabled boolean)
|
349
275
|
*/
|
350
|
-
|
351
|
-
|
352
276
|
const withItemData = _sessionStrategy => {
|
353
277
|
const {
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
278
|
+
get,
|
279
|
+
end
|
280
|
+
} = _sessionStrategy,
|
281
|
+
sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
|
359
282
|
return _objectSpread(_objectSpread({}, sessionStrategy), {}, {
|
360
283
|
get: async _ref3 => {
|
361
284
|
var _req$headers, _req$headers$authoriz;
|
362
|
-
|
363
285
|
let {
|
364
|
-
|
365
|
-
createContext
|
286
|
+
context
|
366
287
|
} = _ref3;
|
288
|
+
const {
|
289
|
+
req
|
290
|
+
} = context;
|
367
291
|
const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
368
292
|
let nextSession;
|
369
|
-
|
293
|
+
if (!req) return;
|
370
294
|
if (_includesInstanceProperty(pathname).call(pathname, '/api/auth')) {
|
371
295
|
return;
|
372
296
|
}
|
373
|
-
|
374
|
-
const sudoContext = createContext({
|
375
|
-
sudo: true
|
376
|
-
});
|
377
|
-
|
297
|
+
const sudoContext = context.sudo();
|
378
298
|
if (((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : (_req$headers$authoriz = _req$headers.authorization) === null || _req$headers$authoriz === void 0 ? void 0 : _req$headers$authoriz.split(' ')[0]) === 'Bearer') {
|
379
299
|
nextSession = await getToken({
|
380
|
-
req,
|
300
|
+
req: req,
|
381
301
|
secret: sessionSecret
|
382
302
|
});
|
383
303
|
} else {
|
@@ -385,11 +305,9 @@ function createAuth(_ref) {
|
|
385
305
|
req
|
386
306
|
});
|
387
307
|
}
|
388
|
-
|
389
308
|
if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
|
390
309
|
return;
|
391
310
|
}
|
392
|
-
|
393
311
|
const reqWithUser = req;
|
394
312
|
reqWithUser.user = {
|
395
313
|
istKey: nextSession.listKey,
|
@@ -397,8 +315,7 @@ function createAuth(_ref) {
|
|
397
315
|
data: nextSession.data
|
398
316
|
};
|
399
317
|
const userSession = await get({
|
400
|
-
|
401
|
-
createContext
|
318
|
+
context
|
402
319
|
});
|
403
320
|
return _objectSpread(_objectSpread(_objectSpread({}, userSession), nextSession), {}, {
|
404
321
|
data: nextSession.data,
|
@@ -408,16 +325,17 @@ function createAuth(_ref) {
|
|
408
325
|
},
|
409
326
|
end: async _ref4 => {
|
410
327
|
let {
|
411
|
-
|
412
|
-
req,
|
413
|
-
createContext
|
328
|
+
context
|
414
329
|
} = _ref4;
|
415
330
|
await end({
|
416
|
-
|
417
|
-
req,
|
418
|
-
createContext
|
331
|
+
context
|
419
332
|
});
|
420
333
|
const TOKEN_NAME = process.env.NODE_ENV === 'production' ? '__Secure-next-auth.session-token' : 'next-auth.session-token';
|
334
|
+
const {
|
335
|
+
req,
|
336
|
+
res
|
337
|
+
} = context;
|
338
|
+
if (!req || !res) return;
|
421
339
|
res.setHeader('Set-Cookie', cookie.serialize(TOKEN_NAME, '', {
|
422
340
|
maxAge: 0,
|
423
341
|
expires: new Date(),
|
@@ -431,6 +349,12 @@ function createAuth(_ref) {
|
|
431
349
|
}
|
432
350
|
});
|
433
351
|
};
|
352
|
+
function defaultIsAccessAllowed(_ref5) {
|
353
|
+
let {
|
354
|
+
session
|
355
|
+
} = _ref5;
|
356
|
+
return session !== undefined;
|
357
|
+
}
|
434
358
|
/**
|
435
359
|
* withAuth
|
436
360
|
*
|
@@ -441,47 +365,37 @@ function createAuth(_ref) {
|
|
441
365
|
* It validates the auth config against the provided keystone config, and preserves existing
|
442
366
|
* config by composing existing extendGraphqlSchema functions and ui config.
|
443
367
|
*/
|
444
|
-
|
445
|
-
|
446
368
|
const withAuth = keystoneConfig => {
|
369
|
+
var _ui;
|
447
370
|
validateConfig(keystoneConfig);
|
448
371
|
let {
|
449
372
|
ui
|
450
373
|
} = keystoneConfig;
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
publicPages
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
return (await pageMiddleware(args)) ?? (keystoneConfig === null || keystoneConfig === void 0 ? void 0 : (_keystoneConfig$ui2 = keystoneConfig.ui) === null || _keystoneConfig$ui2 === void 0 ? void 0 : (_keystoneConfig$ui2$p = _keystoneConfig$ui2.pageMiddleware) === null || _keystoneConfig$ui2$p === void 0 ? void 0 : _keystoneConfig$ui2$p.call(_keystoneConfig$ui2, args));
|
462
|
-
},
|
374
|
+
if (!((_ui = ui) !== null && _ui !== void 0 && _ui.isDisabled)) {
|
375
|
+
const {
|
376
|
+
getAdditionalFiles = [],
|
377
|
+
isAccessAllowed = defaultIsAccessAllowed,
|
378
|
+
pageMiddleware,
|
379
|
+
publicPages = []
|
380
|
+
} = ui || {};
|
381
|
+
ui = _objectSpread(_objectSpread({}, ui), {}, {
|
382
|
+
publicPages: [...publicPages, ...authPublicPages],
|
463
383
|
isAccessAllowed: async context => {
|
464
|
-
var _context$req
|
465
|
-
|
466
|
-
|
467
|
-
req
|
468
|
-
} = context;
|
469
|
-
const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname; // Allow nextjs scripts and static files to be accessed without auth
|
470
|
-
|
471
|
-
if (_includesInstanceProperty(pathname).call(pathname, '/_next/')) {
|
472
|
-
return true;
|
473
|
-
} // Allow keystone to access /api/__keystone_api_build for hot reloading
|
474
|
-
|
475
|
-
|
476
|
-
if (process.env.NODE_ENV !== 'production' && ((_context$req = context.req) === null || _context$req === void 0 ? void 0 : _context$req.url) !== undefined && new _URL(context.req.url, 'http://example.com').pathname === `${customPath}/api/__keystone_api_build`) {
|
384
|
+
var _context$req;
|
385
|
+
const pathname = url.parse((_context$req = context.req) === null || _context$req === void 0 ? void 0 : _context$req.url).pathname;
|
386
|
+
if (_startsWithInstanceProperty(pathname).call(pathname, `${customPath}/_next`) || _startsWithInstanceProperty(pathname).call(pathname, `${customPath}/__next`) || _startsWithInstanceProperty(pathname).call(pathname, `${customPath}/api/auth/`) || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn) || pages !== null && pages !== void 0 && pages.error && _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.error) || pages !== null && pages !== void 0 && pages.signOut && _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signOut)) {
|
477
387
|
return true;
|
478
388
|
}
|
479
|
-
|
480
|
-
|
389
|
+
return await isAccessAllowed(context);
|
390
|
+
},
|
391
|
+
getAdditionalFiles: [...getAdditionalFiles, authGetAdditionalFiles],
|
392
|
+
pageMiddleware: async args => {
|
393
|
+
const shouldRedirect = await authMiddleware(args);
|
394
|
+
if (shouldRedirect) return shouldRedirect;
|
395
|
+
return pageMiddleware === null || pageMiddleware === void 0 ? void 0 : pageMiddleware(args);
|
481
396
|
}
|
482
397
|
});
|
483
398
|
}
|
484
|
-
|
485
399
|
if (!keystoneConfig.session) throw new TypeError('Missing .session configuration');
|
486
400
|
const session = withItemData(keystoneConfig.session);
|
487
401
|
const existingExtendGraphQLSchema = keystoneConfig.extendGraphqlSchema;
|
@@ -496,16 +410,15 @@ function createAuth(_ref) {
|
|
496
410
|
extendGraphqlSchema: existingExtendGraphQLSchema ? schema => existingExtendGraphQLSchema(extendGraphqlSchema(schema)) : extendGraphqlSchema
|
497
411
|
});
|
498
412
|
};
|
499
|
-
|
500
413
|
return {
|
501
|
-
withAuth
|
414
|
+
withAuth
|
415
|
+
// In the future we may want to return the following so that developers can
|
502
416
|
// roll their own. This is pending a review of the use cases this might be
|
503
417
|
// appropriate for, along with documentation and testing.
|
504
418
|
// ui: { enableSessionItem: true, pageMiddleware, getAdditionalFiles, publicPages },
|
505
419
|
// fields,
|
506
420
|
// extendGraphqlSchema,
|
507
421
|
// validateConfig,
|
508
|
-
|
509
422
|
};
|
510
423
|
}
|
511
424
|
|
package/package.json
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
{
|
2
2
|
"name": "@opensaas/keystone-nextjs-auth",
|
3
|
-
"version": "
|
3
|
+
"version": "27.0.0",
|
4
4
|
"repository": "https://github.com/opensaasau/keystone-nextjs-auth",
|
5
5
|
"license": "MIT",
|
6
6
|
"main": "dist/opensaas-keystone-nextjs-auth.cjs.js",
|
7
7
|
"module": "dist/opensaas-keystone-nextjs-auth.esm.js",
|
8
8
|
"dependencies": {
|
9
|
-
"@babel/runtime": "^7.
|
10
|
-
"@babel/runtime-corejs3": "^7.
|
11
|
-
"@types/ejs": "^3.1.
|
9
|
+
"@babel/runtime": "^7.21.0",
|
10
|
+
"@babel/runtime-corejs3": "^7.21.0",
|
11
|
+
"@types/ejs": "^3.1.2",
|
12
12
|
"cookie": "^0.5.0",
|
13
13
|
"cross-fetch": "^3.1.5",
|
14
14
|
"ejs": "^3.1.8",
|
15
15
|
"fast-deep-equal": "^3.1.3",
|
16
|
-
"next-auth": "^4.
|
16
|
+
"next-auth": "^4.19.2"
|
17
17
|
},
|
18
18
|
"devDependencies": {
|
19
|
-
"@keystone-6/core": "
|
19
|
+
"@keystone-6/core": "5.0.0",
|
20
20
|
"react": "^18.2.0"
|
21
21
|
},
|
22
22
|
"peerDependencies": {
|
23
|
-
"@keystone-6/core": "
|
23
|
+
"@keystone-6/core": "5.0.0",
|
24
24
|
"react": "^18.2.0"
|
25
25
|
},
|
26
26
|
"publishConfig": {
|
@@ -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
|
}
|