feat: 凍結されたユーザーのコンテンツを見えないようにする (MisskeyIO#134)

ついでにEntityServiceの型定義、meのoptionalをやめる
This commit is contained in:
まっちゃとーにゅ
2023-08-08 20:13:05 +09:00
committed by GitHub
parent 3b73874196
commit 7f0acd3ea4
70 changed files with 742 additions and 325 deletions

View File

@@ -71,7 +71,7 @@ export class NodeinfoServerService {
const activeHalfyear = null;
const activeMonth = null;
const proxyAccount = meta.proxyAccountId ? await this.userEntityService.pack(meta.proxyAccountId).catch(() => null) : null;
const proxyAccount = meta.proxyAccountId ? await this.userEntityService.pack(meta.proxyAccountId, null).catch(() => null) : null;
const basePolicies = { ...DEFAULT_POLICIES, ...meta.policies };

View File

@@ -12,6 +12,7 @@ import { MetaService } from '@/core/MetaService.js';
import { createTemp } from '@/misc/create-temp.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import { ApiError } from './error.js';
import { RateLimiterService } from './RateLimiterService.js';
import { ApiLoggerService } from './ApiLoggerService.js';
@@ -356,7 +357,7 @@ export class ApiCallService implements OnApplicationShutdown {
// API invoking
return await ep.exec(data, user, token, file, request.ip, request.headers).catch((err: Error) => {
if (err instanceof ApiError || err instanceof AuthenticationError) {
if (err instanceof ApiError || err instanceof IdentifiableError || err instanceof AuthenticationError) {
throw err;
} else {
const errId = randomUUID();

View File

@@ -155,7 +155,7 @@ export class ApiServerService {
return {
ok: true,
token: token.token,
user: await this.userEntityService.pack(token.userId, null, { detail: true }),
user: await this.userEntityService.pack(token.userId, { id: token.userId }, { detail: true }),
};
} else {
return {

View File

@@ -117,7 +117,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const reports = await query.limit(ps.limit).getMany();
return await this.abuseUserReportEntityService.packMany(reports);
return await this.abuseUserReportEntityService.packMany(reports, me);
});
}
}

View File

@@ -78,7 +78,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const files = await query.limit(ps.limit).getMany();
return await this.driveFileEntityService.packMany(files, { detail: true, withUser: true, self: true });
return await this.driveFileEntityService.packMany(files, me, { detail: true, withUser: true, self: true });
});
}
}

View File

@@ -76,7 +76,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const reports = await query.limit(ps.limit).getMany();
return await this.moderationLogEntityService.packMany(reports);
return await this.moderationLogEntityService.packMany(reports, me);
});
}
}

View File

@@ -61,7 +61,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
secret: secret,
}).then(x => this.appsRepository.findOneByOrFail(x.identifiers[0]));
return await this.appEntityService.pack(app, null, {
return await this.appEntityService.pack(app, me, {
detail: true,
includeSecret: true,
});

View File

@@ -110,7 +110,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
return {
accessToken: accessToken.token,
user: await this.userEntityService.pack(session.userId, null, {
user: await this.userEntityService.pack(session.userId, me, {
detail: true,
}),
};

View File

@@ -75,7 +75,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const files = await query.limit(ps.limit).getMany();
return await this.driveFileEntityService.packMany(files, { detail: false, self: true });
return await this.driveFileEntityService.packMany(files, me, { detail: false, self: true });
});
}
}

View File

@@ -108,7 +108,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
requestIp: instance.enableIpLogging ? ip : null,
requestHeaders: instance.enableIpLogging ? headers : null,
});
return await this.driveFileEntityService.pack(driveFile, { self: true });
return await this.driveFileEntityService.pack(driveFile, me, { self: true });
} catch (err) {
if (err instanceof Error || typeof err === 'string') {
console.error(err);

View File

@@ -47,7 +47,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
userId: me.id,
});
return await this.driveFileEntityService.packMany(files, { self: true });
return await this.driveFileEntityService.packMany(files, me, { self: true });
});
}
}

View File

@@ -50,7 +50,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
folderId: ps.folderId ?? IsNull(),
});
return await Promise.all(files.map(file => this.driveFileEntityService.pack(file, { self: true })));
return await Promise.all(files.map(file => this.driveFileEntityService.pack(file, me, { self: true })));
});
}
}

View File

@@ -84,7 +84,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
throw new ApiError(meta.errors.accessDenied);
}
return await this.driveFileEntityService.pack(file, {
return await this.driveFileEntityService.pack(file, me, {
detail: true,
withUser: true,
self: true,

View File

@@ -129,7 +129,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
isSensitive: file.isSensitive,
});
const fileObj = await this.driveFileEntityService.pack(file, { self: true });
const fileObj = await this.driveFileEntityService.pack(file, me, { self: true });
// Publish fileUpdated event
this.globalEventService.publishDriveStream(me.id, 'fileUpdated', fileObj);

View File

@@ -51,7 +51,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
) {
super(meta, paramDef, async (ps, user, _1, _2, _3, ip, headers) => {
this.driveService.uploadFromUrl({ url: ps.url, user, folderId: ps.folderId, sensitive: ps.isSensitive, force: ps.force, comment: ps.comment, requestIp: ip, requestHeaders: headers }).then(file => {
this.driveFileEntityService.pack(file, { self: true }).then(packedFile => {
this.driveFileEntityService.pack(file, user, { self: true }).then(packedFile => {
this.globalEventService.publishMainStream(user.id, 'urlUploadFinished', {
marker: ps.marker,
file: packedFile,

View File

@@ -58,7 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const files = await query.limit(ps.limit).getMany();
return await this.driveFileEntityService.packMany(files, { detail: false, self: true });
return await this.driveFileEntityService.packMany(files, me, { detail: false, self: true });
});
}
}

View File

@@ -60,7 +60,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
permissions: ps.permissions,
}).then(x => this.flashsRepository.findOneByOrFail(x.identifiers[0]));
return await this.flashEntityService.pack(flash);
return await this.flashEntityService.pack(flash, me);
});
}
}

View File

@@ -51,7 +51,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
.limit(ps.limit)
.getMany();
return await this.flashEntityService.packMany(flashs);
return await this.flashEntityService.packMany(flashs, me);
});
}
}

View File

@@ -67,7 +67,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
.limit(ps.limit)
.getMany();
return await Promise.all(requests.map(req => this.followRequestEntityService.pack(req)));
return await this.followRequestEntityService.packMany(requests, me);
});
}
}

View File

@@ -51,7 +51,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
.limit(ps.limit)
.getMany();
return await this.pageEntityService.packMany(pages);
return await this.pageEntityService.packMany(pages, me);
});
}
}

View File

@@ -341,7 +341,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
};
if (ps.detail) {
const proxyAccount = instance.proxyAccountId ? await this.userEntityService.pack(instance.proxyAccountId).catch(() => null) : null;
const proxyAccount = instance.proxyAccountId ? await this.userEntityService.pack(instance.proxyAccountId, null).catch(() => null) : null;
response.proxyAccountName = proxyAccount ? proxyAccount.username : null;
response.features = {

View File

@@ -81,7 +81,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const notes = await query.limit(ps.limit).getMany();
return await this.noteEntityService.packMany(notes);
return await this.noteEntityService.packMany(notes, me);
});
}
}

View File

@@ -117,7 +117,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
font: ps.font,
})).then(x => this.pagesRepository.findOneByOrFail(x.identifiers[0]));
return await this.pageEntityService.pack(page);
return await this.pageEntityService.pack(page, me);
});
}
}

View File

@@ -77,7 +77,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
// Pull the user
await this.userListJoiningsRepository.delete({ userListId: userList.id, userId: user.id });
this.globalEventService.publishUserListStream(userList.id, 'userRemoved', await this.userEntityService.pack(user));
this.globalEventService.publishUserListStream(userList.id, 'userRemoved', await this.userEntityService.pack(user, me));
});
}
}

View File

@@ -51,7 +51,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
.limit(ps.limit)
.getMany();
return await this.pageEntityService.packMany(pages);
return await this.pageEntityService.packMany(pages, me);
});
}
}

View File

@@ -1,7 +1,6 @@
import { randomUUID } from 'node:crypto';
import { randomUUID, randomBytes } from 'node:crypto';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { randomBytes } from 'node:crypto';
import { Inject, Injectable } from '@nestjs/common';
import { createBullBoard } from '@bull-board/api';
import { BullMQAdapter } from '@bull-board/api/bullMQAdapter.js';
@@ -33,6 +32,7 @@ import { deepClone } from '@/misc/clone.js';
import { bindThis } from '@/decorators.js';
import { FlashEntityService } from '@/core/entities/FlashEntityService.js';
import { RoleService } from '@/core/RoleService.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import manifest from './manifest.json' assert { type: 'json' };
import { FeedService } from './FeedService.js';
import { UrlPreviewService } from './UrlPreviewService.js';
@@ -201,7 +201,7 @@ export class ClientServerService {
const csp = this.config.contentSecurityPolicy
?? 'script-src \'self\' ' +
'https://challenges.cloudflare.com https://hcaptcha.com https://*.hcaptcha.com https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://www.recaptcha.net/recaptcha/ {scriptNonce}; ' +
'worker-src blob: \'self\'; ' +
'worker-src blob: \'self\'; ' +
'base-uri \'self\'; object-src \'self\'; report-uri /csp-error';
reply.header('Content-Security-Policy-Report-Only', csp.replace('{scriptNonce}', `'nonce-${scriptNonce}'`));
done();
@@ -489,22 +489,29 @@ export class ClientServerService {
});
if (note) {
const _note = await this.noteEntityService.pack(note);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: note.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
try {
const _note = await this.noteEntityService.pack(note, null);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: note.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
}
return await reply.view('note', {
note: _note,
profile,
avatarUrl: _note.user.avatarUrl,
// TODO: Let locale changeable by instance setting
summary: getNoteSummary(_note),
...this.generateCommonPugData(meta),
});
} catch (err) {
if ((err as IdentifiableError).id === '8ca4f428-b32e-4f83-ac43-406ed7cd0452') {
return await renderBase(reply);
}
throw err;
}
return await reply.view('note', {
note: _note,
profile,
avatarUrl: _note.user.avatarUrl,
// TODO: Let locale changeable by instance setting
summary: getNoteSummary(_note),
...this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
}
@@ -526,24 +533,31 @@ export class ClientServerService {
});
if (page) {
const _page = await this.pageEntityService.pack(page);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: page.userId });
const meta = await this.metaService.fetch();
if (['public'].includes(page.visibility)) {
reply.header('Cache-Control', 'public, max-age=15');
} else {
reply.header('Cache-Control', 'private, max-age=0, must-revalidate');
try {
const _page = await this.pageEntityService.pack(page, null);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: page.userId });
const meta = await this.metaService.fetch();
if (['public'].includes(page.visibility)) {
reply.header('Cache-Control', 'public, max-age=15');
} else {
reply.header('Cache-Control', 'private, max-age=0, must-revalidate');
}
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
}
return await reply.view('page', {
page: _page,
profile,
avatarUrl: _page.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} catch (err) {
if ((err as IdentifiableError).id === '8ca4f428-b32e-4f83-ac43-406ed7cd0452') {
return await renderBase(reply);
}
throw err;
}
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
}
return await reply.view('page', {
page: _page,
profile,
avatarUrl: _page.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
}
@@ -556,20 +570,27 @@ export class ClientServerService {
});
if (flash) {
const _flash = await this.flashEntityService.pack(flash);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: flash.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
try {
const _flash = await this.flashEntityService.pack(flash, null);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: flash.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
}
return await reply.view('flash', {
flash: _flash,
profile,
avatarUrl: _flash.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} catch (err) {
if ((err as IdentifiableError).id === '8ca4f428-b32e-4f83-ac43-406ed7cd0452') {
return await renderBase(reply);
}
throw err;
}
return await reply.view('flash', {
flash: _flash,
profile,
avatarUrl: _flash.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
}
@@ -582,20 +603,27 @@ export class ClientServerService {
});
if (clip && clip.isPublic) {
const _clip = await this.clipEntityService.pack(clip);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: clip.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
try {
const _clip = await this.clipEntityService.pack(clip, null);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: clip.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
}
return await reply.view('clip', {
clip: _clip,
profile,
avatarUrl: _clip.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} catch (err) {
if ((err as IdentifiableError).id === '8ca4f428-b32e-4f83-ac43-406ed7cd0452') {
return await renderBase(reply);
}
throw err;
}
return await reply.view('clip', {
clip: _clip,
profile,
avatarUrl: _clip.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
}
@@ -606,20 +634,27 @@ export class ClientServerService {
const post = await this.galleryPostsRepository.findOneBy({ id: request.params.post });
if (post) {
const _post = await this.galleryPostEntityService.pack(post);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: post.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
try {
const _post = await this.galleryPostEntityService.pack(post, null);
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: post.userId });
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
if (profile.preventAiLearning) {
reply.header('X-Robots-Tag', 'noimageai');
reply.header('X-Robots-Tag', 'noai');
}
return await reply.view('gallery-post', {
post: _post,
profile,
avatarUrl: _post.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} catch (err) {
if ((err as IdentifiableError).id === '8ca4f428-b32e-4f83-ac43-406ed7cd0452') {
return await renderBase(reply);
}
throw err;
}
return await reply.view('gallery-post', {
post: _post,
profile,
avatarUrl: _post.user.avatarUrl,
...this.generateCommonPugData(meta),
});
} else {
return await renderBase(reply);
}
@@ -632,7 +667,7 @@ export class ClientServerService {
});
if (channel) {
const _channel = await this.channelEntityService.pack(channel);
const _channel = await this.channelEntityService.pack(channel, null);
const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15');
return await reply.view('channel', {