@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
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# @opensaas-keystone/nextjs-auth
|
2
2
|
|
3
|
+
## 27.1.0
|
4
|
+
|
5
|
+
### Minor Changes
|
6
|
+
|
7
|
+
- dd2923f: Fixes custom Prisma Path config
|
8
|
+
|
9
|
+
## 27.0.0
|
10
|
+
|
11
|
+
### Major Changes
|
12
|
+
|
13
|
+
- ec29144: Update dependency @keystone-6/core to v5
|
14
|
+
|
15
|
+
### Patch Changes
|
16
|
+
|
17
|
+
- 0a8ea8e: Update patch dependencies (patch)
|
18
|
+
|
3
19
|
## 26.0.0
|
4
20
|
|
5
21
|
### Major Changes
|
@@ -1,2 +1,2 @@
|
|
1
1
|
import { NextAuthTemplateProps } from '../pages/NextAuthPage';
|
2
|
-
export declare const authTemplate: ({ autoCreate, identityField, listKey, sessionData, sessionSecret, }: NextAuthTemplateProps) => string;
|
2
|
+
export declare const authTemplate: ({ autoCreate, identityField, listKey, sessionData, sessionSecret, prismaClientPath, }: NextAuthTemplateProps) => string;
|
@@ -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
|
|