@opensaas/keystone-nextjs-auth 21.1.1 → 22.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -131,8 +131,17 @@ const getSchemaExtension = ({
131
131
 
132
132
  const template = `
133
133
  import getNextAuthPage from '@opensaas/keystone-nextjs-auth/pages/NextAuthPage';
134
- import { query } from '.keystone/api';
135
134
  import keystoneConfig from '../../../../../keystone';
135
+ import { PrismaClient } from '.prisma/client';
136
+ import { createQueryAPI } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/node-api';
137
+
138
+ const prisma = global.prisma || PrismaClient
139
+
140
+ if (process.env.NODE_ENV !== 'production') global.prisma = prisma
141
+
142
+ const query = global.query || createQueryAPI(keystoneConfig, prisma);
143
+
144
+ if (process.env.NODE_ENV !== 'production') global.query = query
136
145
 
137
146
  export default getNextAuthPage({
138
147
  autoCreate: <%= autoCreate %>,
@@ -163,7 +172,7 @@ const authTemplate = ({
163
172
  return authOut;
164
173
  };
165
174
 
166
- const _excluded = ["get", "start"];
175
+ const _excluded = ["get", "end"];
167
176
  /**
168
177
  * createAuth function
169
178
  *
@@ -186,7 +195,7 @@ function createAuth({
186
195
  // part of the createAuth API (in which case its use cases need to be documented and tested)
187
196
  // or whether always being true is what we want, in which case we can refactor our code
188
197
  // to match this. -TL
189
- const customPath = !keystonePath || keystonePath === "/" ? "" : keystonePath;
198
+ const customPath = !keystonePath || keystonePath === '/' ? '' : keystonePath;
190
199
  /**
191
200
  * pageMiddleware
192
201
  *
@@ -209,16 +218,16 @@ function createAuth({
209
218
  const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
210
219
 
211
220
  if (isValidSession) {
212
- if (pathname === `${customPath}/api/auth/signin`) {
221
+ 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)) {
213
222
  return {
214
- kind: "redirect",
223
+ kind: 'redirect',
215
224
  to: `${customPath}`
216
225
  };
217
226
  }
218
227
 
219
- if (customPath !== "" && pathname === "/") {
228
+ if (customPath !== '' && pathname === '/') {
220
229
  return {
221
- kind: "redirect",
230
+ kind: 'redirect',
222
231
  to: `${customPath}`
223
232
  };
224
233
  }
@@ -226,13 +235,13 @@ function createAuth({
226
235
  return;
227
236
  }
228
237
 
229
- if (_includesInstanceProperty(pathname).call(pathname, "/_next/") || _includesInstanceProperty(pathname).call(pathname, "/api/auth/") || _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn) || _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.error) || _includesInstanceProperty(pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signOut)) {
238
+ 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)) {
230
239
  return;
231
240
  }
232
241
 
233
242
  if (!session && !_includesInstanceProperty(pathname).call(pathname, `${customPath}/api/auth/`)) {
234
243
  return {
235
- kind: "redirect",
244
+ kind: 'redirect',
236
245
  to: (pages === null || pages === void 0 ? void 0 : pages.signIn) || `${customPath}/api/auth/signin`
237
246
  };
238
247
  }
@@ -249,8 +258,8 @@ function createAuth({
249
258
 
250
259
  const getAdditionalFiles = () => {
251
260
  const filesToWrite = [{
252
- mode: "write",
253
- outputPath: "pages/api/auth/[...nextauth].js",
261
+ mode: 'write',
262
+ outputPath: 'pages/api/auth/[...nextauth].js',
254
263
  src: authTemplate({
255
264
  autoCreate,
256
265
  identityField,
@@ -259,8 +268,8 @@ function createAuth({
259
268
  sessionSecret
260
269
  })
261
270
  }, {
262
- mode: "write",
263
- outputPath: "next.config.js",
271
+ mode: 'write',
272
+ outputPath: 'next.config.js',
264
273
  src: nextConfigTemplate({
265
274
  keystonePath: customPath
266
275
  })
@@ -337,64 +346,70 @@ function createAuth({
337
346
  const withItemData = _sessionStrategy => {
338
347
  const {
339
348
  get,
340
- start
349
+ end
341
350
  } = _sessionStrategy,
342
351
  sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
343
352
 
344
353
  return _objectSpread(_objectSpread({}, sessionStrategy), {}, {
345
- start: async ({
346
- res
347
- }) => {
348
- console.log("start");
349
- const session = await start({
350
- res
351
- });
352
- return session;
353
- },
354
354
  get: async ({
355
- req
355
+ req,
356
+ createContext
356
357
  }) => {
357
- var _req$headers$authoriz;
358
+ var _req$headers, _req$headers$authoriz;
358
359
 
360
+ const session = await get({
361
+ req,
362
+ createContext
363
+ });
364
+ const sudoContext = createContext({
365
+ sudo: true
366
+ });
359
367
  const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
368
+ let nextSession;
360
369
 
361
- if (_includesInstanceProperty(pathname).call(pathname, "/api/auth")) {
370
+ if (_includesInstanceProperty(pathname).call(pathname, '/api/auth')) {
362
371
  return;
363
372
  }
364
373
 
365
- if (((_req$headers$authoriz = req.headers.authorization) === null || _req$headers$authoriz === void 0 ? void 0 : _req$headers$authoriz.split(" ")[0]) === "Bearer") {
366
- var _token$data;
367
-
368
- const token = await getToken({
374
+ 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') {
375
+ nextSession = await getToken({
369
376
  req,
370
377
  secret: sessionSecret
371
378
  });
372
-
373
- if (token !== null && token !== void 0 && (_token$data = token.data) !== null && _token$data !== void 0 && _token$data.id) {
374
- return token;
375
- }
379
+ } else {
380
+ nextSession = await getSession({
381
+ req
382
+ });
376
383
  }
377
384
 
378
- const nextSession = await getSession({
379
- req
380
- });
381
-
382
- if (nextSession) {
383
- return nextSession;
385
+ if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
386
+ return;
384
387
  }
388
+
389
+ return _objectSpread(_objectSpread({}, nextSession), {}, {
390
+ data: nextSession.data,
391
+ listKey: nextSession.listKey,
392
+ itemId: nextSession.itemId
393
+ }, session);
385
394
  },
386
395
  end: async ({
387
396
  res,
388
- req
397
+ req,
398
+ createContext
389
399
  }) => {
390
- const TOKEN_NAME = process.env.NODE_ENV === "production" ? "__Secure-next-auth.session-token" : "next-auth.session-token";
391
- res.setHeader("Set-Cookie", cookie.serialize(TOKEN_NAME, "", {
400
+ await end({
401
+ res,
402
+ req,
403
+ createContext
404
+ });
405
+ const TOKEN_NAME = process.env.NODE_ENV === 'production' ? '__Secure-next-auth.session-token' : 'next-auth.session-token';
406
+ res.setHeader('Set-Cookie', cookie.serialize(TOKEN_NAME, '', {
392
407
  maxAge: 0,
393
408
  expires: new Date(),
394
409
  httpOnly: true,
395
- secure: process.env.NODE_ENV === "production",
396
- path: "/",
397
- sameSite: "lax",
410
+ secure: process.env.NODE_ENV === 'production',
411
+ path: '/',
412
+ sameSite: 'lax',
398
413
  // TODO: Update parse to URL
399
414
  domain: url.parse(req.url).hostname
400
415
  }));
@@ -439,12 +454,12 @@ function createAuth({
439
454
  } = context;
440
455
  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
441
456
 
442
- if (_includesInstanceProperty(pathname).call(pathname, "/_next/")) {
457
+ if (_includesInstanceProperty(pathname).call(pathname, '/_next/')) {
443
458
  return true;
444
459
  } // Allow keystone to access /api/__keystone_api_build for hot reloading
445
460
 
446
461
 
447
- 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`) {
462
+ 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`) {
448
463
  return true;
449
464
  }
450
465
 
@@ -453,7 +468,7 @@ function createAuth({
453
468
  });
454
469
  }
455
470
 
456
- if (!keystoneConfig.session) throw new TypeError("Missing .session configuration");
471
+ if (!keystoneConfig.session) throw new TypeError('Missing .session configuration');
457
472
  const session = withItemData(keystoneConfig.session);
458
473
  const existingExtendGraphQLSchema = keystoneConfig.extendGraphqlSchema;
459
474
  return _objectSpread(_objectSpread({}, keystoneConfig), {}, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensaas/keystone-nextjs-auth",
3
- "version": "21.1.1",
3
+ "version": "22.2.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",
@@ -17,16 +17,14 @@
17
17
  },
18
18
  "devDependencies": {
19
19
  "@keystone-6/core": "^1.1.0",
20
- "next": "12.1.0",
21
20
  "react": "^17.0.2"
22
21
  },
23
22
  "peerDependencies": {
24
23
  "@keystone-6/core": "^1.1.0",
25
- "next": "12.1.0",
26
24
  "react": "^17.0.2"
27
25
  },
28
26
  "engines": {
29
- "node": "^12.20 || >= 14.13"
27
+ "node": "^14.13 || >= 16.13"
30
28
  },
31
29
  "publishConfig": {
32
30
  "access": "public"
@@ -3,12 +3,10 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
6
- var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
7
6
  var NextAuth = require('next-auth');
8
7
 
9
8
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
10
9
 
11
- var _JSON$stringify__default = /*#__PURE__*/_interopDefault(_JSON$stringify);
12
10
  var NextAuth__default = /*#__PURE__*/_interopDefault(NextAuth);
13
11
 
14
12
  async function findMatchingIdentity(identityField, identity, queryAPI) {
@@ -70,9 +68,7 @@ function NextAuthPage(props) {
70
68
  resolver,
71
69
  sessionData,
72
70
  sessionSecret
73
- } = props; // TODO: (v1.1). https://github.com/ijsto/keystone-6-oauth/projects/1#card-78602004
74
-
75
- console.log('NextAuthPages... ', pages);
71
+ } = props;
76
72
 
77
73
  if (!query) {
78
74
  console.error('NextAuthPage got no query.');
@@ -85,7 +81,6 @@ function NextAuthPage(props) {
85
81
  }
86
82
 
87
83
  const list = query[listKey];
88
- const queryAPI = query[listKey];
89
84
  const protectIdentities = true;
90
85
  return NextAuth__default["default"]({
91
86
  cookies,
@@ -115,7 +110,7 @@ function NextAuthPage(props) {
115
110
  account,
116
111
  profile
117
112
  }) : {};
118
- const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI); // ID
113
+ const result = await validateNextAuth(identityField, identity, protectIdentities, list); // ID
119
114
 
120
115
  const data = _objectSpread({
121
116
  [identityField]: identity
@@ -123,26 +118,38 @@ function NextAuthPage(props) {
123
118
 
124
119
  if (!result.success) {
125
120
  if (!autoCreate) {
126
- console.log('`autoCreate` if set to `false`, skipping user auto-creation');
127
121
  return false;
128
122
  }
129
123
 
130
- console.log('`autoCreate` if set to `true`, auto-creating a new user');
131
124
  const createUser = await list.createOne({
132
125
  data
133
126
  }).then(returned => {
134
- console.log('User Created', _JSON$stringify__default["default"](returned));
135
- return true;
127
+ return {
128
+ success: true,
129
+ user: returned
130
+ };
136
131
  }).catch(error => {
137
- console.log(error);
132
+ console.error(error);
138
133
  throw new Error(error);
139
134
  });
140
- console.log('Created User', createUser);
141
- return createUser;
142
- } // await list.updateOne({where: {id: result.item.id}, data});
143
-
135
+ return createUser.success;
136
+ }
144
137
 
145
- return result.success;
138
+ const updateUser = await list.updateOne({
139
+ where: {
140
+ id: result.item.id
141
+ },
142
+ data
143
+ }).then(returned => {
144
+ return {
145
+ success: true,
146
+ user: returned
147
+ };
148
+ }).catch(error => {
149
+ console.error(error);
150
+ throw new Error(error);
151
+ });
152
+ return updateUser.success;
146
153
  },
147
154
 
148
155
  async redirect({
@@ -155,12 +162,20 @@ function NextAuthPage(props) {
155
162
  session,
156
163
  token
157
164
  }) {
158
- const returnSession = _objectSpread(_objectSpread({}, session), {}, {
159
- data: token.data,
160
- subject: token.sub,
161
- listKey: token.listKey,
162
- itemId: token.itemId
163
- });
165
+ let returnSession = session;
166
+
167
+ if (!token.itemId) {
168
+ return {
169
+ expires: '0'
170
+ };
171
+ } else {
172
+ returnSession = _objectSpread(_objectSpread({}, session), {}, {
173
+ data: token.data,
174
+ subject: token.sub,
175
+ listKey: token.listKey,
176
+ itemId: token.itemId
177
+ });
178
+ }
164
179
 
165
180
  return returnSession;
166
181
  },
@@ -169,26 +184,22 @@ function NextAuthPage(props) {
169
184
  token
170
185
  }) {
171
186
  const identity = token.sub;
187
+ const result = await validateNextAuth(identityField, identity, protectIdentities, list);
172
188
 
173
- if (!token.itemId) {
174
- const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
175
-
176
- if (!result.success) {
177
- return token;
178
- }
179
-
189
+ if (!result.success) {
190
+ token.itemId = null;
191
+ } else {
180
192
  token.itemId = result.item.id;
193
+ const data = await query[listKey].findOne({
194
+ where: {
195
+ id: token.itemId
196
+ },
197
+ query: sessionData || 'id'
198
+ });
199
+ token.data = data;
181
200
  }
182
201
 
183
- const data = await query[listKey].findOne({
184
- where: {
185
- id: token.itemId
186
- },
187
- query: sessionData || 'id'
188
- });
189
-
190
202
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
191
- data,
192
203
  subject: token.sub,
193
204
  listKey
194
205
  });
@@ -3,12 +3,10 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
6
- var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
7
6
  var NextAuth = require('next-auth');
8
7
 
9
8
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
10
9
 
11
- var _JSON$stringify__default = /*#__PURE__*/_interopDefault(_JSON$stringify);
12
10
  var NextAuth__default = /*#__PURE__*/_interopDefault(NextAuth);
13
11
 
14
12
  async function findMatchingIdentity(identityField, identity, queryAPI) {
@@ -70,9 +68,7 @@ function NextAuthPage(props) {
70
68
  resolver,
71
69
  sessionData,
72
70
  sessionSecret
73
- } = props; // TODO: (v1.1). https://github.com/ijsto/keystone-6-oauth/projects/1#card-78602004
74
-
75
- console.log('NextAuthPages... ', pages);
71
+ } = props;
76
72
 
77
73
  if (!query) {
78
74
  console.error('NextAuthPage got no query.');
@@ -85,7 +81,6 @@ function NextAuthPage(props) {
85
81
  }
86
82
 
87
83
  const list = query[listKey];
88
- const queryAPI = query[listKey];
89
84
  const protectIdentities = true;
90
85
  return NextAuth__default["default"]({
91
86
  cookies,
@@ -115,7 +110,7 @@ function NextAuthPage(props) {
115
110
  account,
116
111
  profile
117
112
  }) : {};
118
- const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI); // ID
113
+ const result = await validateNextAuth(identityField, identity, protectIdentities, list); // ID
119
114
 
120
115
  const data = _objectSpread({
121
116
  [identityField]: identity
@@ -123,26 +118,38 @@ function NextAuthPage(props) {
123
118
 
124
119
  if (!result.success) {
125
120
  if (!autoCreate) {
126
- console.log('`autoCreate` if set to `false`, skipping user auto-creation');
127
121
  return false;
128
122
  }
129
123
 
130
- console.log('`autoCreate` if set to `true`, auto-creating a new user');
131
124
  const createUser = await list.createOne({
132
125
  data
133
126
  }).then(returned => {
134
- console.log('User Created', _JSON$stringify__default["default"](returned));
135
- return true;
127
+ return {
128
+ success: true,
129
+ user: returned
130
+ };
136
131
  }).catch(error => {
137
- console.log(error);
132
+ console.error(error);
138
133
  throw new Error(error);
139
134
  });
140
- console.log('Created User', createUser);
141
- return createUser;
142
- } // await list.updateOne({where: {id: result.item.id}, data});
143
-
135
+ return createUser.success;
136
+ }
144
137
 
145
- return result.success;
138
+ const updateUser = await list.updateOne({
139
+ where: {
140
+ id: result.item.id
141
+ },
142
+ data
143
+ }).then(returned => {
144
+ return {
145
+ success: true,
146
+ user: returned
147
+ };
148
+ }).catch(error => {
149
+ console.error(error);
150
+ throw new Error(error);
151
+ });
152
+ return updateUser.success;
146
153
  },
147
154
 
148
155
  async redirect({
@@ -155,12 +162,20 @@ function NextAuthPage(props) {
155
162
  session,
156
163
  token
157
164
  }) {
158
- const returnSession = _objectSpread(_objectSpread({}, session), {}, {
159
- data: token.data,
160
- subject: token.sub,
161
- listKey: token.listKey,
162
- itemId: token.itemId
163
- });
165
+ let returnSession = session;
166
+
167
+ if (!token.itemId) {
168
+ return {
169
+ expires: '0'
170
+ };
171
+ } else {
172
+ returnSession = _objectSpread(_objectSpread({}, session), {}, {
173
+ data: token.data,
174
+ subject: token.sub,
175
+ listKey: token.listKey,
176
+ itemId: token.itemId
177
+ });
178
+ }
164
179
 
165
180
  return returnSession;
166
181
  },
@@ -169,26 +184,22 @@ function NextAuthPage(props) {
169
184
  token
170
185
  }) {
171
186
  const identity = token.sub;
187
+ const result = await validateNextAuth(identityField, identity, protectIdentities, list);
172
188
 
173
- if (!token.itemId) {
174
- const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
175
-
176
- if (!result.success) {
177
- return token;
178
- }
179
-
189
+ if (!result.success) {
190
+ token.itemId = null;
191
+ } else {
180
192
  token.itemId = result.item.id;
193
+ const data = await query[listKey].findOne({
194
+ where: {
195
+ id: token.itemId
196
+ },
197
+ query: sessionData || 'id'
198
+ });
199
+ token.data = data;
181
200
  }
182
201
 
183
- const data = await query[listKey].findOne({
184
- where: {
185
- id: token.itemId
186
- },
187
- query: sessionData || 'id'
188
- });
189
-
190
202
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
191
- data,
192
203
  subject: token.sub,
193
204
  listKey
194
205
  });