@opensaas/keystone-nextjs-auth 26.0.0 → 27.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/CHANGELOG.md +16 -0
- package/dist/declarations/src/pages/NextAuthPage.d.ts +1 -0
- package/dist/declarations/src/templates/auth.d.ts +1 -1
- package/dist/opensaas-keystone-nextjs-auth.cjs.dev.js +34 -62
- package/dist/opensaas-keystone-nextjs-auth.cjs.prod.js +34 -62
- package/dist/opensaas-keystone-nextjs-auth.esm.js +33 -62
- package/package.json +7 -7
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.dev.js +4 -28
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.prod.js +4 -28
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.esm.js +4 -28
- package/src/index.ts +10 -5
- package/src/pages/NextAuthPage.tsx +1 -0
- package/src/templates/auth.ts +3 -1
@@ -9,6 +9,7 @@ var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instan
|
|
9
9
|
var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
|
10
10
|
var _startsWithInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/starts-with');
|
11
11
|
var url = require('url');
|
12
|
+
var path = require('path');
|
12
13
|
var react = require('next-auth/react');
|
13
14
|
var jwt = require('next-auth/jwt');
|
14
15
|
var cookie = require('cookie');
|
@@ -41,6 +42,7 @@ var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstancePro
|
|
41
42
|
var _JSON$stringify__default = /*#__PURE__*/_interopDefault(_JSON$stringify);
|
42
43
|
var _startsWithInstanceProperty__default = /*#__PURE__*/_interopDefault(_startsWithInstanceProperty);
|
43
44
|
var url__default = /*#__PURE__*/_interopDefault(url);
|
45
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
44
46
|
var cookie__namespace = /*#__PURE__*/_interopNamespace(cookie);
|
45
47
|
var ejs__default = /*#__PURE__*/_interopDefault(ejs);
|
46
48
|
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
|
@@ -75,17 +77,14 @@ function getBaseAuthSchema(_ref) {
|
|
75
77
|
types: [base.object(listKey)],
|
76
78
|
resolveType: (root, context) => {
|
77
79
|
var _context$session;
|
78
|
-
|
79
80
|
return (_context$session = context.session) === null || _context$session === void 0 ? void 0 : _context$session.listKey;
|
80
81
|
}
|
81
82
|
}),
|
82
|
-
|
83
83
|
resolve(root, args, _ref2) {
|
84
84
|
let {
|
85
85
|
session,
|
86
86
|
db
|
87
87
|
} = _ref2;
|
88
|
-
|
89
88
|
if (typeof (session === null || session === void 0 ? void 0 : session.itemId) === 'string' && typeof session.listKey === 'string') {
|
90
89
|
return db[session.listKey].findOne({
|
91
90
|
where: {
|
@@ -93,10 +92,8 @@ function getBaseAuthSchema(_ref) {
|
|
93
92
|
}
|
94
93
|
});
|
95
94
|
}
|
96
|
-
|
97
95
|
return null;
|
98
96
|
}
|
99
|
-
|
100
97
|
})
|
101
98
|
}
|
102
99
|
};
|
@@ -111,7 +108,6 @@ const getSchemaExtension = _ref => {
|
|
111
108
|
} = _ref;
|
112
109
|
return core.graphql.extend(base => {
|
113
110
|
var _context;
|
114
|
-
|
115
111
|
const baseSchema = getBaseAuthSchema({
|
116
112
|
listKey,
|
117
113
|
base
|
@@ -124,7 +120,7 @@ const template = `
|
|
124
120
|
import { getContext } from '@keystone-6/core/context';
|
125
121
|
import getNextAuthPage from '@opensaas/keystone-nextjs-auth/pages/NextAuthPage';
|
126
122
|
import keystoneConfig from '../../../../../keystone';
|
127
|
-
import * as PrismaModule from '
|
123
|
+
import * as PrismaModule from '<%= prismaClientPath %>';
|
128
124
|
|
129
125
|
const keystoneQueryAPI = global.keystoneQueryAPI || getContext(keystoneConfig, PrismaModule).sudo().query;
|
130
126
|
|
@@ -148,19 +144,22 @@ const authTemplate = _ref => {
|
|
148
144
|
identityField,
|
149
145
|
listKey,
|
150
146
|
sessionData,
|
151
|
-
sessionSecret
|
147
|
+
sessionSecret,
|
148
|
+
prismaClientPath
|
152
149
|
} = _ref;
|
153
150
|
const authOut = ejs__default["default"].render(template, {
|
154
151
|
identityField,
|
155
152
|
sessionData,
|
156
153
|
listKey,
|
157
154
|
autoCreate,
|
158
|
-
sessionSecret
|
155
|
+
sessionSecret,
|
156
|
+
prismaClientPath
|
159
157
|
});
|
160
158
|
return authOut;
|
161
159
|
};
|
162
160
|
|
163
161
|
const _excluded = ["get", "end"];
|
162
|
+
|
164
163
|
/**
|
165
164
|
* createAuth function
|
166
165
|
*
|
@@ -184,6 +183,7 @@ function createAuth(_ref) {
|
|
184
183
|
// part of the createAuth API (in which case its use cases need to be documented and tested)
|
185
184
|
// or whether always being true is what we want, in which case we can refactor our code
|
186
185
|
// to match this. -TL
|
186
|
+
|
187
187
|
const customPath = !keystonePath || keystonePath === '/' ? '' : keystonePath;
|
188
188
|
/**
|
189
189
|
* pageMiddleware
|
@@ -195,36 +195,32 @@ function createAuth(_ref) {
|
|
195
195
|
* - to the init page when initFirstItem is configured, and there are no user in the database
|
196
196
|
* - to the signin page when no valid session is present
|
197
197
|
*/
|
198
|
-
|
199
198
|
const authMiddleware = async _ref2 => {
|
200
199
|
let {
|
201
200
|
context,
|
202
|
-
|
201
|
+
wasAccessAllowed
|
203
202
|
} = _ref2;
|
204
203
|
const {
|
205
|
-
req
|
206
|
-
session
|
204
|
+
req
|
207
205
|
} = context;
|
208
206
|
const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
209
|
-
|
210
|
-
if (isValidSession) {
|
207
|
+
if (wasAccessAllowed) {
|
211
208
|
if (customPath !== '' && pathname === '/') {
|
212
209
|
return {
|
213
210
|
kind: 'redirect',
|
214
211
|
to: `${customPath}`
|
215
212
|
};
|
216
213
|
}
|
217
|
-
|
218
214
|
return;
|
219
215
|
}
|
220
|
-
|
221
|
-
if (!session && !_includesInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`)) {
|
216
|
+
if (!wasAccessAllowed && !_includesInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`)) {
|
222
217
|
return {
|
223
218
|
kind: 'redirect',
|
224
219
|
to: (pages === null || pages === void 0 ? void 0 : pages.signIn) || `${customPath}/api/auth/signin`
|
225
220
|
};
|
226
221
|
}
|
227
222
|
};
|
223
|
+
|
228
224
|
/**
|
229
225
|
* authGetAdditionalFiles
|
230
226
|
*
|
@@ -233,9 +229,8 @@ function createAuth(_ref) {
|
|
233
229
|
*
|
234
230
|
* The signin page is always included, and the init page is included when initFirstItem is set
|
235
231
|
*/
|
236
|
-
|
237
|
-
|
238
|
-
const authGetAdditionalFiles = () => {
|
232
|
+
const authGetAdditionalFiles = config => {
|
233
|
+
const prismaClientPath = config.db.prismaClientPath ? path__default["default"].join('../../../../../', config.db.prismaClientPath) : '@prisma/client';
|
239
234
|
const filesToWrite = [{
|
240
235
|
mode: 'write',
|
241
236
|
outputPath: 'pages/api/auth/[...nextauth].js',
|
@@ -244,7 +239,8 @@ function createAuth(_ref) {
|
|
244
239
|
identityField,
|
245
240
|
listKey,
|
246
241
|
sessionData,
|
247
|
-
sessionSecret
|
242
|
+
sessionSecret,
|
243
|
+
prismaClientPath
|
248
244
|
})
|
249
245
|
}, {
|
250
246
|
mode: 'write',
|
@@ -255,84 +251,75 @@ function createAuth(_ref) {
|
|
255
251
|
}];
|
256
252
|
return filesToWrite;
|
257
253
|
};
|
254
|
+
|
258
255
|
/**
|
259
256
|
* publicAuthPages
|
260
257
|
*
|
261
258
|
* Must be added to the ui.publicPages config
|
262
259
|
*/
|
263
|
-
|
264
|
-
|
265
|
-
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`]; // TODO: Add Provider Types
|
260
|
+
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`];
|
261
|
+
// TODO: Add Provider Types
|
266
262
|
// @ts-ignore
|
267
|
-
|
268
263
|
function addPages(provider) {
|
269
264
|
const name = provider.id;
|
270
265
|
authPublicPages.push(`${customPath}/api/auth/signin/${name}`);
|
271
266
|
authPublicPages.push(`${customPath}/api/auth/callback/${name}`);
|
272
267
|
}
|
273
|
-
|
274
268
|
_mapInstanceProperty__default["default"](providers).call(providers, addPages);
|
269
|
+
|
275
270
|
/**
|
276
271
|
* extendGraphqlSchema
|
277
272
|
*
|
278
273
|
* Must be added to the extendGraphqlSchema config. Can be composed.
|
279
274
|
*/
|
280
|
-
|
281
|
-
|
282
275
|
const extendGraphqlSchema = getSchemaExtension({
|
283
276
|
identityField,
|
284
277
|
listKey
|
285
278
|
});
|
279
|
+
|
286
280
|
/**
|
287
281
|
* validateConfig
|
288
282
|
*
|
289
283
|
* Validates the provided auth config; optional step when integrating auth
|
290
284
|
*/
|
291
|
-
|
292
285
|
const validateConfig = keystoneConfig => {
|
293
286
|
const listConfig = keystoneConfig.lists[listKey];
|
294
|
-
|
295
287
|
if (listConfig === undefined) {
|
296
288
|
const msg = `A createAuth() invocation specifies the list "${listKey}" but no list with that key has been defined.`;
|
297
289
|
throw new Error(msg);
|
298
|
-
}
|
290
|
+
}
|
291
|
+
|
292
|
+
// TODO: Check if providers
|
299
293
|
// TODO: Check other required commands/data
|
294
|
+
|
300
295
|
// TODO: Check for String-like typing for identityField? How?
|
301
296
|
// TODO: Validate that the identifyField is unique.
|
302
297
|
// TODO: If this field isn't required, what happens if I try to log in as `null`?
|
303
|
-
|
304
|
-
|
305
298
|
const identityFieldConfig = listConfig.fields[identityField];
|
306
|
-
|
307
299
|
if (identityFieldConfig === undefined) {
|
308
300
|
const identityFieldName = _JSON$stringify__default["default"](identityField);
|
309
|
-
|
310
301
|
const msg = `A createAuth() invocation for the "${listKey}" list specifies ${identityFieldName} as its identityField but no field with that key exists on the list.`;
|
311
302
|
throw new Error(msg);
|
312
303
|
}
|
313
304
|
};
|
305
|
+
|
314
306
|
/**
|
315
307
|
* withItemData
|
316
308
|
*
|
317
309
|
* Automatically injects a session.data value with the authenticated item
|
318
310
|
*/
|
319
|
-
|
320
311
|
/* TODO:
|
321
312
|
- [ ] We could support additional where input to validate item sessions (e.g an isEnabled boolean)
|
322
313
|
*/
|
323
|
-
|
324
|
-
|
325
314
|
const withItemData = _sessionStrategy => {
|
326
315
|
const {
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
316
|
+
get,
|
317
|
+
end
|
318
|
+
} = _sessionStrategy,
|
319
|
+
sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
|
332
320
|
return _objectSpread(_objectSpread({}, sessionStrategy), {}, {
|
333
321
|
get: async _ref3 => {
|
334
322
|
var _req$headers, _req$headers$authoriz;
|
335
|
-
|
336
323
|
let {
|
337
324
|
context
|
338
325
|
} = _ref3;
|
@@ -342,13 +329,10 @@ function createAuth(_ref) {
|
|
342
329
|
const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
343
330
|
let nextSession;
|
344
331
|
if (!req) return;
|
345
|
-
|
346
332
|
if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/api/auth')) {
|
347
333
|
return;
|
348
334
|
}
|
349
|
-
|
350
335
|
const sudoContext = context.sudo();
|
351
|
-
|
352
336
|
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') {
|
353
337
|
nextSession = await jwt.getToken({
|
354
338
|
req: req,
|
@@ -359,11 +343,9 @@ function createAuth(_ref) {
|
|
359
343
|
req
|
360
344
|
});
|
361
345
|
}
|
362
|
-
|
363
346
|
if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
|
364
347
|
return;
|
365
348
|
}
|
366
|
-
|
367
349
|
const reqWithUser = req;
|
368
350
|
reqWithUser.user = {
|
369
351
|
istKey: nextSession.listKey,
|
@@ -405,7 +387,6 @@ function createAuth(_ref) {
|
|
405
387
|
}
|
406
388
|
});
|
407
389
|
};
|
408
|
-
|
409
390
|
function defaultIsAccessAllowed(_ref5) {
|
410
391
|
let {
|
411
392
|
session
|
@@ -422,16 +403,12 @@ function createAuth(_ref) {
|
|
422
403
|
* It validates the auth config against the provided keystone config, and preserves existing
|
423
404
|
* config by composing existing extendGraphqlSchema functions and ui config.
|
424
405
|
*/
|
425
|
-
|
426
|
-
|
427
406
|
const withAuth = keystoneConfig => {
|
428
407
|
var _ui;
|
429
|
-
|
430
408
|
validateConfig(keystoneConfig);
|
431
409
|
let {
|
432
410
|
ui
|
433
411
|
} = keystoneConfig;
|
434
|
-
|
435
412
|
if (!((_ui = ui) !== null && _ui !== void 0 && _ui.isDisabled)) {
|
436
413
|
const {
|
437
414
|
getAdditionalFiles = [],
|
@@ -443,13 +420,10 @@ function createAuth(_ref) {
|
|
443
420
|
publicPages: [...publicPages, ...authPublicPages],
|
444
421
|
isAccessAllowed: async context => {
|
445
422
|
var _context$req;
|
446
|
-
|
447
423
|
const pathname = url__default["default"].parse((_context$req = context.req) === null || _context$req === void 0 ? void 0 : _context$req.url).pathname;
|
448
|
-
|
449
424
|
if (_startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/_next`) || _startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/__next`) || _startsWithInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`) || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn) || pages !== null && pages !== void 0 && pages.error && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.error) || pages !== null && pages !== void 0 && pages.signOut && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signOut)) {
|
450
425
|
return true;
|
451
426
|
}
|
452
|
-
|
453
427
|
return await isAccessAllowed(context);
|
454
428
|
},
|
455
429
|
getAdditionalFiles: [...getAdditionalFiles, authGetAdditionalFiles],
|
@@ -460,7 +434,6 @@ function createAuth(_ref) {
|
|
460
434
|
}
|
461
435
|
});
|
462
436
|
}
|
463
|
-
|
464
437
|
if (!keystoneConfig.session) throw new TypeError('Missing .session configuration');
|
465
438
|
const session = withItemData(keystoneConfig.session);
|
466
439
|
const existingExtendGraphQLSchema = keystoneConfig.extendGraphqlSchema;
|
@@ -475,16 +448,15 @@ function createAuth(_ref) {
|
|
475
448
|
extendGraphqlSchema: existingExtendGraphQLSchema ? schema => existingExtendGraphQLSchema(extendGraphqlSchema(schema)) : extendGraphqlSchema
|
476
449
|
});
|
477
450
|
};
|
478
|
-
|
479
451
|
return {
|
480
|
-
withAuth
|
452
|
+
withAuth
|
453
|
+
// In the future we may want to return the following so that developers can
|
481
454
|
// roll their own. This is pending a review of the use cases this might be
|
482
455
|
// appropriate for, along with documentation and testing.
|
483
456
|
// ui: { enableSessionItem: true, pageMiddleware, getAdditionalFiles, publicPages },
|
484
457
|
// fields,
|
485
458
|
// extendGraphqlSchema,
|
486
459
|
// validateConfig,
|
487
|
-
|
488
460
|
};
|
489
461
|
}
|
490
462
|
|
@@ -5,6 +5,7 @@ import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance
|
|
5
5
|
import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringify';
|
6
6
|
import _startsWithInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/starts-with';
|
7
7
|
import url from 'url';
|
8
|
+
import path from 'path';
|
8
9
|
import { getSession } from 'next-auth/react';
|
9
10
|
import { getToken } from 'next-auth/jwt';
|
10
11
|
import * as cookie from 'cookie';
|
@@ -42,17 +43,14 @@ function getBaseAuthSchema(_ref) {
|
|
42
43
|
types: [base.object(listKey)],
|
43
44
|
resolveType: (root, context) => {
|
44
45
|
var _context$session;
|
45
|
-
|
46
46
|
return (_context$session = context.session) === null || _context$session === void 0 ? void 0 : _context$session.listKey;
|
47
47
|
}
|
48
48
|
}),
|
49
|
-
|
50
49
|
resolve(root, args, _ref2) {
|
51
50
|
let {
|
52
51
|
session,
|
53
52
|
db
|
54
53
|
} = _ref2;
|
55
|
-
|
56
54
|
if (typeof (session === null || session === void 0 ? void 0 : session.itemId) === 'string' && typeof session.listKey === 'string') {
|
57
55
|
return db[session.listKey].findOne({
|
58
56
|
where: {
|
@@ -60,10 +58,8 @@ function getBaseAuthSchema(_ref) {
|
|
60
58
|
}
|
61
59
|
});
|
62
60
|
}
|
63
|
-
|
64
61
|
return null;
|
65
62
|
}
|
66
|
-
|
67
63
|
})
|
68
64
|
}
|
69
65
|
};
|
@@ -78,7 +74,6 @@ const getSchemaExtension = _ref => {
|
|
78
74
|
} = _ref;
|
79
75
|
return graphql.extend(base => {
|
80
76
|
var _context;
|
81
|
-
|
82
77
|
const baseSchema = getBaseAuthSchema({
|
83
78
|
listKey,
|
84
79
|
base
|
@@ -91,7 +86,7 @@ const template = `
|
|
91
86
|
import { getContext } from '@keystone-6/core/context';
|
92
87
|
import getNextAuthPage from '@opensaas/keystone-nextjs-auth/pages/NextAuthPage';
|
93
88
|
import keystoneConfig from '../../../../../keystone';
|
94
|
-
import * as PrismaModule from '
|
89
|
+
import * as PrismaModule from '<%= prismaClientPath %>';
|
95
90
|
|
96
91
|
const keystoneQueryAPI = global.keystoneQueryAPI || getContext(keystoneConfig, PrismaModule).sudo().query;
|
97
92
|
|
@@ -115,19 +110,22 @@ const authTemplate = _ref => {
|
|
115
110
|
identityField,
|
116
111
|
listKey,
|
117
112
|
sessionData,
|
118
|
-
sessionSecret
|
113
|
+
sessionSecret,
|
114
|
+
prismaClientPath
|
119
115
|
} = _ref;
|
120
116
|
const authOut = ejs.render(template, {
|
121
117
|
identityField,
|
122
118
|
sessionData,
|
123
119
|
listKey,
|
124
120
|
autoCreate,
|
125
|
-
sessionSecret
|
121
|
+
sessionSecret,
|
122
|
+
prismaClientPath
|
126
123
|
});
|
127
124
|
return authOut;
|
128
125
|
};
|
129
126
|
|
130
127
|
const _excluded = ["get", "end"];
|
128
|
+
|
131
129
|
/**
|
132
130
|
* createAuth function
|
133
131
|
*
|
@@ -151,6 +149,7 @@ function createAuth(_ref) {
|
|
151
149
|
// part of the createAuth API (in which case its use cases need to be documented and tested)
|
152
150
|
// or whether always being true is what we want, in which case we can refactor our code
|
153
151
|
// to match this. -TL
|
152
|
+
|
154
153
|
const customPath = !keystonePath || keystonePath === '/' ? '' : keystonePath;
|
155
154
|
/**
|
156
155
|
* pageMiddleware
|
@@ -162,36 +161,32 @@ function createAuth(_ref) {
|
|
162
161
|
* - to the init page when initFirstItem is configured, and there are no user in the database
|
163
162
|
* - to the signin page when no valid session is present
|
164
163
|
*/
|
165
|
-
|
166
164
|
const authMiddleware = async _ref2 => {
|
167
165
|
let {
|
168
166
|
context,
|
169
|
-
|
167
|
+
wasAccessAllowed
|
170
168
|
} = _ref2;
|
171
169
|
const {
|
172
|
-
req
|
173
|
-
session
|
170
|
+
req
|
174
171
|
} = context;
|
175
172
|
const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
176
|
-
|
177
|
-
if (isValidSession) {
|
173
|
+
if (wasAccessAllowed) {
|
178
174
|
if (customPath !== '' && pathname === '/') {
|
179
175
|
return {
|
180
176
|
kind: 'redirect',
|
181
177
|
to: `${customPath}`
|
182
178
|
};
|
183
179
|
}
|
184
|
-
|
185
180
|
return;
|
186
181
|
}
|
187
|
-
|
188
|
-
if (!session && !_includesInstanceProperty(pathname).call(pathname, `${customPath}/api/auth/`)) {
|
182
|
+
if (!wasAccessAllowed && !_includesInstanceProperty(pathname).call(pathname, `${customPath}/api/auth/`)) {
|
189
183
|
return {
|
190
184
|
kind: 'redirect',
|
191
185
|
to: (pages === null || pages === void 0 ? void 0 : pages.signIn) || `${customPath}/api/auth/signin`
|
192
186
|
};
|
193
187
|
}
|
194
188
|
};
|
189
|
+
|
195
190
|
/**
|
196
191
|
* authGetAdditionalFiles
|
197
192
|
*
|
@@ -200,9 +195,8 @@ function createAuth(_ref) {
|
|
200
195
|
*
|
201
196
|
* The signin page is always included, and the init page is included when initFirstItem is set
|
202
197
|
*/
|
203
|
-
|
204
|
-
|
205
|
-
const authGetAdditionalFiles = () => {
|
198
|
+
const authGetAdditionalFiles = config => {
|
199
|
+
const prismaClientPath = config.db.prismaClientPath ? path.join('../../../../../', config.db.prismaClientPath) : '@prisma/client';
|
206
200
|
const filesToWrite = [{
|
207
201
|
mode: 'write',
|
208
202
|
outputPath: 'pages/api/auth/[...nextauth].js',
|
@@ -211,7 +205,8 @@ function createAuth(_ref) {
|
|
211
205
|
identityField,
|
212
206
|
listKey,
|
213
207
|
sessionData,
|
214
|
-
sessionSecret
|
208
|
+
sessionSecret,
|
209
|
+
prismaClientPath
|
215
210
|
})
|
216
211
|
}, {
|
217
212
|
mode: 'write',
|
@@ -222,84 +217,75 @@ function createAuth(_ref) {
|
|
222
217
|
}];
|
223
218
|
return filesToWrite;
|
224
219
|
};
|
220
|
+
|
225
221
|
/**
|
226
222
|
* publicAuthPages
|
227
223
|
*
|
228
224
|
* Must be added to the ui.publicPages config
|
229
225
|
*/
|
230
|
-
|
231
|
-
|
232
|
-
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`]; // TODO: Add Provider Types
|
226
|
+
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`];
|
227
|
+
// TODO: Add Provider Types
|
233
228
|
// @ts-ignore
|
234
|
-
|
235
229
|
function addPages(provider) {
|
236
230
|
const name = provider.id;
|
237
231
|
authPublicPages.push(`${customPath}/api/auth/signin/${name}`);
|
238
232
|
authPublicPages.push(`${customPath}/api/auth/callback/${name}`);
|
239
233
|
}
|
240
|
-
|
241
234
|
_mapInstanceProperty(providers).call(providers, addPages);
|
235
|
+
|
242
236
|
/**
|
243
237
|
* extendGraphqlSchema
|
244
238
|
*
|
245
239
|
* Must be added to the extendGraphqlSchema config. Can be composed.
|
246
240
|
*/
|
247
|
-
|
248
|
-
|
249
241
|
const extendGraphqlSchema = getSchemaExtension({
|
250
242
|
identityField,
|
251
243
|
listKey
|
252
244
|
});
|
245
|
+
|
253
246
|
/**
|
254
247
|
* validateConfig
|
255
248
|
*
|
256
249
|
* Validates the provided auth config; optional step when integrating auth
|
257
250
|
*/
|
258
|
-
|
259
251
|
const validateConfig = keystoneConfig => {
|
260
252
|
const listConfig = keystoneConfig.lists[listKey];
|
261
|
-
|
262
253
|
if (listConfig === undefined) {
|
263
254
|
const msg = `A createAuth() invocation specifies the list "${listKey}" but no list with that key has been defined.`;
|
264
255
|
throw new Error(msg);
|
265
|
-
}
|
256
|
+
}
|
257
|
+
|
258
|
+
// TODO: Check if providers
|
266
259
|
// TODO: Check other required commands/data
|
260
|
+
|
267
261
|
// TODO: Check for String-like typing for identityField? How?
|
268
262
|
// TODO: Validate that the identifyField is unique.
|
269
263
|
// TODO: If this field isn't required, what happens if I try to log in as `null`?
|
270
|
-
|
271
|
-
|
272
264
|
const identityFieldConfig = listConfig.fields[identityField];
|
273
|
-
|
274
265
|
if (identityFieldConfig === undefined) {
|
275
266
|
const identityFieldName = _JSON$stringify(identityField);
|
276
|
-
|
277
267
|
const msg = `A createAuth() invocation for the "${listKey}" list specifies ${identityFieldName} as its identityField but no field with that key exists on the list.`;
|
278
268
|
throw new Error(msg);
|
279
269
|
}
|
280
270
|
};
|
271
|
+
|
281
272
|
/**
|
282
273
|
* withItemData
|
283
274
|
*
|
284
275
|
* Automatically injects a session.data value with the authenticated item
|
285
276
|
*/
|
286
|
-
|
287
277
|
/* TODO:
|
288
278
|
- [ ] We could support additional where input to validate item sessions (e.g an isEnabled boolean)
|
289
279
|
*/
|
290
|
-
|
291
|
-
|
292
280
|
const withItemData = _sessionStrategy => {
|
293
281
|
const {
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
282
|
+
get,
|
283
|
+
end
|
284
|
+
} = _sessionStrategy,
|
285
|
+
sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
|
299
286
|
return _objectSpread(_objectSpread({}, sessionStrategy), {}, {
|
300
287
|
get: async _ref3 => {
|
301
288
|
var _req$headers, _req$headers$authoriz;
|
302
|
-
|
303
289
|
let {
|
304
290
|
context
|
305
291
|
} = _ref3;
|
@@ -309,13 +295,10 @@ function createAuth(_ref) {
|
|
309
295
|
const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
310
296
|
let nextSession;
|
311
297
|
if (!req) return;
|
312
|
-
|
313
298
|
if (_includesInstanceProperty(pathname).call(pathname, '/api/auth')) {
|
314
299
|
return;
|
315
300
|
}
|
316
|
-
|
317
301
|
const sudoContext = context.sudo();
|
318
|
-
|
319
302
|
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') {
|
320
303
|
nextSession = await getToken({
|
321
304
|
req: req,
|
@@ -326,11 +309,9 @@ function createAuth(_ref) {
|
|
326
309
|
req
|
327
310
|
});
|
328
311
|
}
|
329
|
-
|
330
312
|
if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
|
331
313
|
return;
|
332
314
|
}
|
333
|
-
|
334
315
|
const reqWithUser = req;
|
335
316
|
reqWithUser.user = {
|
336
317
|
istKey: nextSession.listKey,
|
@@ -372,7 +353,6 @@ function createAuth(_ref) {
|
|
372
353
|
}
|
373
354
|
});
|
374
355
|
};
|
375
|
-
|
376
356
|
function defaultIsAccessAllowed(_ref5) {
|
377
357
|
let {
|
378
358
|
session
|
@@ -389,16 +369,12 @@ function createAuth(_ref) {
|
|
389
369
|
* It validates the auth config against the provided keystone config, and preserves existing
|
390
370
|
* config by composing existing extendGraphqlSchema functions and ui config.
|
391
371
|
*/
|
392
|
-
|
393
|
-
|
394
372
|
const withAuth = keystoneConfig => {
|
395
373
|
var _ui;
|
396
|
-
|
397
374
|
validateConfig(keystoneConfig);
|
398
375
|
let {
|
399
376
|
ui
|
400
377
|
} = keystoneConfig;
|
401
|
-
|
402
378
|
if (!((_ui = ui) !== null && _ui !== void 0 && _ui.isDisabled)) {
|
403
379
|
const {
|
404
380
|
getAdditionalFiles = [],
|
@@ -410,13 +386,10 @@ function createAuth(_ref) {
|
|
410
386
|
publicPages: [...publicPages, ...authPublicPages],
|
411
387
|
isAccessAllowed: async context => {
|
412
388
|
var _context$req;
|
413
|
-
|
414
389
|
const pathname = url.parse((_context$req = context.req) === null || _context$req === void 0 ? void 0 : _context$req.url).pathname;
|
415
|
-
|
416
390
|
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)) {
|
417
391
|
return true;
|
418
392
|
}
|
419
|
-
|
420
393
|
return await isAccessAllowed(context);
|
421
394
|
},
|
422
395
|
getAdditionalFiles: [...getAdditionalFiles, authGetAdditionalFiles],
|
@@ -427,7 +400,6 @@ function createAuth(_ref) {
|
|
427
400
|
}
|
428
401
|
});
|
429
402
|
}
|
430
|
-
|
431
403
|
if (!keystoneConfig.session) throw new TypeError('Missing .session configuration');
|
432
404
|
const session = withItemData(keystoneConfig.session);
|
433
405
|
const existingExtendGraphQLSchema = keystoneConfig.extendGraphqlSchema;
|
@@ -442,16 +414,15 @@ function createAuth(_ref) {
|
|
442
414
|
extendGraphqlSchema: existingExtendGraphQLSchema ? schema => existingExtendGraphQLSchema(extendGraphqlSchema(schema)) : extendGraphqlSchema
|
443
415
|
});
|
444
416
|
};
|
445
|
-
|
446
417
|
return {
|
447
|
-
withAuth
|
418
|
+
withAuth
|
419
|
+
// In the future we may want to return the following so that developers can
|
448
420
|
// roll their own. This is pending a review of the use cases this might be
|
449
421
|
// appropriate for, along with documentation and testing.
|
450
422
|
// ui: { enableSessionItem: true, pageMiddleware, getAdditionalFiles, publicPages },
|
451
423
|
// fields,
|
452
424
|
// extendGraphqlSchema,
|
453
425
|
// validateConfig,
|
454
|
-
|
455
426
|
};
|
456
427
|
}
|
457
428
|
|