@bigid/apps-infrastructure-node-js 1.213.0 → 1.218.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.
@@ -0,0 +1,20 @@
1
+ import { ExecutionContext } from "./executionContext";
2
+ export interface TokenOptions {
3
+ executionContext?: ExecutionContext;
4
+ accessToken?: string;
5
+ }
6
+ export interface AppConfigurationsParams {
7
+ key: string;
8
+ executionContext?: ExecutionContext;
9
+ accessToken?: string;
10
+ bigidUrl?: string;
11
+ }
12
+ export type CacheEntry = {
13
+ value: string | null;
14
+ expiry: number;
15
+ };
16
+ export type AppsConfigurationsManagement = {
17
+ appName: string;
18
+ shouldInitAppConfigurationsPollingFromBigID?: boolean;
19
+ manifest: Record<string, any>;
20
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,6 +7,7 @@ export type ExecutionContext = {
7
7
  bigidToken: string;
8
8
  updateResultCallback: any;
9
9
  tpaId: string;
10
+ tpaName: string;
10
11
  };
11
12
  export type GeneralParam = {
12
13
  paramName: string;
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from './abstractProviders';
2
2
  export * from './dto';
3
3
  export * from './utils';
4
- export { updateActionStatusToBigID, uploadAttachment, getValueFromAppStorage, saveInStorage, executeHttpGet, scheduleFunction, unscheduleFunction, unscheduleAllFunctions, deleteKeyFromAppStorage, sendBiEvent, getCommandsRegistrations, executeCommand, getExecutionStatus, registerActionAsCommand, fetchDataSourceCredentials, } from './services';
4
+ export { updateActionStatusToBigID, uploadAttachment, getValueFromAppStorage, saveInStorage, executeHttpGet, scheduleFunction, unscheduleFunction, unscheduleAllFunctions, deleteKeyFromAppStorage, sendBiEvent, getCommandsRegistrations, executeCommand, getExecutionStatus, registerActionAsCommand, fetchDataSourceCredentials, getAppConfiguration, } from './services';
5
5
  export { deployServer, ServerInit } from './server';
package/lib/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.deployServer = exports.fetchDataSourceCredentials = exports.registerActionAsCommand = exports.getExecutionStatus = exports.executeCommand = exports.getCommandsRegistrations = exports.sendBiEvent = exports.deleteKeyFromAppStorage = exports.unscheduleAllFunctions = exports.unscheduleFunction = exports.scheduleFunction = exports.executeHttpGet = exports.saveInStorage = exports.getValueFromAppStorage = exports.uploadAttachment = exports.updateActionStatusToBigID = void 0;
17
+ exports.deployServer = exports.getAppConfiguration = exports.fetchDataSourceCredentials = exports.registerActionAsCommand = exports.getExecutionStatus = exports.executeCommand = exports.getCommandsRegistrations = exports.sendBiEvent = exports.deleteKeyFromAppStorage = exports.unscheduleAllFunctions = exports.unscheduleFunction = exports.scheduleFunction = exports.executeHttpGet = exports.saveInStorage = exports.getValueFromAppStorage = exports.uploadAttachment = exports.updateActionStatusToBigID = void 0;
18
18
  __exportStar(require("./abstractProviders"), exports);
19
19
  __exportStar(require("./dto"), exports);
20
20
  __exportStar(require("./utils"), exports);
@@ -34,5 +34,6 @@ Object.defineProperty(exports, "executeCommand", { enumerable: true, get: functi
34
34
  Object.defineProperty(exports, "getExecutionStatus", { enumerable: true, get: function () { return services_1.getExecutionStatus; } });
35
35
  Object.defineProperty(exports, "registerActionAsCommand", { enumerable: true, get: function () { return services_1.registerActionAsCommand; } });
36
36
  Object.defineProperty(exports, "fetchDataSourceCredentials", { enumerable: true, get: function () { return services_1.fetchDataSourceCredentials; } });
37
+ Object.defineProperty(exports, "getAppConfiguration", { enumerable: true, get: function () { return services_1.getAppConfiguration; } });
37
38
  var server_1 = require("./server");
38
39
  Object.defineProperty(exports, "deployServer", { enumerable: true, get: function () { return server_1.deployServer; } });
package/lib/server.d.ts CHANGED
@@ -3,6 +3,7 @@ import { ManifestProvider } from './abstractProviders';
3
3
  import { IconsProviders } from './abstractProviders';
4
4
  import { ExecutionProvider } from './abstractProviders/executionProvider';
5
5
  import { ConfigureProvider } from './abstractProviders/configureProvider';
6
+ import { AppsConfigurationsManagement } from './dto/appsConfigurationsManagement';
6
7
  export type ServerInit = {
7
8
  manifestController: ManifestProvider;
8
9
  iconsController: IconsProviders;
@@ -13,5 +14,6 @@ export type ServerInit = {
13
14
  expressBodyLimit?: string;
14
15
  signatureValidationEnabled?: boolean;
15
16
  baseUrl?: string;
17
+ appConfigurationsManagement?: AppsConfigurationsManagement;
16
18
  };
17
- export declare const deployServer: ({ manifestController, iconsController, executionController, serverPort, configureController, additionalEndpoints, expressBodyLimit, signatureValidationEnabled, baseUrl, }: ServerInit) => void;
19
+ export declare const deployServer: ({ manifestController, iconsController, executionController, serverPort, configureController, additionalEndpoints, expressBodyLimit, signatureValidationEnabled, baseUrl, appConfigurationsManagement, }: ServerInit) => void;
package/lib/server.js CHANGED
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
36
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
37
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -44,13 +54,26 @@ const logsProvider_1 = require("./abstractProviders/logsProvider");
44
54
  const http_errors_1 = __importDefault(require("http-errors"));
45
55
  const configureProvider_1 = require("./abstractProviders/configureProvider");
46
56
  const signatureValidationInterceptor_1 = require("./interceptor/signatureValidationInterceptor");
57
+ const appsConfigurationsManagementService_1 = require("./services/appsConfigurationsManagementService");
47
58
  const app = (0, express_1.default)();
48
- const deployServer = ({ manifestController, iconsController, executionController, serverPort, configureController, additionalEndpoints, expressBodyLimit, signatureValidationEnabled = false, baseUrl, }) => {
59
+ const deployServer = ({ manifestController, iconsController, executionController, serverPort, configureController, additionalEndpoints, expressBodyLimit, signatureValidationEnabled = false, baseUrl, appConfigurationsManagement, }) => {
60
+ if (appConfigurationsManagement) {
61
+ (0, appsConfigurationsManagementService_1.initAppConfigurationsManagement)(appConfigurationsManagement)
62
+ .then(() => (0, utils_1.logInfo)('App configurations management initialized successfully'))
63
+ .catch(err => (0, utils_1.logError)('Failed to initialize App configurations management, err:', err));
64
+ }
49
65
  app.use(express_1.default.urlencoded({ extended: false }));
50
66
  app.use(bodyParser.json({ limit: expressBodyLimit || '5mb' }));
51
67
  app.get('/assets/icon', (req, res) => res.sendFile(iconsController.getIconPath()));
52
68
  app.get('/assets/sideBarIcon', (req, res) => res.sendFile(iconsController.getSideBarIconPath()));
53
- app.get('/manifest', manifestController.getManifest);
69
+ app.get('/manifest', (req, res) => {
70
+ const originalSend = res.send.bind(res);
71
+ res.send = (manifestString) => {
72
+ const enrichedBody = (0, appsConfigurationsManagementService_1.enrichManifestWithEnvConfigurations)(manifestString);
73
+ return originalSend(enrichedBody);
74
+ };
75
+ manifestController.getManifest(req, res);
76
+ });
54
77
  app.get('/logs', (req, res) => __awaiter(void 0, void 0, void 0, function* () { return yield (0, logsProvider_1.fetchLogs)(req, res); }));
55
78
  executionController &&
56
79
  app.post('/execute', signatureValidationEnabled ? (0, signatureValidationInterceptor_1.signatureValidationInterceptor)(baseUrl) : (req, res, next) => next(), (req, res) => __awaiter(void 0, void 0, void 0, function* () { return yield (0, executionProvider_1.handleExecution)(req, res, executionController); }));
@@ -12,13 +12,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.registerActionAsCommand = exports.getExecutionStatus = exports.executeCommand = exports.getCommandsRegistrations = void 0;
13
13
  const bigidProxyService_1 = require("./bigidProxyService");
14
14
  const tokenUtil_1 = require("../utils/tokenUtil");
15
- const REFRESH_TOKEN = process.env.BIGID_REFRESH_TOKEN;
16
- const getBigidAccessToken = () => __awaiter(void 0, void 0, void 0, function* () {
17
- if (!REFRESH_TOKEN) {
18
- throw new Error('BIGID_REFRESH_TOKEN must be supplied as an ENV var in order to call bigid actions hub');
19
- }
20
- return yield (0, tokenUtil_1.getAccessTokenFromRefreshToken)(REFRESH_TOKEN);
21
- });
22
15
  /**
23
16
  * use this method to get the currently registered action-center commands.
24
17
  * the method is building an execution context for the api call, so you must provide REFRESH_TOKEN and BIGID_BASE_URL as ENV variables
@@ -27,7 +20,7 @@ const getBigidAccessToken = () => __awaiter(void 0, void 0, void 0, function* ()
27
20
  */
28
21
  const getCommandsRegistrations = (accessToken) => __awaiter(void 0, void 0, void 0, function* () {
29
22
  try {
30
- const bigidToken = accessToken || (yield getBigidAccessToken());
23
+ const bigidToken = accessToken || (yield (0, tokenUtil_1.getBigidAccessToken)());
31
24
  const { data: { commands }, } = yield (0, bigidProxyService_1.doCallToUrl)(bigidToken, bigidProxyService_1.RequestMethod.GET, `${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands`);
32
25
  return commands;
33
26
  }
@@ -51,7 +44,7 @@ exports.getCommandsRegistrations = getCommandsRegistrations;
51
44
  */
52
45
  const executeCommand = (actionName, command, requestorAppName, webhookEndpoint, params, accessToken) => __awaiter(void 0, void 0, void 0, function* () {
53
46
  try {
54
- const bigidToken = accessToken || (yield getBigidAccessToken());
47
+ const bigidToken = accessToken || (yield (0, tokenUtil_1.getBigidAccessToken)());
55
48
  const { data: { executionId }, } = yield (0, bigidProxyService_1.doCallToUrl)(bigidToken, bigidProxyService_1.RequestMethod.POST, `${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands/execute`, Object.assign({ actionName,
56
49
  command, feedbackRequestorDetails: requestorAppName && webhookEndpoint
57
50
  ? {
@@ -75,7 +68,7 @@ exports.executeCommand = executeCommand;
75
68
  */
76
69
  const getExecutionStatus = (executionId, accessToken) => __awaiter(void 0, void 0, void 0, function* () {
77
70
  try {
78
- const bigidToken = accessToken || (yield getBigidAccessToken());
71
+ const bigidToken = accessToken || (yield (0, tokenUtil_1.getBigidAccessToken)());
79
72
  const { data } = yield (0, bigidProxyService_1.doCallToUrl)(bigidToken, bigidProxyService_1.RequestMethod.GET, `${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands/execute/${executionId}`);
80
73
  return data;
81
74
  }
@@ -94,7 +87,7 @@ exports.getExecutionStatus = getExecutionStatus;
94
87
  */
95
88
  const registerActionAsCommand = (applicationName, actionName, command, accessToken) => __awaiter(void 0, void 0, void 0, function* () {
96
89
  try {
97
- const bigidToken = accessToken || (yield getBigidAccessToken());
90
+ const bigidToken = accessToken || (yield (0, tokenUtil_1.getBigidAccessToken)());
98
91
  yield (0, bigidProxyService_1.doCallToUrl)(bigidToken, bigidProxyService_1.RequestMethod.POST, `${process.env.BIGID_BASE_URL}/api/v1/action-center/general-commands/register`, {
99
92
  applicationName,
100
93
  actionName,
@@ -0,0 +1,4 @@
1
+ import { AppsConfigurationsManagement, AppConfigurationsParams } from '../dto/appsConfigurationsManagement';
2
+ export declare const initAppConfigurationsManagement: (appsConfigurationsManagement: AppsConfigurationsManagement) => Promise<void>;
3
+ export declare const getAppConfiguration: (appConfigurationsParams: AppConfigurationsParams) => Promise<string | null>;
4
+ export declare const enrichManifestWithEnvConfigurations: (originalManifestString: string) => string;
@@ -0,0 +1,154 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.enrichManifestWithEnvConfigurations = exports.getAppConfiguration = exports.initAppConfigurationsManagement = void 0;
13
+ const bigidProxyService_1 = require("./bigidProxyService");
14
+ const tokenUtil_1 = require("../utils/tokenUtil");
15
+ const tokenUtil_2 = require("../utils/tokenUtil");
16
+ const schedulerService_1 = require("./schedulerService");
17
+ const batchProcessManager_1 = require("./batchProcessManager");
18
+ const utils_1 = require("../utils");
19
+ const APP_CONFIGURATIONS_CACHE_TTL = 10 * 1000;
20
+ const appConfigurationsCache = new Map();
21
+ let appConfigurationsManagementParams;
22
+ const initAppConfigurationsManagement = (appsConfigurationsManagement) => __awaiter(void 0, void 0, void 0, function* () {
23
+ setAppConfigurationsManagementParams(appsConfigurationsManagement);
24
+ const { shouldInitAppConfigurationsPollingFromBigID: shouldInitAppConfigurationsPollingFromBigID, appName } = appsConfigurationsManagement;
25
+ if (process.env.BIGID_BASE_URL && appName) {
26
+ yield initApplicationConfigurationInConfigServer();
27
+ if (shouldInitAppConfigurationsPollingFromBigID) {
28
+ (0, schedulerService_1.scheduleFunction)('AppConfigurationsInCachePerTenant', '* * * * *', updateAppConfigurationsInCache);
29
+ }
30
+ }
31
+ });
32
+ exports.initAppConfigurationsManagement = initAppConfigurationsManagement;
33
+ const setAppConfigurationsManagementParams = (AppConfigurationsManagement) => {
34
+ appConfigurationsManagementParams = AppConfigurationsManagement;
35
+ };
36
+ const initApplicationConfigurationInConfigServer = () => __awaiter(void 0, void 0, void 0, function* () {
37
+ try {
38
+ if ((0, schedulerService_1.isMultiTenantMode)()) {
39
+ yield (0, batchProcessManager_1.handleBatchProcess)(setApplicationConfigurationInConfigServer);
40
+ }
41
+ else {
42
+ const token = yield (0, tokenUtil_1.getBigidAccessToken)();
43
+ const decodedToken = (0, tokenUtil_2.decodeToken)(token);
44
+ const tenantId = (decodedToken === null || decodedToken === void 0 ? void 0 : decodedToken.tenantId) || 'SINGLE_TENANT';
45
+ yield setApplicationConfigurationInConfigServer(tenantId, '', token);
46
+ }
47
+ }
48
+ catch (e) {
49
+ throw new Error(`Could not get/update app configurations from BigID: ${e}`);
50
+ }
51
+ });
52
+ const setApplicationConfigurationInConfigServer = (tenantId, url, token) => __awaiter(void 0, void 0, void 0, function* () {
53
+ const baseUrl = url || process.env.BIGID_BASE_URL;
54
+ if (!baseUrl || !(appConfigurationsManagementParams === null || appConfigurationsManagementParams === void 0 ? void 0 : appConfigurationsManagementParams.manifest)) {
55
+ throw new Error(`url and manifest must be provided`);
56
+ }
57
+ try {
58
+ const initAppConfigurationsEndPoint = createUrl(baseUrl, generateTpaConfigurationEndpoint(appConfigurationsManagementParams.appName));
59
+ const manifestString = JSON.stringify(appConfigurationsManagementParams.manifest);
60
+ const enrichedManifestString = (0, exports.enrichManifestWithEnvConfigurations)(manifestString);
61
+ const manifest = JSON.parse(enrichedManifestString);
62
+ yield (0, bigidProxyService_1.doCallToUrl)(token, bigidProxyService_1.RequestMethod.POST, initAppConfigurationsEndPoint, { manifest });
63
+ }
64
+ catch (e) {
65
+ throw new Error(`Could not get/update app configurations from BigID: ${e}`);
66
+ }
67
+ });
68
+ const updateAppConfigurationsInCache = (tenantId, url, token) => __awaiter(void 0, void 0, void 0, function* () {
69
+ const decodedToken = (0, tokenUtil_2.decodeToken)(token);
70
+ const primaryKey = (decodedToken === null || decodedToken === void 0 ? void 0 : decodedToken.tenantId) || tenantId || token;
71
+ try {
72
+ const allAppConfigurations = yield fetchAppConfigurations(token, url);
73
+ updateAppConfigurationInCache(primaryKey, allAppConfigurations);
74
+ }
75
+ catch (e) {
76
+ throw new Error(`Could not get/update app configurations from BigID: ${e}`);
77
+ }
78
+ });
79
+ const getAppConfiguration = (appConfigurationsParams) => __awaiter(void 0, void 0, void 0, function* () {
80
+ var _a;
81
+ const { key, executionContext, accessToken, bigidUrl } = appConfigurationsParams;
82
+ if (!(appConfigurationsManagementParams === null || appConfigurationsManagementParams === void 0 ? void 0 : appConfigurationsManagementParams.appName)) {
83
+ throw new Error('The appName parameter must be provided to the deployServer function to enable calling the getAppConfiguration function.');
84
+ }
85
+ const token = (executionContext === null || executionContext === void 0 ? void 0 : executionContext.bigidToken) || accessToken || (yield (0, tokenUtil_1.getBigidAccessToken)());
86
+ const decodedToken = (0, tokenUtil_2.decodeToken)(token);
87
+ const url = (_a = ((executionContext === null || executionContext === void 0 ? void 0 : executionContext.bigidBaseUrl) || bigidUrl || process.env.BIGID_BASE_URL)) === null || _a === void 0 ? void 0 : _a.replace('/api/v1', '');
88
+ if (!url || !token) {
89
+ throw new Error(`url and token must be provided`);
90
+ }
91
+ const primaryKey = (decodedToken === null || decodedToken === void 0 ? void 0 : decodedToken.tenantId) || token;
92
+ const secondaryKey = key;
93
+ const cachedValue = getAppConfigurationFromCache(primaryKey, secondaryKey);
94
+ if (cachedValue !== null) {
95
+ return cachedValue;
96
+ }
97
+ try {
98
+ const appConfigurationsValues = yield fetchAppConfigurations(token, url, executionContext === null || executionContext === void 0 ? void 0 : executionContext.tpaName);
99
+ const appConfigurationValue = appConfigurationsValues[key];
100
+ updateAppConfigurationInCache(primaryKey, appConfigurationsValues);
101
+ return appConfigurationValue;
102
+ }
103
+ catch (e) {
104
+ throw new Error(`Could not get app configuration: ${key} from BigID: ${e}`);
105
+ }
106
+ });
107
+ exports.getAppConfiguration = getAppConfiguration;
108
+ const fetchAppConfigurations = (token, url, appNameFromExecutionContext) => __awaiter(void 0, void 0, void 0, function* () {
109
+ const appConfigurationsEndPoint = createUrl(url, generateTpaConfigurationEndpoint(appNameFromExecutionContext !== null && appNameFromExecutionContext !== void 0 ? appNameFromExecutionContext : appConfigurationsManagementParams.appName));
110
+ const { data = {} } = yield (0, bigidProxyService_1.doCallToUrl)(token, bigidProxyService_1.RequestMethod.GET, appConfigurationsEndPoint);
111
+ return data;
112
+ });
113
+ const updateAppConfigurationInCache = (primaryKey, appConfigurationsRecord) => {
114
+ const expiry = Date.now() + APP_CONFIGURATIONS_CACHE_TTL;
115
+ let existingSecondaryCache = appConfigurationsCache.get(primaryKey);
116
+ if (!existingSecondaryCache) {
117
+ existingSecondaryCache = new Map();
118
+ appConfigurationsCache.set(primaryKey, existingSecondaryCache);
119
+ }
120
+ for (const [secondaryKey, value] of Object.entries(appConfigurationsRecord)) {
121
+ existingSecondaryCache.set(secondaryKey, { value, expiry });
122
+ }
123
+ };
124
+ const getAppConfigurationFromCache = (primaryKey, secondaryKey) => {
125
+ const secondaryCache = appConfigurationsCache.get(primaryKey);
126
+ if (!secondaryCache) {
127
+ return null;
128
+ }
129
+ const entry = secondaryCache.get(secondaryKey);
130
+ if (entry && entry.expiry > Date.now()) {
131
+ return entry.value;
132
+ }
133
+ secondaryCache.delete(secondaryKey);
134
+ if (secondaryCache.size === 0) {
135
+ appConfigurationsCache.delete(primaryKey);
136
+ }
137
+ return null;
138
+ };
139
+ const createUrl = (baseUrl, path) => {
140
+ const normalizedBaseUrl = baseUrl.startsWith('http') ? baseUrl : `https://${baseUrl}`;
141
+ return new URL(path, normalizedBaseUrl).href;
142
+ };
143
+ const enrichManifestWithEnvConfigurations = (originalManifestString) => {
144
+ const manifestJson = JSON.parse(originalManifestString);
145
+ if (manifestJson['app_configurations']) {
146
+ manifestJson['app_configurations'].env = process.env;
147
+ }
148
+ (0, utils_1.logInfo)(`App manifest was enriched with env vars for app_configurations section`);
149
+ return JSON.stringify(manifestJson);
150
+ };
151
+ exports.enrichManifestWithEnvConfigurations = enrichManifestWithEnvConfigurations;
152
+ const generateTpaConfigurationEndpoint = (appName) => {
153
+ return `api/v1/tpa/app-configurations/${appName}`;
154
+ };
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
36
  exports.decryptWithKey = exports.decrypt = void 0;
27
37
  const crypto = __importStar(require("crypto"));
@@ -2,3 +2,4 @@ export * from './bigidProxyService';
2
2
  export * from './dataSourceService';
3
3
  export * from './actionsHubService';
4
4
  export { scheduleFunction, unscheduleAllFunctions, unscheduleFunction } from './schedulerService';
5
+ export { getAppConfiguration } from './appsConfigurationsManagementService';
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.unscheduleFunction = exports.unscheduleAllFunctions = exports.scheduleFunction = void 0;
17
+ exports.getAppConfiguration = exports.unscheduleFunction = exports.unscheduleAllFunctions = exports.scheduleFunction = void 0;
18
18
  __exportStar(require("./bigidProxyService"), exports);
19
19
  __exportStar(require("./dataSourceService"), exports);
20
20
  __exportStar(require("./actionsHubService"), exports);
@@ -22,3 +22,5 @@ var schedulerService_1 = require("./schedulerService");
22
22
  Object.defineProperty(exports, "scheduleFunction", { enumerable: true, get: function () { return schedulerService_1.scheduleFunction; } });
23
23
  Object.defineProperty(exports, "unscheduleAllFunctions", { enumerable: true, get: function () { return schedulerService_1.unscheduleAllFunctions; } });
24
24
  Object.defineProperty(exports, "unscheduleFunction", { enumerable: true, get: function () { return schedulerService_1.unscheduleFunction; } });
25
+ var appsConfigurationsManagementService_1 = require("./appsConfigurationsManagementService");
26
+ Object.defineProperty(exports, "getAppConfiguration", { enumerable: true, get: function () { return appsConfigurationsManagementService_1.getAppConfiguration; } });
@@ -9,3 +9,4 @@ import { BatchFunction } from './batchProcessManager';
9
9
  export declare const scheduleFunction: (batchUN: string, cronExpression: string, callback: BatchFunction) => void;
10
10
  export declare const unscheduleFunction: (batchUN: string) => void;
11
11
  export declare const unscheduleAllFunctions: () => void;
12
+ export declare const isMultiTenantMode: () => boolean;
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.unscheduleAllFunctions = exports.unscheduleFunction = exports.scheduleFunction = void 0;
12
+ exports.isMultiTenantMode = exports.unscheduleAllFunctions = exports.unscheduleFunction = exports.scheduleFunction = void 0;
13
13
  const batchProcessManager_1 = require("./batchProcessManager");
14
14
  const node_schedule_1 = require("node-schedule");
15
15
  const tokenUtil_1 = require("../utils/tokenUtil");
@@ -27,7 +27,7 @@ const scheduleSingleTenantProcess = (batchUN, cronExpression, callback) => __awa
27
27
  * @param callback - the function that will be called.
28
28
  */
29
29
  const scheduleFunction = (batchUN, cronExpression, callback) => {
30
- process.env.MULTI_TENANT_MODE
30
+ (0, exports.isMultiTenantMode)()
31
31
  ? (0, node_schedule_1.scheduleJob)(batchUN, cronExpression, () => (0, batchProcessManager_1.handleBatchProcess)(callback))
32
32
  : scheduleSingleTenantProcess(batchUN, cronExpression, callback);
33
33
  };
@@ -39,3 +39,7 @@ const unscheduleFunction = (batchUN) => {
39
39
  exports.unscheduleFunction = unscheduleFunction;
40
40
  const unscheduleAllFunctions = () => Object.keys(node_schedule_1.scheduledJobs).forEach(jobName => node_schedule_1.scheduledJobs[jobName].cancel());
41
41
  exports.unscheduleAllFunctions = unscheduleAllFunctions;
42
+ const isMultiTenantMode = () => {
43
+ return [true, 'true'].includes(process.env.MULTI_TENANT_MODE || '');
44
+ };
45
+ exports.isMultiTenantMode = isMultiTenantMode;
@@ -1,4 +1,7 @@
1
+ import { JwtPayload } from 'jsonwebtoken';
2
+ export declare const getBigidAccessToken: () => Promise<string>;
1
3
  export declare const getAccessTokenFromRefreshToken: (refreshToken: string) => Promise<string>;
2
4
  export declare const getTokenByUsernameAndPassword: (username?: string, password?: string) => Promise<string>;
3
5
  export declare const getAuth0Token: () => Promise<string>;
4
6
  export declare const tokenExchange: (auth0Token: string, tenantId?: string) => Promise<string>;
7
+ export declare const decodeToken: (token: string) => JwtPayload;
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
36
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
37
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12,11 +45,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
45
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
46
  };
14
47
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.tokenExchange = exports.getAuth0Token = exports.getTokenByUsernameAndPassword = exports.getAccessTokenFromRefreshToken = void 0;
48
+ exports.decodeToken = exports.tokenExchange = exports.getAuth0Token = exports.getTokenByUsernameAndPassword = exports.getAccessTokenFromRefreshToken = exports.getBigidAccessToken = void 0;
16
49
  const axios_1 = __importDefault(require("axios"));
17
50
  const https_1 = require("https");
18
51
  const services_1 = require("../services");
19
52
  const appLogger_1 = require("./appLogger");
53
+ const jwt = __importStar(require("jsonwebtoken"));
20
54
  const auth0Payload = {
21
55
  client_id: process.env.CLIENT_ID,
22
56
  client_secret: process.env.CLIENT_SECRET,
@@ -25,6 +59,14 @@ const auth0Payload = {
25
59
  };
26
60
  let auth0Token;
27
61
  let accessToken;
62
+ const REFRESH_TOKEN = process.env.BIGID_REFRESH_TOKEN;
63
+ const getBigidAccessToken = () => __awaiter(void 0, void 0, void 0, function* () {
64
+ if (!REFRESH_TOKEN) {
65
+ throw new Error('BIGID_REFRESH_TOKEN must be supplied as an ENV var in order to call bigid actions hub');
66
+ }
67
+ return yield (0, exports.getAccessTokenFromRefreshToken)(REFRESH_TOKEN);
68
+ });
69
+ exports.getBigidAccessToken = getBigidAccessToken;
28
70
  const getAccessTokenFromRefreshToken = (refreshToken) => __awaiter(void 0, void 0, void 0, function* () {
29
71
  if (canUseLocalToken(accessToken))
30
72
  return accessToken;
@@ -78,3 +120,8 @@ const canUseLocalToken = (token) => {
78
120
  const { exp } = getTokenPayloadAsJson(token);
79
121
  return Date.now() < exp * 1000;
80
122
  };
123
+ const decodeToken = (token) => {
124
+ const decodedToken = jwt.decode(token);
125
+ return decodedToken;
126
+ };
127
+ exports.decodeToken = decodeToken;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bigid/apps-infrastructure-node-js",
3
- "version": "1.213.0",
3
+ "version": "1.218.0",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -31,11 +31,13 @@
31
31
  "typescript": "^4.5.2"
32
32
  },
33
33
  "dependencies": {
34
+ "@types/jsonwebtoken": "^9.0.7",
34
35
  "axios": "1.7.4",
35
36
  "express": "4.21.0",
36
37
  "follow-redirects": "1.15.6",
37
38
  "form-data": "^4.0.0",
38
39
  "http-errors": "^1.8.1",
40
+ "jsonwebtoken": "^9.0.2",
39
41
  "log4js": "^6.4.0",
40
42
  "minimatch": "3.0.5",
41
43
  "mocha": "10.2.0",
@@ -0,0 +1,24 @@
1
+ import { ExecutionContext } from "./executionContext";
2
+
3
+ export interface TokenOptions {
4
+ executionContext?: ExecutionContext;
5
+ accessToken?: string;
6
+ }
7
+
8
+ export interface AppConfigurationsParams {
9
+ key: string;
10
+ executionContext?: ExecutionContext;
11
+ accessToken?: string;
12
+ bigidUrl?: string;
13
+ }
14
+
15
+ export type CacheEntry = {
16
+ value: string | null;
17
+ expiry: number;
18
+ };
19
+
20
+ export type AppsConfigurationsManagement = {
21
+ appName: string;
22
+ shouldInitAppConfigurationsPollingFromBigID?: boolean;
23
+ manifest: Record<string, any>;
24
+ };
@@ -7,6 +7,7 @@ export type ExecutionContext = {
7
7
  bigidToken: string;
8
8
  updateResultCallback: any;
9
9
  tpaId: string;
10
+ tpaName: string;
10
11
  };
11
12
 
12
13
  export type GeneralParam = {
package/src/index.ts CHANGED
@@ -17,5 +17,6 @@ export {
17
17
  getExecutionStatus,
18
18
  registerActionAsCommand,
19
19
  fetchDataSourceCredentials,
20
+ getAppConfiguration,
20
21
  } from './services';
21
22
  export { deployServer, ServerInit } from './server';
package/src/server.ts CHANGED
@@ -8,6 +8,11 @@ import { fetchLogs } from './abstractProviders/logsProvider';
8
8
  import createError from 'http-errors';
9
9
  import { ConfigureProvider, handleTenantConfigure } from './abstractProviders/configureProvider';
10
10
  import { signatureValidationInterceptor } from './interceptor/signatureValidationInterceptor';
11
+ import { AppsConfigurationsManagement } from './dto/appsConfigurationsManagement';
12
+ import {
13
+ enrichManifestWithEnvConfigurations,
14
+ initAppConfigurationsManagement,
15
+ } from './services/appsConfigurationsManagementService';
11
16
 
12
17
  export type ServerInit = {
13
18
  manifestController: ManifestProvider;
@@ -19,6 +24,7 @@ export type ServerInit = {
19
24
  expressBodyLimit?: string;
20
25
  signatureValidationEnabled?: boolean;
21
26
  baseUrl?: string;
27
+ appConfigurationsManagement?: AppsConfigurationsManagement;
22
28
  };
23
29
 
24
30
  const app = express();
@@ -33,13 +39,28 @@ export const deployServer = ({
33
39
  expressBodyLimit,
34
40
  signatureValidationEnabled = false,
35
41
  baseUrl,
42
+ appConfigurationsManagement,
36
43
  }: ServerInit): void => {
44
+ if (appConfigurationsManagement) {
45
+ initAppConfigurationsManagement(appConfigurationsManagement)
46
+ .then(() => logInfo('App configurations management initialized successfully'))
47
+ .catch(err => logError('Failed to initialize App configurations management, err:', err));
48
+ }
37
49
  app.use(express.urlencoded({ extended: false }));
38
50
  app.use(bodyParser.json({ limit: expressBodyLimit || '5mb' }));
39
51
 
40
52
  app.get('/assets/icon', (req, res) => res.sendFile(iconsController.getIconPath()));
41
53
  app.get('/assets/sideBarIcon', (req, res) => res.sendFile(iconsController.getSideBarIconPath()));
42
- app.get('/manifest', manifestController.getManifest);
54
+
55
+ app.get('/manifest', (req, res) => {
56
+ const originalSend = res.send.bind(res);
57
+ res.send = (manifestString: string) => {
58
+ const enrichedBody = enrichManifestWithEnvConfigurations(manifestString);
59
+ return originalSend(enrichedBody);
60
+ };
61
+ manifestController.getManifest(req, res);
62
+ });
63
+
43
64
  app.get('/logs', async (req: Request, res: Response) => await fetchLogs(req, res));
44
65
 
45
66
  executionController &&
@@ -1,15 +1,5 @@
1
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
- };
2
+ import { getBigidAccessToken } from '../utils/tokenUtil';
13
3
 
14
4
  export type Param = {
15
5
  name: string;
@@ -0,0 +1,168 @@
1
+ import { doCallToUrl, RequestMethod } from './bigidProxyService';
2
+ import { getBigidAccessToken } from '../utils/tokenUtil';
3
+ import { CacheEntry, AppsConfigurationsManagement, AppConfigurationsParams } from '../dto/appsConfigurationsManagement';
4
+ import { decodeToken } from '../utils/tokenUtil';
5
+ import { isMultiTenantMode, scheduleFunction } from './schedulerService';
6
+ import { handleBatchProcess } from './batchProcessManager';
7
+ import { logInfo } from '../utils';
8
+
9
+ const APP_CONFIGURATIONS_CACHE_TTL = 10 * 1000;
10
+
11
+ const appConfigurationsCache: Map<string, Map<string, CacheEntry>> = new Map();
12
+ let appConfigurationsManagementParams: AppsConfigurationsManagement;
13
+
14
+ export const initAppConfigurationsManagement = async (
15
+ appsConfigurationsManagement: AppsConfigurationsManagement,
16
+ ): Promise<void> => {
17
+ setAppConfigurationsManagementParams(appsConfigurationsManagement);
18
+ const { shouldInitAppConfigurationsPollingFromBigID: shouldInitAppConfigurationsPollingFromBigID, appName } =
19
+ appsConfigurationsManagement;
20
+ if (process.env.BIGID_BASE_URL && appName) {
21
+ await initApplicationConfigurationInConfigServer();
22
+ if (shouldInitAppConfigurationsPollingFromBigID) {
23
+ scheduleFunction('AppConfigurationsInCachePerTenant', '* * * * *', updateAppConfigurationsInCache);
24
+ }
25
+ }
26
+ };
27
+
28
+ const setAppConfigurationsManagementParams = (AppConfigurationsManagement: AppsConfigurationsManagement): void => {
29
+ appConfigurationsManagementParams = AppConfigurationsManagement;
30
+ };
31
+
32
+ const initApplicationConfigurationInConfigServer = async (): Promise<void> => {
33
+ try {
34
+ if (isMultiTenantMode()) {
35
+ await handleBatchProcess(setApplicationConfigurationInConfigServer);
36
+ } else {
37
+ const token = await getBigidAccessToken();
38
+ const decodedToken = decodeToken(token);
39
+ const tenantId = decodedToken?.tenantId || 'SINGLE_TENANT';
40
+ await setApplicationConfigurationInConfigServer(tenantId, '', token);
41
+ }
42
+ } catch (e) {
43
+ throw new Error(`Could not get/update app configurations from BigID: ${e}`);
44
+ }
45
+ };
46
+
47
+ const setApplicationConfigurationInConfigServer = async (
48
+ tenantId: string,
49
+ url: string,
50
+ token: string,
51
+ ): Promise<void> => {
52
+ const baseUrl = url || process.env.BIGID_BASE_URL;
53
+ if (!baseUrl || !appConfigurationsManagementParams?.manifest) {
54
+ throw new Error(`url and manifest must be provided`);
55
+ }
56
+ try {
57
+ const initAppConfigurationsEndPoint = createUrl(
58
+ baseUrl,
59
+ generateTpaConfigurationEndpoint(appConfigurationsManagementParams.appName),
60
+ );
61
+ const manifestString = JSON.stringify(appConfigurationsManagementParams.manifest);
62
+ const enrichedManifestString = enrichManifestWithEnvConfigurations(manifestString);
63
+ const manifest = JSON.parse(enrichedManifestString);
64
+ await doCallToUrl(token, RequestMethod.POST, initAppConfigurationsEndPoint, { manifest });
65
+ } catch (e) {
66
+ throw new Error(`Could not get/update app configurations from BigID: ${e}`);
67
+ }
68
+ };
69
+
70
+ const updateAppConfigurationsInCache = async (tenantId: string, url: string, token: string): Promise<void> => {
71
+ const decodedToken = decodeToken(token);
72
+ const primaryKey = decodedToken?.tenantId || tenantId || token;
73
+ try {
74
+ const allAppConfigurations = await fetchAppConfigurations(token, url);
75
+ updateAppConfigurationInCache(primaryKey, allAppConfigurations);
76
+ } catch (e) {
77
+ throw new Error(`Could not get/update app configurations from BigID: ${e}`);
78
+ }
79
+ };
80
+
81
+ export const getAppConfiguration = async (appConfigurationsParams: AppConfigurationsParams): Promise<string | null> => {
82
+ const { key, executionContext, accessToken, bigidUrl } = appConfigurationsParams;
83
+ if (!appConfigurationsManagementParams?.appName) {
84
+ throw new Error(
85
+ 'The appName parameter must be provided to the deployServer function to enable calling the getAppConfiguration function.',
86
+ );
87
+ }
88
+ const token = executionContext?.bigidToken || accessToken || (await getBigidAccessToken());
89
+ const decodedToken = decodeToken(token);
90
+ const url = (executionContext?.bigidBaseUrl || bigidUrl || process.env.BIGID_BASE_URL)?.replace('/api/v1', '');
91
+ if (!url || !token) {
92
+ throw new Error(`url and token must be provided`);
93
+ }
94
+ const primaryKey = decodedToken?.tenantId || token;
95
+ const secondaryKey = key;
96
+ const cachedValue = getAppConfigurationFromCache(primaryKey, secondaryKey);
97
+ if (cachedValue !== null) {
98
+ return cachedValue;
99
+ }
100
+ try {
101
+ const appConfigurationsValues = await fetchAppConfigurations(token, url, executionContext?.tpaName);
102
+ const appConfigurationValue = appConfigurationsValues[key];
103
+ updateAppConfigurationInCache(primaryKey, appConfigurationsValues);
104
+ return appConfigurationValue;
105
+ } catch (e) {
106
+ throw new Error(`Could not get app configuration: ${key} from BigID: ${e}`);
107
+ }
108
+ };
109
+
110
+ const fetchAppConfigurations = async (
111
+ token: string,
112
+ url: string,
113
+ appNameFromExecutionContext?: string,
114
+ ): Promise<Record<string, any>> => {
115
+ const appConfigurationsEndPoint = createUrl(
116
+ url,
117
+ generateTpaConfigurationEndpoint(appNameFromExecutionContext ?? appConfigurationsManagementParams.appName),
118
+ );
119
+ const { data = {} } = await doCallToUrl(token!, RequestMethod.GET, appConfigurationsEndPoint);
120
+ return data;
121
+ };
122
+
123
+ const updateAppConfigurationInCache = (primaryKey: string, appConfigurationsRecord: Record<string, any>) => {
124
+ const expiry = Date.now() + APP_CONFIGURATIONS_CACHE_TTL;
125
+ let existingSecondaryCache = appConfigurationsCache.get(primaryKey);
126
+ if (!existingSecondaryCache) {
127
+ existingSecondaryCache = new Map<string, CacheEntry>();
128
+ appConfigurationsCache.set(primaryKey, existingSecondaryCache);
129
+ }
130
+ for (const [secondaryKey, value] of Object.entries(appConfigurationsRecord)) {
131
+ existingSecondaryCache.set(secondaryKey, { value, expiry });
132
+ }
133
+ };
134
+
135
+ const getAppConfigurationFromCache = (primaryKey: string, secondaryKey: string): string | null => {
136
+ const secondaryCache = appConfigurationsCache.get(primaryKey);
137
+ if (!secondaryCache) {
138
+ return null;
139
+ }
140
+ const entry = secondaryCache.get(secondaryKey);
141
+ if (entry && entry.expiry > Date.now()) {
142
+ return entry.value;
143
+ }
144
+
145
+ secondaryCache.delete(secondaryKey);
146
+ if (secondaryCache.size === 0) {
147
+ appConfigurationsCache.delete(primaryKey);
148
+ }
149
+ return null;
150
+ };
151
+
152
+ const createUrl = (baseUrl: string, path: string): string => {
153
+ const normalizedBaseUrl = baseUrl.startsWith('http') ? baseUrl : `https://${baseUrl}`;
154
+ return new URL(path, normalizedBaseUrl).href;
155
+ };
156
+
157
+ export const enrichManifestWithEnvConfigurations = (originalManifestString: string): string => {
158
+ const manifestJson = JSON.parse(originalManifestString);
159
+ if (manifestJson['app_configurations']) {
160
+ manifestJson['app_configurations'].env = process.env;
161
+ }
162
+ logInfo(`App manifest was enriched with env vars for app_configurations section`);
163
+ return JSON.stringify(manifestJson);
164
+ };
165
+
166
+ const generateTpaConfigurationEndpoint = (appName: string) => {
167
+ return `api/v1/tpa/app-configurations/${appName}`;
168
+ };
@@ -3,3 +3,4 @@ export * from './dataSourceService';
3
3
  export * from './actionsHubService';
4
4
 
5
5
  export { scheduleFunction, unscheduleAllFunctions, unscheduleFunction } from './schedulerService';
6
+ export { getAppConfiguration } from './appsConfigurationsManagementService';
@@ -25,7 +25,7 @@ const scheduleSingleTenantProcess = async (
25
25
  * @param callback - the function that will be called.
26
26
  */
27
27
  export const scheduleFunction = (batchUN: string, cronExpression: string, callback: BatchFunction): void => {
28
- process.env.MULTI_TENANT_MODE
28
+ isMultiTenantMode()
29
29
  ? scheduleJob(batchUN, cronExpression, () => handleBatchProcess(callback))
30
30
  : scheduleSingleTenantProcess(batchUN, cronExpression, callback);
31
31
  };
@@ -37,3 +37,7 @@ export const unscheduleFunction = (batchUN: string): void => {
37
37
 
38
38
  export const unscheduleAllFunctions = (): void =>
39
39
  Object.keys(scheduledJobs).forEach(jobName => scheduledJobs[jobName].cancel());
40
+
41
+ export const isMultiTenantMode = (): boolean => {
42
+ return [true, 'true'].includes(process.env.MULTI_TENANT_MODE || '');
43
+ }
@@ -2,6 +2,8 @@ import axios from 'axios';
2
2
  import { Agent } from 'https';
3
3
  import { doCallToUrl, executePost, RequestMethod } from '../services';
4
4
  import { logError, logInfo } from './appLogger';
5
+ import * as jwt from 'jsonwebtoken';
6
+ import { JwtPayload } from 'jsonwebtoken';
5
7
 
6
8
  const auth0Payload = {
7
9
  client_id: process.env.CLIENT_ID,
@@ -13,6 +15,16 @@ const auth0Payload = {
13
15
  let auth0Token: string;
14
16
  let accessToken: string;
15
17
 
18
+ const REFRESH_TOKEN = process.env.BIGID_REFRESH_TOKEN;
19
+
20
+ export const getBigidAccessToken = async (): Promise<string> => {
21
+ if (!REFRESH_TOKEN) {
22
+ throw new Error('BIGID_REFRESH_TOKEN must be supplied as an ENV var in order to call bigid actions hub');
23
+ }
24
+
25
+ return await getAccessTokenFromRefreshToken(REFRESH_TOKEN);
26
+ };
27
+
16
28
  export const getAccessTokenFromRefreshToken = async (refreshToken: string) => {
17
29
  if (canUseLocalToken(accessToken)) return accessToken;
18
30
  const bigidBaseUrl = process.env.BIGID_BASE_URL;
@@ -79,3 +91,8 @@ const canUseLocalToken = (token: string): boolean => {
79
91
  const { exp } = getTokenPayloadAsJson(token);
80
92
  return Date.now() < exp * 1000;
81
93
  };
94
+
95
+ export const decodeToken = (token: string): JwtPayload => {
96
+ const decodedToken = jwt.decode(token);
97
+ return <JwtPayload>decodedToken;
98
+ };