@opensaas/keystone-nextjs-auth 22.0.0 → 22.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,15 @@
1
1
  # @opensaas-keystone/nextjs-auth
2
2
 
3
+ ## 22.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b89f4e7: Invalidate user when deleted from database
8
+
9
+ ### Patch Changes
10
+
11
+ - b89f4e7: signin pages error fix
12
+
3
13
  ## 22.0.0
4
14
 
5
15
  ### Major Changes
@@ -21,11 +21,6 @@ export declare type AuthSessionStrategy<StoredSessionData> = {
21
21
  createContext: CreateContext;
22
22
  }) => Promise<StoredSessionData | undefined>;
23
23
  };
24
- export declare type NextAuthSession = {
25
- listKey: string;
26
- itemId: string;
27
- data: any;
28
- };
29
24
  export declare type NextAuthProviders = Provider[];
30
25
  declare type KeytoneOAuthOptions = {
31
26
  providers: NextAuthProviders;
@@ -242,7 +242,7 @@ function createAuth({
242
242
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
243
243
 
244
244
  if (isValidSession) {
245
- if (pathname === `${customPath}/api/auth/signin`) {
245
+ if (pathname === `${customPath}/api/auth/signin` || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn)) {
246
246
  return {
247
247
  kind: 'redirect',
248
248
  to: `${customPath}`
@@ -375,36 +375,41 @@ function createAuth({
375
375
  return 'false';
376
376
  },
377
377
  get: async ({
378
- req
378
+ req,
379
+ createContext
379
380
  }) => {
380
381
  var _req$headers, _req$headers$authoriz;
381
382
 
383
+ const sudoContext = createContext({
384
+ sudo: true
385
+ });
382
386
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
387
+ let nextSession;
383
388
 
384
389
  if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/api/auth')) {
385
390
  return;
386
391
  }
387
392
 
388
393
  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') {
389
- var _token$data;
390
-
391
- const token = await jwt.getToken({
394
+ nextSession = await jwt.getToken({
392
395
  req,
393
396
  secret: sessionSecret
394
397
  });
398
+ } else {
399
+ nextSession = await react.getSession({
400
+ req
401
+ });
402
+ }
395
403
 
396
- if (token !== null && token !== void 0 && (_token$data = token.data) !== null && _token$data !== void 0 && _token$data.id) {
397
- return token;
398
- }
404
+ if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
405
+ return;
399
406
  }
400
407
 
401
- const nextSession = await react.getSession({
402
- req
408
+ return _objectSpread(_objectSpread({}, nextSession), {}, {
409
+ data: nextSession.data,
410
+ listKey: nextSession.listKey,
411
+ itemId: nextSession.itemId
403
412
  });
404
-
405
- if (nextSession) {
406
- return nextSession;
407
- }
408
413
  },
409
414
  end: async ({
410
415
  res,
@@ -241,7 +241,7 @@ function createAuth({
241
241
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
242
242
 
243
243
  if (isValidSession) {
244
- if (pathname === `${customPath}/api/auth/signin`) {
244
+ if (pathname === `${customPath}/api/auth/signin` || pages !== null && pages !== void 0 && pages.signIn && _includesInstanceProperty__default["default"](pathname).call(pathname, pages === null || pages === void 0 ? void 0 : pages.signIn)) {
245
245
  return {
246
246
  kind: 'redirect',
247
247
  to: `${customPath}`
@@ -374,36 +374,41 @@ function createAuth({
374
374
  return 'false';
375
375
  },
376
376
  get: async ({
377
- req
377
+ req,
378
+ createContext
378
379
  }) => {
379
380
  var _req$headers, _req$headers$authoriz;
380
381
 
382
+ const sudoContext = createContext({
383
+ sudo: true
384
+ });
381
385
  const pathname = url__default["default"].parse(req === null || req === void 0 ? void 0 : req.url).pathname;
386
+ let nextSession;
382
387
 
383
388
  if (_includesInstanceProperty__default["default"](pathname).call(pathname, '/api/auth')) {
384
389
  return;
385
390
  }
386
391
 
387
392
  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') {
388
- var _token$data;
389
-
390
- const token = await jwt.getToken({
393
+ nextSession = await jwt.getToken({
391
394
  req,
392
395
  secret: sessionSecret
393
396
  });
397
+ } else {
398
+ nextSession = await react.getSession({
399
+ req
400
+ });
401
+ }
394
402
 
395
- if (token !== null && token !== void 0 && (_token$data = token.data) !== null && _token$data !== void 0 && _token$data.id) {
396
- return token;
397
- }
403
+ if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
404
+ return;
398
405
  }
399
406
 
400
- const nextSession = await react.getSession({
401
- req
407
+ return _objectSpread(_objectSpread({}, nextSession), {}, {
408
+ data: nextSession.data,
409
+ listKey: nextSession.listKey,
410
+ itemId: nextSession.itemId
402
411
  });
403
-
404
- if (nextSession) {
405
- return nextSession;
406
- }
407
412
  },
408
413
  end: async ({
409
414
  res,
@@ -209,7 +209,7 @@ function createAuth({
209
209
  const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
210
210
 
211
211
  if (isValidSession) {
212
- if (pathname === `${customPath}/api/auth/signin`) {
212
+ 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
213
  return {
214
214
  kind: 'redirect',
215
215
  to: `${customPath}`
@@ -342,36 +342,41 @@ function createAuth({
342
342
  return 'false';
343
343
  },
344
344
  get: async ({
345
- req
345
+ req,
346
+ createContext
346
347
  }) => {
347
348
  var _req$headers, _req$headers$authoriz;
348
349
 
350
+ const sudoContext = createContext({
351
+ sudo: true
352
+ });
349
353
  const pathname = url.parse(req === null || req === void 0 ? void 0 : req.url).pathname;
354
+ let nextSession;
350
355
 
351
356
  if (_includesInstanceProperty(pathname).call(pathname, '/api/auth')) {
352
357
  return;
353
358
  }
354
359
 
355
360
  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') {
356
- var _token$data;
357
-
358
- const token = await getToken({
361
+ nextSession = await getToken({
359
362
  req,
360
363
  secret: sessionSecret
361
364
  });
365
+ } else {
366
+ nextSession = await getSession({
367
+ req
368
+ });
369
+ }
362
370
 
363
- if (token !== null && token !== void 0 && (_token$data = token.data) !== null && _token$data !== void 0 && _token$data.id) {
364
- return token;
365
- }
371
+ if (!nextSession || !nextSession.listKey || nextSession.listKey !== listKey || !nextSession.itemId || !sudoContext.query[listKey] || !nextSession.itemId) {
372
+ return;
366
373
  }
367
374
 
368
- const nextSession = await getSession({
369
- req
375
+ return _objectSpread(_objectSpread({}, nextSession), {}, {
376
+ data: nextSession.data,
377
+ listKey: nextSession.listKey,
378
+ itemId: nextSession.itemId
370
379
  });
371
-
372
- if (nextSession) {
373
- return nextSession;
374
- }
375
380
  },
376
381
  end: async ({
377
382
  res,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensaas/keystone-nextjs-auth",
3
- "version": "22.0.0",
3
+ "version": "22.1.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"
@@ -167,13 +167,22 @@ function NextAuthPage(props) {
167
167
  session,
168
168
  token
169
169
  }) {
170
- const returnSession = _objectSpread(_objectSpread({}, session), {}, {
171
- data: token.data,
172
- subject: token.sub,
173
- listKey: token.listKey,
174
- itemId: token.itemId
175
- });
170
+ let returnSession = session;
171
+
172
+ if (!token.itemId) {
173
+ return {
174
+ expires: '0'
175
+ };
176
+ } else {
177
+ returnSession = _objectSpread(_objectSpread({}, session), {}, {
178
+ data: token.data,
179
+ subject: token.sub,
180
+ listKey: token.listKey,
181
+ itemId: token.itemId
182
+ });
183
+ }
176
184
 
185
+ console.log('Session', returnSession);
177
186
  return returnSession;
178
187
  },
179
188
 
@@ -181,26 +190,22 @@ function NextAuthPage(props) {
181
190
  token
182
191
  }) {
183
192
  const identity = token.sub;
193
+ const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
184
194
 
185
- if (!token.itemId) {
186
- const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
187
-
188
- if (!result.success) {
189
- return token;
190
- }
191
-
195
+ if (!result.success) {
196
+ token.itemId = null;
197
+ } else {
192
198
  token.itemId = result.item.id;
199
+ const data = await query[listKey].findOne({
200
+ where: {
201
+ id: token.itemId
202
+ },
203
+ query: sessionData || 'id'
204
+ });
205
+ token.data = data;
193
206
  }
194
207
 
195
- const data = await query[listKey].findOne({
196
- where: {
197
- id: token.itemId
198
- },
199
- query: sessionData || 'id'
200
- });
201
-
202
208
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
203
- data,
204
209
  subject: token.sub,
205
210
  listKey
206
211
  });
@@ -167,13 +167,22 @@ function NextAuthPage(props) {
167
167
  session,
168
168
  token
169
169
  }) {
170
- const returnSession = _objectSpread(_objectSpread({}, session), {}, {
171
- data: token.data,
172
- subject: token.sub,
173
- listKey: token.listKey,
174
- itemId: token.itemId
175
- });
170
+ let returnSession = session;
171
+
172
+ if (!token.itemId) {
173
+ return {
174
+ expires: '0'
175
+ };
176
+ } else {
177
+ returnSession = _objectSpread(_objectSpread({}, session), {}, {
178
+ data: token.data,
179
+ subject: token.sub,
180
+ listKey: token.listKey,
181
+ itemId: token.itemId
182
+ });
183
+ }
176
184
 
185
+ console.log('Session', returnSession);
177
186
  return returnSession;
178
187
  },
179
188
 
@@ -181,26 +190,22 @@ function NextAuthPage(props) {
181
190
  token
182
191
  }) {
183
192
  const identity = token.sub;
193
+ const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
184
194
 
185
- if (!token.itemId) {
186
- const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
187
-
188
- if (!result.success) {
189
- return token;
190
- }
191
-
195
+ if (!result.success) {
196
+ token.itemId = null;
197
+ } else {
192
198
  token.itemId = result.item.id;
199
+ const data = await query[listKey].findOne({
200
+ where: {
201
+ id: token.itemId
202
+ },
203
+ query: sessionData || 'id'
204
+ });
205
+ token.data = data;
193
206
  }
194
207
 
195
- const data = await query[listKey].findOne({
196
- where: {
197
- id: token.itemId
198
- },
199
- query: sessionData || 'id'
200
- });
201
-
202
208
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
203
- data,
204
209
  subject: token.sub,
205
210
  listKey
206
211
  });
@@ -159,13 +159,22 @@ function NextAuthPage(props) {
159
159
  session,
160
160
  token
161
161
  }) {
162
- const returnSession = _objectSpread(_objectSpread({}, session), {}, {
163
- data: token.data,
164
- subject: token.sub,
165
- listKey: token.listKey,
166
- itemId: token.itemId
167
- });
162
+ let returnSession = session;
163
+
164
+ if (!token.itemId) {
165
+ return {
166
+ expires: '0'
167
+ };
168
+ } else {
169
+ returnSession = _objectSpread(_objectSpread({}, session), {}, {
170
+ data: token.data,
171
+ subject: token.sub,
172
+ listKey: token.listKey,
173
+ itemId: token.itemId
174
+ });
175
+ }
168
176
 
177
+ console.log('Session', returnSession);
169
178
  return returnSession;
170
179
  },
171
180
 
@@ -173,26 +182,22 @@ function NextAuthPage(props) {
173
182
  token
174
183
  }) {
175
184
  const identity = token.sub;
185
+ const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
176
186
 
177
- if (!token.itemId) {
178
- const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
179
-
180
- if (!result.success) {
181
- return token;
182
- }
183
-
187
+ if (!result.success) {
188
+ token.itemId = null;
189
+ } else {
184
190
  token.itemId = result.item.id;
191
+ const data = await query[listKey].findOne({
192
+ where: {
193
+ id: token.itemId
194
+ },
195
+ query: sessionData || 'id'
196
+ });
197
+ token.data = data;
185
198
  }
186
199
 
187
- const data = await query[listKey].findOne({
188
- where: {
189
- id: token.itemId
190
- },
191
- query: sessionData || 'id'
192
- });
193
-
194
200
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
195
- data,
196
201
  subject: token.sub,
197
202
  listKey
198
203
  });
package/src/index.ts CHANGED
@@ -14,10 +14,11 @@ import { Provider } from 'next-auth/providers';
14
14
 
15
15
  import * as cookie from 'cookie';
16
16
 
17
+ import { Session } from 'next-auth';
17
18
  import { nextConfigTemplate } from './templates/next-config';
18
19
  // import * as Path from 'path';
19
20
 
20
- import { AuthConfig, KeystoneOAuthConfig, NextAuthSession, AuthSessionStrategy } from './types';
21
+ import { AuthConfig, KeystoneOAuthConfig, AuthSessionStrategy } from './types';
21
22
  import { getSchemaExtension } from './schema';
22
23
  import { authTemplate } from './templates/auth';
23
24
 
@@ -64,7 +65,10 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
64
65
  const pathname = url.parse(req?.url!).pathname!;
65
66
 
66
67
  if (isValidSession) {
67
- if (pathname === `${customPath}/api/auth/signin`) {
68
+ if (
69
+ pathname === `${customPath}/api/auth/signin` ||
70
+ (pages?.signIn && pathname.includes(pages?.signIn))
71
+ ) {
68
72
  return { kind: 'redirect', to: `${customPath}` };
69
73
  }
70
74
  if (customPath !== '' && pathname === '/') {
@@ -189,33 +193,45 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
189
193
  */
190
194
  const withItemData = (
191
195
  _sessionStrategy: AuthSessionStrategy<Record<string, any>>
192
- ): AuthSessionStrategy<NextAuthSession | never> => {
196
+ ): AuthSessionStrategy<{ listKey: string; itemId: string; data: any }> => {
193
197
  const { get, ...sessionStrategy } = _sessionStrategy;
194
198
  return {
195
199
  ...sessionStrategy,
196
200
  start: async () => {
197
201
  return 'false';
198
202
  },
199
- get: async ({ req }) => {
203
+ get: async ({ req, createContext }) => {
204
+ const sudoContext = createContext({ sudo: true });
200
205
  const pathname = url.parse(req?.url!).pathname!;
206
+ let nextSession: Session;
201
207
  if (pathname.includes('/api/auth')) {
202
208
  return;
203
209
  }
204
210
  if (req.headers?.authorization?.split(' ')[0] === 'Bearer') {
205
- const token = (await getToken({
211
+ nextSession = (await getToken({
206
212
  req,
207
213
  secret: sessionSecret,
208
- })) as NextAuthSession;
209
-
210
- if (token?.data?.id) {
211
- return token;
212
- }
214
+ })) as Session;
215
+ } else {
216
+ nextSession = (await getSession({ req })) as Session;
213
217
  }
214
- const nextSession: unknown = await getSession({ req });
215
218
 
216
- if (nextSession) {
217
- return nextSession as NextAuthSession;
219
+ if (
220
+ !nextSession ||
221
+ !nextSession.listKey ||
222
+ nextSession.listKey !== listKey ||
223
+ !nextSession.itemId ||
224
+ !sudoContext.query[listKey] ||
225
+ !nextSession.itemId
226
+ ) {
227
+ return;
218
228
  }
229
+ return {
230
+ ...nextSession,
231
+ data: nextSession.data,
232
+ listKey: nextSession.listKey,
233
+ itemId: nextSession.itemId,
234
+ };
219
235
  },
220
236
  end: async ({ res, req }) => {
221
237
  const TOKEN_NAME =
@@ -119,37 +119,38 @@ export default function NextAuthPage(props: NextAuthPageProps) {
119
119
  return url;
120
120
  },
121
121
  async session({ session, token }) {
122
- const returnSession = {
123
- ...session,
124
- data: token.data,
125
- subject: token.sub,
126
- listKey: token.listKey,
127
- itemId: token.itemId,
128
- };
122
+ let returnSession = session;
123
+ if (!token.itemId) {
124
+ return { expires: '0' };
125
+ } else {
126
+ returnSession = {
127
+ ...session,
128
+ data: token.data,
129
+ subject: token.sub,
130
+ listKey: token.listKey as string,
131
+ itemId: token.itemId as string,
132
+ };
133
+ }
134
+ console.log('Session', returnSession);
135
+
129
136
  return returnSession;
130
137
  },
131
138
  async jwt({ token }) {
132
139
  const identity = token.sub as number | string;
133
- if (!token.itemId) {
134
- const result = await validateNextAuth(
135
- identityField,
136
- identity,
137
- protectIdentities,
138
- queryAPI
139
- );
140
-
141
- if (!result.success) {
142
- return token;
143
- }
140
+ const result = await validateNextAuth(identityField, identity, protectIdentities, queryAPI);
141
+
142
+ if (!result.success) {
143
+ token.itemId = null;
144
+ } else {
144
145
  token.itemId = result.item.id;
146
+ const data = await query[listKey].findOne({
147
+ where: { id: token.itemId },
148
+ query: sessionData || 'id',
149
+ });
150
+ token.data = data;
145
151
  }
146
- const data = await query[listKey].findOne({
147
- where: { id: token.itemId },
148
- query: sessionData || 'id',
149
- });
150
152
  const returnToken = {
151
153
  ...token,
152
- data,
153
154
  subject: token.sub,
154
155
  listKey,
155
156
  };
@@ -23,8 +23,6 @@ export declare type AuthSessionStrategy<StoredSessionData> = {
23
23
  }) => Promise<StoredSessionData | undefined>;
24
24
  };
25
25
 
26
- export type NextAuthSession = { listKey: string; itemId: string; data: any };
27
-
28
26
  export type NextAuthProviders = Provider[];
29
27
 
30
28
  type KeytoneOAuthOptions = {
@@ -0,0 +1,19 @@
1
+ import NextAuth from 'next-auth';
2
+ import { JWT } from 'next-auth/jwt';
3
+
4
+ declare module 'next-auth' {
5
+ interface JWT {
6
+ data?: any | undefined;
7
+ subject?: string | undefined;
8
+ listKey?: string;
9
+ itemId?: string | undefined;
10
+ name?: string | null | undefined;
11
+ email?: string | null | undefined;
12
+ picture?: string | null | undefined;
13
+ sub?: string | null | undefined;
14
+ expires?: string | null | undefined;
15
+ }
16
+ interface Session extends JWT {
17
+ user?: any;
18
+ }
19
+ }