Merge tag '2025.4.0' into merge/2025-03-24
# Conflicts: # .github/workflows/storybook.yml # locales/index.d.ts # package.json # packages/backend/src/models/json-schema/role.ts # packages/frontend/src/components/MkPageWindow.vue # packages/frontend/src/pages/admin/roles.editor.vue # packages/frontend/src/pages/admin/roles.vue # packages/frontend/src/pages/settings/preferences.vue # packages/frontend/src/pages/settings/privacy.vue # packages/frontend/src/pages/timeline.vue # packages/frontend/src/pref-migrate.ts # packages/frontend/src/ui/_common_/common.vue # packages/frontend/src/ui/deck.vue # packages/frontend/src/ui/universal.vue # packages/misskey-js/src/autogen/types.ts
This commit is contained in:
commit
7132696285
98 changed files with 1621 additions and 2087 deletions
|
|
@ -114,7 +114,7 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
if (note.visibility === 'specified') return false;
|
||||
if (note.visibility === 'followers') return false;
|
||||
|
||||
if (antenna.hideNotesInSensitiveChannel && note.channel?.isSensitive) return false;
|
||||
if (antenna.excludeNotesInSensitiveChannel && note.channel?.isSensitive) return false;
|
||||
|
||||
if (antenna.excludeBots && noteUser.isBot) return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,40 @@ export class ChatService {
|
|||
) {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async getChatAvailability(userId: MiUser['id']): Promise<{ read: boolean; write: boolean; }> {
|
||||
const policies = await this.roleService.getUserPolicies(userId);
|
||||
|
||||
switch (policies.chatAvailability) {
|
||||
case 'available':
|
||||
return {
|
||||
read: true,
|
||||
write: true,
|
||||
};
|
||||
case 'readonly':
|
||||
return {
|
||||
read: true,
|
||||
write: false,
|
||||
};
|
||||
case 'unavailable':
|
||||
return {
|
||||
read: false,
|
||||
write: false,
|
||||
};
|
||||
default:
|
||||
throw new Error('invalid chat availability (unreachable)');
|
||||
}
|
||||
}
|
||||
|
||||
/** getChatAvailabilityの糖衣。主にAPI呼び出し時に走らせて、権限的に問題ない場合はそのまま続行する */
|
||||
@bindThis
|
||||
public async checkChatAvailability(userId: MiUser['id'], permission: 'read' | 'write') {
|
||||
const policy = await this.getChatAvailability(userId);
|
||||
if (policy[permission] === false) {
|
||||
throw new Error('ROLE_PERMISSION_DENIED');
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async createMessageToUser(fromUser: { id: MiUser['id']; host: MiUser['host']; }, toUser: MiUser, params: {
|
||||
text?: string | null;
|
||||
|
|
@ -140,7 +174,7 @@ export class ChatService {
|
|||
}
|
||||
}
|
||||
|
||||
if (!(await this.roleService.getUserPolicies(toUser.id)).canChat) {
|
||||
if (!(await this.getChatAvailability(toUser.id)).write) {
|
||||
throw new Error('recipient is cannot chat (policy)');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export type RolePolicies = {
|
|||
canImportFollowing: boolean;
|
||||
canImportMuting: boolean;
|
||||
canImportUserLists: boolean;
|
||||
canChat: boolean;
|
||||
chatAvailability: 'available' | 'readonly' | 'unavailable';
|
||||
};
|
||||
|
||||
export const DEFAULT_POLICIES: RolePolicies = {
|
||||
|
|
@ -104,7 +104,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
|||
canImportFollowing: true,
|
||||
canImportMuting: true,
|
||||
canImportUserLists: true,
|
||||
canChat: true,
|
||||
chatAvailability: 'available',
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -376,6 +376,12 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||
return aggregate(policies.map(policy => policy.useDefault ? basePolicies[name] : policy.value));
|
||||
}
|
||||
|
||||
function aggregateChatAvailability(vs: RolePolicies['chatAvailability'][]) {
|
||||
if (vs.some(v => v === 'available')) return 'available';
|
||||
if (vs.some(v => v === 'readonly')) return 'readonly';
|
||||
return 'unavailable';
|
||||
}
|
||||
|
||||
return {
|
||||
gtlAvailable: calc('gtlAvailable', vs => vs.some(v => v === true)),
|
||||
btlAvailable: calc('btlAvailable', vs => vs.some(v => v === true)),
|
||||
|
|
@ -411,7 +417,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
|||
canImportFollowing: calc('canImportFollowing', vs => vs.some(v => v === true)),
|
||||
canImportMuting: calc('canImportMuting', vs => vs.some(v => v === true)),
|
||||
canImportUserLists: calc('canImportUserLists', vs => vs.some(v => v === true)),
|
||||
canChat: calc('canChat', vs => vs.some(v => v === true)),
|
||||
chatAvailability: calc('chatAvailability', aggregateChatAvailability),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export class AntennaEntityService {
|
|||
excludeBots: antenna.excludeBots,
|
||||
withReplies: antenna.withReplies,
|
||||
withFile: antenna.withFile,
|
||||
hideNotesInSensitiveChannel: antenna.hideNotesInSensitiveChannel,
|
||||
excludeNotesInSensitiveChannel: antenna.excludeNotesInSensitiveChannel,
|
||||
isActive: antenna.isActive,
|
||||
hasUnreadNote: false, // TODO
|
||||
notify: false, // 後方互換性のため
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
followersVisibility: profile!.followersVisibility,
|
||||
followingVisibility: profile!.followingVisibility,
|
||||
chatScope: user.chatScope,
|
||||
canChat: this.roleService.getUserPolicies(user.id).then(r => r.canChat),
|
||||
canChat: this.roleService.getUserPolicies(user.id).then(r => r.chatAvailability === 'available'),
|
||||
roles: this.roleService.getUserRoles(user.id).then(roles => roles.filter(role => role.isPublic).sort((a, b) => b.displayOrder - a.displayOrder).map(role => ({
|
||||
id: role.id,
|
||||
name: role.name,
|
||||
|
|
|
|||
|
|
@ -104,5 +104,5 @@ export class MiAntenna {
|
|||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public hideNotesInSensitiveChannel: boolean;
|
||||
public excludeNotesInSensitiveChannel: boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export const packedAntennaSchema = {
|
|||
optional: false, nullable: false,
|
||||
default: false,
|
||||
},
|
||||
hideNotesInSensitiveChannel: {
|
||||
excludeNotesInSensitiveChannel: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
default: false,
|
||||
|
|
|
|||
|
|
@ -300,9 +300,10 @@ export const packedRolePoliciesSchema = {
|
|||
type: 'integer',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
canChat: {
|
||||
type: 'boolean',
|
||||
chatAvailability: {
|
||||
type: 'string',
|
||||
optional: false, nullable: false,
|
||||
enum: ['available', 'readonly', 'unavailable'],
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export const paramDef = {
|
|||
excludeBots: { type: 'boolean' },
|
||||
withReplies: { type: 'boolean' },
|
||||
withFile: { type: 'boolean' },
|
||||
hideNotesInSensitiveChannel: { type: 'boolean' },
|
||||
excludeNotesInSensitiveChannel: { type: 'boolean' },
|
||||
},
|
||||
required: ['name', 'src', 'keywords', 'excludeKeywords', 'users', 'caseSensitive', 'withReplies', 'withFile'],
|
||||
} as const;
|
||||
|
|
@ -140,7 +140,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
excludeBots: ps.excludeBots,
|
||||
withReplies: ps.withReplies,
|
||||
withFile: ps.withFile,
|
||||
hideNotesInSensitiveChannel: ps.hideNotesInSensitiveChannel,
|
||||
excludeNotesInSensitiveChannel: ps.excludeNotesInSensitiveChannel,
|
||||
});
|
||||
|
||||
this.globalEventService.publishInternalEvent('antennaCreated', antenna);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ export const paramDef = {
|
|||
excludeBots: { type: 'boolean' },
|
||||
withReplies: { type: 'boolean' },
|
||||
withFile: { type: 'boolean' },
|
||||
hideNotesInSensitiveChannel: { type: 'boolean' },
|
||||
excludeNotesInSensitiveChannel: { type: 'boolean' },
|
||||
},
|
||||
required: ['antennaId'],
|
||||
} as const;
|
||||
|
|
@ -136,7 +136,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
excludeBots: ps.excludeBots,
|
||||
withReplies: ps.withReplies,
|
||||
withFile: ps.withFile,
|
||||
hideNotesInSensitiveChannel: ps.hideNotesInSensitiveChannel,
|
||||
excludeNotesInSensitiveChannel: ps.excludeNotesInSensitiveChannel,
|
||||
isActive: true,
|
||||
lastUsedAt: new Date(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const history = ps.room ? await this.chatService.roomHistory(me.id, ps.limit) : await this.chatService.userHistory(me.id, ps.limit);
|
||||
|
||||
const packedMessages = await this.chatEntityService.packMessagesDetailed(history, me);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ export const meta = {
|
|||
tags: ['chat'],
|
||||
|
||||
requireCredential: true,
|
||||
requiredRolePolicy: 'canChat',
|
||||
|
||||
prohibitMoved: true,
|
||||
|
||||
|
|
@ -74,6 +73,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
const room = await this.chatService.findRoomById(ps.toRoomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ export const meta = {
|
|||
tags: ['chat'],
|
||||
|
||||
requireCredential: true,
|
||||
requiredRolePolicy: 'canChat',
|
||||
|
||||
prohibitMoved: true,
|
||||
|
||||
|
|
@ -86,6 +85,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
let file = null;
|
||||
if (ps.fileId != null) {
|
||||
file = await this.driveFilesRepository.findOneBy({
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ export const meta = {
|
|||
tags: ['chat'],
|
||||
|
||||
requireCredential: true,
|
||||
requiredRolePolicy: 'canChat',
|
||||
|
||||
kind: 'write:chat',
|
||||
|
||||
|
|
@ -43,6 +42,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
const message = await this.chatService.findMyMessageById(me.id, ps.messageId);
|
||||
if (message == null) {
|
||||
throw new ApiError(meta.errors.noSuchMessage);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ export const meta = {
|
|||
tags: ['chat'],
|
||||
|
||||
requireCredential: true,
|
||||
requiredRolePolicy: 'canChat',
|
||||
|
||||
kind: 'write:chat',
|
||||
|
||||
|
|
@ -44,6 +43,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
await this.chatService.react(ps.messageId, me.id, ps.reaction);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const room = await this.chatService.findRoomById(ps.roomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
if (ps.roomId != null) {
|
||||
const room = await this.chatService.findRoomById(ps.roomId);
|
||||
if (room == null) {
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const message = await this.chatService.findMessageById(ps.messageId);
|
||||
if (message == null) {
|
||||
throw new ApiError(meta.errors.noSuchMessage);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ export const meta = {
|
|||
tags: ['chat'],
|
||||
|
||||
requireCredential: true,
|
||||
requiredRolePolicy: 'canChat',
|
||||
|
||||
kind: 'write:chat',
|
||||
|
||||
|
|
@ -44,6 +43,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
await this.chatService.unreact(ps.messageId, me.id, ps.reaction);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private getterService: GetterService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const other = await this.getterService.getUser(ps.userId).catch(err => {
|
||||
if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
|
||||
throw err;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ export const meta = {
|
|||
tags: ['chat'],
|
||||
|
||||
requireCredential: true,
|
||||
requiredRolePolicy: 'canChat',
|
||||
|
||||
prohibitMoved: true,
|
||||
|
||||
|
|
@ -52,6 +51,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
const room = await this.chatService.createRoom(me, {
|
||||
name: ps.name,
|
||||
description: ps.description ?? '',
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
const room = await this.chatService.findRoomById(ps.roomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ export const meta = {
|
|||
tags: ['chat'],
|
||||
|
||||
requireCredential: true,
|
||||
requiredRolePolicy: 'canChat',
|
||||
|
||||
prohibitMoved: true,
|
||||
|
||||
|
|
@ -57,6 +56,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
const room = await this.chatService.findMyRoomById(me.id, ps.roomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
await this.chatService.ignoreRoomInvitation(me.id, ps.roomId);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const invitations = await this.chatService.getReceivedRoomInvitationsWithPagination(me.id, ps.limit, ps.sinceId, ps.untilId);
|
||||
return this.chatEntityService.packRoomInvitations(invitations, me);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const room = await this.chatService.findMyRoomById(me.id, ps.roomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
await this.chatService.joinToRoom(me.id, ps.roomId);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const memberships = await this.chatService.getMyMemberships(me.id, ps.limit, ps.sinceId, ps.untilId);
|
||||
|
||||
return this.chatEntityService.packRoomMemberships(memberships, me, {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
await this.chatService.leaveRoom(me.id, ps.roomId);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const room = await this.chatService.findRoomById(ps.roomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
await this.chatService.muteRoom(me.id, ps.roomId, ps.mute);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatService: ChatService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const rooms = await this.chatService.getOwnedRoomsWithPagination(me.id, ps.limit, ps.sinceId, ps.untilId);
|
||||
return this.chatEntityService.packRooms(rooms, me);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'read');
|
||||
|
||||
const room = await this.chatService.findRoomById(ps.roomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private chatEntityService: ChatEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
await this.chatService.checkChatAvailability(me.id, 'write');
|
||||
|
||||
const room = await this.chatService.findMyRoomById(me.id, ps.roomId);
|
||||
if (room == null) {
|
||||
throw new ApiError(meta.errors.noSuchRoom);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ class GlobalTimelineChannel extends Channel {
|
|||
if (note.visibility !== 'public') return;
|
||||
if (note.channelId != null) return;
|
||||
if (note.user.requireSigninToViewContents && this.user == null) return;
|
||||
if (note.renote && note.renote.user.requireSigninToViewContents && this.user == null) return;
|
||||
if (note.reply && note.reply.user.requireSigninToViewContents && this.user == null) return;
|
||||
|
||||
if (isRenotePacked(note) && !isQuotePacked(note) && !this.withRenotes) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ class LocalTimelineChannel extends Channel {
|
|||
if (note.visibility !== 'public') return;
|
||||
if (note.channelId != null) return;
|
||||
if (note.user.requireSigninToViewContents && this.user == null) return;
|
||||
if (note.renote && note.renote.user.requireSigninToViewContents && this.user == null) return;
|
||||
if (note.reply && note.reply.user.requireSigninToViewContents && this.user == null) return;
|
||||
|
||||
// 関係ない返信は除外
|
||||
if (note.reply && this.user && !this.following[note.userId]?.withReplies && !this.withReplies) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue