Skip to content

Commit

Permalink
Merge pull request #711 from update-host
Browse files Browse the repository at this point in the history
2024.5.0-host.2c
  • Loading branch information
u1-liquid authored Aug 17, 2024
2 parents 154b622 + 6b66d9b commit b5e000e
Show file tree
Hide file tree
Showing 27 changed files with 268 additions and 90 deletions.
2 changes: 2 additions & 0 deletions locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,7 @@ failedToUpload: "Upload failed"
cannotUploadBecauseInappropriate: "This file could not be uploaded because parts of it have been detected as potentially inappropriate."
cannotUploadBecauseNoFreeSpace: "Upload failed due to lack of Drive capacity."
cannotUploadBecauseExceedsFileSizeLimit: "This file cannot be uploaded as it exceeds the file size limit."
cannotUploadBecauseTimeout: "The file could not be uploaded due to a connection timeout."
beta: "Beta"
enableAutoSensitive: "Automatic marking as sensitive"
enableAutoSensitiveDescription: "Allows automatic detection and marking of sensitive media through Machine Learning where possible. Even if this option is disabled, it may be enabled instance-wide."
Expand Down Expand Up @@ -2273,6 +2274,7 @@ _profile:
sectionName: "Section name"
sectionNameNoneDescription: "Do not display the section name"
sectionNameNone: "Section without name"
policyDisplayLimitExceeded: "The number of items displayed exceeds the current limit ({max}). This item will not be displayed."
_exportOrImport:
allNotes: "All notes"
favoritedNotes: "Favorite notes"
Expand Down
12 changes: 12 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3928,6 +3928,10 @@ export interface Locale extends ILocale {
* ファイルサイズの制限を超えているためアップロードできません。
*/
"cannotUploadBecauseExceedsFileSizeLimit": string;
/**
* 接続がタイムアウトしたため、ファイルをアップロードできませんでした。
*/
"cannotUploadBecauseTimeout": string;
/**
* ベータ
*/
Expand Down Expand Up @@ -5095,6 +5099,10 @@ export interface Locale extends ILocale {
* 相互リンク
*/
"mutualLink": string;
/**
* このファイルをドライブに保存する
*/
"saveThisFile": string;
"_bubbleGame": {
/**
* 遊び方
Expand Down Expand Up @@ -8862,6 +8870,10 @@ export interface Locale extends ILocale {
* 名前が表示されないセクション
*/
"sectionNameNone": string;
/**
* 表示上限({max}個)を超えているため、この項目は表示されません。
*/
"policyDisplayLimitExceeded": ParameterizedString<"max">;
};
"_exportOrImport": {
/**
Expand Down
3 changes: 3 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ failedToUpload: "アップロード失敗"
cannotUploadBecauseInappropriate: "不適切な内容を含む可能性があると判定されたためアップロードできません。"
cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためアップロードできません。"
cannotUploadBecauseExceedsFileSizeLimit: "ファイルサイズの制限を超えているためアップロードできません。"
cannotUploadBecauseTimeout: "接続がタイムアウトしたため、ファイルをアップロードできませんでした。"
beta: "ベータ"
enableAutoSensitive: "自動センシティブ判定"
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにセンシティブフラグを設定します。この機能をオフにしても、サーバーによっては自動で設定されることがあります。"
Expand Down Expand Up @@ -1269,6 +1270,7 @@ blockThisUser: "このユーザーをブロックする"
muteThisUser: "このユーザーをミュートする"
here: "こちら"
mutualLink: "相互リンク"
saveThisFile: "このファイルをドライブに保存する"

_bubbleGame:
howToPlay: "遊び方"
Expand Down Expand Up @@ -2329,6 +2331,7 @@ _profile:
sectionName: "セクション名"
sectionNameNoneDescription: "セクション名を表示しないようにする"
sectionNameNone: "名前が表示されないセクション"
policyDisplayLimitExceeded: "表示上限({max}個)を超えているため、この項目は表示されません。"

_exportOrImport:
allNotes: "全てのノート"
Expand Down
4 changes: 3 additions & 1 deletion locales/ko-KR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,7 @@ failedToUpload: "업로드 실패"
cannotUploadBecauseInappropriate: "이 파일은 부적절한 내용을 포함한다고 판단되어 업로드할 수 없습니다."
cannotUploadBecauseNoFreeSpace: "드라이브 용량이 부족하여 업로드할 수 없습니다."
cannotUploadBecauseExceedsFileSizeLimit: "파일 크기가 너무 크기 때문에 업로드할 수 없습니다."
cannotUploadBecauseTimeout: "접속 시간이 초과되어 파일을 업로드할 수 없습니다."
beta: "베타"
enableAutoSensitive: "자동 NSFW 탐지"
enableAutoSensitiveDescription: "이용 가능할 경우 기계학습을 통해 자동으로 미디어 NSFW를 설정합니다. 이 기능을 해제하더라도, 서버 정책에 따라 자동으로 설정될 수 있습니다."
Expand Down Expand Up @@ -2255,8 +2256,9 @@ _profile:
addMutualLink: "서로링크 추가"
addMutualLinkSection: "섹션 추가"
sectionName: "섹션 이름"
sectionNameNoneDescription: "섹션 이름이 표시되지 않도록 합니다."
sectionNameNoneDescription: "섹션 이름이 표시되지 않도록 합니다"
sectionNameNone: "이름이 표시되지 않는 섹션"
policyDisplayLimitExceeded: "표시 제한({max}개)을 초과하였기 때문에 이 항목은 표시되지 않습니다."
_exportOrImport:
allNotes: "모든 노트"
favoritedNotes: "즐겨찾기한 노트"
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "misskey",
"version": "2024.5.0-host.2b",
"version": "2024.5.0-host.2c",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/MisskeyIO/misskey.git"
},
"packageManager": "pnpm@9.1.2",
"packageManager": "pnpm@9.7.1",
"workspaces": [
"packages/frontend",
"packages/backend",
Expand Down
18 changes: 11 additions & 7 deletions packages/backend/src/core/ClipService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ export class ClipService {
throw new ClipService.NoSuchClipError();
}

if (await this.clipNotesRepository.existsBy({ clipId, noteId })) {
throw new ClipService.AlreadyAddedError();
}

const policies = await this.roleService.getUserPolicies(me.id);

const currentClipCount = await this.clipsRepository.countBy({
Expand All @@ -143,6 +147,13 @@ export class ClipService {
throw new ClipService.ClipLimitExceededError();
}

const currentNoteCount = await this.clipNotesRepository.countBy({
clipId: clip.id,
});
if (currentNoteCount >= policies.noteEachClipsLimit) {
throw new ClipService.TooManyClipNotesError();
}

const currentNoteCounts = await this.clipNotesRepository
.createQueryBuilder('cn')
.select('COUNT(*)')
Expand All @@ -154,13 +165,6 @@ export class ClipService {
throw new ClipService.ClipNotesLimitExceededError();
}

const currentNoteCount = await this.clipNotesRepository.countBy({
clipId: clip.id,
});
if (currentNoteCount >= policies.noteEachClipsLimit) {
throw new ClipService.TooManyClipNotesError();
}

try {
await this.clipNotesRepository.insert({
id: this.idService.gen(),
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/core/RoleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
rateLimitFactor: 1,
avatarDecorationLimit: 1,
mutualLinkSectionLimit: 1,
mutualLinkLimit: 15,
mutualLinkLimit: 3,
};

@Injectable()
Expand Down
64 changes: 61 additions & 3 deletions packages/backend/src/core/UserSuspendService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ import { bindThis } from '@/decorators.js';
import { DI } from '@/di-symbols.js';
import type Logger from '@/logger.js';
import type { MiUser } from '@/models/User.js';
import type { FollowingsRepository, FollowRequestsRepository } from '@/models/_.js';
import type {
AntennasRepository,
ClipNotesRepository,
ClipsRepository,
FollowingsRepository,
FollowRequestsRepository,
UserListMembershipsRepository,
UserListsRepository,
WebhooksRepository,
} from '@/models/_.js';
import { QueueService } from '@/core/QueueService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
Expand All @@ -30,6 +39,24 @@ export class UserSuspendService {
@Inject(DI.followRequestsRepository)
private followRequestsRepository: FollowRequestsRepository,

@Inject(DI.antennasRepository)
private antennasRepository: AntennasRepository,

@Inject(DI.webhooksRepository)
private webhooksRepository: WebhooksRepository,

@Inject(DI.userListsRepository)
private userListsRepository: UserListsRepository,

@Inject(DI.clipsRepository)
private clipsRepository: ClipsRepository,

@Inject(DI.clipNotesRepository)
private clipNotesRepository: ClipNotesRepository,

@Inject(DI.userListMembershipsRepository)
private userListMembershipsRepository: UserListMembershipsRepository,

private queueService: QueueService,
private globalEventService: GlobalEventService,
private apRendererService: ApRendererService,
Expand All @@ -45,10 +72,41 @@ export class UserSuspendService {

this.globalEventService.publishInternalEvent('userChangeSuspendedState', { id: user.id, isSuspended: true });

await Promise.all([
const promises: Promise<unknown>[] = [];

let cursor = '';
while (true) { // eslint-disable-line @typescript-eslint/no-unnecessary-condition, no-constant-condition
const clipNotes = await this.clipNotesRepository.createQueryBuilder('c')
.select('c.id')
.innerJoin('c.note', 'n')
.where('n.userId = :userId', { userId: user.id })
.andWhere('c.id > :cursor', { cursor })
.orderBy('c.id', 'ASC')
.limit(500)
.getRawMany<{ id: string }>();

if (clipNotes.length === 0) break;

cursor = clipNotes.at(-1)?.id ?? '';

promises.push(this.clipNotesRepository.createQueryBuilder()
.delete()
.where('id IN (:...ids)', { ids: clipNotes.map((clipNote) => clipNote.id) })
.execute());
}

await Promise.allSettled([
this.followRequestsRepository.delete({ followeeId: user.id }),
this.followRequestsRepository.delete({ followerId: user.id }),
]).catch(() => null);

this.antennasRepository.delete({ userId: user.id }),
this.webhooksRepository.delete({ userId: user.id }),
this.userListsRepository.delete({ userId: user.id }),
this.clipsRepository.delete({ userId: user.id }),

...promises,
this.userListMembershipsRepository.delete({ userId: user.id }),
]);

if (this.userEntityService.isLocalUser(user)) {
// 知り得る全SharedInboxにDelete配信
Expand Down
12 changes: 11 additions & 1 deletion packages/backend/src/core/activitypub/ApRendererService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,14 +466,24 @@ export class ApRendererService {
this.userProfilesRepository.findOneByOrFail({ userId: user.id }),
]);

const attachment = profile.fields.map(field => ({
const profileFields = profile.fields.map(field => ({
type: 'PropertyValue',
name: field.name,
value: (field.value.startsWith('http://') || field.value.startsWith('https://'))
? `<a href="${new URL(field.value).href}" rel="me nofollow noopener" target="_blank">${new URL(field.value).href}</a>`
: field.value,
}));

const mutualLinks = profile.mutualLinkSections.flatMap(section =>
section.mutualLinks.map(link => ({
type: 'PropertyValue',
name: section.name ?? link.description ?? 'Link',
value: `<a href="${link.url}" target="_blank">${link.description ?? link.url}</a>`,
})),
);

const attachment = mutualLinks.concat(profileFields);

const emojis = await this.getEmojis(user.emojis);
const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji));

Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/core/entities/UserEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ export class UserEntityService implements OnModuleInit {
lang: profile!.lang,
fields: profile!.fields,
verifiedLinks: profile!.verifiedLinks,
mutualLinkSections: profile!.mutualLinkSections,
mutualLinkSections: isMe ? profile!.mutualLinkSections : profile!.mutualLinkSections.slice(0, policies!.mutualLinkSectionLimit).map(section => ({ ...section, mutualLinks: section.mutualLinks.slice(0, policies!.mutualLinkLimit) })),
followersCount: followersCount ?? 0,
followingCount: followingCount ?? 0,
notesCount: user.notesCount,
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/models/UserProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export class MiUserProfile {
name: string | null;
mutualLinks: {
id: string;
url: string;
fileId: MiDriveFile['id'];
description: string | null;
imgSrc: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/models/json-schema/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ export const packedUserDetailedNotMeOnlySchema = {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
url: { type: 'string' },
url: { type: 'string', format: 'url' },
fileId: { type: 'string', format: 'misskey:id' },
description: { type: 'string', nullable: true },
imgSrc: { type: 'string' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { MetaService } from '@/core/MetaService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';

export const meta = {
tags: ['admin', 'role'],
Expand All @@ -33,12 +34,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
private metaService: MetaService,
private globalEventService: GlobalEventService,
private moderationLogService: ModerationLogService,
) {
super(meta, paramDef, async (ps) => {
super(meta, paramDef, async (ps, me) => {
const before = await this.metaService.fetch(true);

await this.metaService.update({
policies: ps.policies,
});
this.globalEventService.publishInternalEvent('policiesUpdated', ps.policies);

const after = await this.metaService.fetch(true);

this.globalEventService.publishInternalEvent('policiesUpdated', after.policies);
this.moderationLogService.log(me, 'updateServerSettings', {
before: before.policies,
after: after.policies,
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
itemId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
required: ['userId', 'itemId'],
} as const;

// eslint-disable-next-line import/no-default-export
Expand All @@ -43,7 +44,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}

await this.userProfilesRepository.update(user.id, {
mutualLinkSections: [],
mutualLinkSections: userProfile.mutualLinkSections.map(section => ({
...section,
mutualLinks: section.mutualLinks.filter(item => item.id !== ps.itemId),
})),
});

this.moderationLogService.log(me, 'unsetUserMutualLink', {
Expand Down
Loading

0 comments on commit b5e000e

Please sign in to comment.