@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/package.json CHANGED
@@ -1,26 +1,26 @@
1
1
  {
2
2
  "name": "@opensaas/keystone-nextjs-auth",
3
- "version": "26.0.0",
3
+ "version": "27.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",
7
7
  "module": "dist/opensaas-keystone-nextjs-auth.esm.js",
8
8
  "dependencies": {
9
- "@babel/runtime": "^7.17.9",
10
- "@babel/runtime-corejs3": "^7.17.9",
11
- "@types/ejs": "^3.1.1",
9
+ "@babel/runtime": "^7.21.0",
10
+ "@babel/runtime-corejs3": "^7.21.0",
11
+ "@types/ejs": "^3.1.2",
12
12
  "cookie": "^0.5.0",
13
13
  "cross-fetch": "^3.1.5",
14
14
  "ejs": "^3.1.8",
15
15
  "fast-deep-equal": "^3.1.3",
16
- "next-auth": "^4.18.0"
16
+ "next-auth": "^4.19.2"
17
17
  },
18
18
  "devDependencies": {
19
- "@keystone-6/core": "4.0.1",
19
+ "@keystone-6/core": "5.0.0",
20
20
  "react": "^18.2.0"
21
21
  },
22
22
  "peerDependencies": {
23
- "@keystone-6/core": "4.0.1",
23
+ "@keystone-6/core": "5.0.0",
24
24
  "react": "^18.2.0"
25
25
  },
26
26
  "publishConfig": {
@@ -14,21 +14,18 @@ async function findMatchingIdentity(identityField, identity, queryAPI) {
14
14
  where: {
15
15
  [identityField]: identity
16
16
  }
17
- }); // Identity failures with helpful errors
18
-
17
+ });
18
+ // Identity failures with helpful errors
19
19
  let code;
20
-
21
20
  if (!item) {
22
21
  code = 'IDENTITY_NOT_FOUND';
23
22
  }
24
-
25
23
  if (code) {
26
24
  return {
27
25
  success: false,
28
26
  code
29
27
  };
30
28
  }
31
-
32
29
  return {
33
30
  success: true,
34
31
  item
@@ -40,14 +37,12 @@ async function validateNextAuth(identityField, identity, protectIdentities, item
40
37
  const {
41
38
  item
42
39
  } = match;
43
-
44
40
  if (item) {
45
41
  return {
46
42
  success: true,
47
43
  item
48
44
  };
49
45
  }
50
-
51
46
  return {
52
47
  success: false,
53
48
  code: protectIdentities ? 'FAILURE' : 'SUBJECT_NOT_FOUND'
@@ -69,17 +64,14 @@ function NextAuthPage(props) {
69
64
  sessionData,
70
65
  sessionSecret
71
66
  } = props;
72
-
73
67
  if (!query) {
74
68
  console.error('NextAuthPage got no query.');
75
69
  return null;
76
70
  }
77
-
78
71
  if (!providers || !providers.length) {
79
72
  console.error('You need to provide at least one provider.');
80
73
  return null;
81
74
  }
82
-
83
75
  const list = query[listKey];
84
76
  const protectIdentities = true;
85
77
  return NextAuth__default["default"]({
@@ -97,7 +89,6 @@ function NextAuthPage(props) {
97
89
  profile
98
90
  } = _ref;
99
91
  let identity;
100
-
101
92
  if (typeof user.id === 'string') {
102
93
  identity = user.id;
103
94
  } else if (typeof user.id === 'number') {
@@ -105,23 +96,20 @@ function NextAuthPage(props) {
105
96
  } else {
106
97
  identity = 0;
107
98
  }
108
-
109
99
  const userInput = resolver ? await resolver({
110
100
  user,
111
101
  account,
112
102
  profile
113
103
  }) : {};
114
- const result = await validateNextAuth(identityField, identity, protectIdentities, list); // ID
115
-
104
+ const result = await validateNextAuth(identityField, identity, protectIdentities, list);
105
+ // ID
116
106
  const data = _objectSpread({
117
107
  [identityField]: identity
118
108
  }, userInput);
119
-
120
109
  if (!result.success) {
121
110
  if (!autoCreate) {
122
111
  return false;
123
112
  }
124
-
125
113
  const createUser = await list.createOne({
126
114
  data
127
115
  }).then(returned => {
@@ -135,7 +123,6 @@ function NextAuthPage(props) {
135
123
  });
136
124
  return createUser.success;
137
125
  }
138
-
139
126
  const updateUser = await list.updateOne({
140
127
  where: {
141
128
  id: result.item.id
@@ -152,21 +139,18 @@ function NextAuthPage(props) {
152
139
  });
153
140
  return updateUser.success;
154
141
  },
155
-
156
142
  async redirect(_ref2) {
157
143
  let {
158
144
  url
159
145
  } = _ref2;
160
146
  return url;
161
147
  },
162
-
163
148
  async session(_ref3) {
164
149
  let {
165
150
  session,
166
151
  token
167
152
  } = _ref3;
168
153
  let returnSession = session;
169
-
170
154
  if (!token.itemId) {
171
155
  return session;
172
156
  } else {
@@ -177,22 +161,17 @@ function NextAuthPage(props) {
177
161
  itemId: token.itemId
178
162
  });
179
163
  }
180
-
181
164
  return returnSession;
182
165
  },
183
-
184
166
  async jwt(_ref4) {
185
167
  let {
186
168
  token
187
169
  } = _ref4;
188
170
  const identity = token.sub;
189
-
190
171
  if (!identity) {
191
172
  return token;
192
173
  }
193
-
194
174
  const result = await validateNextAuth(identityField, identity, protectIdentities, list);
195
-
196
175
  if (!result.success) {
197
176
  token.itemId = undefined;
198
177
  } else {
@@ -205,15 +184,12 @@ function NextAuthPage(props) {
205
184
  });
206
185
  token.data = data;
207
186
  }
208
-
209
187
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
210
188
  subject: token.sub,
211
189
  listKey
212
190
  });
213
-
214
191
  return returnToken;
215
192
  }
216
-
217
193
  }
218
194
  });
219
195
  }
@@ -14,21 +14,18 @@ async function findMatchingIdentity(identityField, identity, queryAPI) {
14
14
  where: {
15
15
  [identityField]: identity
16
16
  }
17
- }); // Identity failures with helpful errors
18
-
17
+ });
18
+ // Identity failures with helpful errors
19
19
  let code;
20
-
21
20
  if (!item) {
22
21
  code = 'IDENTITY_NOT_FOUND';
23
22
  }
24
-
25
23
  if (code) {
26
24
  return {
27
25
  success: false,
28
26
  code
29
27
  };
30
28
  }
31
-
32
29
  return {
33
30
  success: true,
34
31
  item
@@ -40,14 +37,12 @@ async function validateNextAuth(identityField, identity, protectIdentities, item
40
37
  const {
41
38
  item
42
39
  } = match;
43
-
44
40
  if (item) {
45
41
  return {
46
42
  success: true,
47
43
  item
48
44
  };
49
45
  }
50
-
51
46
  return {
52
47
  success: false,
53
48
  code: protectIdentities ? 'FAILURE' : 'SUBJECT_NOT_FOUND'
@@ -69,17 +64,14 @@ function NextAuthPage(props) {
69
64
  sessionData,
70
65
  sessionSecret
71
66
  } = props;
72
-
73
67
  if (!query) {
74
68
  console.error('NextAuthPage got no query.');
75
69
  return null;
76
70
  }
77
-
78
71
  if (!providers || !providers.length) {
79
72
  console.error('You need to provide at least one provider.');
80
73
  return null;
81
74
  }
82
-
83
75
  const list = query[listKey];
84
76
  const protectIdentities = true;
85
77
  return NextAuth__default["default"]({
@@ -97,7 +89,6 @@ function NextAuthPage(props) {
97
89
  profile
98
90
  } = _ref;
99
91
  let identity;
100
-
101
92
  if (typeof user.id === 'string') {
102
93
  identity = user.id;
103
94
  } else if (typeof user.id === 'number') {
@@ -105,23 +96,20 @@ function NextAuthPage(props) {
105
96
  } else {
106
97
  identity = 0;
107
98
  }
108
-
109
99
  const userInput = resolver ? await resolver({
110
100
  user,
111
101
  account,
112
102
  profile
113
103
  }) : {};
114
- const result = await validateNextAuth(identityField, identity, protectIdentities, list); // ID
115
-
104
+ const result = await validateNextAuth(identityField, identity, protectIdentities, list);
105
+ // ID
116
106
  const data = _objectSpread({
117
107
  [identityField]: identity
118
108
  }, userInput);
119
-
120
109
  if (!result.success) {
121
110
  if (!autoCreate) {
122
111
  return false;
123
112
  }
124
-
125
113
  const createUser = await list.createOne({
126
114
  data
127
115
  }).then(returned => {
@@ -135,7 +123,6 @@ function NextAuthPage(props) {
135
123
  });
136
124
  return createUser.success;
137
125
  }
138
-
139
126
  const updateUser = await list.updateOne({
140
127
  where: {
141
128
  id: result.item.id
@@ -152,21 +139,18 @@ function NextAuthPage(props) {
152
139
  });
153
140
  return updateUser.success;
154
141
  },
155
-
156
142
  async redirect(_ref2) {
157
143
  let {
158
144
  url
159
145
  } = _ref2;
160
146
  return url;
161
147
  },
162
-
163
148
  async session(_ref3) {
164
149
  let {
165
150
  session,
166
151
  token
167
152
  } = _ref3;
168
153
  let returnSession = session;
169
-
170
154
  if (!token.itemId) {
171
155
  return session;
172
156
  } else {
@@ -177,22 +161,17 @@ function NextAuthPage(props) {
177
161
  itemId: token.itemId
178
162
  });
179
163
  }
180
-
181
164
  return returnSession;
182
165
  },
183
-
184
166
  async jwt(_ref4) {
185
167
  let {
186
168
  token
187
169
  } = _ref4;
188
170
  const identity = token.sub;
189
-
190
171
  if (!identity) {
191
172
  return token;
192
173
  }
193
-
194
174
  const result = await validateNextAuth(identityField, identity, protectIdentities, list);
195
-
196
175
  if (!result.success) {
197
176
  token.itemId = undefined;
198
177
  } else {
@@ -205,15 +184,12 @@ function NextAuthPage(props) {
205
184
  });
206
185
  token.data = data;
207
186
  }
208
-
209
187
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
210
188
  subject: token.sub,
211
189
  listKey
212
190
  });
213
-
214
191
  return returnToken;
215
192
  }
216
-
217
193
  }
218
194
  });
219
195
  }
@@ -6,21 +6,18 @@ async function findMatchingIdentity(identityField, identity, queryAPI) {
6
6
  where: {
7
7
  [identityField]: identity
8
8
  }
9
- }); // Identity failures with helpful errors
10
-
9
+ });
10
+ // Identity failures with helpful errors
11
11
  let code;
12
-
13
12
  if (!item) {
14
13
  code = 'IDENTITY_NOT_FOUND';
15
14
  }
16
-
17
15
  if (code) {
18
16
  return {
19
17
  success: false,
20
18
  code
21
19
  };
22
20
  }
23
-
24
21
  return {
25
22
  success: true,
26
23
  item
@@ -32,14 +29,12 @@ async function validateNextAuth(identityField, identity, protectIdentities, item
32
29
  const {
33
30
  item
34
31
  } = match;
35
-
36
32
  if (item) {
37
33
  return {
38
34
  success: true,
39
35
  item
40
36
  };
41
37
  }
42
-
43
38
  return {
44
39
  success: false,
45
40
  code: protectIdentities ? 'FAILURE' : 'SUBJECT_NOT_FOUND'
@@ -61,17 +56,14 @@ function NextAuthPage(props) {
61
56
  sessionData,
62
57
  sessionSecret
63
58
  } = props;
64
-
65
59
  if (!query) {
66
60
  console.error('NextAuthPage got no query.');
67
61
  return null;
68
62
  }
69
-
70
63
  if (!providers || !providers.length) {
71
64
  console.error('You need to provide at least one provider.');
72
65
  return null;
73
66
  }
74
-
75
67
  const list = query[listKey];
76
68
  const protectIdentities = true;
77
69
  return NextAuth({
@@ -89,7 +81,6 @@ function NextAuthPage(props) {
89
81
  profile
90
82
  } = _ref;
91
83
  let identity;
92
-
93
84
  if (typeof user.id === 'string') {
94
85
  identity = user.id;
95
86
  } else if (typeof user.id === 'number') {
@@ -97,23 +88,20 @@ function NextAuthPage(props) {
97
88
  } else {
98
89
  identity = 0;
99
90
  }
100
-
101
91
  const userInput = resolver ? await resolver({
102
92
  user,
103
93
  account,
104
94
  profile
105
95
  }) : {};
106
- const result = await validateNextAuth(identityField, identity, protectIdentities, list); // ID
107
-
96
+ const result = await validateNextAuth(identityField, identity, protectIdentities, list);
97
+ // ID
108
98
  const data = _objectSpread({
109
99
  [identityField]: identity
110
100
  }, userInput);
111
-
112
101
  if (!result.success) {
113
102
  if (!autoCreate) {
114
103
  return false;
115
104
  }
116
-
117
105
  const createUser = await list.createOne({
118
106
  data
119
107
  }).then(returned => {
@@ -127,7 +115,6 @@ function NextAuthPage(props) {
127
115
  });
128
116
  return createUser.success;
129
117
  }
130
-
131
118
  const updateUser = await list.updateOne({
132
119
  where: {
133
120
  id: result.item.id
@@ -144,21 +131,18 @@ function NextAuthPage(props) {
144
131
  });
145
132
  return updateUser.success;
146
133
  },
147
-
148
134
  async redirect(_ref2) {
149
135
  let {
150
136
  url
151
137
  } = _ref2;
152
138
  return url;
153
139
  },
154
-
155
140
  async session(_ref3) {
156
141
  let {
157
142
  session,
158
143
  token
159
144
  } = _ref3;
160
145
  let returnSession = session;
161
-
162
146
  if (!token.itemId) {
163
147
  return session;
164
148
  } else {
@@ -169,22 +153,17 @@ function NextAuthPage(props) {
169
153
  itemId: token.itemId
170
154
  });
171
155
  }
172
-
173
156
  return returnSession;
174
157
  },
175
-
176
158
  async jwt(_ref4) {
177
159
  let {
178
160
  token
179
161
  } = _ref4;
180
162
  const identity = token.sub;
181
-
182
163
  if (!identity) {
183
164
  return token;
184
165
  }
185
-
186
166
  const result = await validateNextAuth(identityField, identity, protectIdentities, list);
187
-
188
167
  if (!result.success) {
189
168
  token.itemId = undefined;
190
169
  } else {
@@ -197,15 +176,12 @@ function NextAuthPage(props) {
197
176
  });
198
177
  token.data = data;
199
178
  }
200
-
201
179
  const returnToken = _objectSpread(_objectSpread({}, token), {}, {
202
180
  subject: token.sub,
203
181
  listKey
204
182
  });
205
-
206
183
  return returnToken;
207
184
  }
208
-
209
185
  }
210
186
  });
211
187
  }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import url from 'url';
2
+ import path from 'path';
2
3
  import {
3
4
  AdminFileToWrite,
4
5
  BaseListTypeInfo,
@@ -61,18 +62,18 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
61
62
  */
62
63
  const authMiddleware: AdminUIConfig<BaseKeystoneTypeInfo>['pageMiddleware'] = async ({
63
64
  context,
64
- isValidSession,
65
+ wasAccessAllowed,
65
66
  }) => {
66
- const { req, session } = context;
67
+ const { req } = context;
67
68
  const pathname = url.parse(req?.url!).pathname!;
68
69
 
69
- if (isValidSession) {
70
+ if (wasAccessAllowed) {
70
71
  if (customPath !== '' && pathname === '/') {
71
72
  return { kind: 'redirect', to: `${customPath}` };
72
73
  }
73
74
  return;
74
75
  }
75
- if (!session && !pathname.includes(`${customPath}/api/auth/`)) {
76
+ if (!wasAccessAllowed && !pathname.includes(`${customPath}/api/auth/`)) {
76
77
  return {
77
78
  kind: 'redirect',
78
79
  to: pages?.signIn || `${customPath}/api/auth/signin`,
@@ -88,7 +89,10 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
88
89
  *
89
90
  * The signin page is always included, and the init page is included when initFirstItem is set
90
91
  */
91
- const authGetAdditionalFiles = () => {
92
+ const authGetAdditionalFiles = (config: KeystoneConfig) => {
93
+ const prismaClientPath = config.db.prismaClientPath
94
+ ? path.join('../../../../../', config.db.prismaClientPath)
95
+ : '@prisma/client';
92
96
  const filesToWrite: AdminFileToWrite[] = [
93
97
  {
94
98
  mode: 'write',
@@ -99,6 +103,7 @@ export function createAuth<GeneratedListTypes extends BaseListTypeInfo>({
99
103
  listKey,
100
104
  sessionData,
101
105
  sessionSecret,
106
+ prismaClientPath,
102
107
  }),
103
108
  },
104
109
  {
@@ -10,6 +10,7 @@ export type NextAuthTemplateProps = {
10
10
  listKey: string;
11
11
  sessionData: string | undefined;
12
12
  sessionSecret: string;
13
+ prismaClientPath: string;
13
14
  };
14
15
 
15
16
  export type CoreNextAuthPageProps = {
@@ -5,7 +5,7 @@ const template = `
5
5
  import { getContext } from '@keystone-6/core/context';
6
6
  import getNextAuthPage from '@opensaas/keystone-nextjs-auth/pages/NextAuthPage';
7
7
  import keystoneConfig from '../../../../../keystone';
8
- import * as PrismaModule from '.prisma/client';
8
+ import * as PrismaModule from '<%= prismaClientPath %>';
9
9
 
10
10
  const keystoneQueryAPI = global.keystoneQueryAPI || getContext(keystoneConfig, PrismaModule).sudo().query;
11
11
 
@@ -30,6 +30,7 @@ export const authTemplate = ({
30
30
  listKey,
31
31
  sessionData,
32
32
  sessionSecret,
33
+ prismaClientPath,
33
34
  }: NextAuthTemplateProps) => {
34
35
  const authOut = ejs.render(template, {
35
36
  identityField,
@@ -37,6 +38,7 @@ export const authTemplate = ({
37
38
  listKey,
38
39
  autoCreate,
39
40
  sessionSecret,
41
+ prismaClientPath,
40
42
  });
41
43
  return authOut;
42
44
  };