@vandenberghinc/volt 1.1.28 → 1.1.30
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/backend/dist/cjs/backend/src/endpoint.js +1 -1
- package/backend/dist/cjs/backend/src/frontend.js +1 -1
- package/backend/dist/cjs/backend/src/rate_limit.d.ts +7 -7
- package/backend/dist/cjs/backend/src/rate_limit.js +1 -8
- package/backend/dist/cjs/backend/src/server.js +1 -1
- package/backend/dist/cjs/backend/src/users.d.ts +3 -1
- package/backend/dist/cjs/backend/src/users.js +29 -9
- package/backend/dist/cjs/backend/src/view.d.ts +3 -1
- package/backend/dist/cjs/backend/src/view.js +6 -1
- package/backend/dist/esm/backend/src/endpoint.js +1 -1
- package/backend/dist/esm/backend/src/frontend.js +1 -1
- package/backend/dist/esm/backend/src/server.js +2 -2
- package/backend/dist/esm/backend/src/view.d.ts +3 -1
- package/backend/dist/esm/backend/src/view.js +6 -1
- package/frontend/dist/backend/src/endpoint.js +1 -1
- package/frontend/dist/backend/src/frontend.js +1 -1
- package/frontend/dist/backend/src/rate_limit.d.ts +7 -7
- package/frontend/dist/backend/src/rate_limit.js +1 -7
- package/frontend/dist/backend/src/server.js +2 -2
- package/frontend/dist/backend/src/users.d.ts +3 -1
- package/frontend/dist/backend/src/users.js +31 -9
- package/frontend/dist/backend/src/view.d.ts +3 -1
- package/frontend/dist/backend/src/view.js +6 -1
- package/frontend/dist/frontend/src/css/adyen.css +92 -0
- package/frontend/dist/frontend/src/css/volt.css +70 -0
- package/package.json +3 -4
|
@@ -27,7 +27,7 @@ const Frontend = {
|
|
|
27
27
|
/** CSS exports. */
|
|
28
28
|
css: {
|
|
29
29
|
/** The default volt css export. */
|
|
30
|
-
volt: __dirname + "/../../../../../frontend/src/css/volt.css"
|
|
30
|
+
volt: __dirname + "/../../../../../frontend/dist/frontend/src/css/volt.css"
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
var stdin_default = Frontend;
|
|
@@ -6,13 +6,19 @@ import * as https from "https";
|
|
|
6
6
|
import * as vlib from "@vandenberghinc/vlib";
|
|
7
7
|
import type { Server } from "./server.js";
|
|
8
8
|
export interface RateLimitGroup {
|
|
9
|
+
/** The rate limit group name. */
|
|
9
10
|
group?: string | null;
|
|
11
|
+
/** The maximum requests per rate limit interval. */
|
|
10
12
|
limit?: number | null;
|
|
13
|
+
/** The rate limit interval in seconds. */
|
|
11
14
|
interval?: number | null;
|
|
12
15
|
}
|
|
13
16
|
export interface RateLimitData {
|
|
17
|
+
/** The rate limit group name. */
|
|
14
18
|
group: string;
|
|
19
|
+
/** The maximum requests per rate limit interval. */
|
|
15
20
|
limit: number;
|
|
21
|
+
/** The rate limit interval in seconds. */
|
|
16
22
|
interval: number;
|
|
17
23
|
}
|
|
18
24
|
export interface RateLimitCacheData {
|
|
@@ -37,13 +43,7 @@ export declare namespace RateLimits {
|
|
|
37
43
|
* @param interval The rate limit interval in seconds, defaults to 60.
|
|
38
44
|
* @docs
|
|
39
45
|
*/
|
|
40
|
-
function add({
|
|
41
|
-
/** The rate limit group name. */
|
|
42
|
-
group,
|
|
43
|
-
/** The maximum requests per rate limit interval. */
|
|
44
|
-
limit,
|
|
45
|
-
/** The rate limit interval in seconds. */
|
|
46
|
-
interval, }: RateLimitGroup): RateLimitData;
|
|
46
|
+
function add({ group, limit, interval }: RateLimitGroup): RateLimitData;
|
|
47
47
|
/**
|
|
48
48
|
* Normalize an IPv4 or IPv6 address into a unique, canonical string suitable for rate limiting keys.
|
|
49
49
|
*
|
|
@@ -40,14 +40,7 @@ var RateLimits;
|
|
|
40
40
|
/** The `global` rate settings. */
|
|
41
41
|
["global", { group: "global", interval: 60, limit: 1e3 }]
|
|
42
42
|
]);
|
|
43
|
-
function add({
|
|
44
|
-
/** The rate limit group name. */
|
|
45
|
-
group = null,
|
|
46
|
-
/** The maximum requests per rate limit interval. */
|
|
47
|
-
limit = null,
|
|
48
|
-
/** The rate limit interval in seconds. */
|
|
49
|
-
interval = null
|
|
50
|
-
}) {
|
|
43
|
+
function add({ group, limit, interval }) {
|
|
51
44
|
const settings = RateLimits2.groups.has(group) ? RateLimits2.groups.get(group) : { group: "", limit: 0, interval: 0 };
|
|
52
45
|
settings.group = group;
|
|
53
46
|
if (limit) {
|
|
@@ -1391,7 +1391,7 @@ Sitemap: ${this.full_domain}/sitemap.xml`;
|
|
|
1391
1391
|
if (this.production) {
|
|
1392
1392
|
for (const endpoint of this.endpoints.values()) {
|
|
1393
1393
|
if (endpoint.view) {
|
|
1394
|
-
await endpoint.view.
|
|
1394
|
+
await endpoint.view.production_initialize();
|
|
1395
1395
|
}
|
|
1396
1396
|
}
|
|
1397
1397
|
}
|
|
@@ -324,6 +324,7 @@ export declare class Users {
|
|
|
324
324
|
* @param username The username of the new account.
|
|
325
325
|
* @param email The email of the new account.
|
|
326
326
|
* @param password The password of the new account.
|
|
327
|
+
* @param verify_password An optional second password input to check against the first input to ensure its the same.
|
|
327
328
|
* @param phone_number The phone number of the user account.
|
|
328
329
|
* @param is_activated Whether the account should be set to activated; by default `!Server.enable_account_activation`.
|
|
329
330
|
* @example
|
|
@@ -335,12 +336,13 @@ export declare class Users {
|
|
|
335
336
|
* password: "HelloWorld!"
|
|
336
337
|
* });
|
|
337
338
|
*/
|
|
338
|
-
create({ first_name, last_name, username, email, password, phone_number, is_activated, _check_username_email, }: {
|
|
339
|
+
create({ first_name, last_name, username, email, password, verify_password, phone_number, is_activated, _check_username_email, }: {
|
|
339
340
|
first_name: string;
|
|
340
341
|
last_name: string;
|
|
341
342
|
username: string;
|
|
342
343
|
email: string;
|
|
343
344
|
password: string;
|
|
345
|
+
verify_password?: string;
|
|
344
346
|
phone_number?: string;
|
|
345
347
|
is_activated?: boolean;
|
|
346
348
|
_check_username_email?: boolean;
|
|
@@ -284,18 +284,18 @@ class Users {
|
|
|
284
284
|
let error = void 0;
|
|
285
285
|
if (pass !== verify_pass) {
|
|
286
286
|
error = "Passwords do not match.";
|
|
287
|
-
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
288
287
|
} else if (pass.length < 8) {
|
|
289
288
|
error = "The password should at least include eight characters.";
|
|
290
|
-
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
291
289
|
} else if (pass.toLowerCase() === pass) {
|
|
292
290
|
error = "The password should at least include one capital letter.";
|
|
293
|
-
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
294
291
|
} else if (!/\d|[!@#$%^&*]/.test(pass)) {
|
|
295
292
|
error = "The password should at least include one numeric or special character.";
|
|
293
|
+
}
|
|
294
|
+
if (error) {
|
|
296
295
|
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
296
|
+
} else {
|
|
297
|
+
return { error: void 0, invalid_fields: void 0 };
|
|
297
298
|
}
|
|
298
|
-
return { error: void 0, invalid_fields: void 0 };
|
|
299
299
|
}
|
|
300
300
|
// ---------------------------------------------------------
|
|
301
301
|
// Authentication (private).
|
|
@@ -664,7 +664,10 @@ class Users {
|
|
|
664
664
|
method: "POST",
|
|
665
665
|
endpoint: "/volt/api/v1/auth/signup",
|
|
666
666
|
content_type: "application/json",
|
|
667
|
-
rate_limit:
|
|
667
|
+
rate_limit: [
|
|
668
|
+
"global",
|
|
669
|
+
{ limit: 5, interval: 60 * 10, group: "volt/Users/signup" }
|
|
670
|
+
],
|
|
668
671
|
params: {
|
|
669
672
|
username: { type: "string", allow_empty: false },
|
|
670
673
|
first_name: { type: "string", allow_empty: false },
|
|
@@ -676,6 +679,7 @@ class Users {
|
|
|
676
679
|
code: { type: "string", required: false }
|
|
677
680
|
},
|
|
678
681
|
callback: async (stream, params) => {
|
|
682
|
+
console.log("signup 1", params);
|
|
679
683
|
const { error, invalid_fields } = this._verify_new_pass(params.password, params.verify_password);
|
|
680
684
|
if (error) {
|
|
681
685
|
return stream.error({
|
|
@@ -736,9 +740,14 @@ class Users {
|
|
|
736
740
|
let uid;
|
|
737
741
|
try {
|
|
738
742
|
uid = await this.create({
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
743
|
+
// dont unpack params since we are performing param validation inside create().
|
|
744
|
+
first_name: params.first_name,
|
|
745
|
+
last_name: params.last_name,
|
|
746
|
+
username: params.username,
|
|
747
|
+
email: params.email,
|
|
748
|
+
password: params.password,
|
|
749
|
+
verify_password: params.verify_password,
|
|
750
|
+
phone_number: params.phone_number,
|
|
742
751
|
is_activated: true,
|
|
743
752
|
// already verified by 2fa or no 2fa is enabled.
|
|
744
753
|
_check_username_email: false
|
|
@@ -1380,6 +1389,7 @@ class Users {
|
|
|
1380
1389
|
* @param username The username of the new account.
|
|
1381
1390
|
* @param email The email of the new account.
|
|
1382
1391
|
* @param password The password of the new account.
|
|
1392
|
+
* @param verify_password An optional second password input to check against the first input to ensure its the same.
|
|
1383
1393
|
* @param phone_number The phone number of the user account.
|
|
1384
1394
|
* @param is_activated Whether the account should be set to activated; by default `!Server.enable_account_activation`.
|
|
1385
1395
|
* @example
|
|
@@ -1391,7 +1401,7 @@ class Users {
|
|
|
1391
1401
|
* password: "HelloWorld!"
|
|
1392
1402
|
* });
|
|
1393
1403
|
*/
|
|
1394
|
-
async create({ first_name, last_name, username, email, password, phone_number = "", is_activated = void 0, _check_username_email = false }) {
|
|
1404
|
+
async create({ first_name, last_name, username, email, password, verify_password, phone_number = "", is_activated = void 0, _check_username_email = false }) {
|
|
1395
1405
|
vlib.schema.validate(arguments[0], {
|
|
1396
1406
|
unknown: false,
|
|
1397
1407
|
throw: true,
|
|
@@ -1401,11 +1411,21 @@ class Users {
|
|
|
1401
1411
|
username: "string",
|
|
1402
1412
|
email: "string",
|
|
1403
1413
|
password: "string",
|
|
1414
|
+
verify_password: { type: "string", required: false },
|
|
1404
1415
|
phone_number: { type: "string", required: false },
|
|
1405
1416
|
is_activated: { type: "boolean", required: false },
|
|
1406
1417
|
_check_username_email: { type: "boolean", required: false }
|
|
1407
1418
|
}
|
|
1408
1419
|
});
|
|
1420
|
+
const { error, invalid_fields } = this._verify_new_pass(password, verify_password ?? password);
|
|
1421
|
+
if (error) {
|
|
1422
|
+
throw new import_errors.ExternalError({
|
|
1423
|
+
type: "InvalidPassword",
|
|
1424
|
+
message: `Invalid password: ${error}.`,
|
|
1425
|
+
status: import_status.Status.bad_request,
|
|
1426
|
+
invalid_fields
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1409
1429
|
if (_check_username_email) {
|
|
1410
1430
|
if (await this.username_exists(username)) {
|
|
1411
1431
|
throw new import_errors.ExternalError({
|
|
@@ -135,7 +135,9 @@ export declare class View {
|
|
|
135
135
|
min_device_width?: number;
|
|
136
136
|
_src?: string;
|
|
137
137
|
});
|
|
138
|
-
|
|
138
|
+
initialize(server: Server, endpoint: Endpoint): void;
|
|
139
|
+
/** Production initialization. */
|
|
140
|
+
production_initialize(): Promise<void>;
|
|
139
141
|
private _dynamic_bundle;
|
|
140
142
|
/** Ensure the view is bundled when required. */
|
|
141
143
|
ensure_bundle(): Promise<void>;
|
|
@@ -109,7 +109,7 @@ class View {
|
|
|
109
109
|
this._bundle = void 0;
|
|
110
110
|
}
|
|
111
111
|
// Initialize.
|
|
112
|
-
|
|
112
|
+
initialize(server, endpoint) {
|
|
113
113
|
if (server === void 0) {
|
|
114
114
|
throw Error('Invalid usage, define parameter "server".');
|
|
115
115
|
}
|
|
@@ -119,6 +119,11 @@ class View {
|
|
|
119
119
|
this.server = server;
|
|
120
120
|
this.endpoint = endpoint;
|
|
121
121
|
}
|
|
122
|
+
/** Production initialization. */
|
|
123
|
+
async production_initialize() {
|
|
124
|
+
await this.ensure_bundle();
|
|
125
|
+
await this._build_html();
|
|
126
|
+
}
|
|
122
127
|
// Bundle the compiled typescript / javascript dynamically on demand to optimize server startup for development purposes.
|
|
123
128
|
async _dynamic_bundle() {
|
|
124
129
|
if (this.server === void 0 || this.endpoint === void 0) {
|
|
@@ -6,7 +6,7 @@ export const Frontend = {
|
|
|
6
6
|
/** CSS exports. */
|
|
7
7
|
css: {
|
|
8
8
|
/** The default volt css export. */
|
|
9
|
-
volt: __dirname + "/../../../../../frontend/src/css/volt.css",
|
|
9
|
+
volt: __dirname + "/../../../../../frontend/dist/frontend/src/css/volt.css",
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
export default Frontend;
|
|
@@ -1642,11 +1642,11 @@ export class Server {
|
|
|
1642
1642
|
async start() {
|
|
1643
1643
|
// Always initialize, even when forking.
|
|
1644
1644
|
await this.initialize();
|
|
1645
|
-
// On production
|
|
1645
|
+
// On production also exec the endpoint production init.
|
|
1646
1646
|
if (this.production) {
|
|
1647
1647
|
for (const endpoint of this.endpoints.values()) {
|
|
1648
1648
|
if (endpoint.view) {
|
|
1649
|
-
await endpoint.view.
|
|
1649
|
+
await endpoint.view.production_initialize();
|
|
1650
1650
|
}
|
|
1651
1651
|
}
|
|
1652
1652
|
}
|
|
@@ -135,7 +135,9 @@ export declare class View {
|
|
|
135
135
|
min_device_width?: number;
|
|
136
136
|
_src?: string;
|
|
137
137
|
});
|
|
138
|
-
|
|
138
|
+
initialize(server: Server, endpoint: Endpoint): void;
|
|
139
|
+
/** Production initialization. */
|
|
140
|
+
production_initialize(): Promise<void>;
|
|
139
141
|
private _dynamic_bundle;
|
|
140
142
|
/** Ensure the view is bundled when required. */
|
|
141
143
|
ensure_bundle(): Promise<void>;
|
|
@@ -171,7 +171,7 @@ export class View {
|
|
|
171
171
|
this._bundle = undefined;
|
|
172
172
|
}
|
|
173
173
|
// Initialize.
|
|
174
|
-
|
|
174
|
+
initialize(server, endpoint) {
|
|
175
175
|
if (server === undefined) {
|
|
176
176
|
throw Error("Invalid usage, define parameter \"server\".");
|
|
177
177
|
}
|
|
@@ -181,6 +181,11 @@ export class View {
|
|
|
181
181
|
this.server = server;
|
|
182
182
|
this.endpoint = endpoint;
|
|
183
183
|
}
|
|
184
|
+
/** Production initialization. */
|
|
185
|
+
async production_initialize() {
|
|
186
|
+
await this.ensure_bundle();
|
|
187
|
+
await this._build_html();
|
|
188
|
+
}
|
|
184
189
|
// Bundle the compiled typescript / javascript dynamically on demand to optimize server startup for development purposes.
|
|
185
190
|
async _dynamic_bundle() {
|
|
186
191
|
// Server & endpoint.
|
|
@@ -6,7 +6,7 @@ export const Frontend = {
|
|
|
6
6
|
/** CSS exports. */
|
|
7
7
|
css: {
|
|
8
8
|
/** The default volt css export. */
|
|
9
|
-
volt: __dirname + "/../../../../../frontend/src/css/volt.css",
|
|
9
|
+
volt: __dirname + "/../../../../../frontend/dist/frontend/src/css/volt.css",
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
export default Frontend;
|
|
@@ -6,13 +6,19 @@ import * as https from "https";
|
|
|
6
6
|
import * as vlib from "@vandenberghinc/vlib";
|
|
7
7
|
import type { Server } from "./server.js";
|
|
8
8
|
export interface RateLimitGroup {
|
|
9
|
+
/** The rate limit group name. */
|
|
9
10
|
group?: string | null;
|
|
11
|
+
/** The maximum requests per rate limit interval. */
|
|
10
12
|
limit?: number | null;
|
|
13
|
+
/** The rate limit interval in seconds. */
|
|
11
14
|
interval?: number | null;
|
|
12
15
|
}
|
|
13
16
|
export interface RateLimitData {
|
|
17
|
+
/** The rate limit group name. */
|
|
14
18
|
group: string;
|
|
19
|
+
/** The maximum requests per rate limit interval. */
|
|
15
20
|
limit: number;
|
|
21
|
+
/** The rate limit interval in seconds. */
|
|
16
22
|
interval: number;
|
|
17
23
|
}
|
|
18
24
|
export interface RateLimitCacheData {
|
|
@@ -37,13 +43,7 @@ export declare namespace RateLimits {
|
|
|
37
43
|
* @param interval The rate limit interval in seconds, defaults to 60.
|
|
38
44
|
* @docs
|
|
39
45
|
*/
|
|
40
|
-
function add({
|
|
41
|
-
/** The rate limit group name. */
|
|
42
|
-
group,
|
|
43
|
-
/** The maximum requests per rate limit interval. */
|
|
44
|
-
limit,
|
|
45
|
-
/** The rate limit interval in seconds. */
|
|
46
|
-
interval, }: RateLimitGroup): RateLimitData;
|
|
46
|
+
function add({ group, limit, interval }: RateLimitGroup): RateLimitData;
|
|
47
47
|
/**
|
|
48
48
|
* Normalize an IPv4 or IPv6 address into a unique, canonical string suitable for rate limiting keys.
|
|
49
49
|
*
|
|
@@ -27,13 +27,7 @@ export var RateLimits;
|
|
|
27
27
|
* @param interval The rate limit interval in seconds, defaults to 60.
|
|
28
28
|
* @docs
|
|
29
29
|
*/
|
|
30
|
-
function add({
|
|
31
|
-
/** The rate limit group name. */
|
|
32
|
-
group = null,
|
|
33
|
-
/** The maximum requests per rate limit interval. */
|
|
34
|
-
limit = null,
|
|
35
|
-
/** The rate limit interval in seconds. */
|
|
36
|
-
interval = null, }) {
|
|
30
|
+
function add({ group, limit, interval }) {
|
|
37
31
|
const settings = RateLimits.groups.has(group)
|
|
38
32
|
? RateLimits.groups.get(group)
|
|
39
33
|
: { group: "", limit: 0, interval: 0 };
|
|
@@ -1642,11 +1642,11 @@ export class Server {
|
|
|
1642
1642
|
async start() {
|
|
1643
1643
|
// Always initialize, even when forking.
|
|
1644
1644
|
await this.initialize();
|
|
1645
|
-
// On production
|
|
1645
|
+
// On production also exec the endpoint production init.
|
|
1646
1646
|
if (this.production) {
|
|
1647
1647
|
for (const endpoint of this.endpoints.values()) {
|
|
1648
1648
|
if (endpoint.view) {
|
|
1649
|
-
await endpoint.view.
|
|
1649
|
+
await endpoint.view.production_initialize();
|
|
1650
1650
|
}
|
|
1651
1651
|
}
|
|
1652
1652
|
}
|
|
@@ -324,6 +324,7 @@ export declare class Users {
|
|
|
324
324
|
* @param username The username of the new account.
|
|
325
325
|
* @param email The email of the new account.
|
|
326
326
|
* @param password The password of the new account.
|
|
327
|
+
* @param verify_password An optional second password input to check against the first input to ensure its the same.
|
|
327
328
|
* @param phone_number The phone number of the user account.
|
|
328
329
|
* @param is_activated Whether the account should be set to activated; by default `!Server.enable_account_activation`.
|
|
329
330
|
* @example
|
|
@@ -335,12 +336,13 @@ export declare class Users {
|
|
|
335
336
|
* password: "HelloWorld!"
|
|
336
337
|
* });
|
|
337
338
|
*/
|
|
338
|
-
create({ first_name, last_name, username, email, password, phone_number, is_activated, _check_username_email, }: {
|
|
339
|
+
create({ first_name, last_name, username, email, password, verify_password, phone_number, is_activated, _check_username_email, }: {
|
|
339
340
|
first_name: string;
|
|
340
341
|
last_name: string;
|
|
341
342
|
username: string;
|
|
342
343
|
email: string;
|
|
343
344
|
password: string;
|
|
345
|
+
verify_password?: string;
|
|
344
346
|
phone_number?: string;
|
|
345
347
|
is_activated?: boolean;
|
|
346
348
|
_check_username_email?: boolean;
|
|
@@ -274,21 +274,22 @@ export class Users {
|
|
|
274
274
|
let error = undefined;
|
|
275
275
|
if (pass !== verify_pass) {
|
|
276
276
|
error = "Passwords do not match.";
|
|
277
|
-
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
278
277
|
}
|
|
279
278
|
else if (pass.length < 8) {
|
|
280
279
|
error = "The password should at least include eight characters.";
|
|
281
|
-
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
282
280
|
}
|
|
283
281
|
else if (pass.toLowerCase() === pass) {
|
|
284
282
|
error = "The password should at least include one capital letter.";
|
|
285
|
-
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
286
283
|
}
|
|
287
284
|
else if (!/\d|[!@#$%^&*]/.test(pass)) {
|
|
288
285
|
error = "The password should at least include one numeric or special character.";
|
|
286
|
+
}
|
|
287
|
+
if (error) {
|
|
289
288
|
return { error, invalid_fields: { password: error, verify_password: error } };
|
|
290
289
|
}
|
|
291
|
-
|
|
290
|
+
else {
|
|
291
|
+
return { error: undefined, invalid_fields: undefined };
|
|
292
|
+
}
|
|
292
293
|
}
|
|
293
294
|
// ---------------------------------------------------------
|
|
294
295
|
// Authentication (private).
|
|
@@ -702,7 +703,10 @@ export class Users {
|
|
|
702
703
|
method: "POST",
|
|
703
704
|
endpoint: "/volt/api/v1/auth/signup",
|
|
704
705
|
content_type: "application/json",
|
|
705
|
-
rate_limit:
|
|
706
|
+
rate_limit: [
|
|
707
|
+
"global",
|
|
708
|
+
{ limit: 5, interval: 60 * 10, group: "volt/Users/signup" }
|
|
709
|
+
],
|
|
706
710
|
params: {
|
|
707
711
|
username: { type: "string", allow_empty: false },
|
|
708
712
|
first_name: { type: "string", allow_empty: false },
|
|
@@ -714,6 +718,7 @@ export class Users {
|
|
|
714
718
|
code: { type: "string", required: false },
|
|
715
719
|
},
|
|
716
720
|
callback: async (stream, params) => {
|
|
721
|
+
console.log("signup 1", params);
|
|
717
722
|
// Verify password.
|
|
718
723
|
const { error, invalid_fields } = this._verify_new_pass(params.password, params.verify_password);
|
|
719
724
|
if (error) {
|
|
@@ -782,9 +787,14 @@ export class Users {
|
|
|
782
787
|
let uid;
|
|
783
788
|
try {
|
|
784
789
|
uid = await this.create({
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
790
|
+
// dont unpack params since we are performing param validation inside create().
|
|
791
|
+
first_name: params.first_name,
|
|
792
|
+
last_name: params.last_name,
|
|
793
|
+
username: params.username,
|
|
794
|
+
email: params.email,
|
|
795
|
+
password: params.password,
|
|
796
|
+
verify_password: params.verify_password,
|
|
797
|
+
phone_number: params.phone_number,
|
|
788
798
|
is_activated: true, // already verified by 2fa or no 2fa is enabled.
|
|
789
799
|
_check_username_email: false, // already checked.
|
|
790
800
|
});
|
|
@@ -1486,6 +1496,7 @@ export class Users {
|
|
|
1486
1496
|
* @param username The username of the new account.
|
|
1487
1497
|
* @param email The email of the new account.
|
|
1488
1498
|
* @param password The password of the new account.
|
|
1499
|
+
* @param verify_password An optional second password input to check against the first input to ensure its the same.
|
|
1489
1500
|
* @param phone_number The phone number of the user account.
|
|
1490
1501
|
* @param is_activated Whether the account should be set to activated; by default `!Server.enable_account_activation`.
|
|
1491
1502
|
* @example
|
|
@@ -1497,7 +1508,7 @@ export class Users {
|
|
|
1497
1508
|
* password: "HelloWorld!"
|
|
1498
1509
|
* });
|
|
1499
1510
|
*/
|
|
1500
|
-
async create({ first_name, last_name, username, email, password, phone_number = "", is_activated = undefined, _check_username_email = false, }) {
|
|
1511
|
+
async create({ first_name, last_name, username, email, password, verify_password, phone_number = "", is_activated = undefined, _check_username_email = false, }) {
|
|
1501
1512
|
// Verify params.
|
|
1502
1513
|
vlib.schema.validate(arguments[0], {
|
|
1503
1514
|
unknown: false,
|
|
@@ -1508,11 +1519,22 @@ export class Users {
|
|
|
1508
1519
|
username: "string",
|
|
1509
1520
|
email: "string",
|
|
1510
1521
|
password: "string",
|
|
1522
|
+
verify_password: { type: "string", required: false },
|
|
1511
1523
|
phone_number: { type: "string", required: false },
|
|
1512
1524
|
is_activated: { type: "boolean", required: false },
|
|
1513
1525
|
_check_username_email: { type: "boolean", required: false },
|
|
1514
1526
|
}
|
|
1515
1527
|
});
|
|
1528
|
+
// Verify password.
|
|
1529
|
+
const { error, invalid_fields } = this._verify_new_pass(password, verify_password ?? password);
|
|
1530
|
+
if (error) {
|
|
1531
|
+
throw new ExternalError({
|
|
1532
|
+
type: "InvalidPassword",
|
|
1533
|
+
message: `Invalid password: ${error}.`,
|
|
1534
|
+
status: Status.bad_request,
|
|
1535
|
+
invalid_fields,
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1516
1538
|
// Check if username & email already exist.
|
|
1517
1539
|
if (_check_username_email) {
|
|
1518
1540
|
if (await this.username_exists(username)) {
|
|
@@ -135,7 +135,9 @@ export declare class View {
|
|
|
135
135
|
min_device_width?: number;
|
|
136
136
|
_src?: string;
|
|
137
137
|
});
|
|
138
|
-
|
|
138
|
+
initialize(server: Server, endpoint: Endpoint): void;
|
|
139
|
+
/** Production initialization. */
|
|
140
|
+
production_initialize(): Promise<void>;
|
|
139
141
|
private _dynamic_bundle;
|
|
140
142
|
/** Ensure the view is bundled when required. */
|
|
141
143
|
ensure_bundle(): Promise<void>;
|
|
@@ -171,7 +171,7 @@ export class View {
|
|
|
171
171
|
this._bundle = undefined;
|
|
172
172
|
}
|
|
173
173
|
// Initialize.
|
|
174
|
-
|
|
174
|
+
initialize(server, endpoint) {
|
|
175
175
|
if (server === undefined) {
|
|
176
176
|
throw Error("Invalid usage, define parameter \"server\".");
|
|
177
177
|
}
|
|
@@ -181,6 +181,11 @@ export class View {
|
|
|
181
181
|
this.server = server;
|
|
182
182
|
this.endpoint = endpoint;
|
|
183
183
|
}
|
|
184
|
+
/** Production initialization. */
|
|
185
|
+
async production_initialize() {
|
|
186
|
+
await this.ensure_bundle();
|
|
187
|
+
await this._build_html();
|
|
188
|
+
}
|
|
184
189
|
// Bundle the compiled typescript / javascript dynamically on demand to optimize server startup for development purposes.
|
|
185
190
|
async _dynamic_bundle() {
|
|
186
191
|
// Server & endpoint.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* Payment method container */
|
|
2
|
+
.adyen-checkout__payment-method {
|
|
3
|
+
border-radius: var(--vpayments_border_radius);
|
|
4
|
+
margin: 5px 0px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/* Buttons */
|
|
8
|
+
.adyen-checkout__button {
|
|
9
|
+
background: var(--vpayments_button_bg);
|
|
10
|
+
color: var(--vpayments_button_fg);
|
|
11
|
+
border-radius: var(--vpayments_button_border_radius);
|
|
12
|
+
transition: filter 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
|
13
|
+
}
|
|
14
|
+
.adyen-checkout__button:hover {
|
|
15
|
+
background: var(--vpayments_button_bg);
|
|
16
|
+
color: var(--vpayments_button_fg);
|
|
17
|
+
filter: brightness(1.1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Selected item circle */
|
|
21
|
+
.adyen-checkout__payment-method__radio {
|
|
22
|
+
border: 1px solid var(--vpayments_border_bg);
|
|
23
|
+
transition: outline 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
|
24
|
+
}
|
|
25
|
+
.adyen-checkout__payment-method__radio--selected {
|
|
26
|
+
background: var(--vpayments_button_bg);
|
|
27
|
+
}
|
|
28
|
+
.adyen-checkout__payment-method__radio--selected::after {
|
|
29
|
+
background: var(--vpayments_button_fg);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Input label names. */
|
|
33
|
+
.adyen-checkout__label > .adyen-checkout__label__text {
|
|
34
|
+
color: var(--vpayments_fg);
|
|
35
|
+
}
|
|
36
|
+
.adyen-checkout__label--focused > .adyen-checkout__label__text {
|
|
37
|
+
color: var(--vpayments_theme_fg);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Input fields */
|
|
41
|
+
.adyen-checkout__input,
|
|
42
|
+
.adyen-checkout__input--text,
|
|
43
|
+
.adyen-checkout__dropdown__button {
|
|
44
|
+
border-radius: var(--vpayments_border_radius);
|
|
45
|
+
border: 1px solid var(--vpayments_border_bg);
|
|
46
|
+
/*box-shadow: 0 0 0 0px transparent; causes the custom inputs like card holder when invalid to stop enabling box-shadow */
|
|
47
|
+
transition: outline 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
|
48
|
+
}
|
|
49
|
+
.adyen-checkout__input:hover,
|
|
50
|
+
.adyen-checkout__input--text:hover,
|
|
51
|
+
.adyen-checkout__dropdown__button:hover {
|
|
52
|
+
border: 1px solid var(--vpayments_border_bg);
|
|
53
|
+
}
|
|
54
|
+
.adyen-checkout__input:focus,
|
|
55
|
+
.adyen-checkout__input:focus:hover,
|
|
56
|
+
.adyen-checkout__input:active,
|
|
57
|
+
.adyen-checkout__input:active:hover,
|
|
58
|
+
.adyen-checkout__input--focus,
|
|
59
|
+
.adyen-checkout__input--focus:hover,
|
|
60
|
+
.adyen-checkout__dropdown__button--active,
|
|
61
|
+
.adyen-checkout__dropdown__button--active:hover {
|
|
62
|
+
border: 1px solid var(--vpayments_theme_fg);
|
|
63
|
+
box-shadow: 0 0 0 2px var(--vpayments_theme_fg_80);
|
|
64
|
+
}
|
|
65
|
+
.adyen-checkout__input--error,
|
|
66
|
+
.adyen-checkout__input--error:hover,
|
|
67
|
+
.adyen-checkout__input--error:required,
|
|
68
|
+
.adyen-checkout__input--invalid,
|
|
69
|
+
.adyen-checkout__input--invalid:hover,
|
|
70
|
+
.adyen-checkout__input--invalid:required,
|
|
71
|
+
.adyen-checkout__dropdown__button--invalid,
|
|
72
|
+
.adyen-checkout__dropdown__button--invalid:hover,
|
|
73
|
+
.adyen-checkout__dropdown__button--invalid:required {
|
|
74
|
+
border: 1px solid var(--vpayments_missing_fg);
|
|
75
|
+
box-shadow: 0 0 0 2px var(--vpayments_missing_fg_80);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Dropdown list */
|
|
79
|
+
.adyen-checkout__dropdown__list {
|
|
80
|
+
/* Dropdown list */
|
|
81
|
+
color: var(--vpayments_fg);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Checkout status container */
|
|
85
|
+
.adyen-checkout__status {
|
|
86
|
+
border: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Adyen checkout dropin */
|
|
90
|
+
.adyen-checkout__dropin {
|
|
91
|
+
width: 100%; /* since the container centers the content. */
|
|
92
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Author: Daan van den Bergh
|
|
3
|
+
Copyright: © 2022 Daan van den Bergh.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* On all elements. */
|
|
7
|
+
* {
|
|
8
|
+
|
|
9
|
+
/* Box sizing on all elements. */
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
-webkit-box-sizing: border-box;
|
|
12
|
+
-mos-box-sizing: border-box;
|
|
13
|
+
-ms-box-sizing: border-box;
|
|
14
|
+
|
|
15
|
+
/* Hide scrollbar.
|
|
16
|
+
-webkit-scrollbar::display: none;
|
|
17
|
+
-ms-overflow-style: none;
|
|
18
|
+
scrollbar-width: none;
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/*kill the transitions on any descendant elements of .volt_notransition*/
|
|
24
|
+
.volt_notransition * {
|
|
25
|
+
transition: none !important;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Hide the scrollbar */
|
|
29
|
+
.volt_hide_scrollbar {
|
|
30
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
31
|
+
scrollbar-width: none; /* Firefox */
|
|
32
|
+
}
|
|
33
|
+
.volt_hide_scrollbar::-webkit-scrollbar {
|
|
34
|
+
display: none;
|
|
35
|
+
background: transparent;
|
|
36
|
+
width: 0 !important
|
|
37
|
+
}
|
|
38
|
+
.volt_hide_scrollbar::-webkit-scrollbar:horizontal {
|
|
39
|
+
height: 0;
|
|
40
|
+
width: 0;
|
|
41
|
+
display: none;
|
|
42
|
+
}
|
|
43
|
+
/* */
|
|
44
|
+
.volt_hide_scrollbar::-webkit-scrollbar-thumb {
|
|
45
|
+
display: none;
|
|
46
|
+
background: transparent;
|
|
47
|
+
}
|
|
48
|
+
.volt_hide_scrollbar::-webkit-scrollbar-horizontal {
|
|
49
|
+
height: 0.5em;
|
|
50
|
+
display: none;
|
|
51
|
+
background: transparent;
|
|
52
|
+
}
|
|
53
|
+
.volt_hide_scrollbar::-webkit-scrollbar-horizontal-track {
|
|
54
|
+
display: none;
|
|
55
|
+
background: transparent;
|
|
56
|
+
}
|
|
57
|
+
.volt_hide_scrollbar::-webkit-scrollbar-thumb-horizontal {
|
|
58
|
+
display: none;
|
|
59
|
+
background: transparent;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Ring loader keyframe. */
|
|
63
|
+
@keyframes RingLoader {
|
|
64
|
+
0% {
|
|
65
|
+
transform: rotate(0deg);
|
|
66
|
+
}
|
|
67
|
+
100% {
|
|
68
|
+
transform: rotate(360deg);
|
|
69
|
+
}
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Daan van den Bergh",
|
|
3
3
|
"name": "@vandenberghinc/volt",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.30",
|
|
5
5
|
"description": "",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"types": "./backend/dist/esm/volt.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"build": "npm run build:backend --silent && npm run build:backend:cjs --silent && npm run build:frontend --silent",
|
|
23
23
|
"build:backend": "tsc -p backend/tsconfig.json",
|
|
24
24
|
"build:backend:cjs": "vts --transform-esm --debug 1 --src backend/dist/esm/ --dest backend/dist/cjs/ --override --platform node --target es2023",
|
|
25
|
-
"build:frontend": "tsc -p frontend/tsconfig.json",
|
|
25
|
+
"build:frontend": "tsc -p frontend/tsconfig.json && rsync -az --delete frontend/src/css/ frontend/dist/frontend/src/css/",
|
|
26
26
|
"start": "node start.js",
|
|
27
27
|
"check-circular-dependencies": "npx madge --circular frontend/src/"
|
|
28
28
|
},
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@vandenberghinc/vhighlight": "^1.3.15",
|
|
38
|
-
"@vandenberghinc/vlib": "^1.6.
|
|
39
|
-
"@vandenberghinc/volt": "1.1.21",
|
|
38
|
+
"@vandenberghinc/vlib": "^1.6.32",
|
|
40
39
|
"blob-stream": "^0.1.3",
|
|
41
40
|
"esbuild": "^0.25.4",
|
|
42
41
|
"mongodb": "^6.19.0",
|