@joystick.js/node-canary 0.0.0-canary.8 → 0.0.0-canary.80
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 -1
- 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 +2 -1
- package/dist/app/accounts/hasLoginTokenExpired.js +1 -2
- package/dist/app/accounts/index.js +2 -0
- package/dist/app/accounts/signup.js +37 -7
- package/dist/app/databases/mongodb/createAccountsIndexes.js +18 -0
- package/dist/app/databases/mongodb/index.js +1 -1
- package/dist/app/databases/mongodb/queries/accounts.js +7 -0
- package/dist/app/databases/postgresql/queries/accounts.js +3 -0
- package/dist/app/databases/stringToSnakeCase.js +6 -0
- package/dist/app/getBrowserSafeRequest.js +3 -2
- package/dist/app/index.js +104 -12
- package/dist/app/middleware/getTranslations.js +64 -0
- package/dist/app/middleware/index.js +4 -5
- package/dist/app/middleware/render.js +11 -68
- package/dist/app/sanitizeAPIResponse.js +1 -6
- package/dist/app/validateSession.js +3 -0
- package/dist/email/templates/reset-password.js +0 -1
- package/dist/index.js +7 -2
- package/dist/lib/escapeHTML.js +9 -0
- package/dist/lib/escapeKeyValuePair.js +13 -0
- package/dist/lib/getBuildPath.js +1 -1
- package/dist/lib/getSSLCertificates.js +1 -1
- package/dist/lib/importFile.js +7 -0
- package/dist/lib/log.js +0 -3
- package/dist/lib/nodeUrlPolyfills.js +7 -14
- package/dist/lib/wait.js +8 -0
- package/dist/ssr/getAPIForDataFunctions.js +33 -0
- package/dist/ssr/getDataFromComponent.js +14 -0
- package/dist/ssr/index.js +5 -41
- package/package.json +2 -1
- package/dist/app/accounts/roles/index.test.js +0 -123
- package/dist/app/index.test.js +0 -575
- package/dist/app/middleware/sanitizeQueryParameters.js +0 -16
- package/dist/email/send.test.js +0 -37
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import util from "util";
|
|
2
|
-
import
|
|
3
|
-
const escapeHTML = (string = "") => {
|
|
4
|
-
return String(string).replace(/[&<>"'`=\/]/g, function(match) {
|
|
5
|
-
return HTML_ENTITY_MAP[match];
|
|
6
|
-
});
|
|
7
|
-
};
|
|
2
|
+
import escapeHTML from "../lib/escapeHTML.js";
|
|
8
3
|
const sanitizeAPIResponse = (data = null) => {
|
|
9
4
|
let sanitizedData = data;
|
|
10
5
|
if (!util.isString(sanitizedData) && !util.isObject(sanitizedData) && !Array.isArray(sanitizedData)) {
|
|
@@ -3,6 +3,9 @@ var validateSession_default = (req = null, res = null, sessions = null) => {
|
|
|
3
3
|
const sessionToken = req?.cookies?.joystickSession;
|
|
4
4
|
const csrfToken = req?.headers["x-joystick-csrf"];
|
|
5
5
|
const session = sessions?.get(sessionToken);
|
|
6
|
+
if (csrfToken === "joystick_test") {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
6
9
|
if (!session || session && session.csrf !== csrfToken) {
|
|
7
10
|
res.status(403).send(JSON.stringify({
|
|
8
11
|
errors: [formatAPIError(new Error("Unauthorized request."))]
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import ui from "@joystick.js/ui";
|
|
2
2
|
const ResetPassword = ui.component({
|
|
3
|
-
id: process.env.NODE_ENV === "test" ? "testComponent1234" : null,
|
|
4
3
|
render: ({ props }) => {
|
|
5
4
|
return `
|
|
6
5
|
<p>A password reset was requested for this email address (${props.emailAddress}). If you requested this reset, click the link below to reset your password:</p>
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import sanitizeHTML from "sanitize-html";
|
|
2
1
|
import fs from "fs";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import { dirname } from "path";
|
|
4
|
+
import sanitizeHTML from "sanitize-html";
|
|
3
5
|
import _accounts from "./app/accounts";
|
|
4
6
|
import _action from "./action/index.js";
|
|
5
7
|
import _websockets from "./websockets";
|
|
@@ -27,16 +29,18 @@ const sanitize = {
|
|
|
27
29
|
allowedTags: sanitizeHTML.defaults.allowedTags
|
|
28
30
|
}
|
|
29
31
|
};
|
|
32
|
+
const currentFilePath = fileURLToPath(import.meta.url);
|
|
33
|
+
const __package = dirname(currentFilePath);
|
|
30
34
|
const __filename = nodeUrlPolyfills.__filename;
|
|
31
35
|
const __dirname = nodeUrlPolyfills.__dirname;
|
|
32
36
|
const id = generateId;
|
|
33
37
|
const origin = getOrigin();
|
|
34
38
|
const settings = loadSettings();
|
|
35
|
-
console.log("HERE", fs.readFileSync(__dirname("dist/app/utils/process.js")?.replace("file://", ""), "utf-8"));
|
|
36
39
|
global.joystick = {
|
|
37
40
|
id: generateId,
|
|
38
41
|
emitters: {},
|
|
39
42
|
settings,
|
|
43
|
+
__package,
|
|
40
44
|
__dirname,
|
|
41
45
|
__filename
|
|
42
46
|
};
|
|
@@ -58,6 +62,7 @@ var src_default = {
|
|
|
58
62
|
export {
|
|
59
63
|
__dirname,
|
|
60
64
|
__filename,
|
|
65
|
+
__package,
|
|
61
66
|
accounts,
|
|
62
67
|
action,
|
|
63
68
|
src_default as default,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import escapeHTML from "./escapeHTML.js";
|
|
2
|
+
var escapeKeyValuePair_default = (target = {}) => {
|
|
3
|
+
const parameters = Object.entries(target || {});
|
|
4
|
+
for (let i = 0; i < parameters?.length; i += 1) {
|
|
5
|
+
const [key, value] = parameters[i];
|
|
6
|
+
delete target[key];
|
|
7
|
+
target[escapeHTML(key)] = escapeHTML(value);
|
|
8
|
+
}
|
|
9
|
+
return target;
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
escapeKeyValuePair_default as default
|
|
13
|
+
};
|
package/dist/lib/getBuildPath.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
var getBuildPath_default = () => {
|
|
3
|
-
if (process.env.NODE_ENV
|
|
3
|
+
if (["development", "test"].includes(process.env.NODE_ENV) || fs.existsSync(".joystick/build")) {
|
|
4
4
|
return ".joystick/build/";
|
|
5
5
|
}
|
|
6
6
|
return "";
|
|
@@ -6,7 +6,7 @@ var getSSLCertificates_default = (ssl = null) => {
|
|
|
6
6
|
const keyPath = process.env.IS_PUSH_DEPLOYED ? pushKeyPath : ssl?.key || null;
|
|
7
7
|
const certExists = fs.existsSync(certPath);
|
|
8
8
|
const keyExists = fs.existsSync(keyPath);
|
|
9
|
-
if (process.env.NODE_ENV
|
|
9
|
+
if (["development", "test"].includes(process.env.NODE_ENV) || !certExists || !keyExists) {
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
12
|
return {
|
package/dist/lib/log.js
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fileURLToPath } from "url";
|
|
2
|
+
import { dirname } from "path";
|
|
2
3
|
var nodeUrlPolyfills_default = {
|
|
3
|
-
__filename: (url =
|
|
4
|
-
|
|
5
|
-
return "";
|
|
6
|
-
}
|
|
7
|
-
const path = new URL(".", url)?.replace("file://", "");
|
|
8
|
-
return path?.pathname;
|
|
4
|
+
__filename: (url = "") => {
|
|
5
|
+
return fileURLToPath(url);
|
|
9
6
|
},
|
|
10
|
-
__dirname: (url =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
console.log({ url });
|
|
15
|
-
const path = new URL("./", url)?.replace("file://", "");
|
|
16
|
-
return path?.pathname || "";
|
|
7
|
+
__dirname: (url = "") => {
|
|
8
|
+
const currentFilePath = fileURLToPath(url);
|
|
9
|
+
return dirname(currentFilePath);
|
|
17
10
|
}
|
|
18
11
|
};
|
|
19
12
|
export {
|
package/dist/lib/wait.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import get from "../api/get";
|
|
2
|
+
import set from "../api/set";
|
|
3
|
+
var getAPIForDataFunctions_default = (req = {}, api = {}) => {
|
|
4
|
+
try {
|
|
5
|
+
return {
|
|
6
|
+
get: (getterName = "", getterOptions = {}) => {
|
|
7
|
+
return get({
|
|
8
|
+
getterName,
|
|
9
|
+
getterOptions: api?.getters[getterName] || {},
|
|
10
|
+
input: getterOptions?.input,
|
|
11
|
+
output: getterOptions?.output,
|
|
12
|
+
context: req?.context,
|
|
13
|
+
APIOptions: api?.options
|
|
14
|
+
});
|
|
15
|
+
},
|
|
16
|
+
set: (setterName = "", setterOptions = {}) => {
|
|
17
|
+
return set({
|
|
18
|
+
setterName,
|
|
19
|
+
setterOptions: api?.setters[setterName] || {},
|
|
20
|
+
input: setterOptions?.input,
|
|
21
|
+
output: setterOptions?.output,
|
|
22
|
+
context: req?.context,
|
|
23
|
+
APIOptions: api?.options
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
} catch (exception) {
|
|
28
|
+
throw new Error(`[ssr.getAPIForDataFunctions] ${exception.message}`);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
getAPIForDataFunctions_default as default
|
|
33
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
var getDataFromComponent_default = async (componentInstance = {}, api = {}, browserSafeRequest = {}) => {
|
|
2
|
+
try {
|
|
3
|
+
const data = await componentInstance.handleFetchData(api, browserSafeRequest, {}, componentInstance);
|
|
4
|
+
return {
|
|
5
|
+
componentId: componentInstance?.id,
|
|
6
|
+
data
|
|
7
|
+
};
|
|
8
|
+
} catch (exception) {
|
|
9
|
+
throw new Error(`[ssr.getDataFromComponent] ${exception.message}`);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
getDataFromComponent_default as default
|
|
14
|
+
};
|
package/dist/ssr/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
|
+
import { __package } from "../index.js";
|
|
2
3
|
import get from "../api/get";
|
|
3
4
|
import set from "../api/set";
|
|
4
5
|
import getBrowserSafeRequest from "../app/getBrowserSafeRequest";
|
|
@@ -7,6 +8,8 @@ import getCSSFromTree from "./getCSSFromTree";
|
|
|
7
8
|
import replaceWhenTags from "./replaceWhenTags";
|
|
8
9
|
import setHeadTagsInHTML from "./setHeadTagsInHTML";
|
|
9
10
|
import { parseHTML } from "linkedom";
|
|
11
|
+
import getDataFromComponent from "./getDataFromComponent.js";
|
|
12
|
+
import getAPIForDataFunctions from "./getAPIForDataFunctions.js";
|
|
10
13
|
const injectCSSIntoHTML = (html, baseCSS = "", css = "") => {
|
|
11
14
|
try {
|
|
12
15
|
return html.replace("${css}", css).replace("${globalCSS}", `<style>${baseCSS || ""}</style>`).replace("${componentCSS}", css);
|
|
@@ -184,7 +187,7 @@ const getBaseCSS = (baseHTMLName = "") => {
|
|
|
184
187
|
try {
|
|
185
188
|
const customBaseCSSPathForEmail = baseHTMLName ? `${process.cwd()}/email/base_${baseHTMLName}.css` : null;
|
|
186
189
|
const customDefaultBaseCSSPathForEmail = `${process.cwd()}/email/base.css`;
|
|
187
|
-
const defaultBaseCSSPathForEmail = process.env.NODE_ENV === "test" ? `${process.cwd()}/src/email/templates/base.css` : `${
|
|
190
|
+
const defaultBaseCSSPathForEmail = process.env.NODE_ENV === "test" ? `${process.cwd()}/src/email/templates/base.css` : `${__package}/email/templates/base.css`;
|
|
188
191
|
let baseCSSPathToFetch = defaultBaseCSSPathForEmail;
|
|
189
192
|
if (fs.existsSync(customDefaultBaseCSSPathForEmail)) {
|
|
190
193
|
baseCSSPathToFetch = customDefaultBaseCSSPathForEmail;
|
|
@@ -242,7 +245,7 @@ const getBaseHTML = (isEmailRender = false, baseEmailHTMLName = "") => {
|
|
|
242
245
|
if (isEmailRender) {
|
|
243
246
|
const customBaseHTMLPathForEmail = baseEmailHTMLName ? `${process.cwd()}/email/base_${baseEmailHTMLName}.html` : null;
|
|
244
247
|
const customDefaultBaseHTMLPathForEmail = `${process.cwd()}/email/base.html`;
|
|
245
|
-
const defaultBaseHTMLPathForEmail = process.env.NODE_ENV === "test" ? `${process.cwd()}/src/email/templates/base.html` : `${
|
|
248
|
+
const defaultBaseHTMLPathForEmail = process.env.NODE_ENV === "test" ? `${process.cwd()}/src/email/templates/base.html` : `${__package}/email/templates/base.html`;
|
|
246
249
|
baseHTMLPathToFetch = defaultBaseHTMLPathForEmail;
|
|
247
250
|
if (fs.existsSync(customDefaultBaseHTMLPathForEmail)) {
|
|
248
251
|
baseHTMLPathToFetch = customDefaultBaseHTMLPathForEmail;
|
|
@@ -289,17 +292,6 @@ const buildTreeForComponent = (componentInstance = {}, ssrTree = {}, translation
|
|
|
289
292
|
throw new Error(`[ssr.buildTreeForComponent] ${exception.message}`);
|
|
290
293
|
}
|
|
291
294
|
};
|
|
292
|
-
const getDataFromComponent = async (componentInstance = {}, api = {}, browserSafeRequest = {}) => {
|
|
293
|
-
try {
|
|
294
|
-
const data = await componentInstance.handleFetchData(api, browserSafeRequest, {}, componentInstance);
|
|
295
|
-
return {
|
|
296
|
-
componentId: componentInstance?.id,
|
|
297
|
-
data
|
|
298
|
-
};
|
|
299
|
-
} catch (exception) {
|
|
300
|
-
throw new Error(`[ssr.getDataFromComponent] ${exception.message}`);
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
295
|
const getTreeForSSR = (componentInstance = {}) => {
|
|
304
296
|
try {
|
|
305
297
|
return {
|
|
@@ -320,34 +312,6 @@ const getComponentInstance = (Component, options = {}) => {
|
|
|
320
312
|
throw new Error(`[ssr.getComponentInstance] ${exception.message}`);
|
|
321
313
|
}
|
|
322
314
|
};
|
|
323
|
-
const getAPIForDataFunctions = (req = {}, api = {}) => {
|
|
324
|
-
try {
|
|
325
|
-
return {
|
|
326
|
-
get: (getterName = "", getterOptions = {}) => {
|
|
327
|
-
return get({
|
|
328
|
-
getterName,
|
|
329
|
-
getterOptions: api?.getters[getterName] || {},
|
|
330
|
-
input: getterOptions?.input,
|
|
331
|
-
output: getterOptions?.output,
|
|
332
|
-
context: req?.context,
|
|
333
|
-
APIOptions: api?.options
|
|
334
|
-
});
|
|
335
|
-
},
|
|
336
|
-
set: (setterName = "", setterOptions = {}) => {
|
|
337
|
-
return set({
|
|
338
|
-
setterName,
|
|
339
|
-
setterOptions: api?.setters[setterName] || {},
|
|
340
|
-
input: setterOptions?.input,
|
|
341
|
-
output: setterOptions?.output,
|
|
342
|
-
context: req?.context,
|
|
343
|
-
APIOptions: api?.options
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
} catch (exception) {
|
|
348
|
-
throw new Error(`[ssr.getAPIForDataFunctions] ${exception.message}`);
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
315
|
const validateOptions = (options) => {
|
|
352
316
|
try {
|
|
353
317
|
if (!options)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joystick.js/node-canary",
|
|
3
|
-
"version": "0.0.0-canary.
|
|
3
|
+
"version": "0.0.0-canary.80",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A Node.js framework for building web apps.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"node-html-parser": "^5.1.0",
|
|
39
39
|
"nodemailer": "^6.7.0",
|
|
40
40
|
"pg": "^8.7.3",
|
|
41
|
+
"pg-escape": "^0.2.0",
|
|
41
42
|
"process": "^0.11.10",
|
|
42
43
|
"query-string": "^7.0.1",
|
|
43
44
|
"sanitize-html": "^2.7.3",
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { jest } from "@jest/globals";
|
|
2
|
-
import { killPortProcess } from "kill-port-process";
|
|
3
|
-
import setAppSettingsForTest from "../../../tests/lib/setAppSettingsForTest";
|
|
4
|
-
import startTestDatabase from "../../../tests/lib/databases/start";
|
|
5
|
-
import stopTestDatabase from "../../../tests/lib/databases/stop";
|
|
6
|
-
import { beforeEach, expect, test } from "@jest/globals";
|
|
7
|
-
import roles from "./index";
|
|
8
|
-
import accounts from "../index";
|
|
9
|
-
jest.mock("../../../../node_modules/dayjs", () => {
|
|
10
|
-
const _dayjs = jest.requireActual("../../../../node_modules/dayjs");
|
|
11
|
-
const _utc = jest.requireActual("../../../../node_modules/dayjs/plugin/utc");
|
|
12
|
-
_dayjs.extend(_utc);
|
|
13
|
-
return () => _dayjs("2022-01-01T00:00:00.000Z");
|
|
14
|
-
});
|
|
15
|
-
setAppSettingsForTest({
|
|
16
|
-
"config": {
|
|
17
|
-
"databases": [
|
|
18
|
-
{
|
|
19
|
-
"provider": "mongodb",
|
|
20
|
-
"users": true,
|
|
21
|
-
"options": {}
|
|
22
|
-
}
|
|
23
|
-
],
|
|
24
|
-
"i18n": {
|
|
25
|
-
"defaultLanguage": "en-US"
|
|
26
|
-
},
|
|
27
|
-
"middleware": {},
|
|
28
|
-
"email": {
|
|
29
|
-
"from": "app@test.com",
|
|
30
|
-
"smtp": {
|
|
31
|
-
"host": "fake.email.com",
|
|
32
|
-
"port": 587,
|
|
33
|
-
"username": "test",
|
|
34
|
-
"password": "password"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"global": {},
|
|
39
|
-
"public": {},
|
|
40
|
-
"private": {}
|
|
41
|
-
});
|
|
42
|
-
global.joystick = {
|
|
43
|
-
settings: {
|
|
44
|
-
config: {
|
|
45
|
-
databases: [{
|
|
46
|
-
"provider": "mongodb",
|
|
47
|
-
"users": true,
|
|
48
|
-
"options": {}
|
|
49
|
-
}]
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
const app = (await import("../../index")).default;
|
|
54
|
-
let instance;
|
|
55
|
-
describe("app/accounts/roles/index.js", () => {
|
|
56
|
-
beforeAll(async () => {
|
|
57
|
-
process.env.PORT = 3600;
|
|
58
|
-
});
|
|
59
|
-
beforeEach(async () => {
|
|
60
|
-
instance = await app({});
|
|
61
|
-
});
|
|
62
|
-
afterEach(async () => {
|
|
63
|
-
if (instance?.server?.close && typeof instance.server.close === "function") {
|
|
64
|
-
instance.server.close();
|
|
65
|
-
}
|
|
66
|
-
await killPortProcess(process.env.PORT);
|
|
67
|
-
});
|
|
68
|
-
afterAll(async () => {
|
|
69
|
-
});
|
|
70
|
-
test("roles.add adds role to roles collection in database", async () => {
|
|
71
|
-
await roles.add("admin");
|
|
72
|
-
const roleExists = await process.databases.mongodb.collection("roles").findOne({ role: "admin" });
|
|
73
|
-
expect(!!roleExists).toBe(true);
|
|
74
|
-
});
|
|
75
|
-
test("roles.remove removes role from roles collection in database", async () => {
|
|
76
|
-
await roles.add("admin");
|
|
77
|
-
await roles.remove("admin");
|
|
78
|
-
const roleExists = await process.databases.mongodb.collection("roles").findOne({ role: "admin" });
|
|
79
|
-
expect(!!roleExists).toBe(false);
|
|
80
|
-
});
|
|
81
|
-
test("roles.list returns a list of roles in the roles collection in database", async () => {
|
|
82
|
-
await roles.add("admin");
|
|
83
|
-
await roles.add("manager");
|
|
84
|
-
await roles.add("employee");
|
|
85
|
-
const rolesInDatabase = await roles.list();
|
|
86
|
-
await roles.remove("admin");
|
|
87
|
-
await roles.remove("manager");
|
|
88
|
-
await roles.remove("employee");
|
|
89
|
-
expect(rolesInDatabase).toEqual(["admin", "manager", "employee"]);
|
|
90
|
-
});
|
|
91
|
-
test("roles.grant adds role to user in users collection in database", async () => {
|
|
92
|
-
await process.databases.mongodb.collection("users").deleteOne({ emailAddress: "test@test.com" });
|
|
93
|
-
const user = await accounts.signup({ emailAddress: "test@test.com", password: "password" });
|
|
94
|
-
await roles.grant(user?.userId, "admin");
|
|
95
|
-
await roles.grant(user?.userId, "rolethatdoesntexist");
|
|
96
|
-
const userAfterGrant = await process.databases.mongodb.collection("users").findOne({ _id: user?.userId });
|
|
97
|
-
const rolesCreated = await process.databases.mongodb.collection("roles").find().toArray();
|
|
98
|
-
expect(userAfterGrant?.roles?.includes("admin")).toBe(true);
|
|
99
|
-
expect(rolesCreated?.length).toBe(2);
|
|
100
|
-
});
|
|
101
|
-
test("roles.revoke removes role from user in users collection in database", async () => {
|
|
102
|
-
await process.databases.mongodb.collection("users").deleteOne({ emailAddress: "test@test.com" });
|
|
103
|
-
const user = await accounts.signup({ emailAddress: "test@test.com", password: "password" });
|
|
104
|
-
await roles.grant(user?.userId, "admin");
|
|
105
|
-
await roles.revoke(user?.userId, "admin");
|
|
106
|
-
const userAfterGrant = await process.databases.mongodb.collection("users").findOne({ _id: user?.userId });
|
|
107
|
-
expect(userAfterGrant?.roles?.includes("admin")).toBe(false);
|
|
108
|
-
});
|
|
109
|
-
test("roles.userHasRole returns true if user has role", async () => {
|
|
110
|
-
await process.databases.mongodb.collection("users").deleteOne({ emailAddress: "test@test.com" });
|
|
111
|
-
const user = await accounts.signup({ emailAddress: "test@test.com", password: "password" });
|
|
112
|
-
await roles.grant(user?.userId, "admin");
|
|
113
|
-
const userHasRole = await roles.userHasRole(user?.userId, "admin");
|
|
114
|
-
expect(userHasRole).toBe(true);
|
|
115
|
-
});
|
|
116
|
-
test("roles.userHasRole returns false if user does not have role", async () => {
|
|
117
|
-
await process.databases.mongodb.collection("users").deleteOne({ emailAddress: "test@test.com" });
|
|
118
|
-
const user = await accounts.signup({ emailAddress: "test@test.com", password: "password" });
|
|
119
|
-
await roles.grant(user?.userId, "admin");
|
|
120
|
-
const userHasRole = await roles.userHasRole(user?.userId, "manager");
|
|
121
|
-
expect(userHasRole).toBe(false);
|
|
122
|
-
});
|
|
123
|
-
});
|