Skip to content

Commit f7213e8

Browse files
committed
UBERF-10272: Allow workspace owners to enable/disable modules
Signed-off-by: Andrey Sobolev <[email protected]>
1 parent eb86e24 commit f7213e8

File tree

6 files changed

+80
-4
lines changed

6 files changed

+80
-4
lines changed

Diff for: models/all/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[
321321
boardModel,
322322
boardId,
323323
{
324-
label: board.string.ConfigLabel,
324+
label: undefined, // board.string.ConfigLabel,
325325
description: board.string.ConfigDescription,
326326
enabled: false,
327327
beta: true,
@@ -333,7 +333,7 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[
333333
bitrixModel,
334334
bitrixId,
335335
{
336-
label: bitrix.string.ConfigLabel,
336+
label: undefined, // bitrix.string.ConfigLabel,
337337
description: bitrix.string.ConfigDescription,
338338
enabled: false,
339339
beta: true,

Diff for: models/setting/src/index.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,7 @@ export function createModel (builder: Builder): void {
289289
icon: setting.icon.Setting,
290290
component: setting.component.Configure,
291291
order: 1200,
292-
role: AccountRole.Owner,
293-
adminOnly: true
292+
role: AccountRole.Owner
294293
},
295294
setting.ids.Configure
296295
)

Diff for: packages/core/src/classes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ export interface PluginConfiguration extends Doc {
268268
pluginId: Plugin
269269
transactions: Ref<Doc>[]
270270

271+
// If not set will not be shown in configuration UI
271272
label?: IntlString
272273
icon?: Asset
273274
description?: IntlString

Diff for: server/middleware/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ export * from './triggers'
3737
export * from './txPush'
3838
export * from './queue'
3939
export * from './identity'
40+
export * from './pluginConfig'

Diff for: server/middleware/src/pluginConfig.ts

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//
2+
// Copyright © 2025 Hardcore Engineering Inc.
3+
//
4+
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License. You may
6+
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
//
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
import { aiBotAccountEmail } from '@hcengineering/ai-bot'
16+
import core, {
17+
AccountRole,
18+
MeasureContext,
19+
Tx,
20+
TxProcessor,
21+
systemAccountUuid,
22+
type Doc,
23+
type SessionData,
24+
type TxApplyIf,
25+
type TxCUD
26+
} from '@hcengineering/core'
27+
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
28+
import { BaseMiddleware, Middleware, TxMiddlewareResult, type PipelineContext } from '@hcengineering/server-core'
29+
30+
/**
31+
* @public
32+
*/
33+
export class PluginConfigurationMiddleware extends BaseMiddleware implements Middleware {
34+
private constructor (context: PipelineContext, next?: Middleware) {
35+
super(context, next)
36+
}
37+
38+
static async create (
39+
ctx: MeasureContext,
40+
context: PipelineContext,
41+
next: Middleware | undefined
42+
): Promise<PluginConfigurationMiddleware> {
43+
return new PluginConfigurationMiddleware(context, next)
44+
}
45+
46+
tx (ctx: MeasureContext<SessionData>, txes: Tx[]): Promise<TxMiddlewareResult> {
47+
const account = ctx.contextData.account
48+
if (account.uuid === systemAccountUuid || account.fullSocialIds.some((it) => it.value === aiBotAccountEmail)) {
49+
// We pass for system accounts and services.
50+
return this.provideTx(ctx, txes)
51+
}
52+
function checkTx (tx: Tx): void {
53+
if (TxProcessor.isExtendsCUD(tx._class)) {
54+
const cud = tx as TxCUD<Doc>
55+
if (cud.objectClass === core.class.PluginConfiguration && ctx.contextData.account.role !== AccountRole.Owner) {
56+
throw new PlatformError(
57+
new Status(Severity.ERROR, platform.status.Forbidden, {
58+
account: account.uuid
59+
})
60+
)
61+
}
62+
}
63+
}
64+
for (const tx of txes) {
65+
checkTx(tx)
66+
if (tx._class === core.class.TxApplyIf) {
67+
const atx = tx as TxApplyIf
68+
atx.txes.forEach(checkTx)
69+
}
70+
}
71+
return this.provideTx(ctx, txes)
72+
}
73+
}

Diff for: server/server-pipeline/src/pipeline.ts

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
ModelMiddleware,
3232
ModifiedMiddleware,
3333
NotificationsMiddleware,
34+
PluginConfigurationMiddleware,
3435
PrivateMiddleware,
3536
QueryJoinMiddleware,
3637
QueueMiddleware,
@@ -119,6 +120,7 @@ export function createServerPipeline (
119120
LookupMiddleware.create,
120121
IdentityMiddleware.create,
121122
ModifiedMiddleware.create,
123+
PluginConfigurationMiddleware.create,
122124
PrivateMiddleware.create,
123125
NotificationsMiddleware.create,
124126
(ctx: MeasureContext, context: PipelineContext, next?: Middleware) =>

0 commit comments

Comments
 (0)