Skip to content

Commit

Permalink
spec(backend/stream): モデレーターにも一般ユーザーと同じく通常の投稿はcdn経由で配信するように (#920)
Browse files Browse the repository at this point in the history
  • Loading branch information
u1-liquid authored Jan 28, 2025
1 parent d7d270b commit 020c4f1
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 40 deletions.
19 changes: 16 additions & 3 deletions packages/backend/src/core/RoleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
* 指定ユーザーのバッジロール一覧取得
*/
@bindThis
public async getUserBadgeRoles(userId: MiUser['id']) {
public async getUserBadgeRoles(userId: MiUser['id'], publicOnly: boolean) {
const now = Date.now();
let assigns = await this.roleAssignmentByUserIdCache.fetch(userId, () => this.roleAssignmentsRepository.findBy({ userId }));
// 期限切れのロールを除外
Expand All @@ -362,12 +362,25 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
if (badgeCondRoles.length > 0) {
const user = roles.some(r => r.target === 'conditional') ? await this.cacheService.findUserById(userId) : null;
const matchedBadgeCondRoles = badgeCondRoles.filter(r => this.evalCond(user!, assignedRoles, r.condFormula));
return [...assignedBadgeRoles, ...matchedBadgeCondRoles];
return this.sortAndMapBadgeRoles([...assignedBadgeRoles, ...matchedBadgeCondRoles], publicOnly);
} else {
return assignedBadgeRoles;
return this.sortAndMapBadgeRoles(assignedBadgeRoles, publicOnly);
}
}

@bindThis
private sortAndMapBadgeRoles(roles: MiRole[], publicOnly: boolean) {
return roles
.filter((r) => r.isPublic || !publicOnly)
.sort((a, b) => b.displayOrder - a.displayOrder)
.map((r) => ({
name: r.name,
iconUrl: r.iconUrl,
displayOrder: r.displayOrder,
behavior: r.badgeBehavior ?? undefined,
}));
}

@bindThis
public async getUserPolicies(userId: MiUser['id'] | null): Promise<RolePolicies> {
const meta = await this.metaService.fetch();
Expand Down
11 changes: 1 addition & 10 deletions packages/backend/src/core/entities/UserEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,16 +499,7 @@ export class UserEntityService implements OnModuleInit {
} : undefined) : undefined,
emojis: this.customEmojiService.populateEmojis(user.emojis, user.host),
onlineStatus: this.getOnlineStatus(user),
badgeRoles: this.roleService.getUserBadgeRoles(user.id).then((rs) => rs
.filter((r) => r.isPublic || iAmModerator)
.sort((a, b) => b.displayOrder - a.displayOrder)
.map((r) => ({
name: r.name,
iconUrl: r.iconUrl,
displayOrder: r.displayOrder,
behavior: r.badgeBehavior ?? undefined,
})),
),
badgeRoles: this.roleService.getUserBadgeRoles(user.id, !iAmModerator),

...(isDetailed ? {
url: profile!.url,
Expand Down
3 changes: 3 additions & 0 deletions packages/backend/src/server/api/StreamingApiServerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js';
import { MiLocalUser } from '@/models/User.js';
import { UserService } from '@/core/UserService.js';
import { RoleService } from '@/core/RoleService.js';
import { ChannelFollowingService } from '@/core/ChannelFollowingService.js';
import { AuthenticateService, AuthenticationError } from './AuthenticateService.js';
import MainStreamConnection from './stream/Connection.js';
Expand All @@ -40,6 +41,7 @@ export class StreamingApiServerService {
private channelsService: ChannelsService,
private notificationService: NotificationService,
private usersService: UserService,
private roleService: RoleService,
private channelFollowingService: ChannelFollowingService,
) {
}
Expand Down Expand Up @@ -99,6 +101,7 @@ export class StreamingApiServerService {
this.noteReadService,
this.notificationService,
this.cacheService,
this.roleService,
this.channelFollowingService,
user, app,
);
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/server/api/stream/Connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { CacheService } from '@/core/CacheService.js';
import { MiFollowing, MiUserProfile } from '@/models/_.js';
import type { StreamEventEmitter, GlobalEvents } from '@/core/GlobalEventService.js';
import { ChannelFollowingService } from '@/core/ChannelFollowingService.js';
import { RoleService } from '@/core/RoleService.js';
import type { ChannelsService } from './ChannelsService.js';
import type { EventEmitter } from 'events';
import type Channel from './channel.js';
Expand All @@ -31,6 +32,7 @@ export default class Connection {
private subscribingNotes: any = {};
private cachedNotes: Packed<'Note'>[] = [];
public userProfile: MiUserProfile | null = null;
public isModerator = false;
public following: Record<string, Pick<MiFollowing, 'withReplies'> | undefined> = {};
public followingChannels: Set<string> = new Set();
public userIdsWhoMeMuting: Set<string> = new Set();
Expand All @@ -44,6 +46,7 @@ export default class Connection {
private noteReadService: NoteReadService,
private notificationService: NotificationService,
private cacheService: CacheService,
private roleService: RoleService,
private channelFollowingService: ChannelFollowingService,

user: MiUser | null | undefined,
Expand Down Expand Up @@ -77,6 +80,7 @@ export default class Connection {
public async init() {
if (this.user != null) {
await this.fetch();
this.isModerator = await this.roleService.isModerator(this.user);

if (!this.fetchIntervalId) {
this.fetchIntervalId = setInterval(this.fetch, 1000 * 10);
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/server/api/stream/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export default abstract class Channel {
return this.connection.userProfile;
}

protected get iAmModerator() {
return this.connection.isModerator;
}

protected get following() {
return this.connection.following;
}
Expand Down
9 changes: 8 additions & 1 deletion packages/backend/src/server/api/stream/channels/antenna.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
*/

import { Injectable } from '@nestjs/common';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import type { GlobalEvents } from '@/core/GlobalEventService.js';
import Channel, { type MiChannelService } from '../channel.js';

Expand All @@ -18,6 +19,7 @@ class AntennaChannel extends Channel {
private minimize: boolean;

constructor(
private roleService: RoleService,
private noteEntityService: NoteEntityService,

id: string,
Expand Down Expand Up @@ -56,11 +58,14 @@ class AntennaChannel extends Channel {
}

if (this.minimize && ['public', 'home'].includes(note.visibility)) {
const badgeRoles = this.iAmModerator ? await this.roleService.getUserBadgeRoles(note.userId, false) : undefined;

this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll?.choices ? { choices: note.poll.choices } : undefined,
reply: note.reply?.myReaction ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote?.myReaction ? { myReaction: note.renote.myReaction } : undefined,
...(badgeRoles?.length ? { user: { badgeRoles } } : {}),
});
} else {
this.send('note', note);
Expand All @@ -84,13 +89,15 @@ export class AntennaChannelService implements MiChannelService<true> {
public readonly kind = AntennaChannel.kind;

constructor(
private roleService: RoleService,
private noteEntityService: NoteEntityService,
) {
}

@bindThis
public create(id: string, connection: Channel['connection']): AntennaChannel {
return new AntennaChannel(
this.roleService,
this.noteEntityService,
id,
connection,
Expand Down
9 changes: 8 additions & 1 deletion packages/backend/src/server/api/stream/channels/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
*/

import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import type { Packed } from '@/misc/json-schema.js';
import { RoleService } from '@/core/RoleService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js';
import Channel, { type MiChannelService } from '../channel.js';

Expand All @@ -18,6 +19,7 @@ class ChannelChannel extends Channel {
private minimize: boolean;

constructor(
private roleService: RoleService,
private noteEntityService: NoteEntityService,

id: string,
Expand Down Expand Up @@ -62,11 +64,14 @@ class ChannelChannel extends Channel {
}

if (this.minimize && ['public', 'home'].includes(note.visibility)) {
const badgeRoles = this.iAmModerator ? await this.roleService.getUserBadgeRoles(note.userId, false) : undefined;

this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll?.choices ? { choices: note.poll.choices } : undefined,
reply: note.reply?.myReaction ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote?.myReaction ? { myReaction: note.renote.myReaction } : undefined,
...(badgeRoles?.length ? { user: { badgeRoles } } : {}),
});
} else {
this.send('note', note);
Expand All @@ -87,13 +92,15 @@ export class ChannelChannelService implements MiChannelService<false> {
public readonly kind = ChannelChannel.kind;

constructor(
private roleService: RoleService,
private noteEntityService: NoteEntityService,
) {
}

@bindThis
public create(id: string, connection: Channel['connection']): ChannelChannel {
return new ChannelChannel(
this.roleService,
this.noteEntityService,
id,
connection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
*/

import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import type { Packed } from '@/misc/json-schema.js';
import { MetaService } from '@/core/MetaService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js';
import Channel, { type MiChannelService } from '../channel.js';

Expand Down Expand Up @@ -92,11 +92,14 @@ class GlobalTimelineChannel extends Channel {
}

if (this.minimize && ['public', 'home'].includes(note.visibility)) {
const badgeRoles = this.iAmModerator ? await this.roleService.getUserBadgeRoles(note.userId, false) : undefined;

this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll?.choices ? { choices: note.poll.choices } : undefined,
reply: note.reply?.myReaction ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote?.myReaction ? { myReaction: note.renote.myReaction } : undefined,
...(badgeRoles?.length ? { user: { badgeRoles } } : {}),
});
} else {
this.send('note', note);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
*/

import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import type { Packed } from '@/misc/json-schema.js';
import { RoleService } from '@/core/RoleService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js';
import Channel, { type MiChannelService } from '../channel.js';

Expand All @@ -20,6 +21,7 @@ class HomeTimelineChannel extends Channel {
private minimize: boolean;

constructor(
private roleService: RoleService,
private noteEntityService: NoteEntityService,

id: string,
Expand Down Expand Up @@ -96,11 +98,14 @@ class HomeTimelineChannel extends Channel {
}

if (this.minimize && ['public', 'home'].includes(note.visibility)) {
const badgeRoles = this.iAmModerator ? await this.roleService.getUserBadgeRoles(note.userId, false) : undefined;

this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll?.choices ? { choices: note.poll.choices } : undefined,
reply: note.reply?.myReaction ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote?.myReaction ? { myReaction: note.renote.myReaction } : undefined,
...(badgeRoles?.length ? { user: { badgeRoles } } : {}),
});
} else {
this.send('note', note);
Expand All @@ -121,13 +126,15 @@ export class HomeTimelineChannelService implements MiChannelService<true> {
public readonly kind = HomeTimelineChannel.kind;

constructor(
private roleService: RoleService,
private noteEntityService: NoteEntityService,
) {
}

@bindThis
public create(id: string, connection: Channel['connection']): HomeTimelineChannel {
return new HomeTimelineChannel(
this.roleService,
this.noteEntityService,
id,
connection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
*/

import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import type { Packed } from '@/misc/json-schema.js';
import { MetaService } from '@/core/MetaService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { isRenotePacked, isQuotePacked } from '@/misc/is-renote.js';
import Channel, { type MiChannelService } from '../channel.js';

Expand Down Expand Up @@ -110,11 +110,14 @@ class HybridTimelineChannel extends Channel {
}

if (this.minimize && ['public', 'home'].includes(note.visibility)) {
const badgeRoles = this.iAmModerator ? await this.roleService.getUserBadgeRoles(note.userId, false) : undefined;

this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll?.choices ? { choices: note.poll.choices } : undefined,
reply: note.reply?.myReaction ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote?.myReaction ? { myReaction: note.renote.myReaction } : undefined,
...(badgeRoles?.length ? { user: { badgeRoles } } : {}),
});
} else {
this.send('note', note);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
*/

import { Injectable } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import type { Packed } from '@/misc/json-schema.js';
import { MetaService } from '@/core/MetaService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { isQuotePacked, isRenotePacked } from '@/misc/is-renote.js';
import Channel, { type MiChannelService } from '../channel.js';

Expand Down Expand Up @@ -95,11 +95,14 @@ class LocalTimelineChannel extends Channel {
}

if (this.minimize && ['public', 'home'].includes(note.visibility)) {
const badgeRoles = this.iAmModerator ? await this.roleService.getUserBadgeRoles(note.userId, false) : undefined;

this.send('note', {
id: note.id, myReaction: note.myReaction,
poll: note.poll?.choices ? { choices: note.poll.choices } : undefined,
reply: note.reply?.myReaction ? { myReaction: note.reply.myReaction } : undefined,
renote: note.renote?.myReaction ? { myReaction: note.renote.myReaction } : undefined,
...(badgeRoles?.length ? { user: { badgeRoles } } : {}),
});
} else {
this.send('note', note);
Expand Down
Loading

0 comments on commit 020c4f1

Please sign in to comment.