From 37f10ea02d85caafe1836fbb052d4205f9f2fa39 Mon Sep 17 00:00:00 2001 From: Alexander Onnikov Date: Wed, 4 Feb 2026 18:14:26 +0700 Subject: [PATCH 1/3] feat: add drive permissions Signed-off-by: Alexander Onnikov --- models/drive/src/index.ts | 57 ++++++++++++- models/drive/src/migration.ts | 4 +- models/drive/src/permissions.ts | 78 ++++++++++++++++++ models/drive/src/plugin.ts | 8 ++ plugins/drive-assets/lang/cs.json | 14 +++- plugins/drive-assets/lang/de.json | 14 +++- plugins/drive-assets/lang/en.json | 14 +++- plugins/drive-assets/lang/es.json | 14 +++- plugins/drive-assets/lang/fr.json | 14 +++- plugins/drive-assets/lang/it.json | 14 +++- plugins/drive-assets/lang/ja.json | 14 +++- plugins/drive-assets/lang/pt.json | 14 +++- plugins/drive-assets/lang/ru.json | 14 +++- plugins/drive-assets/lang/tr.json | 14 +++- plugins/drive-assets/lang/zh.json | 14 +++- .../src/components/CreateDrive.svelte | 60 ++++++-------- .../src/components/DriveSpaceHeader.svelte | 26 +++++- .../src/components/FilePanel.svelte | 22 +++-- .../src/components/FolderBrowser.svelte | 9 +- plugins/drive-resources/src/index.ts | 82 +++++++++++++++++-- plugins/drive/src/plugin.ts | 22 ++++- plugins/drive/src/types.ts | 2 +- 22 files changed, 448 insertions(+), 76 deletions(-) diff --git a/models/drive/src/index.ts b/models/drive/src/index.ts index 68171798fd1..5614644a890 100644 --- a/models/drive/src/index.ts +++ b/models/drive/src/index.ts @@ -234,6 +234,12 @@ function defineDrive (builder: Builder): void { icon: drive.icon.Drive, baseClass: drive.class.Drive, availablePermissions: [ + drive.permission.CreateFolder, + drive.permission.UpdateFolder, + drive.permission.RemoveFolder, + drive.permission.CreateFile, + drive.permission.UpdateFile, + drive.permission.RemoveFile, core.permission.UpdateSpace, core.permission.ArchiveSpace, core.permission.ForbidDeleteObject @@ -326,7 +332,8 @@ function defineDrive (builder: Builder): void { mode: ['context', 'browser'], application: drive.app.Drive, group: 'create' - } + }, + visibilityTester: drive.function.CanCreateFolder }, drive.action.CreateRootFolder ) @@ -475,6 +482,7 @@ function defineFolder (builder: Builder): void { actions: [ view.action.Open, view.action.OpenInNewTab, + view.action.Delete, print.action.Print, tracker.action.EditRelatedTargets, tracker.action.NewRelatedIssue @@ -494,7 +502,8 @@ function defineFolder (builder: Builder): void { mode: ['context', 'browser'], application: drive.app.Drive, group: 'create' - } + }, + visibilityTester: drive.function.CanCreateFolder }, drive.action.CreateChildFolder ) @@ -518,6 +527,25 @@ function defineFolder (builder: Builder): void { drive.action.RenameFolder ) + createAction( + builder, + { + action: view.actionImpl.Delete, + label: view.string.Delete, + icon: view.icon.Delete, + category: drive.category.Drive, + input: 'none', + target: drive.class.Folder, + context: { + mode: ['context', 'browser'], + application: drive.app.Drive, + group: 'edit' + }, + visibilityTester: drive.function.CanDeleteFolder + }, + drive.action.DeleteFolder + ) + createAction(builder, { ...actionTemplates.move, action: view.actionImpl.ShowPopup, @@ -529,6 +557,7 @@ function defineFolder (builder: Builder): void { } }, target: drive.class.Folder, + visibilityTester: drive.function.CanUpdateFolder, context: { mode: ['browser', 'context'], group: 'tools' @@ -569,7 +598,8 @@ function defineFileVersion (builder: Builder): void { mode: ['context', 'browser'], application: drive.app.Drive, group: 'edit' - } + }, + visibilityTester: drive.function.CanUpdateFileVersion }, drive.action.RestoreFileVersion ) @@ -649,6 +679,7 @@ function defineFile (builder: Builder): void { actions: [ view.action.Open, view.action.OpenInNewTab, + view.action.Delete, print.action.Print, tracker.action.EditRelatedTargets, tracker.action.NewRelatedIssue @@ -692,6 +723,25 @@ function defineFile (builder: Builder): void { drive.action.RenameFile ) + createAction( + builder, + { + action: view.actionImpl.Delete, + label: view.string.Delete, + icon: view.icon.Delete, + category: drive.category.Drive, + input: 'none', + target: drive.class.File, + context: { + mode: ['context', 'browser'], + application: drive.app.Drive, + group: 'edit' + }, + visibilityTester: drive.function.CanDeleteFile + }, + drive.action.DeleteFile + ) + // createAction( // builder, // { @@ -721,6 +771,7 @@ function defineFile (builder: Builder): void { } }, target: drive.class.File, + visibilityTester: drive.function.CanUpdateFile, context: { mode: ['browser', 'context'], group: 'tools' diff --git a/models/drive/src/migration.ts b/models/drive/src/migration.ts index 317028c4178..1e628420ec4 100644 --- a/models/drive/src/migration.ts +++ b/models/drive/src/migration.ts @@ -14,7 +14,7 @@ // import core, { type Blob, type Ref, DOMAIN_BLOB, generateId, toIdMap } from '@hcengineering/core' -import type { Drive, File, FileVersion, Resource } from '@hcengineering/drive' +import type { File, FileVersion, Resource } from '@hcengineering/drive' import { type MigrateOperation, type MigrationClient, @@ -56,7 +56,7 @@ async function migrateFileVersions (client: MigrationClient): Promise { collection: 'versions', modifiedOn: file.modifiedOn, modifiedBy: file.modifiedBy, - space: file.space as Ref, + space: file.space, title: exfile.title, file: blob._id, size: blob.size, diff --git a/models/drive/src/permissions.ts b/models/drive/src/permissions.ts index 89b28e7f091..15da59471ce 100644 --- a/models/drive/src/permissions.ts +++ b/models/drive/src/permissions.ts @@ -3,6 +3,84 @@ import core from '@hcengineering/core' import drive from '@hcengineering/drive' export function definePermissions (builder: Builder): void { + builder.createDoc( + core.class.Permission, + core.space.Model, + { + scope: 'space', + label: drive.string.CreateFilePermission, + description: drive.string.CreateFilePermissionDescription, + txClass: core.class.TxCreateDoc, + objectClass: drive.class.File + }, + drive.permission.CreateFile + ) + + builder.createDoc( + core.class.Permission, + core.space.Model, + { + scope: 'space', + label: drive.string.UpdateFilePermission, + description: drive.string.UpdateFilePermissionDescription, + txClass: core.class.TxUpdateDoc, + objectClass: drive.class.File + }, + drive.permission.UpdateFile + ) + + builder.createDoc( + core.class.Permission, + core.space.Model, + { + scope: 'space', + label: drive.string.RemoveFilePermission, + description: drive.string.RemoveFilePermissionDescription, + txClass: core.class.TxRemoveDoc, + objectClass: drive.class.File + }, + drive.permission.RemoveFile + ) + + builder.createDoc( + core.class.Permission, + core.space.Model, + { + scope: 'space', + label: drive.string.CreateFolderPermission, + description: drive.string.CreateFolderPermissionDescription, + txClass: core.class.TxCreateDoc, + objectClass: drive.class.Folder + }, + drive.permission.CreateFolder + ) + + builder.createDoc( + core.class.Permission, + core.space.Model, + { + scope: 'space', + label: drive.string.UpdateFolderPermission, + description: drive.string.UpdateFolderPermissionDescription, + txClass: core.class.TxUpdateDoc, + objectClass: drive.class.Folder + }, + drive.permission.UpdateFolder + ) + + builder.createDoc( + core.class.Permission, + core.space.Model, + { + scope: 'space', + label: drive.string.RemoveFolderPermission, + description: drive.string.RemoveFolderPermissionDescription, + txClass: core.class.TxRemoveDoc, + objectClass: drive.class.Folder + }, + drive.permission.RemoveFolder + ) + builder.createDoc( core.class.Permission, core.space.Model, diff --git a/models/drive/src/plugin.ts b/models/drive/src/plugin.ts index ddfe0386f1e..d2738d1f23d 100644 --- a/models/drive/src/plugin.ts +++ b/models/drive/src/plugin.ts @@ -53,8 +53,14 @@ export default mergeIds(driveId, drive, { DriveLinkProvider: '' as Resource<(doc: Doc, props: Record) => Promise>, FolderLinkProvider: '' as Resource<(doc: Doc, props: Record) => Promise>, FileLinkProvider: '' as Resource<(doc: Doc, props: Record) => Promise>, + CanCreateFolder: '' as Resource, + CanUpdateFile: '' as Resource, + CanUpdateFolder: '' as Resource, + CanDeleteFile: '' as Resource, + CanDeleteFolder: '' as Resource, CanRenameFile: '' as Resource, CanRenameFolder: '' as Resource, + CanUpdateFileVersion: '' as Resource, CanDeleteFileVersion: '' as Resource, FileTitleProvider: '' as Resource<(client: Client, ref: Ref, doc?: Doc) => Promise>, FolderTitleProvider: '' as Resource<(client: Client, ref: Ref, doc?: Doc) => Promise> @@ -79,6 +85,8 @@ export default mergeIds(driveId, drive, { CreateRootFolder: '' as Ref, EditDrive: '' as Ref, DownloadFile: '' as Ref, + DeleteFile: '' as Ref, + DeleteFolder: '' as Ref, RenameFile: '' as Ref, RenameFolder: '' as Ref, DeleteFileVersion: '' as Ref, diff --git a/plugins/drive-assets/lang/cs.json b/plugins/drive-assets/lang/cs.json index 572ef6bd6d6..b94ff6023b2 100644 --- a/plugins/drive-assets/lang/cs.json +++ b/plugins/drive-assets/lang/cs.json @@ -28,6 +28,18 @@ "Restore": "Obnovit", "Root": "/", "ForbidCreateDrivePermission": "Zakázat vytvoření disku", - "ForbidCreateDrivePermissionDescription": "Zakazuje uživatelům vytvářet nové disky" + "ForbidCreateDrivePermissionDescription": "Zakazuje uživatelům vytvářet nové disky", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/de.json b/plugins/drive-assets/lang/de.json index 87561f3b80f..bbfe19d61a3 100644 --- a/plugins/drive-assets/lang/de.json +++ b/plugins/drive-assets/lang/de.json @@ -28,6 +28,18 @@ "Restore": "Wiederherstellen", "Root": "/", "ForbidCreateDrivePermission": "Laufwerkserstellung verbieten", - "ForbidCreateDrivePermissionDescription": "Verbietet Benutzern die Erstellung neuer Laufwerke" + "ForbidCreateDrivePermissionDescription": "Verbietet Benutzern die Erstellung neuer Laufwerke", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/en.json b/plugins/drive-assets/lang/en.json index 8738cf2c0b2..42edd37a3fc 100644 --- a/plugins/drive-assets/lang/en.json +++ b/plugins/drive-assets/lang/en.json @@ -28,6 +28,18 @@ "Restore": "Restore", "Root": "/", "ForbidCreateDrivePermission": "Forbid create drive", - "ForbidCreateDrivePermissionDescription": "Forbid users creating new drives" + "ForbidCreateDrivePermissionDescription": "Forbid users creating new drives", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/es.json b/plugins/drive-assets/lang/es.json index 82b9c90b850..be7d853d81f 100644 --- a/plugins/drive-assets/lang/es.json +++ b/plugins/drive-assets/lang/es.json @@ -28,6 +28,18 @@ "Restore": "Restaurar", "Root": "/", "ForbidCreateDrivePermission": "Prohibir crear unidad", - "ForbidCreateDrivePermissionDescription": "Prohíbe a los usuarios crear nuevas unidades" + "ForbidCreateDrivePermissionDescription": "Prohíbe a los usuarios crear nuevas unidades", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/fr.json b/plugins/drive-assets/lang/fr.json index 7449db4e140..adcc48f9b69 100644 --- a/plugins/drive-assets/lang/fr.json +++ b/plugins/drive-assets/lang/fr.json @@ -28,6 +28,18 @@ "Restore": "Restaurer", "Root": "/", "ForbidCreateDrivePermission": "Interdire la création de disque", - "ForbidCreateDrivePermissionDescription": "Interdit aux utilisateurs de créer de nouveaux disques" + "ForbidCreateDrivePermissionDescription": "Interdit aux utilisateurs de créer de nouveaux disques", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/it.json b/plugins/drive-assets/lang/it.json index dda4478ceea..d9b8c523ec2 100644 --- a/plugins/drive-assets/lang/it.json +++ b/plugins/drive-assets/lang/it.json @@ -28,6 +28,18 @@ "Restore": "Ripristina", "Root": "/", "ForbidCreateDrivePermission": "Vieta creazione drive", - "ForbidCreateDrivePermissionDescription": "Vieta agli utenti di creare nuovi drive" + "ForbidCreateDrivePermissionDescription": "Vieta agli utenti di creare nuovi drive", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/ja.json b/plugins/drive-assets/lang/ja.json index 43ff045e8c1..9596ddeaa84 100644 --- a/plugins/drive-assets/lang/ja.json +++ b/plugins/drive-assets/lang/ja.json @@ -28,6 +28,18 @@ "Restore": "復元", "Root": "/", "ForbidCreateDrivePermission": "ドライブの作成禁止", - "ForbidCreateDrivePermissionDescription": "ユーザーが新しいドライブを作成することを禁止します" + "ForbidCreateDrivePermissionDescription": "ユーザーが新しいドライブを作成することを禁止します", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/pt.json b/plugins/drive-assets/lang/pt.json index d2289f8a91e..e691004698f 100644 --- a/plugins/drive-assets/lang/pt.json +++ b/plugins/drive-assets/lang/pt.json @@ -28,6 +28,18 @@ "Restore": "Restaurar", "Root": "/", "ForbidCreateDrivePermission": "Proibir criação de unidade", - "ForbidCreateDrivePermissionDescription": "Proíbe os utilizadores de criar novas unidades" + "ForbidCreateDrivePermissionDescription": "Proíbe os utilizadores de criar novas unidades", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/ru.json b/plugins/drive-assets/lang/ru.json index f297656b074..da753aa8c37 100644 --- a/plugins/drive-assets/lang/ru.json +++ b/plugins/drive-assets/lang/ru.json @@ -28,6 +28,18 @@ "Restore": "Восстановить", "Root": "/", "ForbidCreateDrivePermission": "Запретить создание диска", - "ForbidCreateDrivePermissionDescription": "Запрещает пользователям создавать новые диски" + "ForbidCreateDrivePermissionDescription": "Запрещает пользователям создавать новые диски", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/tr.json b/plugins/drive-assets/lang/tr.json index ebeada621fd..87fd56e6691 100644 --- a/plugins/drive-assets/lang/tr.json +++ b/plugins/drive-assets/lang/tr.json @@ -26,6 +26,18 @@ "EditDrive": "Sürücüyü Düzenle", "Rename": "Yeniden adlandır", "Restore": "Geri yükle", - "Root": "/" + "Root": "/", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-assets/lang/zh.json b/plugins/drive-assets/lang/zh.json index 6b9699f3a6b..9fbe3d648b0 100644 --- a/plugins/drive-assets/lang/zh.json +++ b/plugins/drive-assets/lang/zh.json @@ -28,6 +28,18 @@ "Restore": "恢复", "Root": "/", "ForbidCreateDrivePermission": "禁止创建磁盘", - "ForbidCreateDrivePermissionDescription": "禁止用户创建新磁盘" + "ForbidCreateDrivePermissionDescription": "禁止用户创建新磁盘", + "CreateFilePermission": "Create File", + "CreateFilePermissionDescription": "Grants users ability to create files", + "UpdateFilePermission": "Update File", + "UpdateFilePermissionDescription": "Grants users ability to update files", + "RemoveFilePermission": "Remove File", + "RemoveFilePermissionDescription": "Grants users ability to remove files", + "CreateFolderPermission": "Create Folder", + "CreateFolderPermissionDescription": "Grants users ability to create folders", + "UpdateFolderPermission": "Update Folder", + "UpdateFolderPermissionDescription": "Grants users ability to update folders", + "RemoveFolderPermission": "Remove Folder", + "RemoveFolderPermissionDescription": "Grants users ability to remove folders" } } diff --git a/plugins/drive-resources/src/components/CreateDrive.svelte b/plugins/drive-resources/src/components/CreateDrive.svelte index d2094d0dae5..4f10b1117fc 100644 --- a/plugins/drive-resources/src/components/CreateDrive.svelte +++ b/plugins/drive-resources/src/components/CreateDrive.svelte @@ -18,7 +18,6 @@ import { AccountArrayEditor, employeeRefByAccountUuidStore } from '@hcengineering/contact-resources' import core, { Data, - DocumentUpdate, RolesAssignment, Ref, Role, @@ -48,6 +47,8 @@ let description: string = drive?.description ?? '' let isPrivate: boolean = drive?.private ?? false + let autoJoin = drive?.autoJoin ?? false + let restricted: boolean = drive?.restricted ?? false let members: AccountUuid[] = drive?.members !== undefined ? hierarchy.clone(drive.members) : [getCurrentAccount().uuid] let owners: AccountUuid[] = drive?.owners !== undefined ? hierarchy.clone(drive.owners) : [getCurrentAccount().uuid] @@ -102,7 +103,9 @@ private: isPrivate, members, owners, - archived: false + autoJoin, + archived: false, + restricted } } @@ -111,41 +114,8 @@ return } - const data = getDriveData() - const update: DocumentUpdate = {} - if (data.name !== drive?.name) { - update.name = data.name - } - if (data.description !== drive?.description) { - update.description = data.description - } - if (data.private !== drive?.private) { - update.private = data.private - } - if (data.members.length !== drive?.members.length) { - update.members = data.members - } else { - for (const member of data.members) { - if (drive.members.findIndex((p) => p === member) === -1) { - update.members = data.members - break - } - } - } - if (data.owners?.length !== drive?.owners?.length) { - update.owners = data.owners - } else { - for (const owner of data.owners ?? []) { - if (drive.owners?.findIndex((p) => p === owner) === -1) { - update.owners = data.owners - break - } - } - } - - if (Object.keys(update).length > 0) { - await client.update(drive, update) - } + const update = getDriveData() + await client.diffUpdate(drive, update) if (!deepEqual(rolesAssignment, getRolesAssignment())) { await client.updateMixin( @@ -307,6 +277,22 @@ /> +
+
+
+ +
+ +
+
+
+ +
+ {#each roles as role}
diff --git a/plugins/drive-resources/src/components/DriveSpaceHeader.svelte b/plugins/drive-resources/src/components/DriveSpaceHeader.svelte index b74ee96630b..a7e44d7f9f2 100644 --- a/plugins/drive-resources/src/components/DriveSpaceHeader.svelte +++ b/plugins/drive-resources/src/components/DriveSpaceHeader.svelte @@ -14,6 +14,7 @@ --> - + diff --git a/plugins/drive-resources/src/components/FilePanel.svelte b/plugins/drive-resources/src/components/FilePanel.svelte index 60744e03b2e..6c2488f2d63 100644 --- a/plugins/drive-resources/src/components/FilePanel.svelte +++ b/plugins/drive-resources/src/components/FilePanel.svelte @@ -14,13 +14,14 @@ --> {#if object} - + {/if} diff --git a/plugins/drive-resources/src/components/MoveResource.svelte b/plugins/drive-resources/src/components/MoveResource.svelte index b150d6c163a..74011d854c2 100644 --- a/plugins/drive-resources/src/components/MoveResource.svelte +++ b/plugins/drive-resources/src/components/MoveResource.svelte @@ -29,7 +29,7 @@ const dispatch = createEventDispatcher() - let space: Ref = value.space as Ref + let space: Ref = value.space let parent: Ref = value.parent as Ref async function save (): Promise { diff --git a/plugins/drive-resources/src/utils.ts b/plugins/drive-resources/src/utils.ts index 347235982fb..18e65984885 100644 --- a/plugins/drive-resources/src/utils.ts +++ b/plugins/drive-resources/src/utils.ts @@ -161,7 +161,7 @@ export async function resolveParents (object: Resource): Promise { } } - const root = await client.findOne(drive.class.Drive, { _id: object.space as Ref }) + const root = await client.findOne(drive.class.Drive, { _id: object.space }) if (root !== undefined) { parents.push(root) } From 1af4a07815940d56ddc6af9e5bda53d115c08e56 Mon Sep 17 00:00:00 2001 From: Alexander Onnikov Date: Fri, 6 Feb 2026 23:29:56 +0700 Subject: [PATCH 3/3] fix deletion permissions Signed-off-by: Alexander Onnikov --- plugins/drive-resources/src/index.ts | 43 ++++++++++++++--------- plugins/view-resources/src/permissions.ts | 22 ++++++++++++ 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/plugins/drive-resources/src/index.ts b/plugins/drive-resources/src/index.ts index 94ebbc9d0b6..b205a79458e 100644 --- a/plugins/drive-resources/src/index.ts +++ b/plugins/drive-resources/src/index.ts @@ -15,12 +15,11 @@ import { permissionsStore } from '@hcengineering/contact-resources' import type { Class, Client, Doc, DocumentQuery, Ref, RelatedDocument, WithLookup } from '@hcengineering/core' -import { checkPermission } from '@hcengineering/core' import drive, { type Drive, type File, type FileVersion, type Folder } from '@hcengineering/drive' import { type Resources } from '@hcengineering/platform' -import { type ObjectSearchResult, getClient, getFileUrl } from '@hcengineering/presentation' +import { type ObjectSearchResult, getFileUrl } from '@hcengineering/presentation' import { showPopup, type Location } from '@hcengineering/ui' -import { canChangeDoc, canCreateObject } from '@hcengineering/view-resources' +import { canChangeDoc, canCreateObject, canDeleteObject, canRemoveDoc } from '@hcengineering/view-resources' import { get } from 'svelte/store' import CreateDrive from './components/CreateDrive.svelte' @@ -194,7 +193,7 @@ export async function CanDeleteFileVersion ( } const permissions = get(permissionsStore) - return docs.map((p) => canChangeDoc(drive.class.File, doc.space, permissions)).every(Boolean) + return docs.every((p) => canChangeDoc(drive.class.File, doc.space, permissions)) } export async function CanCreateFolder (doc: Drive | Folder | Array | undefined): Promise { @@ -220,21 +219,33 @@ export async function CanUpdateFolder (doc: Folder | Folder[] | undefined): Prom } export async function CanDeleteFile (doc: File | File[] | undefined): Promise { - if (doc === undefined || Array.isArray(doc)) { - return false - } - // TODO - const client = getClient() - return await checkPermission(client, drive.permission.RemoveFile, doc.space) + if (doc === undefined) return false + doc = Array.isArray(doc) ? doc : [doc] + + const permissions = get(permissionsStore) + const results = await Promise.all( + doc.map(async (p) => { + return permissions.restrictedSpaces.has(p.space) + ? canRemoveDoc(drive.class.File, p.space, permissions) + : await canDeleteObject(doc) + }) + ) + return results.every(Boolean) } export async function CanDeleteFolder (doc: Folder | Folder[] | undefined): Promise { - if (doc === undefined || Array.isArray(doc)) { - return false - } - // TODO - const client = getClient() - return await checkPermission(client, drive.permission.RemoveFolder, doc.space) + if (doc === undefined) return false + doc = Array.isArray(doc) ? doc : [doc] + + const permissions = get(permissionsStore) + const results = await Promise.all( + doc.map(async (p) => { + return permissions.restrictedSpaces.has(p.space) + ? canRemoveDoc(drive.class.Folder, p.space, permissions) + : await canDeleteObject(doc) + }) + ) + return results.every(Boolean) } export async function FileTitleProvider (client: Client, ref: Ref, doc?: File): Promise { diff --git a/plugins/view-resources/src/permissions.ts b/plugins/view-resources/src/permissions.ts index 1c37399de3e..c1c368ca45c 100644 --- a/plugins/view-resources/src/permissions.ts +++ b/plugins/view-resources/src/permissions.ts @@ -85,6 +85,28 @@ export function canChangeDoc (_class: Ref>, space: Ref, store: return !store.restrictedSpaces.has(space) } +export function canRemoveDoc (_class: Ref>, space: Ref, store: PermissionsStore): boolean { + const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false + if (arePermissionsDisabled) return true + if (store.whitelist.has(space)) return true + if (store.ps[space] !== undefined) { + const client = getClient() + const h = client.getHierarchy() + const ancestors = h.getAncestors(_class) + const permissions = client.getModel().findAllSync(core.class.Permission, { txClass: core.class.TxRemoveDoc }) + for (const ancestor of ancestors) { + const curr = permissions.filter((p) => p.objectClass === ancestor && p.txMatch === undefined) + for (const permission of curr) { + if (store.ps[space]?.has(permission._id)) { + return permission.forbid !== true + } + } + } + } + + return !store.restrictedSpaces.has(space) +} + export function canCreateObject (_class: Ref>, space: Ref, store: PermissionsStore): boolean { const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false if (arePermissionsDisabled) return true