Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/pretty-jeans-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/apps-engine': minor
'@rocket.chat/meteor': minor
---

Fix an issue where action buttons registered by apps would be displayed even if their apps were disabled
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export const registerActionButtonsHandler = ({ api, _manager }: AppsRestApi) =>
'actionButtons',
{ authRequired: false },
{
get() {
const buttons = _manager.getUIActionButtonManager().getAllActionButtons();
async get() {
const buttons = await _manager.getUIActionButtonManager().getAllActionButtons();

return API.v1.success(buttons);
},
Expand Down
2 changes: 1 addition & 1 deletion packages/apps-engine/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"scripts": {
"start": "run-s .:build:clean .:build:watch",
"testunit": "run-p .:test:node .:test:deno",
".:test:node": "NODE_ENV=test ts-node ./tests/runner.ts",
".:test:node": "NODE_ENV=test ts-node --transpileOnly ./tests/runner.ts",
".:test:deno": "cd deno-runtime && deno task test",
".:lint:eslint": "eslint .",
".:lint:deno": "deno lint --ignore=deno-runtime/.deno deno-runtime/",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AppStatusUtils } from '../../definition/AppStatus';
import type { IUIActionButton, IUIActionButtonDescriptor } from '../../definition/ui';
import type { AppManager } from '../AppManager';
import type { AppActivationBridge } from '../bridges';
Expand All @@ -8,9 +9,12 @@ import { AppPermissions } from '../permissions/AppPermissions';
export class UIActionButtonManager {
private readonly activationBridge: AppActivationBridge;

private readonly manager: AppManager;

private registeredActionButtons = new Map<string, Map<string, IUIActionButtonDescriptor>>();

constructor(manager: AppManager) {
this.manager = manager;
this.activationBridge = manager.getBridges().getAppActivationBridge();
}

Expand Down Expand Up @@ -39,18 +43,37 @@ export class UIActionButtonManager {
return this.registeredActionButtons.get(appId);
}

public getAllActionButtons() {
public async getAllActionButtons(): Promise<Array<IUIActionButton>> {
const buttonList: Array<IUIActionButton> = [];

// Flatten map to a simple list of all buttons
this.registeredActionButtons.forEach((appButtons, appId) =>
// Flatten map to a simple list of buttons from enabled apps only
for (const [appId, appButtons] of this.registeredActionButtons) {
const app = this.manager.getOneById(appId);

// Skip if app doesn't exist
if (!app) {
continue;
}

// or if it is not enabled
try {
const appStatus = await app.getStatus();
if (!AppStatusUtils.isEnabled(appStatus)) {
continue;
}
} catch (error) {
// If we can't get the app status, skip this app's buttons
continue;
}

// Add buttons from this enabled app
appButtons.forEach((button) =>
buttonList.push({
...button,
appId,
}),
),
);
);
}

return buttonList;
}
Expand Down
Loading
Loading