@adminforth/open-signup 1.3.0 → 2.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/build.log +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +36 -9
- package/dist/types.d.ts +5 -0
- package/index.ts +40 -7
- package/package.json +3 -3
- package/types.ts +7 -0
package/build.log
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
10
10
|
adminforth: IAdminForth;
|
|
11
11
|
constructor(options: PluginOptions);
|
|
12
12
|
modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource): Promise<void>;
|
|
13
|
+
getAllowedOrigins(): string[];
|
|
13
14
|
validateConfigAfterDiscover(adminforth: IAdminForth, resourceConfig: AdminForthResource): void;
|
|
14
15
|
instanceUniqueRepresentation(pluginOptions: any): string;
|
|
15
16
|
doLogin(email: string, response: any, extra: HttpExtra): Promise<{
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import AdminForth, { AdminForthPlugin,
|
|
10
|
+
import AdminForth, { AdminForthPlugin, Filters, suggestIfTypo, AdminForthDataTypes } from "adminforth";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
const completeVerifiedSignupBodySchema = z.object({
|
|
13
13
|
token: z.string(),
|
|
@@ -94,8 +94,27 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
94
94
|
adminforth.config.auth.beforeLoginConfirmation = [];
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
const rawOrigins = this.options.expectedOrigin;
|
|
98
|
+
const originList = Array.isArray(rawOrigins) ? rawOrigins : [rawOrigins];
|
|
99
|
+
if (!rawOrigins || originList.length === 0 || originList.some(o => !o)) {
|
|
100
|
+
throw new Error('EmailPasswordReset: expectedOrigin is required. Set it to the admin panel origin(s) ' +
|
|
101
|
+
'(e.g. "https://admin.example.com") so reset links can only point to a trusted host.');
|
|
102
|
+
}
|
|
103
|
+
for (const origin of originList) {
|
|
104
|
+
try {
|
|
105
|
+
new URL(origin);
|
|
106
|
+
}
|
|
107
|
+
catch (_a) {
|
|
108
|
+
throw new Error(`EmailPasswordReset: expectedOrigin "${origin}" is not a valid absolute URL/origin.`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
97
111
|
});
|
|
98
112
|
}
|
|
113
|
+
getAllowedOrigins() {
|
|
114
|
+
const rawOrigins = this.options.expectedOrigin;
|
|
115
|
+
const originList = Array.isArray(rawOrigins) ? rawOrigins : [rawOrigins];
|
|
116
|
+
return originList.map(o => new URL(o).origin);
|
|
117
|
+
}
|
|
99
118
|
validateConfigAfterDiscover(adminforth, resourceConfig) {
|
|
100
119
|
if (this.options.confirmEmails) {
|
|
101
120
|
this.options.confirmEmails.adapter.validate();
|
|
@@ -159,11 +178,9 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
159
178
|
method: 'POST',
|
|
160
179
|
path: `/plugin/${this.pluginInstanceId}/complete-verified-signup`,
|
|
161
180
|
noAuth: true,
|
|
181
|
+
request_schema: completeVerifiedSignupBodySchema,
|
|
162
182
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response, headers, query, cookies, tr, requestUrl }) {
|
|
163
|
-
const
|
|
164
|
-
if ('error' in parsed)
|
|
165
|
-
return parsed.error;
|
|
166
|
-
const data = parsed.data;
|
|
183
|
+
const data = body;
|
|
167
184
|
const { token, password } = data;
|
|
168
185
|
if (!token) {
|
|
169
186
|
return { error: yield tr('Invalid token', 'opensignup'), ok: false };
|
|
@@ -194,12 +211,10 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
194
211
|
method: 'POST',
|
|
195
212
|
path: `/plugin/${this.pluginInstanceId}/signup`,
|
|
196
213
|
noAuth: true,
|
|
214
|
+
request_schema: signupBodySchema,
|
|
197
215
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, response, headers, query, cookies, tr, requestUrl }) {
|
|
198
216
|
var _b, _c;
|
|
199
|
-
const
|
|
200
|
-
if ('error' in parsed)
|
|
201
|
-
return parsed.error;
|
|
202
|
-
const data = parsed.data;
|
|
217
|
+
const data = body;
|
|
203
218
|
const { email, url, password } = data;
|
|
204
219
|
if (!email || typeof email !== 'string') {
|
|
205
220
|
return { error: yield tr('Email is required', 'opensignup'), ok: false };
|
|
@@ -207,6 +222,18 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
207
222
|
if (!this.options.confirmEmails && !password) {
|
|
208
223
|
return { error: yield tr('Password is required', 'opensignup'), ok: false };
|
|
209
224
|
}
|
|
225
|
+
let resetLink;
|
|
226
|
+
try {
|
|
227
|
+
const parsedUrl = new URL(url);
|
|
228
|
+
if (!this.getAllowedOrigins().includes(parsedUrl.origin)) {
|
|
229
|
+
return { error: 'Invalid reset url', ok: false };
|
|
230
|
+
}
|
|
231
|
+
parsedUrl.hash = '';
|
|
232
|
+
resetLink = parsedUrl.toString();
|
|
233
|
+
}
|
|
234
|
+
catch (_d) {
|
|
235
|
+
return { error: 'Invalid reset url', ok: false };
|
|
236
|
+
}
|
|
210
237
|
const extra = { body, headers, query, cookies, requestUrl: url };
|
|
211
238
|
// validate email
|
|
212
239
|
if (this.emailField.validation) {
|
package/dist/types.d.ts
CHANGED
|
@@ -54,4 +54,9 @@ export interface PluginOptions extends PluginsCommonOptions {
|
|
|
54
54
|
* Signup component order inder login button
|
|
55
55
|
*/
|
|
56
56
|
loginPageComponentOrder?: number;
|
|
57
|
+
/**
|
|
58
|
+
* The origin(s) (scheme + host + optional port) of the admin panel that are
|
|
59
|
+
* allowed to appear in password reset links, e.g. "https://admin.example.com".
|
|
60
|
+
*/
|
|
61
|
+
expectedOrigin: string | string[];
|
|
57
62
|
}
|
package/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import AdminForth, { AdminForthPlugin,
|
|
1
|
+
import AdminForth, { AdminForthPlugin, Filters, suggestIfTypo, AdminForthDataTypes } from "adminforth";
|
|
2
2
|
import type { IAdminForth, IHttpServer, AdminForthComponentDeclaration, AdminForthResourceColumn, AdminForthResource, BeforeLoginConfirmationFunction, HttpExtra } from "adminforth";
|
|
3
3
|
import type { PluginOptions } from './types.js';
|
|
4
4
|
import { z } from "zod";
|
|
@@ -106,6 +106,28 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
106
106
|
adminforth.config.auth.beforeLoginConfirmation = [];
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
const rawOrigins = this.options.expectedOrigin;
|
|
111
|
+
const originList = Array.isArray(rawOrigins) ? rawOrigins : [rawOrigins];
|
|
112
|
+
if (!rawOrigins || originList.length === 0 || originList.some(o => !o)) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
'EmailPasswordReset: expectedOrigin is required. Set it to the admin panel origin(s) ' +
|
|
115
|
+
'(e.g. "https://admin.example.com") so reset links can only point to a trusted host.'
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
for (const origin of originList) {
|
|
119
|
+
try {
|
|
120
|
+
new URL(origin);
|
|
121
|
+
} catch {
|
|
122
|
+
throw new Error(`EmailPasswordReset: expectedOrigin "${origin}" is not a valid absolute URL/origin.`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
getAllowedOrigins(): string[] {
|
|
128
|
+
const rawOrigins = this.options.expectedOrigin;
|
|
129
|
+
const originList = Array.isArray(rawOrigins) ? rawOrigins : [rawOrigins];
|
|
130
|
+
return originList.map(o => new URL(o).origin);
|
|
109
131
|
}
|
|
110
132
|
|
|
111
133
|
validateConfigAfterDiscover(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
|
|
@@ -185,10 +207,9 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
185
207
|
method: 'POST',
|
|
186
208
|
path: `/plugin/${this.pluginInstanceId}/complete-verified-signup`,
|
|
187
209
|
noAuth: true,
|
|
210
|
+
request_schema: completeVerifiedSignupBodySchema,
|
|
188
211
|
handler: async ({ body, response, headers, query, cookies, tr, requestUrl }) => {
|
|
189
|
-
const
|
|
190
|
-
if ('error' in parsed) return parsed.error;
|
|
191
|
-
const data = parsed.data;
|
|
212
|
+
const data = body as z.infer<typeof completeVerifiedSignupBodySchema>;
|
|
192
213
|
const { token, password } = data;
|
|
193
214
|
if (!token) {
|
|
194
215
|
return { error: await tr('Invalid token', 'opensignup'), ok: false };
|
|
@@ -223,10 +244,9 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
223
244
|
method: 'POST',
|
|
224
245
|
path: `/plugin/${this.pluginInstanceId}/signup`,
|
|
225
246
|
noAuth: true,
|
|
247
|
+
request_schema: signupBodySchema,
|
|
226
248
|
handler: async ({ body, response, headers, query, cookies, tr, requestUrl }) => {
|
|
227
|
-
const
|
|
228
|
-
if ('error' in parsed) return parsed.error;
|
|
229
|
-
const data = parsed.data;
|
|
249
|
+
const data = body as z.infer<typeof signupBodySchema>;
|
|
230
250
|
const { email, url, password } = data;
|
|
231
251
|
if (!email || typeof email !== 'string') {
|
|
232
252
|
return { error: await tr('Email is required', 'opensignup'), ok: false };
|
|
@@ -234,6 +254,19 @@ export default class OpenSignupPlugin extends AdminForthPlugin {
|
|
|
234
254
|
if (!this.options.confirmEmails && !password) {
|
|
235
255
|
return { error: await tr('Password is required', 'opensignup'), ok: false };
|
|
236
256
|
}
|
|
257
|
+
|
|
258
|
+
let resetLink: string;
|
|
259
|
+
try {
|
|
260
|
+
const parsedUrl = new URL(url);
|
|
261
|
+
if (!this.getAllowedOrigins().includes(parsedUrl.origin)) {
|
|
262
|
+
return { error: 'Invalid reset url', ok: false };
|
|
263
|
+
}
|
|
264
|
+
parsedUrl.hash = '';
|
|
265
|
+
resetLink = parsedUrl.toString();
|
|
266
|
+
} catch {
|
|
267
|
+
return { error: 'Invalid reset url', ok: false };
|
|
268
|
+
}
|
|
269
|
+
|
|
237
270
|
const extra = { body, headers, query, cookies, requestUrl: url };
|
|
238
271
|
// validate email
|
|
239
272
|
if (this.emailField.validation) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminforth/open-signup",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"zod": "^4.3.6"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"adminforth": "^3.
|
|
30
|
+
"adminforth": "^3.8.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.10.7",
|
|
34
|
-
"adminforth": "^3.
|
|
34
|
+
"adminforth": "^3.8.2",
|
|
35
35
|
"semantic-release": "^24.2.1",
|
|
36
36
|
"semantic-release-slack-bot": "^4.0.2",
|
|
37
37
|
"typescript": "^5.7.3"
|
package/types.ts
CHANGED
|
@@ -70,4 +70,11 @@ export interface PluginOptions extends PluginsCommonOptions {
|
|
|
70
70
|
* Signup component order inder login button
|
|
71
71
|
*/
|
|
72
72
|
loginPageComponentOrder?: number;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The origin(s) (scheme + host + optional port) of the admin panel that are
|
|
76
|
+
* allowed to appear in password reset links, e.g. "https://admin.example.com".
|
|
77
|
+
*/
|
|
78
|
+
expectedOrigin: string | string[];
|
|
79
|
+
|
|
73
80
|
}
|