@opensaas/keystone-nextjs-auth 26.0.0 → 27.1.0

Sign up to get free protection for your applications and to get access to all the features.
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