Skip to content
This repository was archived by the owner on Nov 5, 2025. It is now read-only.

Commit 12d825a

Browse files
authored
Merge pull request #450 from RocketChat/release-1.28.1
Release 1.28.1
2 parents 7b96e9e + cc9a146 commit 12d825a

File tree

4 files changed

+61
-52
lines changed

4 files changed

+61
-52
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rocket.chat/apps-engine",
3-
"version": "1.28.0",
3+
"version": "1.28.1",
44
"description": "The engine code for the Rocket.Chat Apps which manages, runs, translates, coordinates and all of that.",
55
"main": "index",
66
"typings": "index",

src/definition/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rocket.chat/apps-ts-definition",
3-
"version": "1.28.0-alpha",
3+
"version": "1.28.1",
44
"description": "Contains the TypeScript definitions for the Rocket.Chat Applications.",
55
"main": "index.js",
66
"typings": "index",

src/server/AppManager.ts

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { Buffer } from 'buffer';
12
import { AppStatus, AppStatusUtils } from '../definition/AppStatus';
2-
import { AppMethod } from '../definition/metadata';
3+
import { AppMethod, IAppInfo } from '../definition/metadata';
34
import { IPermission } from '../definition/permissions/IPermission';
45
import { IUser, UserType } from '../definition/users';
56
import { AppBridges, PersistenceBridge, UserBridge } from './bridges';
@@ -274,12 +275,7 @@ export class AppManager {
274275

275276
for (const app of this.apps.values()) {
276277
if (app.getStatus() === AppStatus.INITIALIZED) {
277-
this.listenerManager.unregisterListeners(app);
278-
this.commandManager.unregisterCommands(app.getID());
279-
this.externalComponentManager.unregisterExternalComponents(app.getID());
280-
this.apiManager.unregisterApis(app.getID());
281-
this.accessorManager.purifyApp(app.getID());
282-
await this.schedulerManager.cleanUp(app.getID());
278+
await this.purgeAppConfig(app);
283279
} else if (!AppStatusUtils.isDisabled(app.getStatus())) {
284280
await this.disable(app.getID(), isManual ? AppStatus.MANUALLY_DISABLED : AppStatus.DISABLED);
285281
}
@@ -403,13 +399,7 @@ export class AppManager {
403399
.catch((e) => console.warn('Error while disabling:', e));
404400
}
405401

406-
this.listenerManager.unregisterListeners(app);
407-
this.listenerManager.lockEssentialEvents(app);
408-
this.commandManager.unregisterCommands(app.getID());
409-
this.externalComponentManager.unregisterExternalComponents(app.getID());
410-
this.apiManager.unregisterApis(app.getID());
411-
this.accessorManager.purifyApp(app.getID());
412-
await this.schedulerManager.cleanUp(app.getID());
402+
await this.purgeAppConfig(app);
413403

414404
await app.setStatus(status, silent);
415405

@@ -463,7 +453,7 @@ export class AppManager {
463453

464454
// Create a user for the app
465455
try {
466-
await this.createAppUser(app);
456+
await this.createAppUser(result.info);
467457

468458
undoSteps.push(() => this.removeAppUser(app));
469459
} catch (err) {
@@ -539,17 +529,12 @@ export class AppManager {
539529
await this.disable(id);
540530
}
541531

542-
this.listenerManager.unregisterListeners(app);
532+
await this.purgeAppConfig(app);
543533
this.listenerManager.releaseEssentialEvents(app);
544-
this.commandManager.unregisterCommands(app.getID());
545-
this.externalComponentManager.purgeExternalComponents(app.getID());
546-
this.apiManager.unregisterApis(app.getID());
547-
this.accessorManager.purifyApp(app.getID());
548534
await this.removeAppUser(app);
549535
await (this.bridges.getPersistenceBridge() as IInternalPersistenceBridge & PersistenceBridge).purge(app.getID());
550536
await this.appMetadataStorage.remove(app.getID());
551537
await this.appSourceStorage.remove(app.getStorageItem()).catch();
552-
await this.schedulerManager.cleanUp(app.getID());
553538

554539
this.apps.delete(app.getID());
555540
}
@@ -593,16 +578,14 @@ export class AppManager {
593578

594579
const stored = await this.appMetadataStorage.update(descriptor);
595580

596-
// Now that is has all been compiled, let's get the
597-
// the App instance from the source.
598581
const app = this.getCompiler().toSandBox(this, descriptor, result);
599582

600583
// Ensure there is an user for the app
601584
try {
602-
await this.createAppUser(app);
585+
await this.createAppUser(result.info);
603586
} catch (err) {
604587
aff.setAppUserError({
605-
username: app.getAppUserUsername(),
588+
username: `${ result.info.nameSlug }.bot`,
606589
message: 'Failed to create an app user for this app.',
607590
});
608591

@@ -612,16 +595,41 @@ export class AppManager {
612595
aff.setApp(app);
613596

614597
if (updateOptions.loadApp) {
615-
await this.bridges.getAppActivationBridge().doAppUpdated(app).catch();
616-
617-
await this.runStartUpProcess(stored, app, false, true);
598+
await this.updateLocal(stored, app);
618599

619-
this.apps.set(app.getID(), app);
600+
await this.bridges.getAppActivationBridge().doAppUpdated(app).catch(() => {});
620601
}
621602

622603
return aff;
623604
}
624605

606+
/**
607+
* Updates the local instance of an app.
608+
*
609+
* If the second parameter is a Buffer of an app package,
610+
* unpackage and instantiate the app's main class
611+
*
612+
* With an instance of a ProxiedApp, start it up and replace
613+
* the reference in the local app collection
614+
*/
615+
public async updateLocal(stored: IAppStorageItem, appPackageOrInstance: ProxiedApp | Buffer) {
616+
const app = await (async () => {
617+
if (appPackageOrInstance instanceof Buffer) {
618+
const parseResult = await this.getParser().unpackageApp(appPackageOrInstance);
619+
620+
return this.getCompiler().toSandBox(this, stored, parseResult);
621+
}
622+
623+
return appPackageOrInstance;
624+
})();
625+
626+
await this.purgeAppConfig(app);
627+
628+
await this.runStartUpProcess(stored, app, false, true);
629+
630+
this.apps.set(app.getID(), app);
631+
}
632+
625633
public getLanguageContent(): { [key: string]: object } {
626634
const langs: { [key: string]: object } = {};
627635

@@ -703,15 +711,13 @@ export class AppManager {
703711

704712
return app.setStatus(AppStatus.DISABLED);
705713
})
706-
.catch((error) => {
714+
.catch(async (error) => {
707715
if (!(error instanceof InvalidLicenseError)) {
708716
console.error(error);
709717
return;
710718
}
711719

712-
this.commandManager.unregisterCommands(app.getID());
713-
this.externalComponentManager.unregisterExternalComponents(app.getID());
714-
this.apiManager.unregisterApis(app.getID());
720+
await this.purgeAppConfig(app);
715721

716722
return app.setStatus(AppStatus.INVALID_LICENSE_DISABLED);
717723
})
@@ -830,10 +836,7 @@ export class AppManager {
830836
status = AppStatus.INVALID_LICENSE_DISABLED;
831837
}
832838

833-
this.commandManager.unregisterCommands(storageItem.id);
834-
this.externalComponentManager.unregisterExternalComponents(storageItem.id);
835-
this.apiManager.unregisterApis(storageItem.id);
836-
await this.schedulerManager.cleanUp(storageItem.id);
839+
await this.purgeAppConfig(app);
837840
result = false;
838841

839842
await app.setStatus(status, silenceStatus);
@@ -849,6 +852,16 @@ export class AppManager {
849852
return result;
850853
}
851854

855+
private async purgeAppConfig(app: ProxiedApp) {
856+
this.listenerManager.unregisterListeners(app);
857+
this.listenerManager.lockEssentialEvents(app);
858+
this.commandManager.unregisterCommands(app.getID());
859+
this.externalComponentManager.unregisterExternalComponents(app.getID());
860+
this.apiManager.unregisterApis(app.getID());
861+
this.accessorManager.purifyApp(app.getID());
862+
await this.schedulerManager.cleanUp(app.getID());
863+
}
864+
852865
/**
853866
* Determines if the App's required settings are set or not.
854867
* Should a packageValue be provided and not empty, then it's considered set.
@@ -907,11 +920,7 @@ export class AppManager {
907920
this.listenerManager.registerListeners(app);
908921
this.listenerManager.releaseEssentialEvents(app);
909922
} else {
910-
this.commandManager.unregisterCommands(app.getID());
911-
this.externalComponentManager.unregisterExternalComponents(app.getID());
912-
this.apiManager.unregisterApis(app.getID());
913-
this.listenerManager.lockEssentialEvents(app);
914-
await this.schedulerManager.cleanUp(app.getID());
923+
await this.purgeAppConfig(app);
915924
}
916925

917926
if (saveToDb) {
@@ -924,25 +933,25 @@ export class AppManager {
924933
return enable;
925934
}
926935

927-
private async createAppUser(app: ProxiedApp): Promise<string> {
928-
const appUser = await (this.bridges.getUserBridge() as IInternalUserBridge & UserBridge).getAppUser(app.getID());
936+
private async createAppUser(appInfo: IAppInfo): Promise<string> {
937+
const appUser = await (this.bridges.getUserBridge() as IInternalUserBridge & UserBridge).getAppUser(appInfo.id);
929938

930939
if (appUser) {
931940
return appUser.id;
932941
}
933942

934943
const userData: Partial<IUser> = {
935-
username: app.getAppUserUsername(),
936-
name: app.getInfo().name,
944+
username: `${ appInfo.nameSlug }.bot`,
945+
name: appInfo.name,
937946
roles: ['app'],
938-
appId: app.getID(),
947+
appId: appInfo.id,
939948
type: UserType.APP,
940949
status: 'online',
941950
isEnabled: true,
942951
};
943952

944-
return (this.bridges.getUserBridge() as IInternalUserBridge & UserBridge).create(userData, app.getID(), {
945-
avatarUrl: app.getInfo().iconFileContent || app.getInfo().iconFile,
953+
return (this.bridges.getUserBridge() as IInternalUserBridge & UserBridge).create(userData, appInfo.id, {
954+
avatarUrl: appInfo.iconFileContent || appInfo.iconFile,
946955
joinDefaultChannels: true,
947956
sendWelcomeEmail: false,
948957
});

0 commit comments

Comments
 (0)