Allow restricting announcement to a set of roles. Fix MkRoleSelectDialog only respecting publicOnly half the time

Closes #682
This commit is contained in:
наб 2025-07-13 00:37:17 +02:00
parent 5dd32123a3
commit f3b5c3f447
No known key found for this signature in database
GPG key ID: BCFD0B018D2658F1
12 changed files with 96 additions and 1 deletions

View file

@ -59,6 +59,7 @@ export const paramDef = {
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'], default: 'info' },
display: { type: 'string', enum: ['normal', 'banner', 'dialog'], default: 'normal' },
forExistingUsers: { type: 'boolean', default: false },
forRoles: { type: 'array', nullable: true, default: null, items: { type: 'string', nullable: false, format: 'misskey:id' }, },
silence: { type: 'boolean', default: false },
needConfirmationToRead: { type: 'boolean', default: false },
confetti: { type: 'boolean', default: false },
@ -82,6 +83,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
icon: ps.icon,
display: ps.display,
forExistingUsers: ps.forExistingUsers,
forRoles: ps.forRoles,
silence: ps.silence,
needConfirmationToRead: ps.needConfirmationToRead,
confetti: ps.confetti,

View file

@ -57,6 +57,15 @@ export const meta = {
type: 'number',
optional: false, nullable: false,
},
forRoles: {
type: 'array',
optional: false, nullable: true,
items: {
type: 'string',
optional: false, nullable: false,
format: 'misskey:id'
}
},
},
},
},
@ -122,6 +131,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
display: announcement.display,
isActive: announcement.isActive,
forExistingUsers: announcement.forExistingUsers,
forRoles: announcement.forRoles,
silence: announcement.silence,
needConfirmationToRead: announcement.needConfirmationToRead,
confetti: announcement.confetti,

View file

@ -36,6 +36,7 @@ export const paramDef = {
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'] },
display: { type: 'string', enum: ['normal', 'banner', 'dialog'] },
forExistingUsers: { type: 'boolean' },
forRoles: { type: 'array', nullable: true, default: null, items: { type: 'string', nullable: false, format: 'misskey:id' }, },
silence: { type: 'boolean' },
needConfirmationToRead: { type: 'boolean' },
confetti: { type: 'boolean' },
@ -66,6 +67,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
display: ps.display,
icon: ps.icon,
forExistingUsers: ps.forExistingUsers,
forRoles: ps.forRoles,
silence: ps.silence,
needConfirmationToRead: ps.needConfirmationToRead,
confetti: ps.confetti,

View file

@ -7,6 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { Brackets } from 'typeorm';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { QueryService } from '@/core/QueryService.js';
import { RoleService } from '@/core/RoleService.js';
import { AnnouncementEntityService } from '@/core/entities/AnnouncementEntityService.js';
import { DI } from '@/di-symbols.js';
import type { AnnouncementsRepository } from '@/models/_.js';
@ -51,14 +52,20 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private announcementsRepository: AnnouncementsRepository,
private queryService: QueryService,
private roleService: RoleService,
private announcementEntityService: AnnouncementEntityService,
) {
super(meta, paramDef, async (ps, me) => {
const roles = me ? await this.roleService.getUserRoles(me) : [];
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId)
.andWhere('announcement.isActive = :isActive', { isActive: ps.isActive })
.andWhere(new Brackets(qb => {
if (me) qb.orWhere('announcement.userId = :meId', { meId: me.id });
qb.orWhere('announcement.userId IS NULL');
}))
.andWhere(new Brackets(qb => {
if (me) qb.orWhere('announcement.forRoles && :roles', { roles: roles.map((r) => r.id) });
qb.orWhere('announcement.forRoles IS NULL');
}));
const announcements = await query.limit(ps.limit).getMany();