diff options
| author | anatawa12 <anatawa12@icloud.com> | 2025-04-03 19:22:49 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-03 19:22:49 +0900 |
| commit | cab82452ecb9aa6f89da22a1177cbf0e01f0462b (patch) | |
| tree | e0cf3599ec319a2ffeb8cc7233bf834c387e304f /packages/backend/src/core | |
| parent | refactor(frontend): refactor MkDateSeparatedList (diff) | |
| download | sharkey-cab82452ecb9aa6f89da22a1177cbf0e01f0462b.tar.gz sharkey-cab82452ecb9aa6f89da22a1177cbf0e01f0462b.tar.bz2 sharkey-cab82452ecb9aa6f89da22a1177cbf0e01f0462b.zip | |
Copy role on move (#15745)
* feat(backend): copyOnMoveAccount
* feat(endpoints): copyOnMoveAccount
* feat(frontend): copyOnMoveAccount
* docs(changelog): アカウントのマイグレーション時に古いアカウントからロールをコピーできるようになりました。
* fix: spdx header for migration
* Update locales/ja-JP.yml
* copyOnMoveAccount -> preserveAssignmentOnMoveAccount
* fix: check for preserveAssignmentOnMoveAccount
---------
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Diffstat (limited to 'packages/backend/src/core')
| -rw-r--r-- | packages/backend/src/core/AccountMoveService.ts | 29 | ||||
| -rw-r--r-- | packages/backend/src/core/RoleService.ts | 1 | ||||
| -rw-r--r-- | packages/backend/src/core/entities/RoleEntityService.ts | 4 |
3 files changed, 33 insertions, 1 deletions
diff --git a/packages/backend/src/core/AccountMoveService.ts b/packages/backend/src/core/AccountMoveService.ts index 0fbb9bcd80..406563bee8 100644 --- a/packages/backend/src/core/AccountMoveService.ts +++ b/packages/backend/src/core/AccountMoveService.ts @@ -24,6 +24,7 @@ import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import InstanceChart from '@/core/chart/charts/instance.js'; import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js'; import { SystemAccountService } from '@/core/SystemAccountService.js'; +import { RoleService } from '@/core/RoleService.js'; @Injectable() export class AccountMoveService { @@ -61,6 +62,7 @@ export class AccountMoveService { private relayService: RelayService, private queueService: QueueService, private systemAccountService: SystemAccountService, + private roleService: RoleService, ) { } @@ -119,6 +121,7 @@ export class AccountMoveService { await Promise.all([ this.copyBlocking(src, dst), this.copyMutings(src, dst), + this.copyRoles(src, dst), this.updateLists(src, dst), ]); } catch { @@ -201,6 +204,32 @@ export class AccountMoveService { await this.mutingsRepository.insert(arrayToInsert); } + @bindThis + public async copyRoles(src: ThinUser, dst: ThinUser): Promise<void> { + // Insert new roles with the same values except userId + // role service may have cache for roles so retrieve roles from service + const [oldRoleAssignments, roles] = await Promise.all([ + this.roleService.getUserAssigns(src.id), + this.roleService.getRoles(), + ]); + + if (oldRoleAssignments.length === 0) return; + + // No promise all since the only async operation is writing to the database + for (const oldRoleAssignment of oldRoleAssignments) { + const role = roles.find(x => x.id === oldRoleAssignment.roleId); + if (role == null) continue; // Very unlikely however removing role may cause this case + if (!role.preserveAssignmentOnMoveAccount) continue; + + try { + await this.roleService.assign(dst.id, role.id, oldRoleAssignment.expiresAt); + } catch (e) { + if (e instanceof RoleService.AlreadyAssignedError) continue; + throw e; + } + } + } + /** * Update lists while moving accounts. * - No removal of the old account from the lists diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 86f8a5caa1..0a2659ee32 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -630,6 +630,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { isModerator: values.isModerator, isExplorable: values.isExplorable, asBadge: values.asBadge, + preserveAssignmentOnMoveAccount: values.preserveAssignmentOnMoveAccount, canEditMembersByModerator: values.canEditMembersByModerator, displayOrder: values.displayOrder, policies: values.policies, diff --git a/packages/backend/src/core/entities/RoleEntityService.ts b/packages/backend/src/core/entities/RoleEntityService.ts index 2a7dc37bce..3fa38c9521 100644 --- a/packages/backend/src/core/entities/RoleEntityService.ts +++ b/packages/backend/src/core/entities/RoleEntityService.ts @@ -13,6 +13,7 @@ import type { MiRole } from '@/models/Role.js'; import { bindThis } from '@/decorators.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; import { IdService } from '@/core/IdService.js'; +import { Packed } from '@/misc/json-schema.js'; @Injectable() export class RoleEntityService { @@ -31,7 +32,7 @@ export class RoleEntityService { public async pack( src: MiRole['id'] | MiRole, me?: { id: MiUser['id'] } | null | undefined, - ) { + ): Promise<Packed<'Role'>> { const role = typeof src === 'object' ? src : await this.rolesRepository.findOneByOrFail({ id: src }); const assignedCount = await this.roleAssignmentsRepository.createQueryBuilder('assign') @@ -67,6 +68,7 @@ export class RoleEntityService { isModerator: role.isModerator, isExplorable: role.isExplorable, asBadge: role.asBadge, + preserveAssignmentOnMoveAccount: role.preserveAssignmentOnMoveAccount, canEditMembersByModerator: role.canEditMembersByModerator, displayOrder: role.displayOrder, policies: policies, |