@bigid/apps-infrastructure-node-js 0.1.0 → 1.180.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/.github/workflows/bigid_config +3 -0
- package/.github/workflows/npmjs_config +3 -0
- package/.github/workflows/private-registry-publish.yml +16 -0
- package/.github/workflows/public-registry-publish.yml +14 -0
- package/CODEOWNERS +1 -0
- package/README.md +31 -2
- package/jsdoc.json +14 -0
- package/lib/abstractProviders/configureProvider.d.ts +10 -0
- package/lib/{routes/router.js → abstractProviders/configureProvider.js} +7 -3
- package/lib/abstractProviders/executionProvider.d.ts +3 -2
- package/lib/abstractProviders/executionProvider.js +5 -10
- package/lib/abstractProviders/index.d.ts +1 -0
- package/lib/abstractProviders/index.js +3 -1
- package/lib/abstractProviders/logsProvider.js +9 -1
- package/lib/abstractProviders/manifestProvider.d.ts +2 -1
- package/lib/dto/actionResponseDetails.d.ts +3 -1
- package/lib/dto/actionResponseDetails.js +2 -1
- package/lib/dto/executionContext.d.ts +8 -5
- package/lib/dto/executionContext.js +0 -14
- package/lib/dto/index.d.ts +1 -1
- package/lib/dto/index.js +1 -3
- package/lib/dto/subExecutionItem.d.ts +7 -0
- package/lib/dto/subExecutionItem.js +12 -0
- package/lib/dto/tenantRegistration.d.ts +5 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +16 -2
- package/lib/server.d.ts +11 -7
- package/lib/server.js +16 -12
- package/lib/services/actionsHubService.d.ts +45 -0
- package/lib/services/actionsHubService.js +105 -0
- package/lib/services/batchProcessManager.d.ts +2 -0
- package/lib/services/batchProcessManager.js +45 -0
- package/lib/services/bigidProxyService.d.ts +28 -13
- package/lib/services/bigidProxyService.js +67 -55
- package/lib/services/dataSourceService.d.ts +4 -0
- package/lib/services/dataSourceService.js +26 -0
- package/lib/services/encryptionService.d.ts +1 -0
- package/lib/services/encryptionService.js +67 -0
- package/lib/services/index.d.ts +3 -0
- package/lib/services/index.js +12 -1
- package/lib/services/schedulerService.d.ts +11 -0
- package/lib/services/schedulerService.js +41 -0
- package/lib/utils/appLogger.d.ts +10 -1
- package/lib/utils/appLogger.js +38 -7
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +15 -3
- package/lib/utils/tokenUtil.d.ts +3 -0
- package/lib/utils/tokenUtil.js +62 -0
- package/package.json +11 -4
- package/src/abstractProviders/configureProvider.ts +15 -0
- package/src/abstractProviders/executionProvider.ts +5 -7
- package/src/abstractProviders/index.ts +1 -0
- package/src/abstractProviders/logsProvider.ts +11 -3
- package/src/abstractProviders/manifestProvider.ts +3 -1
- package/src/dto/actionResponseDetails.ts +5 -1
- package/src/dto/executionContext.ts +8 -23
- package/src/dto/index.ts +2 -2
- package/src/dto/subExecutionItem.ts +13 -0
- package/src/dto/tenantRegistration.ts +5 -0
- package/src/index.ts +17 -1
- package/src/server.ts +33 -20
- package/src/services/actionsHubService.ts +141 -0
- package/src/services/batchProcessManager.ts +39 -0
- package/src/services/bigidProxyService.ts +84 -62
- package/src/services/dataSourceService.ts +20 -0
- package/src/services/encryptionService.ts +44 -0
- package/src/services/index.ts +5 -1
- package/src/services/schedulerService.ts +39 -0
- package/src/utils/appLogger.ts +44 -6
- package/src/utils/index.ts +1 -1
- package/src/utils/tokenUtil.ts +65 -0
- package/.dcignore +0 -1547
- package/.idea/apps-infrastructure-node-js.iml +0 -9
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -7
- package/.idea/runConfigurations.xml +0 -10
- package/.idea/snyk.project.settings.xml +0 -6
- package/.idea/vcs.xml +0 -6
- package/lib/appTypes/actionResponseDetails.d.ts +0 -6
- package/lib/appTypes/executionContext.d.ts +0 -10
- package/lib/appTypes/executionContext.js +0 -2
- package/lib/appTypes/index.d.ts +0 -2
- package/lib/appTypes/index.js +0 -2
- package/lib/dto/keysValuesToStore.d.ts +0 -5
- package/lib/dto/keysValuesToStore.js +0 -19
- package/lib/routes/router.d.ts +0 -1
- /package/lib/{appTypes/actionResponseDetails.js → dto/tenantRegistration.js} +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.tokenExchange = exports.getAuth0Token = exports.getAccessTokenFromRefreshToken = void 0;
|
|
16
|
+
const axios_1 = __importDefault(require("axios"));
|
|
17
|
+
const https_1 = require("https");
|
|
18
|
+
const services_1 = require("../services");
|
|
19
|
+
const auth0Payload = {
|
|
20
|
+
client_id: process.env.CLIENT_ID,
|
|
21
|
+
client_secret: process.env.CLIENT_SECRET,
|
|
22
|
+
audience: process.env.AUTH0_AUDIENCE || 'bigid-api-v1',
|
|
23
|
+
grant_type: 'client_credentials',
|
|
24
|
+
};
|
|
25
|
+
let auth0Token;
|
|
26
|
+
let accessToken;
|
|
27
|
+
const getAccessTokenFromRefreshToken = (refreshToken) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
if (canUseLocalToken(accessToken))
|
|
29
|
+
return accessToken;
|
|
30
|
+
const bigidBaseUrl = process.env.BIGID_BASE_URL;
|
|
31
|
+
const { data: { systemToken }, } = yield (0, services_1.doCallToUrl)(refreshToken, services_1.RequestMethod.GET, new URL('api/v1/refresh-access-token', bigidBaseUrl).toString());
|
|
32
|
+
accessToken = systemToken;
|
|
33
|
+
return accessToken;
|
|
34
|
+
});
|
|
35
|
+
exports.getAccessTokenFromRefreshToken = getAccessTokenFromRefreshToken;
|
|
36
|
+
const getAuth0Token = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
var _a;
|
|
38
|
+
if (canUseLocalToken(auth0Token))
|
|
39
|
+
return auth0Token;
|
|
40
|
+
const auth0Domain = (_a = process.env.AUTH0_DOMAIN) === null || _a === void 0 ? void 0 : _a.replace(/\/$/, '');
|
|
41
|
+
const { data: { access_token }, } = yield axios_1.default.post(`${auth0Domain}/oauth/token`, auth0Payload);
|
|
42
|
+
auth0Token = access_token;
|
|
43
|
+
return access_token;
|
|
44
|
+
});
|
|
45
|
+
exports.getAuth0Token = getAuth0Token;
|
|
46
|
+
const tokenExchange = (auth0Token, tenantId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
const { data: { data }, } = yield axios_1.default.post(`${process.env.BIGID_BASE_URL}/api/v1/token-exchange`, { tenantId }, {
|
|
48
|
+
headers: { authorization: auth0Token },
|
|
49
|
+
httpsAgent: new https_1.Agent({
|
|
50
|
+
rejectUnauthorized: false,
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
return data[0];
|
|
54
|
+
});
|
|
55
|
+
exports.tokenExchange = tokenExchange;
|
|
56
|
+
const getTokenPayloadAsJson = (token) => JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
57
|
+
const canUseLocalToken = (token) => {
|
|
58
|
+
if (!token)
|
|
59
|
+
return false;
|
|
60
|
+
const { exp } = getTokenPayloadAsJson(token);
|
|
61
|
+
return Date.now() < exp * 1000;
|
|
62
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigid/apps-infrastructure-node-js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.180.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"docs": "npx tsc && ./node_modules/.bin/jsdoc -c jsdoc.json"
|
|
8
|
+
},
|
|
6
9
|
"types": "lib/index.d.ts",
|
|
7
10
|
"repository": {
|
|
8
11
|
"type": "git",
|
|
@@ -14,6 +17,7 @@
|
|
|
14
17
|
"@types/express": "^4.17.13",
|
|
15
18
|
"@types/http-errors": "^1.8.1",
|
|
16
19
|
"@types/node": "^16.11.10",
|
|
20
|
+
"@types/node-schedule": "^2.1.0",
|
|
17
21
|
"@typescript-eslint/eslint-plugin": "4.6.1",
|
|
18
22
|
"@typescript-eslint/parser": "4.6.1",
|
|
19
23
|
"eslint": "7.12.1",
|
|
@@ -24,10 +28,13 @@
|
|
|
24
28
|
"typescript": "^4.5.2"
|
|
25
29
|
},
|
|
26
30
|
"dependencies": {
|
|
27
|
-
"axios": "
|
|
28
|
-
"
|
|
31
|
+
"axios": "0.24.0",
|
|
32
|
+
"follow-redirects": "1.15.2",
|
|
33
|
+
"express": "4.17.3",
|
|
29
34
|
"form-data": "^4.0.0",
|
|
30
35
|
"http-errors": "^1.8.1",
|
|
31
|
-
"
|
|
36
|
+
"jsdoc": "4.0.2",
|
|
37
|
+
"log4js": "^6.4.0",
|
|
38
|
+
"node-schedule": "2.1.1"
|
|
32
39
|
}
|
|
33
40
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
|
|
3
|
+
export type ConfigurePayload = {
|
|
4
|
+
tenantId: string;
|
|
5
|
+
bigidBaseUrl?: string;
|
|
6
|
+
isDeleted?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const handleTenantConfigure = async (req: Request, res: Response, configureProvider: ConfigureProvider) => {
|
|
10
|
+
await configureProvider.configureTenant(req.body, res);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export abstract class ConfigureProvider {
|
|
14
|
+
public abstract configureTenant(configurePayload: ConfigurePayload, res: Response): Promise<void> | void;
|
|
15
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Request, Response } from 'express';
|
|
2
|
-
import { ActionResponseDetails } from '../dto
|
|
3
|
-
import { setValuesForBigIDProxy } from '../services';
|
|
2
|
+
import { ActionResponseDetails, ExecutionContext } from '../dto';
|
|
4
3
|
|
|
5
4
|
export const StatusEnum = {
|
|
6
5
|
COMPLETED: 'COMPLETED',
|
|
@@ -9,12 +8,11 @@ export const StatusEnum = {
|
|
|
9
8
|
};
|
|
10
9
|
|
|
11
10
|
export const handleExecution = async (req: Request, res: Response, executionProvider: ExecutionProvider) => {
|
|
12
|
-
|
|
13
|
-
await executionProvider.executeAction(req, res);
|
|
11
|
+
await executionProvider.executeAction(req.body, res);
|
|
14
12
|
};
|
|
15
13
|
|
|
16
14
|
export abstract class ExecutionProvider {
|
|
17
|
-
public abstract executeAction(
|
|
15
|
+
public abstract executeAction(executionContext: ExecutionContext, res: Response): Promise<void>;
|
|
18
16
|
|
|
19
17
|
generateSyncSuccessMessage = (res: Response, executionId: string, message: string) =>
|
|
20
18
|
res.status(200).json(new ActionResponseDetails(executionId, StatusEnum.COMPLETED, 1, message));
|
|
@@ -22,6 +20,6 @@ export abstract class ExecutionProvider {
|
|
|
22
20
|
generateAsyncSuccessMessage = (res: Response, executionId: string, message: string) =>
|
|
23
21
|
res.status(202).json(new ActionResponseDetails(executionId, StatusEnum.IN_PROGRESS, 0, message));
|
|
24
22
|
|
|
25
|
-
generateFailedResponse = (res: Response, executionId: string,
|
|
26
|
-
res.status(400).json(new ActionResponseDetails(executionId, StatusEnum.ERROR, 0,
|
|
23
|
+
generateFailedResponse = (res: Response, executionId: string, errorMessage: string) =>
|
|
24
|
+
res.status(400).json(new ActionResponseDetails(executionId, StatusEnum.ERROR, 0, errorMessage));
|
|
27
25
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
2
|
import { Request, Response } from 'express';
|
|
3
3
|
import { LOGS_PATH } from '../utils/constants';
|
|
4
4
|
|
|
5
|
-
export const fetchLogs = (req: Request, res: Response) =>
|
|
6
|
-
|
|
5
|
+
export const fetchLogs = (req: Request, res: Response) => {
|
|
6
|
+
const tenantId = req.headers.tenantid;
|
|
7
|
+
const data = readFileSync(LOGS_PATH, { encoding: 'utf8' });
|
|
8
|
+
const lines = data.split('\n');
|
|
9
|
+
const tenantLogLines = lines
|
|
10
|
+
.filter(line => line.includes(`[tenantId: ${tenantId}`) || !line.includes('[tenantId: '))
|
|
11
|
+
.join('\n');
|
|
12
|
+
|
|
13
|
+
return res.send(tenantLogLines);
|
|
14
|
+
};
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
+
import { SubExecutionItem } from "./subExecutionItem";
|
|
2
|
+
|
|
1
3
|
export class ActionResponseDetails {
|
|
2
4
|
executionId: string;
|
|
3
5
|
statusEnum: string;
|
|
4
6
|
progress: number;
|
|
5
7
|
message: string;
|
|
6
8
|
additionalData?: any;
|
|
9
|
+
subExecutionItems?: SubExecutionItem[];
|
|
7
10
|
|
|
8
|
-
constructor(executionId: string, statusEnum: string, progress: number, message: string, additionalData?: any) {
|
|
11
|
+
constructor(executionId: string, statusEnum: string, progress: number, message: string, additionalData?: any, subExecutionItems?: SubExecutionItem[]) {
|
|
9
12
|
this.executionId = executionId;
|
|
10
13
|
this.statusEnum = statusEnum;
|
|
11
14
|
this.progress = progress;
|
|
12
15
|
this.message = message;
|
|
13
16
|
this.additionalData = additionalData;
|
|
17
|
+
this.subExecutionItems = subExecutionItems;
|
|
14
18
|
}
|
|
15
19
|
}
|
|
@@ -1,30 +1,15 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type ExecutionContext = {
|
|
2
2
|
actionName: string;
|
|
3
3
|
executionId: string;
|
|
4
|
-
globalParams:
|
|
5
|
-
actionParams:
|
|
4
|
+
globalParams: Array<GeneralParam>;
|
|
5
|
+
actionParams: Array<GeneralParam>;
|
|
6
6
|
bigidBaseUrl: string;
|
|
7
7
|
bigidToken: string;
|
|
8
8
|
updateResultCallback: any;
|
|
9
9
|
tpaId: string;
|
|
10
|
+
};
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
actionParams: Record<string, string>,
|
|
16
|
-
bigidBaseUrl: string,
|
|
17
|
-
bigidToken: string,
|
|
18
|
-
updateResultCallback: any,
|
|
19
|
-
tpaId: string,
|
|
20
|
-
) {
|
|
21
|
-
this.actionName = actionName;
|
|
22
|
-
this.executionId = executionId;
|
|
23
|
-
this.globalParams = globalParams;
|
|
24
|
-
this.actionParams = actionParams;
|
|
25
|
-
this.bigidBaseUrl = bigidBaseUrl;
|
|
26
|
-
this.bigidToken = bigidToken;
|
|
27
|
-
this.updateResultCallback = updateResultCallback;
|
|
28
|
-
this.tpaId = tpaId;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
12
|
+
export type GeneralParam = {
|
|
13
|
+
paramName: string;
|
|
14
|
+
paramValue: string;
|
|
15
|
+
};
|
package/src/dto/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { ExecutionContext } from './executionContext';
|
|
2
|
-
export { ActionResponseDetails } from './actionResponseDetails';
|
|
1
|
+
export { ExecutionContext, GeneralParam } from './executionContext';
|
|
2
|
+
export { ActionResponseDetails } from './actionResponseDetails';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class SubExecutionItem {
|
|
2
|
+
name: string;
|
|
3
|
+
statusEnum: string;
|
|
4
|
+
message?: string;
|
|
5
|
+
errorCode?: string;
|
|
6
|
+
|
|
7
|
+
constructor(name: string, statusEnum: string, message?: string, errorCode?: string) {
|
|
8
|
+
this.name = name;
|
|
9
|
+
this.statusEnum = statusEnum;
|
|
10
|
+
this.message = message;
|
|
11
|
+
this.errorCode = errorCode;
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
export * from './abstractProviders';
|
|
2
2
|
export * from './dto';
|
|
3
3
|
export * from './utils';
|
|
4
|
-
export {
|
|
4
|
+
export {
|
|
5
|
+
updateActionStatusToBigID,
|
|
6
|
+
uploadAttachment,
|
|
7
|
+
getValueFromAppStorage,
|
|
8
|
+
saveInStorage,
|
|
9
|
+
executeHttpGet,
|
|
10
|
+
scheduleFunction,
|
|
11
|
+
unscheduleFunction,
|
|
12
|
+
unscheduleAllFunctions,
|
|
13
|
+
deleteKeyFromAppStorage,
|
|
14
|
+
sendBiEvent,
|
|
15
|
+
getCommandsRegistrations,
|
|
16
|
+
executeCommand,
|
|
17
|
+
getExecutionStatus,
|
|
18
|
+
registerActionAsCommand,
|
|
19
|
+
fetchDataSourceCredentials,
|
|
20
|
+
} from './services';
|
|
5
21
|
export { deployServer, ServerInit } from './server';
|
package/src/server.ts
CHANGED
|
@@ -1,36 +1,49 @@
|
|
|
1
|
-
import express, { NextFunction, Request, Response } from 'express';
|
|
2
|
-
import { ManifestProvider } from './abstractProviders
|
|
3
|
-
import {
|
|
4
|
-
import { IconsProviders } from './abstractProviders
|
|
1
|
+
import express, { Express, NextFunction, Request, Response } from 'express';
|
|
2
|
+
import { ManifestProvider } from './abstractProviders';
|
|
3
|
+
import { logInfo, logError } from './utils';
|
|
4
|
+
import { IconsProviders } from './abstractProviders';
|
|
5
5
|
import { ExecutionProvider, handleExecution } from './abstractProviders/executionProvider';
|
|
6
6
|
import { fetchLogs } from './abstractProviders/logsProvider';
|
|
7
7
|
import createError from 'http-errors';
|
|
8
|
+
import { ConfigureProvider, handleTenantConfigure } from './abstractProviders/configureProvider';
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
+
export type ServerInit = {
|
|
10
11
|
manifestController: ManifestProvider;
|
|
11
12
|
iconsController: IconsProviders;
|
|
12
|
-
executionController
|
|
13
|
+
executionController?: ExecutionProvider;
|
|
14
|
+
configureController?: ConfigureProvider;
|
|
13
15
|
serverPort?: number;
|
|
14
|
-
|
|
16
|
+
additionalEndpoints?: (app: Express) => void;
|
|
17
|
+
};
|
|
15
18
|
|
|
16
19
|
const app = express();
|
|
17
20
|
|
|
18
|
-
export const deployServer = (
|
|
21
|
+
export const deployServer = ({
|
|
22
|
+
manifestController,
|
|
23
|
+
iconsController,
|
|
24
|
+
executionController,
|
|
25
|
+
serverPort,
|
|
26
|
+
configureController,
|
|
27
|
+
additionalEndpoints,
|
|
28
|
+
}: ServerInit): void => {
|
|
19
29
|
app.use(express.json());
|
|
20
30
|
app.use(express.urlencoded({ extended: false }));
|
|
21
31
|
|
|
22
|
-
app.get('/assets/icon', (req, res) => res.sendFile(
|
|
23
|
-
app.get('/assets/sideBarIcon', (req, res) => res.sendFile(
|
|
24
|
-
app.get('/manifest',
|
|
25
|
-
app.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
app.get('/assets/icon', (req, res) => res.sendFile(iconsController.getIconPath()));
|
|
33
|
+
app.get('/assets/sideBarIcon', (req, res) => res.sendFile(iconsController.getSideBarIconPath()));
|
|
34
|
+
app.get('/manifest', manifestController.getManifest);
|
|
35
|
+
app.get('/logs', async (req: Request, res: Response) => await fetchLogs(req, res));
|
|
36
|
+
|
|
37
|
+
executionController &&
|
|
38
|
+
app.post('/execute', async (req: Request, res: Response) => await handleExecution(req, res, executionController));
|
|
39
|
+
configureController &&
|
|
40
|
+
app.post(
|
|
41
|
+
'/configure',
|
|
42
|
+
async (req: Request, res: Response) => await handleTenantConfigure(req, res, configureController),
|
|
43
|
+
);
|
|
44
|
+
additionalEndpoints && additionalEndpoints(app);
|
|
30
45
|
|
|
31
|
-
app.listen(process.env.PORT ||
|
|
32
|
-
appLogger.info(`Started server at port ${process.env.PORT || serverInit.serverPort}`),
|
|
33
|
-
);
|
|
46
|
+
app.listen(process.env.PORT || serverPort, () => logInfo(`Started server at port ${process.env.PORT || serverPort}`));
|
|
34
47
|
|
|
35
48
|
// catch 404 and forward to error handler
|
|
36
49
|
app.use((req: Request, res: Response, next: NextFunction) => next(createError(404)));
|
|
@@ -38,7 +51,7 @@ export const deployServer = (serverInit: ServerInit) => {
|
|
|
38
51
|
// error handler
|
|
39
52
|
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
|
|
40
53
|
const { message, status } = err;
|
|
41
|
-
|
|
54
|
+
logError(err);
|
|
42
55
|
res.locals.message = message;
|
|
43
56
|
res.locals.error = req.app.get('env') === 'development' ? err : {};
|
|
44
57
|
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { doCallToUrl, RequestMethod } from './bigidProxyService';
|
|
2
|
+
import { getAccessTokenFromRefreshToken } from '../utils/tokenUtil';
|
|
3
|
+
|
|
4
|
+
const REFRESH_TOKEN = process.env.BIGID_REFRESH_TOKEN;
|
|
5
|
+
|
|
6
|
+
const getBigidAccessToken = async (): Promise<string> => {
|
|
7
|
+
if (!REFRESH_TOKEN) {
|
|
8
|
+
throw new Error('BIGID_REFRESH_TOKEN must be supplied as an ENV var in order to call bigid actions hub');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return await getAccessTokenFromRefreshToken(REFRESH_TOKEN);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type Param = {
|
|
15
|
+
name: string;
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type Command = {
|
|
20
|
+
actionName: string;
|
|
21
|
+
command: string;
|
|
22
|
+
params: Param[];
|
|
23
|
+
id: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* use this method to get the currently registered action-center commands.
|
|
28
|
+
* the method is building an execution context for the api call, so you must provide REFRESH_TOKEN and BIGID_BASE_URL as ENV variables
|
|
29
|
+
*
|
|
30
|
+
* @return {Promise<Command[]>} array of the action-center register commands
|
|
31
|
+
*/
|
|
32
|
+
export const getCommandsRegistrations = async (): Promise<Command[]> => {
|
|
33
|
+
try {
|
|
34
|
+
const bigidToken = await getBigidAccessToken();
|
|
35
|
+
const {
|
|
36
|
+
data: { commands },
|
|
37
|
+
} = await doCallToUrl(
|
|
38
|
+
bigidToken,
|
|
39
|
+
RequestMethod.GET,
|
|
40
|
+
`${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands`,
|
|
41
|
+
);
|
|
42
|
+
return commands;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
throw new Error(`Could not get commands registrations from bigid: ${e}`);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* use this method to execute an action-center commands.
|
|
50
|
+
* this method is used without endpoint for getting status messages, but rather return an execution id.
|
|
51
|
+
* the execution id can be used to poll the current execution status of the executed command.
|
|
52
|
+
*
|
|
53
|
+
* @param {string} actionName - the action name to be executed.
|
|
54
|
+
* @param {string} command - the command to be executed.
|
|
55
|
+
* @param {string} requestorAppName - the app name of the execution requestor.
|
|
56
|
+
* @param {string} webhookEndpoint - the endpoint of the requestor app to receive execution status messages.
|
|
57
|
+
* @param {Record<string, any>} params - the relevant params of the action to be executed.
|
|
58
|
+
* @return {Promise<string>} execution id of the executed action.
|
|
59
|
+
*/
|
|
60
|
+
export const executeCommand = async (
|
|
61
|
+
actionName: string,
|
|
62
|
+
command: string,
|
|
63
|
+
requestorAppName?: string,
|
|
64
|
+
webhookEndpoint?: string,
|
|
65
|
+
params?: Record<string, any>[],
|
|
66
|
+
): Promise<string> => {
|
|
67
|
+
try {
|
|
68
|
+
const bigidToken = await getBigidAccessToken();
|
|
69
|
+
const {
|
|
70
|
+
data: { executionId },
|
|
71
|
+
} = await doCallToUrl(
|
|
72
|
+
bigidToken,
|
|
73
|
+
RequestMethod.POST,
|
|
74
|
+
`${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands/execute`,
|
|
75
|
+
{
|
|
76
|
+
actionName,
|
|
77
|
+
command,
|
|
78
|
+
feedbackRequestorDetails:
|
|
79
|
+
requestorAppName && webhookEndpoint
|
|
80
|
+
? {
|
|
81
|
+
requestorAppName,
|
|
82
|
+
requestorFeedbackEndpoint: webhookEndpoint,
|
|
83
|
+
}
|
|
84
|
+
: null,
|
|
85
|
+
...(params && { params }),
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
return executionId;
|
|
89
|
+
} catch (e) {
|
|
90
|
+
throw new Error(`Could not execute ${command}: ${e}`);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* use this method to poll an execution status from the action-center.
|
|
96
|
+
*
|
|
97
|
+
* @param {string} execution - the execution id to poll status for.
|
|
98
|
+
* @return object with the updated status details.
|
|
99
|
+
*/
|
|
100
|
+
export const getExecutionStatus = async (executionId: string): Promise<any> => {
|
|
101
|
+
try {
|
|
102
|
+
const bigidToken = await getBigidAccessToken();
|
|
103
|
+
const { data } = await doCallToUrl(
|
|
104
|
+
bigidToken,
|
|
105
|
+
RequestMethod.GET,
|
|
106
|
+
`${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands/execute/${executionId}`,
|
|
107
|
+
);
|
|
108
|
+
return data;
|
|
109
|
+
} catch (e) {
|
|
110
|
+
throw new Error(`Could not get status for execution id ${executionId}: ${e}`);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* use this method to register application action as an action center command.
|
|
116
|
+
*
|
|
117
|
+
* @param {string} applicationName - the application name of the command to be registered.
|
|
118
|
+
* @param {string} actionName - the action name of the command to be registered.
|
|
119
|
+
* @param {string} command - the command to be registered.
|
|
120
|
+
*/
|
|
121
|
+
export const registerActionAsCommand = async (
|
|
122
|
+
applicationName: string,
|
|
123
|
+
actionName: string,
|
|
124
|
+
command: string,
|
|
125
|
+
): Promise<void> => {
|
|
126
|
+
try {
|
|
127
|
+
const bigidToken = await getBigidAccessToken();
|
|
128
|
+
await doCallToUrl(
|
|
129
|
+
bigidToken,
|
|
130
|
+
RequestMethod.POST,
|
|
131
|
+
`${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands/register`,
|
|
132
|
+
{
|
|
133
|
+
applicationName,
|
|
134
|
+
actionName,
|
|
135
|
+
command,
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
} catch (e) {
|
|
139
|
+
throw new Error(`Could not register ${command}: ${e}`);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getAuth0Token, tokenExchange } from '../utils/tokenUtil';
|
|
2
|
+
import { getTenantRegistrations } from './bigidProxyService';
|
|
3
|
+
import { TenantRegistration } from '../dto/tenantRegistration';
|
|
4
|
+
import { logError, logInfo } from '../utils';
|
|
5
|
+
import { basename } from 'path';
|
|
6
|
+
|
|
7
|
+
export type BatchFunction = (tenantId: string, tenantDomain: string, tenantToken: string) => void;
|
|
8
|
+
const scriptName = basename(__filename).replace('.ts', '');
|
|
9
|
+
|
|
10
|
+
export const handleBatchProcess = async (callback: BatchFunction): Promise<void> => {
|
|
11
|
+
try {
|
|
12
|
+
logInfo(`Starting scheduled process: ${callback.name}`);
|
|
13
|
+
const auth0Token = await getAuth0Token();
|
|
14
|
+
const bigidToken = await tokenExchange(auth0Token);
|
|
15
|
+
const appRegistrations = await getTenantRegistrations(bigidToken);
|
|
16
|
+
appRegistrations.forEach(tenantRegistration => executeBatchForTenant(auth0Token, tenantRegistration, callback));
|
|
17
|
+
} catch (err: any) {
|
|
18
|
+
logError(`Problem occurred while fetching registrations info: ${err.message}`);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const executeBatchForTenant = async (
|
|
23
|
+
auth0Token: string,
|
|
24
|
+
tenantRegistration: TenantRegistration,
|
|
25
|
+
callback: BatchFunction,
|
|
26
|
+
): Promise<void> => {
|
|
27
|
+
const { tenantId, tenantDomain, companyName } = tenantRegistration;
|
|
28
|
+
try {
|
|
29
|
+
logInfo(`Fetching token for scheduled process`, { tenantId, functionName: executeBatchForTenant.name, scriptName });
|
|
30
|
+
const tenantToken = await tokenExchange(auth0Token, tenantId);
|
|
31
|
+
callback(tenantId, tenantDomain, tenantToken);
|
|
32
|
+
} catch (err: any) {
|
|
33
|
+
logError(`Problem occurred while starting scheduled process for tenant: ${companyName}. error: ${err.message}`, {
|
|
34
|
+
tenantId,
|
|
35
|
+
functionName: executeBatchForTenant.name,
|
|
36
|
+
scriptName,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|