feat(backend): copyOnMoveAccount
This commit is contained in:
parent
3ec5bf114b
commit
3ac98f2032
|
@ -0,0 +1,13 @@
|
||||||
|
export class RoleCopyOnMoveAccount1743558299182 {
|
||||||
|
name = 'RoleCopyOnMoveAccount1743558299182'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "role" ADD "copyOnMoveAccount" boolean NOT NULL DEFAULT false`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "role"."copyOnMoveAccount" IS 'If true, the role will be copied to moved to the new user on moving a user.'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "role"."copyOnMoveAccount" IS 'If true, the role will be copied to moved to the new user on moving a user.'`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "copyOnMoveAccount"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||||
import InstanceChart from '@/core/chart/charts/instance.js';
|
import InstanceChart from '@/core/chart/charts/instance.js';
|
||||||
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
|
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
|
||||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||||
|
import { RoleService } from '@/core/RoleService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AccountMoveService {
|
export class AccountMoveService {
|
||||||
|
@ -61,6 +62,7 @@ export class AccountMoveService {
|
||||||
private relayService: RelayService,
|
private relayService: RelayService,
|
||||||
private queueService: QueueService,
|
private queueService: QueueService,
|
||||||
private systemAccountService: SystemAccountService,
|
private systemAccountService: SystemAccountService,
|
||||||
|
private roleService: RoleService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +121,7 @@ export class AccountMoveService {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.copyBlocking(src, dst),
|
this.copyBlocking(src, dst),
|
||||||
this.copyMutings(src, dst),
|
this.copyMutings(src, dst),
|
||||||
|
this.copyRoles(src, dst),
|
||||||
this.updateLists(src, dst),
|
this.updateLists(src, dst),
|
||||||
]);
|
]);
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -201,6 +204,31 @@ export class AccountMoveService {
|
||||||
await this.mutingsRepository.insert(arrayToInsert);
|
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
|
||||||
|
|
||||||
|
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.
|
* Update lists while moving accounts.
|
||||||
* - No removal of the old account from the lists
|
* - No removal of the old account from the lists
|
||||||
|
|
|
@ -630,6 +630,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
||||||
isModerator: values.isModerator,
|
isModerator: values.isModerator,
|
||||||
isExplorable: values.isExplorable,
|
isExplorable: values.isExplorable,
|
||||||
asBadge: values.asBadge,
|
asBadge: values.asBadge,
|
||||||
|
copyOnMoveAccount: values.copyOnMoveAccount,
|
||||||
canEditMembersByModerator: values.canEditMembersByModerator,
|
canEditMembersByModerator: values.canEditMembersByModerator,
|
||||||
displayOrder: values.displayOrder,
|
displayOrder: values.displayOrder,
|
||||||
policies: values.policies,
|
policies: values.policies,
|
||||||
|
|
|
@ -248,6 +248,12 @@ export class MiRole {
|
||||||
})
|
})
|
||||||
public isExplorable: boolean;
|
public isExplorable: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
comment: 'If true, the role will be copied to moved to the new user on moving a user.',
|
||||||
|
})
|
||||||
|
public copyOnMoveAccount: boolean;
|
||||||
|
|
||||||
@Column('boolean', {
|
@Column('boolean', {
|
||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue