@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 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
@@ -8,6 +8,7 @@ export type NextAuthTemplateProps = {
8
8
  listKey: string;
9
9
  sessionData: string | undefined;
10
10
  sessionSecret: string;
11
+ prismaClientPath: string;
11
12
  };
12
13
  export type CoreNextAuthPageProps = {
13
14
  cookies?: Partial<CookiesOptions>;
@@ -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 '.prisma/client';
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
- isValidSession
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
- } // TODO: Check if providers
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
- get,
328
- end
329
- } = _sessionStrategy,
330
- sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
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 // In the future we may want to return the following so that developers can
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