@opensaas/keystone-nextjs-auth 20.3.0 → 21.0.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 +19 -0
- package/README.md +5 -3
- package/dist/declarations/src/gql/getBaseAuthSchema.d.ts +1 -3
- package/dist/declarations/src/index.d.ts +4 -4
- package/dist/declarations/src/pages/NextAuthPage.d.ts +16 -9
- package/dist/declarations/src/schema.d.ts +1 -3
- package/dist/declarations/src/templates/auth.d.ts +4 -12
- package/dist/declarations/src/types.d.ts +17 -20
- package/dist/opensaas-keystone-nextjs-auth.cjs.dev.js +87 -74
- package/dist/opensaas-keystone-nextjs-auth.cjs.prod.js +85 -74
- package/dist/opensaas-keystone-nextjs-auth.esm.js +85 -74
- package/package.json +7 -7
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.dev.js +36 -29
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.prod.js +36 -29
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.esm.js +36 -29
- package/src/gql/getBaseAuthSchema.ts +0 -4
- package/src/index.ts +71 -61
- package/src/pages/NextAuthPage.tsx +58 -37
- package/src/schema.ts +0 -22
- package/src/templates/auth.ts +11 -28
- package/src/templates/next-config.ts +3 -0
- package/src/types.ts +20 -21
- package/src/gql/getInitFirstItemSchema.ts +0 -81
@@ -5,15 +5,17 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
6
6
|
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
|
7
7
|
var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/includes');
|
8
|
+
var _indexOfInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/index-of');
|
9
|
+
var _Object$values = require('@babel/runtime-corejs3/core-js-stable/object/values');
|
8
10
|
var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
|
9
11
|
var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
|
10
|
-
|
12
|
+
require('@babel/runtime-corejs3/core-js-stable/url');
|
11
13
|
var url = require('url');
|
12
14
|
var react = require('next-auth/react');
|
15
|
+
var jwt = require('next-auth/jwt');
|
13
16
|
var cookie = require('cookie');
|
14
17
|
var ejs = require('ejs');
|
15
18
|
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
|
16
|
-
var graphql = require('graphql');
|
17
19
|
var core = require('@keystone-6/core');
|
18
20
|
|
19
21
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
@@ -37,9 +39,10 @@ function _interopNamespace(e) {
|
|
37
39
|
}
|
38
40
|
|
39
41
|
var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
|
42
|
+
var _indexOfInstanceProperty__default = /*#__PURE__*/_interopDefault(_indexOfInstanceProperty);
|
43
|
+
var _Object$values__default = /*#__PURE__*/_interopDefault(_Object$values);
|
40
44
|
var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
|
41
45
|
var _JSON$stringify__default = /*#__PURE__*/_interopDefault(_JSON$stringify);
|
42
|
-
var _URL__default = /*#__PURE__*/_interopDefault(_URL);
|
43
46
|
var url__default = /*#__PURE__*/_interopDefault(url);
|
44
47
|
var cookie__namespace = /*#__PURE__*/_interopNamespace(cookie);
|
45
48
|
var ejs__default = /*#__PURE__*/_interopDefault(ejs);
|
@@ -54,6 +57,9 @@ module.exports = withPreconstruct({
|
|
54
57
|
typescript: {
|
55
58
|
ignoreBuildErrors: true,
|
56
59
|
},
|
60
|
+
env: {
|
61
|
+
NEXTAUTH_URL: process.env.NEXTAUTH_URL || 'http://localhost:<%= process.env.PORT || 3000 %><%= keystonePath || '' %>/api/auth',
|
62
|
+
},
|
57
63
|
eslint: {
|
58
64
|
ignoreDuringBuilds: true,
|
59
65
|
},
|
@@ -109,7 +115,6 @@ const nextConfigTemplate = ({
|
|
109
115
|
|
110
116
|
function getBaseAuthSchema({
|
111
117
|
listKey,
|
112
|
-
gqlNames,
|
113
118
|
base
|
114
119
|
}) {
|
115
120
|
const extension = {
|
@@ -149,22 +154,12 @@ function getBaseAuthSchema({
|
|
149
154
|
}
|
150
155
|
|
151
156
|
const getSchemaExtension = ({
|
152
|
-
|
153
|
-
listKey,
|
154
|
-
gqlNames
|
157
|
+
listKey
|
155
158
|
}) => core.graphql.extend(base => {
|
156
159
|
var _context;
|
157
160
|
|
158
|
-
const uniqueWhereInputType = graphql.assertInputObjectType(base.schema.getType(`${listKey}WhereUniqueInput`));
|
159
|
-
const identityFieldOnUniqueWhere = uniqueWhereInputType.getFields()[identityField];
|
160
|
-
|
161
|
-
if ((identityFieldOnUniqueWhere === null || identityFieldOnUniqueWhere === void 0 ? void 0 : identityFieldOnUniqueWhere.type) !== graphql.GraphQLString && (identityFieldOnUniqueWhere === null || identityFieldOnUniqueWhere === void 0 ? void 0 : identityFieldOnUniqueWhere.type) !== graphql.GraphQLID) {
|
162
|
-
throw new Error(`createAuth was called with an identityField of ${identityField} on the list ${listKey} ` + `but that field doesn't allow being searched uniquely with a String or ID. ` + `You should likely add \`isIndexed: 'unique'\` ` + `to the field at ${listKey}.${identityField}`);
|
163
|
-
}
|
164
|
-
|
165
161
|
const baseSchema = getBaseAuthSchema({
|
166
162
|
listKey,
|
167
|
-
gqlNames,
|
168
163
|
base
|
169
164
|
});
|
170
165
|
return _filterInstanceProperty__default["default"](_context = [baseSchema.extension]).call(_context, x => x !== undefined);
|
@@ -176,44 +171,35 @@ import { query } from '.keystone/api';
|
|
176
171
|
import keystoneConfig from '../../../../../keystone';
|
177
172
|
|
178
173
|
export default getNextAuthPage({
|
174
|
+
autoCreate: <%= autoCreate %>,
|
179
175
|
identityField: '<%= identityField %>',
|
180
|
-
sessionData: '<%= sessionData %>',
|
181
176
|
listKey: '<%= listKey %>',
|
182
|
-
|
183
|
-
accountMap: <%- JSON.stringify(accountMap) %>,
|
184
|
-
profileMap: <%- JSON.stringify(profileMap) %>,
|
185
|
-
autoCreate: <%= autoCreate %>,
|
186
|
-
sessionSecret: '<%= sessionSecret %>',
|
177
|
+
pages: keystoneConfig.pages,
|
187
178
|
providers: keystoneConfig.providers,
|
188
179
|
query,
|
180
|
+
resolver: keystoneConfig.resolver,
|
181
|
+
sessionData: '<%= sessionData %>',
|
182
|
+
sessionSecret: '<%= sessionSecret %>',
|
189
183
|
});
|
190
184
|
`;
|
191
185
|
const authTemplate = ({
|
192
|
-
|
186
|
+
autoCreate,
|
193
187
|
identityField,
|
194
|
-
sessionData,
|
195
188
|
listKey,
|
196
|
-
|
197
|
-
userMap,
|
198
|
-
accountMap,
|
199
|
-
profileMap,
|
189
|
+
sessionData,
|
200
190
|
sessionSecret
|
201
191
|
}) => {
|
202
192
|
const authOut = ejs__default["default"].render(template, {
|
203
|
-
gqlNames,
|
204
193
|
identityField,
|
205
194
|
sessionData,
|
206
195
|
listKey,
|
207
196
|
autoCreate,
|
208
|
-
userMap,
|
209
|
-
accountMap,
|
210
|
-
profileMap,
|
211
197
|
sessionSecret
|
212
198
|
});
|
213
199
|
return authOut;
|
214
200
|
};
|
215
201
|
|
216
|
-
const _excluded = ["get"];
|
202
|
+
const _excluded = ["get", "start"];
|
217
203
|
/**
|
218
204
|
* createAuth function
|
219
205
|
*
|
@@ -221,31 +207,21 @@ const _excluded = ["get"];
|
|
221
207
|
*/
|
222
208
|
|
223
209
|
function createAuth({
|
224
|
-
listKey,
|
225
|
-
identityField,
|
226
|
-
sessionData,
|
227
210
|
autoCreate,
|
228
|
-
|
229
|
-
|
230
|
-
|
211
|
+
cookies,
|
212
|
+
identityField,
|
213
|
+
listKey,
|
231
214
|
keystonePath,
|
215
|
+
pages,
|
216
|
+
resolver,
|
232
217
|
providers,
|
218
|
+
sessionData,
|
233
219
|
sessionSecret
|
234
220
|
}) {
|
235
221
|
// The protectIdentities flag is currently under review to see whether it should be
|
236
222
|
// part of the createAuth API (in which case its use cases need to be documented and tested)
|
237
223
|
// or whether always being true is what we want, in which case we can refactor our code
|
238
224
|
// to match this. -TL
|
239
|
-
const gqlNames = {
|
240
|
-
// Core
|
241
|
-
authenticateItemWithPassword: `authenticate${listKey}WithPassword`,
|
242
|
-
ItemAuthenticationWithPasswordResult: `${listKey}AuthenticationWithPasswordResult`,
|
243
|
-
ItemAuthenticationWithPasswordSuccess: `${listKey}AuthenticationWithPasswordSuccess`,
|
244
|
-
ItemAuthenticationWithPasswordFailure: `${listKey}AuthenticationWithPasswordFailure`,
|
245
|
-
// Initial data
|
246
|
-
CreateInitialInput: `CreateInitial${listKey}Input`,
|
247
|
-
createInitialItem: `createInitial${listKey}`
|
248
|
-
};
|
249
225
|
const customPath = !keystonePath || keystonePath === '/' ? '' : keystonePath;
|
250
226
|
/**
|
251
227
|
* pageMiddleware
|
@@ -262,16 +238,14 @@ function createAuth({
|
|
262
238
|
context,
|
263
239
|
isValidSession
|
264
240
|
}) => {
|
241
|
+
var _context;
|
242
|
+
|
265
243
|
const {
|
266
244
|
req,
|
267
245
|
session
|
268
246
|
} = context;
|
269
247
|
const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
270
248
|
|
271
|
-
if (pathname === `${customPath}/api/__keystone_api_build`) {
|
272
|
-
return;
|
273
|
-
}
|
274
|
-
|
275
249
|
if (isValidSession) {
|
276
250
|
if (pathname === `${customPath}/api/auth/signin`) {
|
277
251
|
return {
|
@@ -290,7 +264,11 @@ function createAuth({
|
|
290
264
|
return;
|
291
265
|
}
|
292
266
|
|
293
|
-
if (
|
267
|
+
if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/_next/') || _includesInstanceProperty__default["default"](pathname).call(pathname, '/api/auth/')) {
|
268
|
+
return;
|
269
|
+
}
|
270
|
+
|
271
|
+
if (!session && !_includesInstanceProperty__default["default"](pathname).call(pathname, `${customPath}/api/auth/`) && !(_indexOfInstanceProperty__default["default"](_context = _Object$values__default["default"](pages)).call(_context, pathname) > -1)) {
|
294
272
|
return {
|
295
273
|
kind: 'redirect',
|
296
274
|
to: `${customPath}/api/auth/signin`
|
@@ -312,14 +290,10 @@ function createAuth({
|
|
312
290
|
mode: 'write',
|
313
291
|
outputPath: 'pages/api/auth/[...nextauth].js',
|
314
292
|
src: authTemplate({
|
315
|
-
|
293
|
+
autoCreate,
|
316
294
|
identityField,
|
317
|
-
sessionData,
|
318
295
|
listKey,
|
319
|
-
|
320
|
-
userMap,
|
321
|
-
accountMap,
|
322
|
-
profileMap,
|
296
|
+
sessionData,
|
323
297
|
sessionSecret
|
324
298
|
})
|
325
299
|
}, {
|
@@ -338,7 +312,8 @@ function createAuth({
|
|
338
312
|
*/
|
339
313
|
|
340
314
|
|
341
|
-
const publicPages = [`${customPath}/api/auth/csrf`, `${customPath}/api/auth/signin`, `${customPath}/api/auth/callback`, `${customPath}/api/auth/session`, `${customPath}/api/auth/providers`, `${customPath}/api/auth/signout`];
|
315
|
+
const publicPages = [`${customPath}/api/__keystone_api_build`, `${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
|
316
|
+
// @ts-ignore
|
342
317
|
|
343
318
|
function addPages(provider) {
|
344
319
|
const name = provider.id;
|
@@ -356,8 +331,7 @@ function createAuth({
|
|
356
331
|
|
357
332
|
const extendGraphqlSchema = getSchemaExtension({
|
358
333
|
identityField,
|
359
|
-
listKey
|
360
|
-
gqlNames
|
334
|
+
listKey
|
361
335
|
});
|
362
336
|
/**
|
363
337
|
* validateConfig
|
@@ -371,7 +345,9 @@ function createAuth({
|
|
371
345
|
if (listConfig === undefined) {
|
372
346
|
const msg = `A createAuth() invocation specifies the list "${listKey}" but no list with that key has been defined.`;
|
373
347
|
throw new Error(msg);
|
374
|
-
} // TODO: Check
|
348
|
+
} // TODO: Check if providers
|
349
|
+
// TODO: Check other required commands/data
|
350
|
+
// TODO: Check for String-like typing for identityField? How?
|
375
351
|
// TODO: Validate that the identifyField is unique.
|
376
352
|
// TODO: If this field isn't required, what happens if I try to log in as `null`?
|
377
353
|
|
@@ -379,9 +355,9 @@ function createAuth({
|
|
379
355
|
const identityFieldConfig = listConfig.fields[identityField];
|
380
356
|
|
381
357
|
if (identityFieldConfig === undefined) {
|
382
|
-
const
|
358
|
+
const identityFieldName = _JSON$stringify__default["default"](identityField);
|
383
359
|
|
384
|
-
const msg = `A createAuth() invocation for the "${listKey}" list specifies ${
|
360
|
+
const msg = `A createAuth() invocation for the "${listKey}" list specifies ${identityFieldName} as its identityField but no field with that key exists on the list.`;
|
385
361
|
throw new Error(msg);
|
386
362
|
}
|
387
363
|
};
|
@@ -397,18 +373,46 @@ function createAuth({
|
|
397
373
|
|
398
374
|
|
399
375
|
const withItemData = _sessionStrategy => {
|
400
|
-
const
|
376
|
+
const {
|
377
|
+
get,
|
378
|
+
start
|
379
|
+
} = _sessionStrategy,
|
380
|
+
sessionStrategy = _objectWithoutProperties(_sessionStrategy, _excluded);
|
401
381
|
|
402
382
|
return _objectSpread(_objectSpread({}, sessionStrategy), {}, {
|
383
|
+
start: async ({
|
384
|
+
res
|
385
|
+
}) => {
|
386
|
+
console.log('start');
|
387
|
+
const session = await start({
|
388
|
+
res
|
389
|
+
});
|
390
|
+
return session;
|
391
|
+
},
|
403
392
|
get: async ({
|
404
393
|
req
|
405
394
|
}) => {
|
395
|
+
var _req$headers$authoriz;
|
396
|
+
|
406
397
|
const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
|
407
398
|
|
408
399
|
if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/api/auth')) {
|
409
400
|
return;
|
410
401
|
}
|
411
402
|
|
403
|
+
if (((_req$headers$authoriz = req.headers.authorization) === null || _req$headers$authoriz === void 0 ? void 0 : _req$headers$authoriz.split(' ')[0]) === 'Bearer') {
|
404
|
+
var _token$data;
|
405
|
+
|
406
|
+
const token = await jwt.getToken({
|
407
|
+
req,
|
408
|
+
secret: sessionSecret
|
409
|
+
});
|
410
|
+
|
411
|
+
if (token !== null && token !== void 0 && (_token$data = token.data) !== null && _token$data !== void 0 && _token$data.id) {
|
412
|
+
return token;
|
413
|
+
}
|
414
|
+
}
|
415
|
+
|
412
416
|
const nextSession = await react.getSession({
|
413
417
|
req
|
414
418
|
});
|
@@ -429,6 +433,7 @@ function createAuth({
|
|
429
433
|
secure: "production" === 'production',
|
430
434
|
path: '/',
|
431
435
|
sameSite: 'lax',
|
436
|
+
// TODO: Update parse to URL
|
432
437
|
domain: url__default["default"].parse(req.url).hostname
|
433
438
|
}));
|
434
439
|
}
|
@@ -465,15 +470,18 @@ function createAuth({
|
|
465
470
|
},
|
466
471
|
enableSessionItem: true,
|
467
472
|
isAccessAllowed: async context => {
|
468
|
-
var
|
469
|
-
// even if the user isn't logged in (which should always be the case if they're seeing /init)
|
473
|
+
var _keystoneConfig$ui3;
|
470
474
|
|
475
|
+
const {
|
476
|
+
req
|
477
|
+
} = context;
|
478
|
+
const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname; // Allow nextjs scripts and static files to be accessed without auth
|
471
479
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
return
|
480
|
+
if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/_next/')) {
|
481
|
+
return true;
|
482
|
+
} // Allow keystone to access /api/__keystone_api_build for hot reloading
|
483
|
+
|
484
|
+
return (_keystoneConfig$ui3 = keystoneConfig.ui) !== null && _keystoneConfig$ui3 !== void 0 && _keystoneConfig$ui3.isAccessAllowed ? keystoneConfig.ui.isAccessAllowed(context) : context.session !== undefined;
|
477
485
|
}
|
478
486
|
});
|
479
487
|
}
|
@@ -483,8 +491,11 @@ function createAuth({
|
|
483
491
|
const existingExtendGraphQLSchema = keystoneConfig.extendGraphqlSchema;
|
484
492
|
return _objectSpread(_objectSpread({}, keystoneConfig), {}, {
|
485
493
|
ui,
|
486
|
-
|
494
|
+
cookies,
|
487
495
|
providers,
|
496
|
+
pages,
|
497
|
+
resolver,
|
498
|
+
session,
|
488
499
|
lists: _objectSpread({}, keystoneConfig.lists),
|
489
500
|
experimental: _objectSpread(_objectSpread({}, keystoneConfig.experimental), {}, {
|
490
501
|
generateNodeAPI: true
|