@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 +16 -0
- package/dist/declarations/src/pages/NextAuthPage.d.ts +1 -0
- package/dist/declarations/src/templates/auth.d.ts +1 -1
- package/dist/opensaas-keystone-nextjs-auth.cjs.dev.js +34 -62
- package/dist/opensaas-keystone-nextjs-auth.cjs.prod.js +34 -62
- package/dist/opensaas-keystone-nextjs-auth.esm.js +33 -62
- package/package.json +7 -7
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.dev.js +4 -28
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.prod.js +4 -28
- package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.esm.js +4 -28
- package/src/index.ts +10 -5
- package/src/pages/NextAuthPage.tsx +1 -0
- package/src/templates/auth.ts +3 -1
package/package.json
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
{
|
2
2
|
"name": "@opensaas/keystone-nextjs-auth",
|
3
|
-
"version": "
|
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.
|
10
|
-
"@babel/runtime-corejs3": "^7.
|
11
|
-
"@types/ejs": "^3.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.
|
16
|
+
"next-auth": "^4.19.2"
|
17
17
|
},
|
18
18
|
"devDependencies": {
|
19
|
-
"@keystone-6/core": "
|
19
|
+
"@keystone-6/core": "5.0.0",
|
20
20
|
"react": "^18.2.0"
|
21
21
|
},
|
22
22
|
"peerDependencies": {
|
23
|
-
"@keystone-6/core": "
|
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
|
-
});
|
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);
|
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
|
}
|
package/pages/NextAuthPage/dist/opensaas-keystone-nextjs-auth-pages-NextAuthPage.cjs.prod.js
CHANGED
@@ -14,21 +14,18 @@ async function findMatchingIdentity(identityField, identity, queryAPI) {
|
|
14
14
|
where: {
|
15
15
|
[identityField]: identity
|
16
16
|
}
|
17
|
-
});
|
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);
|
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
|
-
});
|
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);
|
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
|
-
|
65
|
+
wasAccessAllowed,
|
65
66
|
}) => {
|
66
|
-
const { req
|
67
|
+
const { req } = context;
|
67
68
|
const pathname = url.parse(req?.url!).pathname!;
|
68
69
|
|
69
|
-
if (
|
70
|
+
if (wasAccessAllowed) {
|
70
71
|
if (customPath !== '' && pathname === '/') {
|
71
72
|
return { kind: 'redirect', to: `${customPath}` };
|
72
73
|
}
|
73
74
|
return;
|
74
75
|
}
|
75
|
-
if (!
|
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
|
{
|
package/src/templates/auth.ts
CHANGED
@@ -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 '
|
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
|
};
|