summaryrefslogtreecommitdiff
path: root/packages/backend
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend')
-rw-r--r--packages/backend/migration/1675557528704-role-icon-badge.js13
-rw-r--r--packages/backend/src/core/DownloadService.ts1
-rw-r--r--packages/backend/src/core/RoleService.ts13
-rw-r--r--packages/backend/src/core/entities/RoleEntityService.ts2
-rw-r--r--packages/backend/src/core/entities/UserEntityService.ts6
-rw-r--r--packages/backend/src/models/entities/Role.ts11
-rw-r--r--packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts6
-rw-r--r--packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts4
-rw-r--r--packages/backend/src/server/FileServerService.ts4
-rw-r--r--packages/backend/src/server/api/endpoints/admin/roles/create.ts6
-rw-r--r--packages/backend/src/server/api/endpoints/admin/roles/update.ts6
-rw-r--r--packages/backend/src/server/api/endpoints/notes/favorites/create.ts4
12 files changed, 73 insertions, 3 deletions
diff --git a/packages/backend/migration/1675557528704-role-icon-badge.js b/packages/backend/migration/1675557528704-role-icon-badge.js
new file mode 100644
index 0000000000..0ebca088e3
--- /dev/null
+++ b/packages/backend/migration/1675557528704-role-icon-badge.js
@@ -0,0 +1,13 @@
+export class roleIconBadge1675557528704 {
+ name = 'roleIconBadge1675557528704'
+
+ async up(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "role" ADD "iconUrl" character varying(512)`);
+ await queryRunner.query(`ALTER TABLE "role" ADD "asBadge" boolean NOT NULL DEFAULT false`);
+ }
+
+ async down(queryRunner) {
+ await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "asBadge"`);
+ await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "iconUrl"`);
+ }
+}
diff --git a/packages/backend/src/core/DownloadService.ts b/packages/backend/src/core/DownloadService.ts
index a971e06fd8..852c1f32e3 100644
--- a/packages/backend/src/core/DownloadService.ts
+++ b/packages/backend/src/core/DownloadService.ts
@@ -60,6 +60,7 @@ export class DownloadService {
retry: {
limit: 0,
},
+ enableUnixSockets: false,
}).on('response', (res: Got.Response) => {
if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !this.config.proxy && res.ip) {
if (this.isPrivateIp(res.ip)) {
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index f8f9231cdd..d15d8c0aee 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -202,6 +202,19 @@ export class RoleService implements OnApplicationShutdown {
return [...assignedRoles, ...matchedCondRoles];
}
+ /**
+ * 指定ユーザーのバッジロール一覧取得
+ */
+ @bindThis
+ public async getUserBadgeRoles(userId: User['id']) {
+ const assigns = await this.roleAssignmentByUserIdCache.fetch(userId, () => this.roleAssignmentsRepository.findBy({ userId }));
+ const assignedRoleIds = assigns.map(x => x.roleId);
+ const roles = await this.rolesCache.fetch(null, () => this.rolesRepository.findBy({}));
+ const assignedBadgeRoles = roles.filter(r => r.asBadge && assignedRoleIds.includes(r.id));
+ // コンディショナルロールも含めるのは負荷高そうだから一旦無し
+ return assignedBadgeRoles;
+ }
+
@bindThis
public async getUserPolicies(userId: User['id'] | null): Promise<RolePolicies> {
const meta = await this.metaService.fetch();
diff --git a/packages/backend/src/core/entities/RoleEntityService.ts b/packages/backend/src/core/entities/RoleEntityService.ts
index 52f3374468..dbb89ff19b 100644
--- a/packages/backend/src/core/entities/RoleEntityService.ts
+++ b/packages/backend/src/core/entities/RoleEntityService.ts
@@ -56,11 +56,13 @@ export class RoleEntityService {
name: role.name,
description: role.description,
color: role.color,
+ iconUrl: role.iconUrl,
target: role.target,
condFormula: role.condFormula,
isPublic: role.isPublic,
isAdministrator: role.isAdministrator,
isModerator: role.isModerator,
+ asBadge: role.asBadge,
canEditMembersByModerator: role.canEditMembersByModerator,
policies: policies,
usersCount: assigns.length,
diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index ff42c07359..eea9d5567d 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -415,6 +415,11 @@ export class UserEntityService implements OnModuleInit {
} : undefined) : undefined,
emojis: this.customEmojiService.populateEmojis(user.emojis, user.host),
onlineStatus: this.getOnlineStatus(user),
+ // パフォーマンス上の理由でローカルユーザーのみ
+ badgeRoles: user.host == null ? this.roleService.getUserBadgeRoles(user.id).then(rs => rs.map(r => ({
+ name: r.name,
+ iconUrl: r.iconUrl,
+ }))) : undefined,
...(opts.detail ? {
url: profile!.url,
@@ -454,6 +459,7 @@ export class UserEntityService implements OnModuleInit {
id: role.id,
name: role.name,
color: role.color,
+ iconUrl: role.iconUrl,
description: role.description,
isModerator: role.isModerator,
isAdministrator: role.isAdministrator,
diff --git a/packages/backend/src/models/entities/Role.ts b/packages/backend/src/models/entities/Role.ts
index abd5f864a2..8cf6811863 100644
--- a/packages/backend/src/models/entities/Role.ts
+++ b/packages/backend/src/models/entities/Role.ts
@@ -102,6 +102,11 @@ export class Role {
})
public color: string | null;
+ @Column('varchar', {
+ length: 512, nullable: true,
+ })
+ public iconUrl: string | null;
+
@Column('enum', {
enum: ['manual', 'conditional'],
default: 'manual',
@@ -118,6 +123,12 @@ export class Role {
})
public isPublic: boolean;
+ // trueの場合ユーザー名の横にバッジとして表示
+ @Column('boolean', {
+ default: false,
+ })
+ public asBadge: boolean;
+
@Column('boolean', {
default: false,
})
diff --git a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts
index 87b23f1891..df024a8f3c 100644
--- a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts
@@ -12,9 +12,9 @@ import type Logger from '@/logger.js';
import { DriveService } from '@/core/DriveService.js';
import { createTemp, createTempDir } from '@/misc/create-temp.js';
import { DownloadService } from '@/core/DownloadService.js';
+import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type Bull from 'bull';
-import { bindThis } from '@/decorators.js';
@Injectable()
export class ExportCustomEmojisProcessorService {
@@ -82,6 +82,10 @@ export class ExportCustomEmojisProcessorService {
});
for (const emoji of customEmojis) {
+ if (!/^[a-zA-Z0-9_]+$/.test(emoji.name)) {
+ this.logger.error(`invalid emoji name: ${emoji.name}`);
+ continue;
+ }
const ext = mime.extension(emoji.type ?? 'image/png');
const fileName = emoji.name + (ext ? '.' + ext : '');
const emojiPath = path + '/' + fileName;
diff --git a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
index 0061c2a8f7..2d43615e25 100644
--- a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
@@ -81,6 +81,10 @@ export class ImportCustomEmojisProcessorService {
for (const record of meta.emojis) {
if (!record.downloaded) continue;
+ if (!/^[a-zA-Z0-9_]+?([a-zA-Z0-9\.]+)?$/.test(record.fileName)) {
+ this.logger.error(`invalid filename: ${record.fileName}`);
+ continue;
+ }
const emojiInfo = record.emoji;
const emojiPath = outputPath + '/' + record.fileName;
await this.emojisRepository.delete({
diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts
index 39bc4c1d96..4bd6d0f556 100644
--- a/packages/backend/src/server/FileServerService.ts
+++ b/packages/backend/src/server/FileServerService.ts
@@ -146,6 +146,8 @@ export class FileServerService {
const url = new URL(`${this.config.mediaProxy}/static.webp`);
url.searchParams.set('url', file.url);
url.searchParams.set('static', '1');
+
+ file.cleanup();
return await reply.redirect(301, url.toString());
} else if (file.mime.startsWith('video/')) {
image = await this.videoProcessingService.generateVideoThumbnail(file.path);
@@ -158,6 +160,8 @@ export class FileServerService {
const url = new URL(`${this.config.mediaProxy}/svg.webp`);
url.searchParams.set('url', file.url);
+
+ file.cleanup();
return await reply.redirect(301, url.toString());
}
}
diff --git a/packages/backend/src/server/api/endpoints/admin/roles/create.ts b/packages/backend/src/server/api/endpoints/admin/roles/create.ts
index f136c6d624..1a2a9fb747 100644
--- a/packages/backend/src/server/api/endpoints/admin/roles/create.ts
+++ b/packages/backend/src/server/api/endpoints/admin/roles/create.ts
@@ -19,11 +19,13 @@ export const paramDef = {
name: { type: 'string' },
description: { type: 'string' },
color: { type: 'string', nullable: true },
+ iconUrl: { type: 'string', nullable: true },
target: { type: 'string' },
condFormula: { type: 'object' },
isPublic: { type: 'boolean' },
isModerator: { type: 'boolean' },
isAdministrator: { type: 'boolean' },
+ asBadge: { type: 'boolean' },
canEditMembersByModerator: { type: 'boolean' },
policies: {
type: 'object',
@@ -33,11 +35,13 @@ export const paramDef = {
'name',
'description',
'color',
+ 'iconUrl',
'target',
'condFormula',
'isPublic',
'isModerator',
'isAdministrator',
+ 'asBadge',
'canEditMembersByModerator',
'policies',
],
@@ -64,11 +68,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
name: ps.name,
description: ps.description,
color: ps.color,
+ iconUrl: ps.iconUrl,
target: ps.target,
condFormula: ps.condFormula,
isPublic: ps.isPublic,
isAdministrator: ps.isAdministrator,
isModerator: ps.isModerator,
+ asBadge: ps.asBadge,
canEditMembersByModerator: ps.canEditMembersByModerator,
policies: ps.policies,
}).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0]));
diff --git a/packages/backend/src/server/api/endpoints/admin/roles/update.ts b/packages/backend/src/server/api/endpoints/admin/roles/update.ts
index fc4c3d8f11..c9f4a9fed8 100644
--- a/packages/backend/src/server/api/endpoints/admin/roles/update.ts
+++ b/packages/backend/src/server/api/endpoints/admin/roles/update.ts
@@ -27,11 +27,13 @@ export const paramDef = {
name: { type: 'string' },
description: { type: 'string' },
color: { type: 'string', nullable: true },
+ iconUrl: { type: 'string', nullable: true },
target: { type: 'string' },
condFormula: { type: 'object' },
isPublic: { type: 'boolean' },
isModerator: { type: 'boolean' },
isAdministrator: { type: 'boolean' },
+ asBadge: { type: 'boolean' },
canEditMembersByModerator: { type: 'boolean' },
policies: {
type: 'object',
@@ -42,11 +44,13 @@ export const paramDef = {
'name',
'description',
'color',
+ 'iconUrl',
'target',
'condFormula',
'isPublic',
'isModerator',
'isAdministrator',
+ 'asBadge',
'canEditMembersByModerator',
'policies',
],
@@ -73,11 +77,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
name: ps.name,
description: ps.description,
color: ps.color,
+ iconUrl: ps.iconUrl,
target: ps.target,
condFormula: ps.condFormula,
isPublic: ps.isPublic,
isModerator: ps.isModerator,
isAdministrator: ps.isAdministrator,
+ asBadge: ps.asBadge,
canEditMembersByModerator: ps.canEditMembersByModerator,
policies: ps.policies,
});
diff --git a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts
index e423f0f109..0ce80a1a63 100644
--- a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts
+++ b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts
@@ -5,8 +5,8 @@ import { IdService } from '@/core/IdService.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { GetterService } from '@/server/api/GetterService.js';
import { DI } from '@/di-symbols.js';
-import { ApiError } from '../../../error.js';
import { AchievementService } from '@/core/AchievementService.js';
+import { ApiError } from '../../../error.js';
export const meta = {
tags: ['notes', 'favorites'],
@@ -79,7 +79,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
userId: me.id,
});
- if (note.userHost == null) {
+ if (note.userHost == null && note.userId !== me.id) {
this.achievementService.create(note.userId, 'myNoteFavorited1');
}
});