@joystick.js/node-canary 0.0.0-canary.35 → 0.0.0-canary.350
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/_package.json +2 -3
- package/dist/action/class.js +21 -0
- package/dist/api/get.js +15 -13
- package/dist/api/set.js +15 -13
- package/dist/app/accounts/createMetadataTableColumns.js +12 -0
- package/dist/app/accounts/deleteUser.js +7 -0
- package/dist/app/accounts/generateSession.js +2 -4
- package/dist/app/accounts/getBrowserSafeUser.js +5 -2
- package/dist/app/accounts/hasLoginTokenExpired.js +1 -2
- package/dist/app/accounts/index.js +2 -0
- package/dist/app/accounts/login.js +6 -0
- package/dist/app/accounts/recoverPassword.js +3 -0
- package/dist/app/accounts/resetPassword.js +6 -0
- package/dist/app/accounts/signup.js +50 -7
- package/dist/app/accounts/verifyEmail.js +3 -0
- package/dist/app/cluster.js +26 -0
- package/dist/app/databases/generate_sql_from_object.js +60 -0
- package/dist/app/databases/mongodb/buildConnectionString.js +1 -1
- package/dist/app/databases/mongodb/createAccountsIndexes.js +18 -0
- package/dist/app/databases/mongodb/createSessionsIndexes.js +10 -0
- package/dist/app/databases/mongodb/index.js +1 -1
- package/dist/app/databases/mongodb/queries/accounts.js +8 -1
- package/dist/app/databases/mongodb/queries/queues.js +60 -33
- package/dist/app/databases/mongodb/queries/sessions.js +21 -0
- package/dist/app/databases/postgresql/createSessionsIndexes.js +10 -0
- package/dist/app/databases/postgresql/createSessionsTables.js +14 -0
- package/dist/app/databases/postgresql/handleCleanupQueues.js +36 -0
- package/dist/app/databases/postgresql/index.js +88 -2
- package/dist/app/databases/postgresql/queries/accounts.js +5 -2
- package/dist/app/databases/postgresql/queries/queues.js +91 -43
- package/dist/app/databases/postgresql/queries/sessions.js +34 -0
- package/dist/app/databases/queryMap.js +6 -2
- package/dist/app/databases/stringToSnakeCase.js +6 -0
- package/dist/app/getBrowserSafeRequest.js +3 -3
- package/dist/app/index.js +229 -78
- package/dist/app/initExpress.js +1 -1
- package/dist/app/middleware/csp.js +2 -2
- package/dist/app/middleware/getTranslations.js +64 -0
- package/dist/app/middleware/get_insecure_landing_page_html.js +71 -0
- package/dist/app/middleware/hmr/client.js +13 -9
- package/dist/app/middleware/index.js +6 -5
- package/dist/app/middleware/insecure.js +3 -4
- package/dist/app/middleware/render.js +8 -66
- package/dist/app/middleware/session.js +11 -11
- package/dist/app/queues/index.js +77 -32
- package/dist/app/registerGetters.js +5 -6
- package/dist/app/registerSetters.js +5 -6
- package/dist/app/runGetter.js +17 -5
- package/dist/app/runSessionQuery.js +15 -0
- package/dist/app/runSetter.js +17 -5
- package/dist/app/sanitizeAPIResponse.js +1 -1
- package/dist/app/validateInstanceToken.js +16 -0
- package/dist/app/validateSession.js +8 -3
- package/dist/app/validateUploaderOptions.js +3 -3
- package/dist/app/validateUploads.js +12 -1
- package/dist/email/send.js +7 -1
- package/dist/email/templates/reset-password.js +0 -1
- package/dist/fixture/index.js +40 -0
- package/dist/index.js +20 -3
- package/dist/lib/constants.js +5 -1
- package/dist/lib/escapeKeyValuePair.js +13 -0
- package/dist/lib/formatAPIError.js +0 -1
- package/dist/lib/getBuildPath.js +1 -1
- package/dist/lib/getSSLCertificates.js +3 -3
- package/dist/lib/importFile.js +7 -0
- package/dist/lib/isValidJSONString.js +1 -1
- package/dist/lib/log.js +0 -3
- package/dist/lib/objectToSQLKeysString.js +1 -1
- package/dist/lib/objectToSQLValuesString.js +1 -1
- package/dist/lib/serializeQueryParameters.js +1 -1
- package/dist/lib/timestamps.js +47 -0
- package/dist/lib/wait.js +8 -0
- package/dist/push/connectMongoDB.js +30 -0
- package/dist/push/logs/index.js +24 -21
- package/dist/settings/load.js +3 -5
- package/dist/ssr/compileCSS.js +4 -4
- package/dist/ssr/findComponentInTree.js +1 -1
- package/dist/ssr/getAPIForDataFunctions.js +35 -0
- package/dist/ssr/getDataFromComponent.js +15 -0
- package/dist/ssr/index.js +19 -45
- package/dist/ssr/replaceWhenTags.js +2 -3
- package/dist/ssr/setHeadTagsInHTML.js +3 -3
- package/dist/test/index.js +9 -0
- package/dist/test/trackFunctionCall.js +17 -0
- package/dist/validation/inputWithSchema/index.js +3 -3
- package/dist/validation/schema/index.js +5 -5
- package/dist/websockets/index.js +4 -0
- package/getSanitizedContext.js +43 -0
- package/package.json +2 -2
- package/dist/app/accounts/roles/index.test.js +0 -123
- package/dist/app/index.test.js +0 -575
- package/dist/app/middleware/sanitizeRequestParameters.js +0 -21
- package/dist/email/send.test.js +0 -37
- package/dist/validation/index.test.js +0 -463
package/_package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joystick.js/node",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
4
|
-
"developmentVersion": "1.0.0-beta.1419",
|
|
3
|
+
"version": "1.0.0-beta.183",
|
|
5
4
|
"type": "module",
|
|
6
5
|
"description": "A Node.js framework for building web apps.",
|
|
7
6
|
"main": "./dist/index.js",
|
|
@@ -17,7 +16,6 @@
|
|
|
17
16
|
"author": "",
|
|
18
17
|
"license": "SAUCR",
|
|
19
18
|
"dependencies": {
|
|
20
|
-
"@tuskdb/node": "^0.11.0",
|
|
21
19
|
"aws-sdk": "^2.1046.0",
|
|
22
20
|
"bcrypt": "^5.0.1",
|
|
23
21
|
"chalk": "^4.1.2",
|
|
@@ -39,6 +37,7 @@
|
|
|
39
37
|
"node-html-parser": "^5.1.0",
|
|
40
38
|
"nodemailer": "^6.7.0",
|
|
41
39
|
"pg": "^8.7.3",
|
|
40
|
+
"pg-escape": "^0.2.0",
|
|
42
41
|
"process": "^0.11.10",
|
|
43
42
|
"query-string": "^7.0.1",
|
|
44
43
|
"sanitize-html": "^2.7.3",
|
package/dist/action/class.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import formatAPIError from "../lib/formatAPIError";
|
|
2
2
|
import validate from "../validation";
|
|
3
|
+
import trackFunctionCall from "../test/trackFunctionCall.js";
|
|
3
4
|
class Action {
|
|
4
5
|
constructor(input = {}) {
|
|
5
6
|
this.name = input?.name;
|
|
@@ -14,9 +15,17 @@ class Action {
|
|
|
14
15
|
return Object.entries(this?.config?.steps || {})?.reduce((serializedSteps = {}, [stepName = "", stepOptions = {}]) => {
|
|
15
16
|
serializedSteps[stepName] = async (...args) => {
|
|
16
17
|
try {
|
|
18
|
+
trackFunctionCall(`node.actions.${this?.name}.steps.${stepName}`, [
|
|
19
|
+
...args,
|
|
20
|
+
this
|
|
21
|
+
]);
|
|
17
22
|
const result = await stepOptions?.run(...args, this);
|
|
18
23
|
if (typeof stepOptions?.onSuccess === "function") {
|
|
19
24
|
stepOptions.onSuccess(result, this);
|
|
25
|
+
trackFunctionCall(`node.actions.${this?.name}.steps.${stepName}.onSuccess`, [
|
|
26
|
+
result,
|
|
27
|
+
this
|
|
28
|
+
]);
|
|
20
29
|
}
|
|
21
30
|
return result;
|
|
22
31
|
} catch (exception) {
|
|
@@ -25,6 +34,10 @@ class Action {
|
|
|
25
34
|
}
|
|
26
35
|
if (typeof stepOptions?.onError === "function") {
|
|
27
36
|
stepOptions.onError(exception, this);
|
|
37
|
+
trackFunctionCall(`node.actions.${this?.name}.steps.${stepName}.onError`, [
|
|
38
|
+
exception,
|
|
39
|
+
this
|
|
40
|
+
]);
|
|
28
41
|
}
|
|
29
42
|
}
|
|
30
43
|
};
|
|
@@ -45,6 +58,9 @@ class Action {
|
|
|
45
58
|
return new Promise(async (resolve, reject) => {
|
|
46
59
|
try {
|
|
47
60
|
this.abort = (error) => {
|
|
61
|
+
trackFunctionCall(`node.actions.${this?.name}.abort`, [
|
|
62
|
+
error
|
|
63
|
+
]);
|
|
48
64
|
reject(error);
|
|
49
65
|
throw error;
|
|
50
66
|
};
|
|
@@ -63,6 +79,11 @@ class Action {
|
|
|
63
79
|
return reject(new Error(formattedValidationErrors));
|
|
64
80
|
}
|
|
65
81
|
}
|
|
82
|
+
trackFunctionCall(`node.actions.${this.name}.run`, [
|
|
83
|
+
input || {},
|
|
84
|
+
this.steps,
|
|
85
|
+
this
|
|
86
|
+
]);
|
|
66
87
|
const result = await this.config?.run(input || {}, this?.steps, this);
|
|
67
88
|
return resolve(result);
|
|
68
89
|
} catch (exception) {
|
package/dist/api/get.js
CHANGED
|
@@ -2,26 +2,28 @@ import runGetter from "../app/runGetter.js";
|
|
|
2
2
|
var get_default = ({
|
|
3
3
|
getterName = "",
|
|
4
4
|
getterOptions = {},
|
|
5
|
+
skip = false,
|
|
5
6
|
input = null,
|
|
6
7
|
output = null,
|
|
7
8
|
context = {},
|
|
8
9
|
APIOptions = {}
|
|
9
10
|
}) => {
|
|
10
11
|
return new Promise((resolve, reject) => {
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
getterName,
|
|
14
|
-
getterOptions,
|
|
15
|
-
input,
|
|
16
|
-
output,
|
|
17
|
-
APIOptions,
|
|
18
|
-
context
|
|
19
|
-
}).then((response) => {
|
|
20
|
-
return resolve(response);
|
|
21
|
-
}).catch((response) => {
|
|
22
|
-
return reject(JSON.stringify(response));
|
|
23
|
-
});
|
|
12
|
+
if (skip) {
|
|
13
|
+
return resolve();
|
|
24
14
|
}
|
|
15
|
+
runGetter({
|
|
16
|
+
getterName,
|
|
17
|
+
getterOptions,
|
|
18
|
+
input,
|
|
19
|
+
output,
|
|
20
|
+
APIOptions,
|
|
21
|
+
context
|
|
22
|
+
}).then((response) => {
|
|
23
|
+
return resolve(response);
|
|
24
|
+
}).catch((response) => {
|
|
25
|
+
return reject(JSON.stringify(response));
|
|
26
|
+
});
|
|
25
27
|
});
|
|
26
28
|
};
|
|
27
29
|
export {
|
package/dist/api/set.js
CHANGED
|
@@ -2,26 +2,28 @@ import runSetter from "../app/runSetter.js";
|
|
|
2
2
|
var set_default = ({
|
|
3
3
|
setterName = "",
|
|
4
4
|
setterOptions = {},
|
|
5
|
+
skip = false,
|
|
5
6
|
input = null,
|
|
6
7
|
output = null,
|
|
7
8
|
context = {},
|
|
8
9
|
APIOptions = {}
|
|
9
10
|
}) => {
|
|
10
11
|
return new Promise((resolve, reject) => {
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
setterName,
|
|
14
|
-
setterOptions,
|
|
15
|
-
input,
|
|
16
|
-
output,
|
|
17
|
-
APIOptions,
|
|
18
|
-
context
|
|
19
|
-
}).then((response) => {
|
|
20
|
-
return resolve(response);
|
|
21
|
-
}).catch((response) => {
|
|
22
|
-
return reject(JSON.stringify(response));
|
|
23
|
-
});
|
|
12
|
+
if (skip) {
|
|
13
|
+
return resolve();
|
|
24
14
|
}
|
|
15
|
+
runSetter({
|
|
16
|
+
setterName,
|
|
17
|
+
setterOptions,
|
|
18
|
+
input,
|
|
19
|
+
output,
|
|
20
|
+
APIOptions,
|
|
21
|
+
context
|
|
22
|
+
}).then((response) => {
|
|
23
|
+
return resolve(response);
|
|
24
|
+
}).catch((response) => {
|
|
25
|
+
return reject(JSON.stringify(response));
|
|
26
|
+
});
|
|
25
27
|
});
|
|
26
28
|
};
|
|
27
29
|
export {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import escape from "pg-escape";
|
|
2
|
+
var createMetadataTableColumns_default = async (usersDatabase = "", sqlizedMetadata = {}) => {
|
|
3
|
+
if (usersDatabase === "postgresql") {
|
|
4
|
+
const columns = Object.keys(sqlizedMetadata || {});
|
|
5
|
+
for (let i = 0; i < columns?.length; i += 1) {
|
|
6
|
+
await process.databases.postgresql.query(escape(`ALTER TABLE users ADD COLUMN IF NOT EXISTS %I TEXT;`, columns[i]));
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
createMetadataTableColumns_default as default
|
|
12
|
+
};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import dayjs from "dayjs";
|
|
2
|
+
import utc from "dayjs/plugin/utc.js";
|
|
2
3
|
import generateId from "../../lib/generateId";
|
|
3
|
-
|
|
4
|
-
const utc = await import("dayjs/plugin/utc");
|
|
5
|
-
dayjs.extend(utc.default);
|
|
6
|
-
}
|
|
4
|
+
dayjs.extend(utc);
|
|
7
5
|
var generateSession_default = () => {
|
|
8
6
|
return {
|
|
9
7
|
token: generateId(64),
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { isObject } from "../../validation/lib/typeValidators";
|
|
2
|
+
import escapeKeyValuePair from "../../lib/escapeKeyValuePair.js";
|
|
2
3
|
var getBrowserSafeUser_default = (user = null) => {
|
|
3
4
|
if (!user || !isObject(user)) {
|
|
4
5
|
return null;
|
|
5
6
|
}
|
|
6
7
|
const unsafeFields = [
|
|
7
8
|
"password",
|
|
9
|
+
"passwordResetTokens",
|
|
8
10
|
"sessions",
|
|
9
|
-
"oauth"
|
|
11
|
+
"oauth",
|
|
12
|
+
"verifyEmailTokens"
|
|
10
13
|
];
|
|
11
|
-
const browserSafeUser = Object.entries(user).filter(([field]) => {
|
|
14
|
+
const browserSafeUser = Object.entries(user || {}).filter(([field]) => {
|
|
12
15
|
return !unsafeFields.includes(field);
|
|
13
16
|
}).reduce((fields, [field, value]) => {
|
|
14
17
|
if (!fields[field]) {
|
|
@@ -5,8 +5,7 @@ var hasLoginTokenExpired_default = async (res, token = null, tokenExpiresAt = nu
|
|
|
5
5
|
unsetAuthenticationCookie(res);
|
|
6
6
|
return true;
|
|
7
7
|
}
|
|
8
|
-
const
|
|
9
|
-
const hasExpired = process.env.NODE_ENV === "test" ? _dayjs().isAfter(_dayjs(tokenExpiresAt)) : dayjs().isAfter(dayjs(tokenExpiresAt));
|
|
8
|
+
const hasExpired = dayjs().isAfter(dayjs(tokenExpiresAt));
|
|
10
9
|
if (hasExpired) {
|
|
11
10
|
unsetAuthenticationCookie(res);
|
|
12
11
|
return true;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _setAuthenticationCookie from "./setAuthenticationCookie.js";
|
|
2
2
|
import _unsetAuthenticationCookie from "./unsetAuthenticationCookie.js";
|
|
3
3
|
import defaultUserOutputFields from "./defaultUserOutputFields";
|
|
4
|
+
import deleteUser from "./deleteUser.js";
|
|
4
5
|
import getBrowserSafeUser from "./getBrowserSafeUser";
|
|
5
6
|
import login from "./login";
|
|
6
7
|
import recoverPassword from "./recoverPassword";
|
|
@@ -14,6 +15,7 @@ var accounts_default = {
|
|
|
14
15
|
_setAuthenticationCookie,
|
|
15
16
|
_unsetAuthenticationCookie,
|
|
16
17
|
defaultUserOutputFields,
|
|
18
|
+
deleteUser,
|
|
17
19
|
getBrowserSafeUser,
|
|
18
20
|
login,
|
|
19
21
|
recoverPassword,
|
|
@@ -41,6 +41,12 @@ const login = async (options, { resolve, reject }) => {
|
|
|
41
41
|
const session = await generateSession();
|
|
42
42
|
await addSessionToUser(user?._id || user?.user_id, session);
|
|
43
43
|
const { password, sessions, ...restOfUser } = user;
|
|
44
|
+
if (typeof process.joystick?._app?.options?.accounts?.onLogin === "function") {
|
|
45
|
+
process.joystick?._app?.options?.accounts?.onLogin({
|
|
46
|
+
...session,
|
|
47
|
+
user
|
|
48
|
+
});
|
|
49
|
+
}
|
|
44
50
|
return resolve({
|
|
45
51
|
...session,
|
|
46
52
|
user: getOutput({
|
|
@@ -11,6 +11,9 @@ var recoverPassword_default = async (options = {}) => {
|
|
|
11
11
|
if (process.env.NODE_ENV === "development") {
|
|
12
12
|
console.log({ url });
|
|
13
13
|
}
|
|
14
|
+
if (typeof process.joystick?._app?.options?.accounts?.onRecoverPassword === "function") {
|
|
15
|
+
process.joystick?._app?.options?.accounts?.onRecoverPassword(options?.emailAddress);
|
|
16
|
+
}
|
|
14
17
|
await sendEmail({
|
|
15
18
|
to: options.emailAddress,
|
|
16
19
|
from: settings?.config?.email?.from,
|
|
@@ -57,6 +57,12 @@ const resetPassword = async (options, { resolve, reject }) => {
|
|
|
57
57
|
password: hashedNewPassword
|
|
58
58
|
});
|
|
59
59
|
await addSessionToUser(updatedUser?._id || updatedUser?.user_id, session);
|
|
60
|
+
if (typeof process.joystick?._app?.options?.accounts?.onResetPassword === "function") {
|
|
61
|
+
process.joystick?._app?.options?.accounts?.onResetPassword({
|
|
62
|
+
user: updatedUser,
|
|
63
|
+
...session
|
|
64
|
+
});
|
|
65
|
+
}
|
|
60
66
|
resolve({
|
|
61
67
|
user: getOutput(updatedUser, options?.output),
|
|
62
68
|
...session
|
|
@@ -6,6 +6,9 @@ import { isObject } from "../../validation/lib/typeValidators";
|
|
|
6
6
|
import getOutput from "../getOutput";
|
|
7
7
|
import typesMap from "../databases/typesMap";
|
|
8
8
|
import getTargetDatabaseProvider from "../databases/getTargetDatabaseProvider.js";
|
|
9
|
+
import stringToSnakeCase from "../databases/stringToSnakeCase.js";
|
|
10
|
+
import createMetadataTableColumns from "./createMetadataTableColumns.js";
|
|
11
|
+
import roles from "./roles/index.js";
|
|
9
12
|
const addSessionToUser = (userId = null, session = null) => {
|
|
10
13
|
try {
|
|
11
14
|
return runUserQuery("addSession", { userId, session });
|
|
@@ -27,6 +30,16 @@ const insertUserInDatabase = async (user = {}) => {
|
|
|
27
30
|
throw new Error(formatErrorString("signup.insertUserInDatabase", exception));
|
|
28
31
|
}
|
|
29
32
|
};
|
|
33
|
+
const sqlizeMetadata = (metadata = {}) => {
|
|
34
|
+
try {
|
|
35
|
+
return Object.entries(metadata || {}).reduce((sqlized = {}, [key, value]) => {
|
|
36
|
+
sqlized[stringToSnakeCase(key)] = value;
|
|
37
|
+
return sqlized;
|
|
38
|
+
}, {});
|
|
39
|
+
} catch (exception) {
|
|
40
|
+
throw new Error(`[actionName.sqlizeMetadata] ${exception.message}`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
30
43
|
const getUserToCreate = async (options = {}) => {
|
|
31
44
|
try {
|
|
32
45
|
const usersDatabase = getTargetDatabaseProvider("users");
|
|
@@ -40,12 +53,25 @@ const getUserToCreate = async (options = {}) => {
|
|
|
40
53
|
if (options?.username) {
|
|
41
54
|
user.username = options?.username;
|
|
42
55
|
}
|
|
43
|
-
if (options?.metadata && isObject(options.metadata) && usersDatabaseType === "sql"
|
|
44
|
-
|
|
56
|
+
if (options?.metadata && isObject(options.metadata) && usersDatabaseType === "sql") {
|
|
57
|
+
const sqlizedMetadata = sqlizeMetadata(options.metadata);
|
|
58
|
+
await createMetadataTableColumns(usersDatabase, sqlizedMetadata);
|
|
59
|
+
const metadata = { ...options?.metadata || {} };
|
|
60
|
+
if (metadata?.roles) {
|
|
61
|
+
delete metadata.roles;
|
|
62
|
+
}
|
|
63
|
+
user = {
|
|
64
|
+
...sqlizeMetadata(metadata),
|
|
65
|
+
...user
|
|
66
|
+
};
|
|
45
67
|
}
|
|
46
68
|
if (options?.metadata && isObject(options.metadata) && usersDatabaseType === "nosql") {
|
|
69
|
+
let metadata = { ...options?.metadata || {} };
|
|
70
|
+
if (metadata?.roles) {
|
|
71
|
+
delete metadata.roles;
|
|
72
|
+
}
|
|
47
73
|
user = {
|
|
48
|
-
...
|
|
74
|
+
...metadata || {},
|
|
49
75
|
...user
|
|
50
76
|
};
|
|
51
77
|
}
|
|
@@ -70,15 +96,32 @@ const signup = async (options, { resolve, reject }) => {
|
|
|
70
96
|
return reject("Password is required.");
|
|
71
97
|
}
|
|
72
98
|
const existingUser = await getExistingUser(options.emailAddress, options.metadata?.username);
|
|
73
|
-
if (existingUser) {
|
|
99
|
+
if (existingUser && process.env.NODE_ENV !== "test") {
|
|
74
100
|
throw new Error(`A user with the ${existingUser.existingUsername ? "username" : "email address"} ${existingUser.existingUsername || existingUser.existingEmailAddress} already exists.`);
|
|
75
101
|
}
|
|
76
|
-
|
|
77
|
-
|
|
102
|
+
let userToCreate;
|
|
103
|
+
let userId = existingUser?._id || existingUser?.user_id;
|
|
104
|
+
if (!existingUser) {
|
|
105
|
+
userToCreate = await getUserToCreate(options);
|
|
106
|
+
userId = await insertUserInDatabase(userToCreate);
|
|
107
|
+
}
|
|
78
108
|
const user = await getUserByUserId(userId);
|
|
79
109
|
const session = generateSession();
|
|
80
110
|
if (user?._id || user?.user_id) {
|
|
81
|
-
await addSessionToUser(user
|
|
111
|
+
await addSessionToUser(user?._id || user?.user_id, session);
|
|
112
|
+
}
|
|
113
|
+
if (options?.metadata?.roles?.length > 0 && process.env.NODE_ENV === "test") {
|
|
114
|
+
for (let i = 0; i < options?.metadata?.roles?.length; i += 1) {
|
|
115
|
+
const role = options?.metadata?.roles[i];
|
|
116
|
+
roles.grant(user?._id || user?.user_id, role);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (typeof process.joystick?._app?.options?.accounts?.onSignup === "function") {
|
|
120
|
+
process.joystick?._app?.options?.accounts?.onSignup({
|
|
121
|
+
...session,
|
|
122
|
+
userId,
|
|
123
|
+
user
|
|
124
|
+
});
|
|
82
125
|
}
|
|
83
126
|
return resolve({
|
|
84
127
|
...session,
|
|
@@ -33,6 +33,9 @@ const verifyEmail = async (options, { resolve, reject }) => {
|
|
|
33
33
|
throw new Error(`A user with this token could not be found.`);
|
|
34
34
|
}
|
|
35
35
|
await markEmailVerifiedAt(user?._id || user?.user_id, options?.token);
|
|
36
|
+
if (typeof process.joystick?._app?.options?.accounts?.onVerifyEmail === "function") {
|
|
37
|
+
process.joystick?._app?.options?.accounts?.onVerifyEmail(user?.emailAddress || user?.email_address);
|
|
38
|
+
}
|
|
36
39
|
resolve();
|
|
37
40
|
} catch (exception) {
|
|
38
41
|
reject(`[verifyEmail] ${exception.message}`);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import cluster from "cluster";
|
|
2
|
+
import os from "os";
|
|
3
|
+
var cluster_default = (callback = null) => {
|
|
4
|
+
const cpus = os.cpus().length;
|
|
5
|
+
if (cluster.isMaster) {
|
|
6
|
+
for (let i = 0; i < cpus; i++) {
|
|
7
|
+
const worker = cluster.fork();
|
|
8
|
+
worker.on("message", (message) => {
|
|
9
|
+
if (process.send) {
|
|
10
|
+
process.send(message);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
process.on("message", (message) => {
|
|
14
|
+
worker.send(message);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
cluster.on("exit", (worker) => {
|
|
18
|
+
console.warn(`Worker ${worker.process.pid} died.`);
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
callback();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
export {
|
|
25
|
+
cluster_default as default
|
|
26
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var generate_sql_from_object_default = {
|
|
2
|
+
create_table: (options = {}) => {
|
|
3
|
+
const columns = Object.entries(options?.columns)?.map(([column_name, column_type]) => {
|
|
4
|
+
return `${column_name} ${column_type}`;
|
|
5
|
+
})?.join(",");
|
|
6
|
+
return {
|
|
7
|
+
statement: `CREATE TABLE IF NOT EXISTS ${options?.table} (${columns})`,
|
|
8
|
+
columns
|
|
9
|
+
};
|
|
10
|
+
},
|
|
11
|
+
add_column: (options = {}) => {
|
|
12
|
+
return {
|
|
13
|
+
statement: `ALTER TABLE ${options?.table} ADD COLUMN IF NOT EXISTS ${options?.column_name} ${options?.column_type}`
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
select: (options = {}) => {
|
|
17
|
+
const column_names = Array.isArray(options?.columns) ? options?.columns?.join(",") : "*";
|
|
18
|
+
const whereEntries = Object.entries(options?.where);
|
|
19
|
+
const where = whereEntries?.map(([key], index) => {
|
|
20
|
+
return `${key} = $${index + 1}`;
|
|
21
|
+
})?.join(",");
|
|
22
|
+
return {
|
|
23
|
+
statement: `SELECT ${column_names} FROM ${options?.table} ${options?.where ? `WHERE ${where}` : ""}`,
|
|
24
|
+
column_names,
|
|
25
|
+
where,
|
|
26
|
+
values: Object.values(options?.where)
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
insert: (options = {}) => {
|
|
30
|
+
const column_names = Object.keys(options?.data)?.join(",");
|
|
31
|
+
const value_placeholders = Object.keys(options?.data)?.map((_, index) => `$${index + 1}`)?.join(",");
|
|
32
|
+
return {
|
|
33
|
+
statement: `INSERT INTO ${options?.table} (${column_names}) VALUES (${value_placeholders})`,
|
|
34
|
+
column_names,
|
|
35
|
+
value_placeholders,
|
|
36
|
+
values: Object.values(options?.data)
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
update: (options = {}) => {
|
|
40
|
+
const whereEntries = Object.entries(options?.where);
|
|
41
|
+
const sets = Object.keys(options?.data).map((key, index) => {
|
|
42
|
+
return `${key} = $${whereEntries.length + index + 1}`;
|
|
43
|
+
})?.join(",");
|
|
44
|
+
const where = whereEntries?.map(([key], index) => {
|
|
45
|
+
return `${key} = $${index + 1}`;
|
|
46
|
+
})?.join(",");
|
|
47
|
+
return {
|
|
48
|
+
statement: `UPDATE ${options?.table} SET ${sets} WHERE ${where}`,
|
|
49
|
+
sets,
|
|
50
|
+
where,
|
|
51
|
+
values: [
|
|
52
|
+
...Object.values(options?.where),
|
|
53
|
+
...Object.values(options?.data)
|
|
54
|
+
]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
export {
|
|
59
|
+
generate_sql_from_object_default as default
|
|
60
|
+
};
|
|
@@ -12,7 +12,7 @@ var buildConnectionString_default = (connection = {}) => {
|
|
|
12
12
|
connectionString = `${connectionString}/${connection.database}`;
|
|
13
13
|
}
|
|
14
14
|
const queryParameters = buildQueryParameters(connection);
|
|
15
|
-
if (Object.keys(queryParameters)?.length > 0) {
|
|
15
|
+
if (Object.keys(queryParameters || {})?.length > 0) {
|
|
16
16
|
connectionString = `${connectionString}?${serializeQueryParameters(queryParameters)}`;
|
|
17
17
|
}
|
|
18
18
|
return connectionString;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const createIndex = async (collectionName = "", index = {}) => {
|
|
2
|
+
return process.databases._users?.collection(collectionName).createIndex(index);
|
|
3
|
+
};
|
|
4
|
+
var createAccountsIndexes_default = async () => {
|
|
5
|
+
await createIndex("users", { _id: 1 });
|
|
6
|
+
await createIndex("users", { emailAddress: 1 });
|
|
7
|
+
await createIndex("users", { username: 1 });
|
|
8
|
+
await createIndex("users", { "sessions.token": 1 });
|
|
9
|
+
await createIndex("users", { "passwordResetTokens.token": 1 });
|
|
10
|
+
await createIndex("users", { "passwordResetTokens.token": 1, _id: 1 });
|
|
11
|
+
await createIndex("users", { roles: 1 });
|
|
12
|
+
await createIndex("users", { roles: 1, _id: 1 });
|
|
13
|
+
await createIndex("roles", { role: 1 });
|
|
14
|
+
await createIndex("roles", { role: 1, userId: 1 });
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
createAccountsIndexes_default as default
|
|
18
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const createIndex = async (collectionName = "", index = {}, options = {}) => {
|
|
2
|
+
return process.databases._users?.collection(collectionName).createIndex(index, options);
|
|
3
|
+
};
|
|
4
|
+
var createSessionsIndexes_default = async () => {
|
|
5
|
+
await createIndex("sessions", { _id: 1 });
|
|
6
|
+
await createIndex("sessions", { createdAt: 1 }, { expireAfterSeconds: 3600 });
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
createSessionsIndexes_default as default
|
|
10
|
+
};
|
|
@@ -17,7 +17,7 @@ var mongodb_default = async (settings = {}, databasePort = 2610) => {
|
|
|
17
17
|
const connectionOptions = {
|
|
18
18
|
useNewUrlParser: true,
|
|
19
19
|
useUnifiedTopology: true,
|
|
20
|
-
ssl: !process.env.NODE_ENV
|
|
20
|
+
ssl: !["development", "test"].includes(process.env.NODE_ENV),
|
|
21
21
|
...settings?.options || {}
|
|
22
22
|
};
|
|
23
23
|
if (settings?.options?.ca) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import generateId from "../../../../lib/generateId";
|
|
2
2
|
import dayjs from "dayjs";
|
|
3
|
+
import utc from "dayjs/plugin/utc.js";
|
|
4
|
+
dayjs.extend(utc);
|
|
3
5
|
var accounts_default = {
|
|
4
6
|
existingUser: async (input = {}) => {
|
|
5
7
|
let existingUserWithEmailAddress;
|
|
@@ -35,6 +37,11 @@ var accounts_default = {
|
|
|
35
37
|
}
|
|
36
38
|
return null;
|
|
37
39
|
},
|
|
40
|
+
deleteUser: async (input = {}) => {
|
|
41
|
+
return process.databases._users?.collection("users").deleteOne({
|
|
42
|
+
_id: input?.userId
|
|
43
|
+
});
|
|
44
|
+
},
|
|
38
45
|
deleteOldSessions: async (input = {}) => {
|
|
39
46
|
const user = await process.databases._users?.collection("users").findOne({
|
|
40
47
|
_id: input?.userId
|
|
@@ -67,7 +74,7 @@ var accounts_default = {
|
|
|
67
74
|
});
|
|
68
75
|
return user;
|
|
69
76
|
},
|
|
70
|
-
|
|
77
|
+
createEmailVerificationToken: async (input) => {
|
|
71
78
|
const token = generateId();
|
|
72
79
|
await process.databases._users?.collection("users").updateOne({
|
|
73
80
|
_id: input?.userId
|