@openinc/parse-server-opendash 3.6.1 → 3.7.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/dist/features/config/helper/isFeatureEnabled.d.ts +1 -0
- package/dist/features/config/helper/isFeatureEnabled.js +27 -0
- package/dist/features/config/index.d.ts +2 -1
- package/dist/features/config/index.js +5 -3
- package/dist/features/permissions/services/registerPermissions.d.ts +6 -0
- package/dist/features/permissions/services/registerPermissions.js +21 -5
- package/dist/features/permissions/types/Permissions.d.ts +1 -1
- package/dist/features/permissions/types/Permissions.js +13 -13
- package/dist/functions/openinc-auth-login-microsoft.d.ts +1 -0
- package/dist/functions/openinc-auth-login-microsoft.js +65 -0
- package/dist/index.js +5 -23
- package/package.json +3 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isFeatureEnabled(feature: string): boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isFeatureEnabled = isFeatureEnabled;
|
|
4
|
+
const __1 = require("..");
|
|
5
|
+
function isFeatureEnabled(feature) {
|
|
6
|
+
const config = __1.ConfigInstance.getInstance();
|
|
7
|
+
switch (feature) {
|
|
8
|
+
case "CORE":
|
|
9
|
+
return config.getBoolean("FEATURE_CORE");
|
|
10
|
+
case "MONITORING":
|
|
11
|
+
return config.getBoolean("FEATURE_MONITORING");
|
|
12
|
+
case "BDE":
|
|
13
|
+
return config.getBoolean("FEATURE_BDE");
|
|
14
|
+
case "GTFS":
|
|
15
|
+
return config.getBoolean("FEATURE_GTFS");
|
|
16
|
+
case "KNOWLEDGE":
|
|
17
|
+
return config.getBoolean("FEATURE_KNOWLEDGE");
|
|
18
|
+
case "MAINTENANCE":
|
|
19
|
+
return config.getBoolean("FEATURE_MAINTENANCE");
|
|
20
|
+
case "DOCUMENTATION":
|
|
21
|
+
return config.getBoolean("FEATURE_DOCUMENTATION");
|
|
22
|
+
case "MIAAS":
|
|
23
|
+
return config.getBoolean("FEATURE_MIAAS");
|
|
24
|
+
default:
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -2,5 +2,6 @@ export { CommonConfigValue, ConfigBooleanValue, ConfigMap, ConfigValue, } from "
|
|
|
2
2
|
export { ConfigState } from "./states/Config";
|
|
3
3
|
export { default as ConfigInstance } from "./services/ConfigInstance";
|
|
4
4
|
export { ConfigKeys } from "./types/ConfigKeys";
|
|
5
|
-
export { customoptions } from "./helper/customOptions";
|
|
6
5
|
export { baseoptions } from "./helper/baseOptions";
|
|
6
|
+
export { customoptions } from "./helper/customOptions";
|
|
7
|
+
export { isFeatureEnabled } from "./helper/isFeatureEnabled";
|
|
@@ -3,14 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.isFeatureEnabled = exports.customoptions = exports.baseoptions = exports.ConfigKeys = exports.ConfigInstance = exports.ConfigState = void 0;
|
|
7
7
|
var Config_1 = require("./states/Config");
|
|
8
8
|
Object.defineProperty(exports, "ConfigState", { enumerable: true, get: function () { return Config_1.ConfigState; } });
|
|
9
9
|
var ConfigInstance_1 = require("./services/ConfigInstance");
|
|
10
10
|
Object.defineProperty(exports, "ConfigInstance", { enumerable: true, get: function () { return __importDefault(ConfigInstance_1).default; } });
|
|
11
11
|
var ConfigKeys_1 = require("./types/ConfigKeys");
|
|
12
12
|
Object.defineProperty(exports, "ConfigKeys", { enumerable: true, get: function () { return ConfigKeys_1.ConfigKeys; } });
|
|
13
|
-
var customOptions_1 = require("./helper/customOptions");
|
|
14
|
-
Object.defineProperty(exports, "customoptions", { enumerable: true, get: function () { return customOptions_1.customoptions; } });
|
|
15
13
|
var baseOptions_1 = require("./helper/baseOptions");
|
|
16
14
|
Object.defineProperty(exports, "baseoptions", { enumerable: true, get: function () { return baseOptions_1.baseoptions; } });
|
|
15
|
+
var customOptions_1 = require("./helper/customOptions");
|
|
16
|
+
Object.defineProperty(exports, "customoptions", { enumerable: true, get: function () { return customOptions_1.customoptions; } });
|
|
17
|
+
var isFeatureEnabled_1 = require("./helper/isFeatureEnabled");
|
|
18
|
+
Object.defineProperty(exports, "isFeatureEnabled", { enumerable: true, get: function () { return isFeatureEnabled_1.isFeatureEnabled; } });
|
|
@@ -4,4 +4,10 @@ import { RegisteredPermission } from "..";
|
|
|
4
4
|
* @returns all permissions
|
|
5
5
|
*/
|
|
6
6
|
export declare function getAllPermissions(): RegisteredPermission[];
|
|
7
|
+
/**
|
|
8
|
+
* Entry point for the permission registration process.
|
|
9
|
+
* It retrieves all tenants and registers the permissions for each tenant.
|
|
10
|
+
* It also ensures that the default admin access permissions are set for each tenant.
|
|
11
|
+
* @returns {Promise<void>}
|
|
12
|
+
*/
|
|
7
13
|
export default function initPermissions(): Promise<void>;
|
|
@@ -12,6 +12,10 @@ const types_1 = require("../../../types");
|
|
|
12
12
|
function getAllPermissions() {
|
|
13
13
|
const permissions = []; // stores all permissions
|
|
14
14
|
for (const key in __1.Permissions) {
|
|
15
|
+
// TODO: Check if the feature is enabled, if not, skip it
|
|
16
|
+
// if (!isFeatureEnabled(key.toUpperCase())) {
|
|
17
|
+
// continue;
|
|
18
|
+
// }
|
|
15
19
|
// iterate over the objects / enums of the Permissions namespace
|
|
16
20
|
if (Object.prototype.hasOwnProperty.call(__1.Permissions, key)) {
|
|
17
21
|
const element = __1.Permissions[key]; // get the object / enum
|
|
@@ -45,10 +49,15 @@ function createPermission(input) {
|
|
|
45
49
|
}
|
|
46
50
|
/**
|
|
47
51
|
* Register all permissions in the database, if not already registered.
|
|
52
|
+
* This function checks if a permission with the same key already exists in the database.
|
|
53
|
+
* If it does, it skips the registration process for that permission.
|
|
54
|
+
* If it doesn't, it creates a new Permission object and saves it to the database.
|
|
55
|
+
* @param tenant the tenant to register the permissions for
|
|
56
|
+
* @returns {Promise<void>}
|
|
48
57
|
*/
|
|
49
58
|
async function registerPermissions(tenant) {
|
|
50
59
|
console.log("[@openinc/parse-server-opendash] Register all permissions");
|
|
51
|
-
|
|
60
|
+
const allPermissions = getAllPermissions().map(async (permission) => {
|
|
52
61
|
const [resultError, result] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Permission)
|
|
53
62
|
.equalTo("key", permission.key)
|
|
54
63
|
.equalTo("tenant", tenant)
|
|
@@ -66,13 +75,14 @@ async function registerPermissions(tenant) {
|
|
|
66
75
|
newPermission.set("description", permission.description);
|
|
67
76
|
await newPermission.save({}, { useMasterKey: true });
|
|
68
77
|
}
|
|
69
|
-
else {
|
|
70
|
-
console.log("[@openinc/parse-server-opendash] Permission already exists", permission.key);
|
|
71
|
-
}
|
|
72
78
|
});
|
|
79
|
+
await Promise.all(allPermissions);
|
|
80
|
+
console.log("[@openinc/parse-server-opendash] All permissions registered successfully");
|
|
73
81
|
}
|
|
74
82
|
/**
|
|
75
83
|
* Set read access for all admin roles to admin overview permission
|
|
84
|
+
* @param tenant the tenant to set the permissions for
|
|
85
|
+
* @returns {Promise<void>}
|
|
76
86
|
*/
|
|
77
87
|
async function ensureDefaultAdminAccess(tenant) {
|
|
78
88
|
console.log("[@openinc/parse-server-opendash] Ensure default admin access permissions");
|
|
@@ -97,13 +107,19 @@ async function ensureDefaultAdminAccess(tenant) {
|
|
|
97
107
|
console.log("[@openinc/parse-server-opendash] Permission not found", __1.Permissions.OpenINCStack.adminoverview);
|
|
98
108
|
}
|
|
99
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Entry point for the permission registration process.
|
|
112
|
+
* It retrieves all tenants and registers the permissions for each tenant.
|
|
113
|
+
* It also ensures that the default admin access permissions are set for each tenant.
|
|
114
|
+
* @returns {Promise<void>}
|
|
115
|
+
*/
|
|
100
116
|
async function initPermissions() {
|
|
101
117
|
const tenants = await new Parse.Query(types_1.Tenant)
|
|
102
118
|
.descending("createdAt")
|
|
103
119
|
.find({ useMasterKey: true });
|
|
104
120
|
if (tenants) {
|
|
105
121
|
for await (const tenant of tenants) {
|
|
106
|
-
await
|
|
122
|
+
await registerPermissions(tenant);
|
|
107
123
|
await ensureDefaultAdminAccess(tenant);
|
|
108
124
|
}
|
|
109
125
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Adding new Permissions here requires the server to restart for registering those.
|
|
5
5
|
*/
|
|
6
6
|
export declare namespace Permissions {
|
|
7
|
-
enum
|
|
7
|
+
enum Maintenance {
|
|
8
8
|
ticket = "maintenance:can-create-ticket",
|
|
9
9
|
schedule = "maintenance:can-create-schedule",
|
|
10
10
|
message = "maintenance:can-create-message",
|
|
@@ -9,22 +9,22 @@ exports.Permissions = void 0;
|
|
|
9
9
|
var Permissions;
|
|
10
10
|
(function (Permissions) {
|
|
11
11
|
// needs to be exported for getAllPermissions() to work
|
|
12
|
-
let
|
|
13
|
-
(function (
|
|
12
|
+
let Maintenance;
|
|
13
|
+
(function (Maintenance) {
|
|
14
14
|
// Create
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
Maintenance["ticket"] = "maintenance:can-create-ticket";
|
|
16
|
+
Maintenance["schedule"] = "maintenance:can-create-schedule";
|
|
17
|
+
Maintenance["message"] = "maintenance:can-create-message";
|
|
18
|
+
Maintenance["machinelog_ticket"] = "maintenance:can-create-machinelog-ticket";
|
|
19
|
+
Maintenance["machinelog_schedule"] = "maintenance:can-create-machinelog-schedule";
|
|
20
|
+
Maintenance["machinelog_message"] = "maintenance:can-create-machinelog-message";
|
|
21
21
|
// Access
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
Maintenance["global"] = "maintenance:can-access-global";
|
|
23
|
+
Maintenance["monitor"] = "maintenance:can-access-monitor";
|
|
24
|
+
Maintenance["monitoring"] = "maintenance:can-access-monitoring";
|
|
25
25
|
// Update
|
|
26
|
-
|
|
27
|
-
})(
|
|
26
|
+
Maintenance["kanban_view"] = "maintenance:can-update-kanban-view";
|
|
27
|
+
})(Maintenance = Permissions.Maintenance || (Permissions.Maintenance = {}));
|
|
28
28
|
let OpenINCStack;
|
|
29
29
|
(function (OpenINCStack) {
|
|
30
30
|
//Access
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function init(name: string): Promise<void>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.init = init;
|
|
7
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
|
+
const jwks_rsa_1 = __importDefault(require("jwks-rsa"));
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
const tenantId = process.env.MICROSOFT_TENANT_ID;
|
|
11
|
+
const appId = process.env.MICROSOFT_APP_ID;
|
|
12
|
+
// Setup JWKS client for Microsoft (replace TENANT_ID)
|
|
13
|
+
const client = (0, jwks_rsa_1.default)({
|
|
14
|
+
jwksUri: `https://login.microsoftonline.com/${tenantId}/discovery/v2.0/keys`,
|
|
15
|
+
});
|
|
16
|
+
function getKey(header, callback) {
|
|
17
|
+
if (!header.kid) {
|
|
18
|
+
return callback(new Error("No kid found in token header"));
|
|
19
|
+
}
|
|
20
|
+
client.getSigningKey(header.kid, (err, key) => {
|
|
21
|
+
if (err || !key) {
|
|
22
|
+
return callback(err || new Error("Key not found"));
|
|
23
|
+
}
|
|
24
|
+
const signingKey = key.getPublicKey();
|
|
25
|
+
callback(null, signingKey);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async function init(name) {
|
|
29
|
+
Parse.Cloud.define(name, async (request) => {
|
|
30
|
+
const token = request.params.token;
|
|
31
|
+
const account = request.params.account;
|
|
32
|
+
if (!token) {
|
|
33
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, "Token missing");
|
|
34
|
+
}
|
|
35
|
+
const verifiedPayload = await new Promise((resolve, reject) => {
|
|
36
|
+
jsonwebtoken_1.default.verify(token, getKey, {
|
|
37
|
+
audience: appId,
|
|
38
|
+
issuer: `https://login.microsoftonline.com/${tenantId}/v2.0`,
|
|
39
|
+
}, (err, decoded) => {
|
|
40
|
+
if (err)
|
|
41
|
+
return reject(err);
|
|
42
|
+
resolve(decoded);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
let user = await new Parse.Query(Parse.User)
|
|
46
|
+
.equalTo("username", verifiedPayload.oid)
|
|
47
|
+
.first({ useMasterKey: true });
|
|
48
|
+
if (!user) {
|
|
49
|
+
user = new Parse.User();
|
|
50
|
+
user.set("username", verifiedPayload.oid);
|
|
51
|
+
user.set("email", account.username);
|
|
52
|
+
user.set("password", (0, crypto_1.randomBytes)(16).toString("hex")); // Generate a random password
|
|
53
|
+
user.set("name", verifiedPayload.name || verifiedPayload.preferred_username);
|
|
54
|
+
user = await user.signUp(null, { useMasterKey: true });
|
|
55
|
+
return user.getSessionToken();
|
|
56
|
+
}
|
|
57
|
+
const sessionToken = "r:" + (0, crypto_1.randomBytes)(16).toString("hex");
|
|
58
|
+
const session = new Parse.Object("_Session");
|
|
59
|
+
session.set("user", user);
|
|
60
|
+
session.set("sessionToken", sessionToken);
|
|
61
|
+
session.set("expiresAt", new Date(Date.now() + 24 * 60 * 60 * 1000 * 7)); // 7 day expiration
|
|
62
|
+
const savedSession = await session.save(null, { useMasterKey: true });
|
|
63
|
+
return savedSession.get("sessionToken");
|
|
64
|
+
});
|
|
65
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -539,6 +539,10 @@ async function autoloadCloudCode(path, regex = /^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$
|
|
|
539
539
|
.filter((name) => regex.test(name));
|
|
540
540
|
for (const name of fns) {
|
|
541
541
|
const { init } = require((0, path_1.join)(path, name));
|
|
542
|
+
if (!init || typeof init !== "function") {
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
console.log(`[@openinc/parse-server-opendash] Autoloading ${name}.js`);
|
|
542
546
|
await init(name).catch((e) => console.error(e));
|
|
543
547
|
}
|
|
544
548
|
}
|
|
@@ -552,32 +556,10 @@ function getFeatureForClassName(className) {
|
|
|
552
556
|
const map = featuremap_json_1.default;
|
|
553
557
|
return map[className] || "unknown";
|
|
554
558
|
}
|
|
555
|
-
function isFeatureEnabled(feature) {
|
|
556
|
-
switch (feature) {
|
|
557
|
-
case "CORE":
|
|
558
|
-
return config.getBoolean("FEATURE_CORE");
|
|
559
|
-
case "MONITORING":
|
|
560
|
-
return config.getBoolean("FEATURE_MONITORING");
|
|
561
|
-
case "BDE":
|
|
562
|
-
return config.getBoolean("FEATURE_BDE");
|
|
563
|
-
case "GTFS":
|
|
564
|
-
return config.getBoolean("FEATURE_GTFS");
|
|
565
|
-
case "KNOWLEDGE":
|
|
566
|
-
return config.getBoolean("FEATURE_KNOWLEDGE");
|
|
567
|
-
case "MAINTENANCE":
|
|
568
|
-
return config.getBoolean("FEATURE_MAINTENANCE");
|
|
569
|
-
case "DOCUMENTATION":
|
|
570
|
-
return config.getBoolean("FEATURE_DOCUMENTATION");
|
|
571
|
-
case "MIAAS":
|
|
572
|
-
return config.getBoolean("FEATURE_MIAAS");
|
|
573
|
-
default:
|
|
574
|
-
return false;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
559
|
function isClassEnabled(className) {
|
|
578
560
|
// if (!config.getBoolean("FEATURES_ENABLED")) return true;
|
|
579
561
|
const feature = getFeatureForClassName(className);
|
|
580
|
-
const enabled = isFeatureEnabled(feature);
|
|
562
|
+
const enabled = (0, config_1.isFeatureEnabled)(feature);
|
|
581
563
|
return enabled;
|
|
582
564
|
}
|
|
583
565
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openinc/parse-server-opendash",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "Parse Server Cloud Code for open.INC Stack.",
|
|
5
5
|
"packageManager": "pnpm@10.11.0",
|
|
6
6
|
"keywords": [
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"schema-up": "parse-server-schema up --prefix OD3_ ./schema",
|
|
53
53
|
"schema-ts": "parse-server-schema typescript --prefix OD3_ --global-sdk ./src/types",
|
|
54
54
|
"typedoc": "typedoc --plugin typedoc-plugin-markdown --hideBreadcrumbs --out docs src/index.ts",
|
|
55
|
-
"predevstart": "./setup_scripts/
|
|
55
|
+
"predevstart": "./setup_scripts/installDeps.sh",
|
|
56
56
|
"devstart": "parse-server ./config.js",
|
|
57
57
|
"featuremap": "node ./scripts/create-featuremap.js",
|
|
58
58
|
"hooks": "node ./scripts/create-hooks.js",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"dayjs": "^1.11.13",
|
|
69
69
|
"fast-equals": "^5.2.2",
|
|
70
70
|
"jsonwebtoken": "^9.0.2",
|
|
71
|
+
"jwks-rsa": "^3.2.0",
|
|
71
72
|
"nodemailer": "^6.10.1",
|
|
72
73
|
"nunjucks": "^3.2.4",
|
|
73
74
|
"parse-server": "^8.2.0",
|