@opensaas/keystone-nextjs-auth 26.0.0 → 27.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 +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
|
};
|