refactor/perf(backend): provide metadata statically (#14601)
* wip * Update ReactionService.ts * Update ApiCallService.ts * Update timeline.ts * Update GlobalModule.ts * Update GlobalModule.ts * Update NoteEntityService.ts * wip * wip * wip * Update ApPersonService.ts * wip * Update GlobalModule.ts * Update mock-resolver.ts * Update RoleService.ts * Update activitypub.ts * Update activitypub.ts * Update activitypub.ts * Update activitypub.ts * Update activitypub.ts * clean up * Update utils.ts * Update UtilityService.ts * Revert "Update utils.ts" This reverts commita27d4be764
. * Revert "Update UtilityService.ts" This reverts commite5fd9e004c
. * vuwa- * Revert "vuwa-" This reverts commit0c3bd12472
. * Update entry.ts * Update entry.ts * Update entry.ts * Update entry.ts * Update jest.setup.ts
This commit is contained in:
@@ -13,7 +13,7 @@ import fastifyRawBody from 'fastify-raw-body';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import type { EmojisRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
||||
import type { EmojisRepository, MiMeta, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
@@ -21,7 +21,6 @@ import { genIdenticon } from '@/misc/gen-identicon.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { ActivityPubServerService } from './ActivityPubServerService.js';
|
||||
import { NodeinfoServerService } from './NodeinfoServerService.js';
|
||||
import { ApiServerService } from './api/ApiServerService.js';
|
||||
@@ -44,6 +43,9 @@ export class ServerService implements OnApplicationShutdown {
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.meta)
|
||||
private meta: MiMeta,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@@ -53,7 +55,6 @@ export class ServerService implements OnApplicationShutdown {
|
||||
@Inject(DI.emojisRepository)
|
||||
private emojisRepository: EmojisRepository,
|
||||
|
||||
private metaService: MetaService,
|
||||
private userEntityService: UserEntityService,
|
||||
private apiServerService: ApiServerService,
|
||||
private openApiServerService: OpenApiServerService,
|
||||
@@ -193,7 +194,7 @@ export class ServerService implements OnApplicationShutdown {
|
||||
reply.header('Content-Type', 'image/png');
|
||||
reply.header('Cache-Control', 'public, max-age=86400');
|
||||
|
||||
if ((await this.metaService.fetch()).enableIdenticonGeneration) {
|
||||
if (this.meta.enableIdenticonGeneration) {
|
||||
return await genIdenticon(request.params.x);
|
||||
} else {
|
||||
return reply.redirect('/static-assets/avatar.png');
|
||||
|
@@ -13,8 +13,7 @@ import { getIpHash } from '@/misc/get-ip-hash.js';
|
||||
import type { MiLocalUser, MiUser } from '@/models/User.js';
|
||||
import type { MiAccessToken } from '@/models/AccessToken.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import type { UserIpsRepository } from '@/models/_.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import type { MiMeta, UserIpsRepository } from '@/models/_.js';
|
||||
import { createTemp } from '@/misc/create-temp.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
@@ -40,13 +39,15 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||
private userIpHistoriesClearIntervalId: NodeJS.Timeout;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private meta: MiMeta,
|
||||
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.userIpsRepository)
|
||||
private userIpsRepository: UserIpsRepository,
|
||||
|
||||
private metaService: MetaService,
|
||||
private authenticateService: AuthenticateService,
|
||||
private rateLimiterService: RateLimiterService,
|
||||
private roleService: RoleService,
|
||||
@@ -265,9 +266,8 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async logIp(request: FastifyRequest, user: MiLocalUser) {
|
||||
const meta = await this.metaService.fetch();
|
||||
if (!meta.enableIpLogging) return;
|
||||
private logIp(request: FastifyRequest, user: MiLocalUser) {
|
||||
if (!this.meta.enableIpLogging) return;
|
||||
const ip = request.ip;
|
||||
const ips = this.userIpHistories.get(user.id);
|
||||
if (ips == null || !ips.has(ip)) {
|
||||
|
@@ -7,9 +7,8 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { IsNull } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, MiRegistrationTicket } from '@/models/_.js';
|
||||
import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, MiRegistrationTicket, MiMeta } from '@/models/_.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { CaptchaService } from '@/core/CaptchaService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { SignupService } from '@/core/SignupService.js';
|
||||
@@ -28,6 +27,9 @@ export class SignupApiService {
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.meta)
|
||||
private meta: MiMeta,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@@ -45,7 +47,6 @@ export class SignupApiService {
|
||||
|
||||
private userEntityService: UserEntityService,
|
||||
private idService: IdService,
|
||||
private metaService: MetaService,
|
||||
private captchaService: CaptchaService,
|
||||
private signupService: SignupService,
|
||||
private signinService: SigninService,
|
||||
@@ -72,31 +73,29 @@ export class SignupApiService {
|
||||
) {
|
||||
const body = request.body;
|
||||
|
||||
const instance = await this.metaService.fetch(true);
|
||||
|
||||
// Verify *Captcha
|
||||
// ただしテスト時はこの機構は障害となるため無効にする
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
if (instance.enableHcaptcha && instance.hcaptchaSecretKey) {
|
||||
await this.captchaService.verifyHcaptcha(instance.hcaptchaSecretKey, body['hcaptcha-response']).catch(err => {
|
||||
if (this.meta.enableHcaptcha && this.meta.hcaptchaSecretKey) {
|
||||
await this.captchaService.verifyHcaptcha(this.meta.hcaptchaSecretKey, body['hcaptcha-response']).catch(err => {
|
||||
throw new FastifyReplyError(400, err);
|
||||
});
|
||||
}
|
||||
|
||||
if (instance.enableMcaptcha && instance.mcaptchaSecretKey && instance.mcaptchaSitekey && instance.mcaptchaInstanceUrl) {
|
||||
await this.captchaService.verifyMcaptcha(instance.mcaptchaSecretKey, instance.mcaptchaSitekey, instance.mcaptchaInstanceUrl, body['m-captcha-response']).catch(err => {
|
||||
if (this.meta.enableMcaptcha && this.meta.mcaptchaSecretKey && this.meta.mcaptchaSitekey && this.meta.mcaptchaInstanceUrl) {
|
||||
await this.captchaService.verifyMcaptcha(this.meta.mcaptchaSecretKey, this.meta.mcaptchaSitekey, this.meta.mcaptchaInstanceUrl, body['m-captcha-response']).catch(err => {
|
||||
throw new FastifyReplyError(400, err);
|
||||
});
|
||||
}
|
||||
|
||||
if (instance.enableRecaptcha && instance.recaptchaSecretKey) {
|
||||
await this.captchaService.verifyRecaptcha(instance.recaptchaSecretKey, body['g-recaptcha-response']).catch(err => {
|
||||
if (this.meta.enableRecaptcha && this.meta.recaptchaSecretKey) {
|
||||
await this.captchaService.verifyRecaptcha(this.meta.recaptchaSecretKey, body['g-recaptcha-response']).catch(err => {
|
||||
throw new FastifyReplyError(400, err);
|
||||
});
|
||||
}
|
||||
|
||||
if (instance.enableTurnstile && instance.turnstileSecretKey) {
|
||||
await this.captchaService.verifyTurnstile(instance.turnstileSecretKey, body['turnstile-response']).catch(err => {
|
||||
if (this.meta.enableTurnstile && this.meta.turnstileSecretKey) {
|
||||
await this.captchaService.verifyTurnstile(this.meta.turnstileSecretKey, body['turnstile-response']).catch(err => {
|
||||
throw new FastifyReplyError(400, err);
|
||||
});
|
||||
}
|
||||
@@ -108,7 +107,7 @@ export class SignupApiService {
|
||||
const invitationCode = body['invitationCode'];
|
||||
const emailAddress = body['emailAddress'];
|
||||
|
||||
if (instance.emailRequiredForSignup) {
|
||||
if (this.meta.emailRequiredForSignup) {
|
||||
if (emailAddress == null || typeof emailAddress !== 'string') {
|
||||
reply.code(400);
|
||||
return;
|
||||
@@ -123,7 +122,7 @@ export class SignupApiService {
|
||||
|
||||
let ticket: MiRegistrationTicket | null = null;
|
||||
|
||||
if (instance.disableRegistration) {
|
||||
if (this.meta.disableRegistration) {
|
||||
if (invitationCode == null || typeof invitationCode !== 'string') {
|
||||
reply.code(400);
|
||||
return;
|
||||
@@ -144,7 +143,7 @@ export class SignupApiService {
|
||||
}
|
||||
|
||||
// メアド認証が有効の場合
|
||||
if (instance.emailRequiredForSignup) {
|
||||
if (this.meta.emailRequiredForSignup) {
|
||||
// メアド認証済みならエラー
|
||||
if (ticket.usedBy) {
|
||||
reply.code(400);
|
||||
@@ -162,7 +161,7 @@ export class SignupApiService {
|
||||
}
|
||||
}
|
||||
|
||||
if (instance.emailRequiredForSignup) {
|
||||
if (this.meta.emailRequiredForSignup) {
|
||||
if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) {
|
||||
throw new FastifyReplyError(400, 'DUPLICATED_USERNAME');
|
||||
}
|
||||
@@ -172,7 +171,7 @@ export class SignupApiService {
|
||||
throw new FastifyReplyError(400, 'USED_USERNAME');
|
||||
}
|
||||
|
||||
const isPreserved = instance.preservedUsernames.map(x => x.toLowerCase()).includes(username.toLowerCase());
|
||||
const isPreserved = this.meta.preservedUsernames.map(x => x.toLowerCase()).includes(username.toLowerCase());
|
||||
if (isPreserved) {
|
||||
throw new FastifyReplyError(400, 'DENIED_USERNAME');
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
@@ -12,7 +12,6 @@ import { isActor, isPost, getApId } from '@/core/activitypub/type.js';
|
||||
import type { SchemaType } from '@/misc/json-schema.js';
|
||||
import { ApResolverService } from '@/core/activitypub/ApResolverService.js';
|
||||
import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
|
||||
import { ApNoteService } from '@/core/activitypub/models/ApNoteService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
@@ -20,6 +19,8 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
import { MiMeta } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['federation'],
|
||||
@@ -88,10 +89,12 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
private utilityService: UtilityService,
|
||||
private userEntityService: UserEntityService,
|
||||
private noteEntityService: NoteEntityService,
|
||||
private metaService: MetaService,
|
||||
private apResolverService: ApResolverService,
|
||||
private apDbResolverService: ApDbResolverService,
|
||||
private apPersonService: ApPersonService,
|
||||
@@ -112,9 +115,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
*/
|
||||
@bindThis
|
||||
private async fetchAny(uri: string, me: MiLocalUser | null | undefined): Promise<SchemaType<typeof meta['res']> | null> {
|
||||
// ブロックしてたら中断
|
||||
const fetchedMeta = await this.metaService.fetch();
|
||||
if (this.utilityService.isBlockedHost(fetchedMeta.blockedHosts, this.utilityService.extractDbHost(uri))) return null;
|
||||
// ブロックしてたら中断
|
||||
if (this.utilityService.isBlockedHost(this.serverSettings.blockedHosts, this.utilityService.extractDbHost(uri))) return null;
|
||||
|
||||
let local = await this.mergePack(me, ...await Promise.all([
|
||||
this.apDbResolverService.getUserFromApId(uri),
|
||||
|
@@ -5,14 +5,12 @@
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { ChannelsRepository, NotesRepository } from '@/models/_.js';
|
||||
import type { ChannelsRepository, MiMeta, NotesRepository } from '@/models/_.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import ActiveUsersChart from '@/core/chart/charts/active-users.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
||||
import { MiLocalUser } from '@/models/User.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
@@ -58,6 +56,9 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@@ -68,16 +69,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
private noteEntityService: NoteEntityService,
|
||||
private queryService: QueryService,
|
||||
private fanoutTimelineEndpointService: FanoutTimelineEndpointService,
|
||||
private cacheService: CacheService,
|
||||
private activeUsersChart: ActiveUsersChart,
|
||||
private metaService: MetaService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
|
||||
const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null);
|
||||
|
||||
const serverSettings = await this.metaService.fetch();
|
||||
|
||||
const channel = await this.channelsRepository.findOneBy({
|
||||
id: ps.channelId,
|
||||
});
|
||||
@@ -88,7 +85,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
if (me) this.activeUsersChart.read(me);
|
||||
|
||||
if (!serverSettings.enableFanoutTimeline) {
|
||||
if (!this.serverSettings.enableFanoutTimeline) {
|
||||
return await this.noteEntityService.packMany(await this.getFromDb({ untilId, sinceId, limit: ps.limit, channelId: channel.id }, me), me);
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,6 @@
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
|
||||
@@ -41,14 +40,10 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
private driveFileEntityService: DriveFileEntityService,
|
||||
private roleService: RoleService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const instance = await this.metaService.fetch(true);
|
||||
|
||||
// Calculate drive usage
|
||||
const usage = await this.driveFileEntityService.calcDriveUsageOf(me.id);
|
||||
|
||||
const policies = await this.roleService.getUserPolicies(me.id);
|
||||
|
@@ -4,14 +4,15 @@
|
||||
*/
|
||||
|
||||
import ms from 'ms';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/const.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { DriveService } from '@/core/DriveService.js';
|
||||
import { ApiError } from '../../../error.js';
|
||||
import { MiMeta } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['drive'],
|
||||
@@ -73,8 +74,10 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
private driveFileEntityService: DriveFileEntityService,
|
||||
private metaService: MetaService,
|
||||
private driveService: DriveService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me, _, file, cleanup, ip, headers) => {
|
||||
@@ -91,8 +94,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
}
|
||||
}
|
||||
|
||||
const instance = await this.metaService.fetch();
|
||||
|
||||
try {
|
||||
// Create file
|
||||
const driveFile = await this.driveService.addFile({
|
||||
@@ -103,8 +104,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
folderId: ps.folderId,
|
||||
force: ps.force,
|
||||
sensitive: ps.isSensitive,
|
||||
requestIp: instance.enableIpLogging ? ip : null,
|
||||
requestHeaders: instance.enableIpLogging ? headers : null,
|
||||
requestIp: this.serverSettings.enableIpLogging ? ip : null,
|
||||
requestHeaders: this.serverSettings.enableIpLogging ? headers : null,
|
||||
});
|
||||
return await this.driveFileEntityService.pack(driveFile, { self: true });
|
||||
} catch (err) {
|
||||
|
@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||
import ms from 'ms';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UserProfilesRepository } from '@/models/_.js';
|
||||
import type { MiMeta, UserProfilesRepository } from '@/models/_.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { EmailService } from '@/core/EmailService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
@@ -15,7 +15,6 @@ import { DI } from '@/di-symbols.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
||||
import { UserAuthService } from '@/core/UserAuthService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
export const meta = {
|
||||
@@ -70,10 +69,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.userProfilesRepository)
|
||||
private userProfilesRepository: UserProfilesRepository,
|
||||
|
||||
private metaService: MetaService,
|
||||
private userEntityService: UserEntityService,
|
||||
private emailService: EmailService,
|
||||
private userAuthService: UserAuthService,
|
||||
@@ -105,7 +106,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
if (!res.available) {
|
||||
throw new ApiError(meta.errors.unavailable);
|
||||
}
|
||||
} else if ((await this.metaService.fetch()).emailRequiredForSignup) {
|
||||
} else if (this.serverSettings.emailRequiredForSignup) {
|
||||
throw new ApiError(meta.errors.emailRequired);
|
||||
}
|
||||
|
||||
|
@@ -17,8 +17,6 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { NoteCreateService } from '@/core/NoteCreateService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { isQuote, isRenote } from '@/misc/is-renote.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Brackets } from 'typeorm';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository, ChannelFollowingsRepository } from '@/models/_.js';
|
||||
import type { NotesRepository, ChannelFollowingsRepository, MiMeta } from '@/models/_.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import ActiveUsersChart from '@/core/chart/charts/active-users.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
@@ -16,7 +16,6 @@ import { CacheService } from '@/core/CacheService.js';
|
||||
import { FanoutTimelineName } from '@/core/FanoutTimelineService.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { MiLocalUser } from '@/models/User.js';
|
||||
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
@@ -74,6 +73,9 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@@ -87,7 +89,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
private cacheService: CacheService,
|
||||
private queryService: QueryService,
|
||||
private userFollowingService: UserFollowingService,
|
||||
private metaService: MetaService,
|
||||
private fanoutTimelineEndpointService: FanoutTimelineEndpointService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
@@ -101,9 +102,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles);
|
||||
|
||||
const serverSettings = await this.metaService.fetch();
|
||||
|
||||
if (!serverSettings.enableFanoutTimeline) {
|
||||
if (!this.serverSettings.enableFanoutTimeline) {
|
||||
const timeline = await this.getFromDb({
|
||||
untilId,
|
||||
sinceId,
|
||||
@@ -156,7 +155,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
allowPartial: ps.allowPartial,
|
||||
me,
|
||||
redisTimelines: timelineConfig,
|
||||
useDbFallback: serverSettings.enableFanoutTimelineDbFallback,
|
||||
useDbFallback: this.serverSettings.enableFanoutTimelineDbFallback,
|
||||
alwaysIncludeMyNotes: true,
|
||||
excludePureRenotes: !ps.withRenotes,
|
||||
noteFilter: note => {
|
||||
|
@@ -5,16 +5,14 @@
|
||||
|
||||
import { Brackets } from 'typeorm';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/_.js';
|
||||
import type { MiMeta, NotesRepository } from '@/models/_.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import ActiveUsersChart from '@/core/chart/charts/active-users.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { MiLocalUser } from '@/models/User.js';
|
||||
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
@@ -66,6 +64,9 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@@ -73,10 +74,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
private roleService: RoleService,
|
||||
private activeUsersChart: ActiveUsersChart,
|
||||
private idService: IdService,
|
||||
private cacheService: CacheService,
|
||||
private fanoutTimelineEndpointService: FanoutTimelineEndpointService,
|
||||
private queryService: QueryService,
|
||||
private metaService: MetaService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
|
||||
@@ -89,9 +88,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles);
|
||||
|
||||
const serverSettings = await this.metaService.fetch();
|
||||
|
||||
if (!serverSettings.enableFanoutTimeline) {
|
||||
if (!this.serverSettings.enableFanoutTimeline) {
|
||||
const timeline = await this.getFromDb({
|
||||
untilId,
|
||||
sinceId,
|
||||
@@ -115,7 +112,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
limit: ps.limit,
|
||||
allowPartial: ps.allowPartial,
|
||||
me,
|
||||
useDbFallback: serverSettings.enableFanoutTimelineDbFallback,
|
||||
useDbFallback: this.serverSettings.enableFanoutTimelineDbFallback,
|
||||
redisTimelines:
|
||||
ps.withFiles ? ['localTimelineWithFiles']
|
||||
: ps.withReplies ? ['localTimeline', 'localTimelineWithReplies']
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Brackets } from 'typeorm';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository, ChannelFollowingsRepository } from '@/models/_.js';
|
||||
import type { NotesRepository, ChannelFollowingsRepository, MiMeta } from '@/models/_.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import ActiveUsersChart from '@/core/chart/charts/active-users.js';
|
||||
@@ -15,7 +15,6 @@ import { IdService } from '@/core/IdService.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
||||
import { MiLocalUser } from '@/models/User.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
||||
|
||||
export const meta = {
|
||||
@@ -56,6 +55,9 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@@ -69,15 +71,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
private fanoutTimelineEndpointService: FanoutTimelineEndpointService,
|
||||
private userFollowingService: UserFollowingService,
|
||||
private queryService: QueryService,
|
||||
private metaService: MetaService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
|
||||
const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null);
|
||||
|
||||
const serverSettings = await this.metaService.fetch();
|
||||
|
||||
if (!serverSettings.enableFanoutTimeline) {
|
||||
if (!this.serverSettings.enableFanoutTimeline) {
|
||||
const timeline = await this.getFromDb({
|
||||
untilId,
|
||||
sinceId,
|
||||
@@ -108,7 +107,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
limit: ps.limit,
|
||||
allowPartial: ps.allowPartial,
|
||||
me,
|
||||
useDbFallback: serverSettings.enableFanoutTimelineDbFallback,
|
||||
useDbFallback: this.serverSettings.enableFanoutTimelineDbFallback,
|
||||
redisTimelines: ps.withFiles ? [`homeTimelineWithFiles:${me.id}`] : [`homeTimeline:${me.id}`],
|
||||
alwaysIncludeMyNotes: true,
|
||||
excludePureRenotes: !ps.withRenotes,
|
||||
|
@@ -4,14 +4,15 @@
|
||||
*/
|
||||
|
||||
import { URLSearchParams } from 'node:url';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||
import { GetterService } from '@/server/api/GetterService.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
import { MiMeta } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['notes'],
|
||||
@@ -59,9 +60,11 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
private noteEntityService: NoteEntityService,
|
||||
private getterService: GetterService,
|
||||
private metaService: MetaService,
|
||||
private httpRequestService: HttpRequestService,
|
||||
private roleService: RoleService,
|
||||
) {
|
||||
@@ -84,9 +87,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
return;
|
||||
}
|
||||
|
||||
const instance = await this.metaService.fetch();
|
||||
|
||||
if (instance.deeplAuthKey == null) {
|
||||
if (this.serverSettings.deeplAuthKey == null) {
|
||||
throw new ApiError(meta.errors.unavailable);
|
||||
}
|
||||
|
||||
@@ -94,11 +95,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
if (targetLang.includes('-')) targetLang = targetLang.split('-')[0];
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('auth_key', instance.deeplAuthKey);
|
||||
params.append('auth_key', this.serverSettings.deeplAuthKey);
|
||||
params.append('text', note.text);
|
||||
params.append('target_lang', targetLang);
|
||||
|
||||
const endpoint = instance.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate';
|
||||
const endpoint = this.serverSettings.deeplIsPro ? 'https://api.deepl.com/v2/translate' : 'https://api-free.deepl.com/v2/translate';
|
||||
|
||||
const res = await this.httpRequestService.send(endpoint, {
|
||||
method: 'POST',
|
||||
|
@@ -5,16 +5,14 @@
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Brackets } from 'typeorm';
|
||||
import type { MiUserList, NotesRepository, UserListMembershipsRepository, UserListsRepository } from '@/models/_.js';
|
||||
import type { MiMeta, MiUserList, NotesRepository, UserListMembershipsRepository, UserListsRepository } from '@/models/_.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import ActiveUsersChart from '@/core/chart/charts/active-users.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { MiLocalUser } from '@/models/User.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
@@ -69,6 +67,9 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@@ -80,11 +81,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
private noteEntityService: NoteEntityService,
|
||||
private activeUsersChart: ActiveUsersChart,
|
||||
private cacheService: CacheService,
|
||||
private idService: IdService,
|
||||
private fanoutTimelineEndpointService: FanoutTimelineEndpointService,
|
||||
private queryService: QueryService,
|
||||
private metaService: MetaService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
|
||||
@@ -99,9 +98,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
throw new ApiError(meta.errors.noSuchList);
|
||||
}
|
||||
|
||||
const serverSettings = await this.metaService.fetch();
|
||||
|
||||
if (!serverSettings.enableFanoutTimeline) {
|
||||
if (!this.serverSettings.enableFanoutTimeline) {
|
||||
const timeline = await this.getFromDb(list, {
|
||||
untilId,
|
||||
sinceId,
|
||||
@@ -124,7 +121,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
limit: ps.limit,
|
||||
allowPartial: ps.allowPartial,
|
||||
me,
|
||||
useDbFallback: serverSettings.enableFanoutTimelineDbFallback,
|
||||
useDbFallback: this.serverSettings.enableFanoutTimelineDbFallback,
|
||||
redisTimelines: ps.withFiles ? [`userListTimelineWithFiles:${list.id}`] : [`userListTimeline:${list.id}`],
|
||||
alwaysIncludeMyNotes: true,
|
||||
excludePureRenotes: !ps.withRenotes,
|
||||
|
@@ -5,11 +5,10 @@
|
||||
|
||||
import { IsNull } from 'typeorm';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import type { MiMeta, UsersRepository } from '@/models/_.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
@@ -38,16 +37,16 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
private metaService: MetaService,
|
||||
private userEntityService: UserEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const meta = await this.metaService.fetch();
|
||||
|
||||
const users = await Promise.all(meta.pinnedUsers.map(acct => Acct.parse(acct)).map(acct => this.usersRepository.findOneBy({
|
||||
const users = await Promise.all(this.serverSettings.pinnedUsers.map(acct => Acct.parse(acct)).map(acct => this.usersRepository.findOneBy({
|
||||
usernameLower: acct.username.toLowerCase(),
|
||||
host: acct.host ?? IsNull(),
|
||||
})));
|
||||
|
@@ -5,9 +5,10 @@
|
||||
|
||||
import * as os from 'node:os';
|
||||
import si from 'systeminformation';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { MiMeta } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: false,
|
||||
@@ -73,10 +74,11 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private metaService: MetaService,
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
) {
|
||||
super(meta, paramDef, async () => {
|
||||
if (!(await this.metaService.fetch()).enableServerMachineStats) return {
|
||||
if (!this.serverSettings.enableServerMachineStats) return {
|
||||
machine: '?',
|
||||
cpu: {
|
||||
model: '?',
|
||||
|
@@ -5,9 +5,8 @@
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import type { SwSubscriptionsRepository } from '@/models/_.js';
|
||||
import type { MiMeta, SwSubscriptionsRepository } from '@/models/_.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { PushNotificationService } from '@/core/PushNotificationService.js';
|
||||
|
||||
@@ -62,11 +61,13 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.swSubscriptionsRepository)
|
||||
private swSubscriptionsRepository: SwSubscriptionsRepository,
|
||||
|
||||
private idService: IdService,
|
||||
private metaService: MetaService,
|
||||
private pushNotificationService: PushNotificationService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
@@ -78,12 +79,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
publickey: ps.publickey,
|
||||
});
|
||||
|
||||
const instance = await this.metaService.fetch(true);
|
||||
|
||||
if (exist != null) {
|
||||
return {
|
||||
state: 'already-subscribed' as const,
|
||||
key: instance.swPublicKey,
|
||||
key: this.serverSettings.swPublicKey,
|
||||
userId: me.id,
|
||||
endpoint: exist.endpoint,
|
||||
sendReadMessage: exist.sendReadMessage,
|
||||
@@ -103,7 +102,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
return {
|
||||
state: 'subscribed' as const,
|
||||
key: instance.swPublicKey,
|
||||
key: this.serverSettings.swPublicKey,
|
||||
userId: me.id,
|
||||
endpoint: ps.endpoint,
|
||||
sendReadMessage: ps.sendReadMessage,
|
||||
|
@@ -5,11 +5,10 @@
|
||||
|
||||
import { IsNull } from 'typeorm';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { UsedUsernamesRepository, UsersRepository } from '@/models/_.js';
|
||||
import type { MiMeta, UsedUsernamesRepository, UsersRepository } from '@/models/_.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { localUsernameSchema } from '@/models/User.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['users'],
|
||||
@@ -39,13 +38,14 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@Inject(DI.usedUsernamesRepository)
|
||||
private usedUsernamesRepository: UsedUsernamesRepository,
|
||||
|
||||
private metaService: MetaService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const exist = await this.usersRepository.countBy({
|
||||
@@ -55,8 +55,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
const exist2 = await this.usedUsernamesRepository.countBy({ username: ps.username.toLowerCase() });
|
||||
|
||||
const meta = await this.metaService.fetch();
|
||||
const isPreserved = meta.preservedUsernames.map(x => x.toLowerCase()).includes(ps.username.toLowerCase());
|
||||
const isPreserved = this.serverSettings.preservedUsernames.map(x => x.toLowerCase()).includes(ps.username.toLowerCase());
|
||||
|
||||
return {
|
||||
available: exist === 0 && exist2 === 0 && !isPreserved,
|
||||
|
@@ -5,14 +5,13 @@
|
||||
|
||||
import { Brackets } from 'typeorm';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { NotesRepository } from '@/models/_.js';
|
||||
import type { MiMeta, NotesRepository } from '@/models/_.js';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { MiLocalUser } from '@/models/User.js';
|
||||
import { FanoutTimelineEndpointService } from '@/core/FanoutTimelineEndpointService.js';
|
||||
import { FanoutTimelineName } from '@/core/FanoutTimelineService.js';
|
||||
@@ -67,6 +66,9 @@ export const paramDef = {
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
|
||||
@@ -75,15 +77,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
private cacheService: CacheService,
|
||||
private idService: IdService,
|
||||
private fanoutTimelineEndpointService: FanoutTimelineEndpointService,
|
||||
private metaService: MetaService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null);
|
||||
const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null);
|
||||
const isSelf = me && (me.id === ps.userId);
|
||||
|
||||
const serverSettings = await this.metaService.fetch();
|
||||
|
||||
if (ps.withReplies && ps.withFiles) throw new ApiError(meta.errors.bothWithRepliesAndWithFiles);
|
||||
|
||||
// early return if me is blocked by requesting user
|
||||
@@ -94,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
}
|
||||
}
|
||||
|
||||
if (!serverSettings.enableFanoutTimeline) {
|
||||
if (!this.serverSettings.enableFanoutTimeline) {
|
||||
const timeline = await this.getFromDb({
|
||||
untilId,
|
||||
sinceId,
|
||||
|
@@ -24,7 +24,6 @@ import type { Config } from '@/config.js';
|
||||
import { getNoteSummary } from '@/misc/get-note-summary.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import type {
|
||||
DbQueue,
|
||||
DeliverQueue,
|
||||
@@ -73,6 +72,9 @@ export class ClientServerService {
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.meta)
|
||||
private meta: MiMeta,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
@@ -109,7 +111,6 @@ export class ClientServerService {
|
||||
private clipEntityService: ClipEntityService,
|
||||
private channelEntityService: ChannelEntityService,
|
||||
private reversiGameEntityService: ReversiGameEntityService,
|
||||
private metaService: MetaService,
|
||||
private urlPreviewService: UrlPreviewService,
|
||||
private feedService: FeedService,
|
||||
private roleService: RoleService,
|
||||
@@ -129,32 +130,30 @@ export class ClientServerService {
|
||||
|
||||
@bindThis
|
||||
private async manifestHandler(reply: FastifyReply) {
|
||||
const instance = await this.metaService.fetch(true);
|
||||
|
||||
let manifest = {
|
||||
// 空文字列の場合右辺を使いたいため
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
'short_name': instance.shortName || instance.name || this.config.host,
|
||||
'short_name': this.meta.shortName || this.meta.name || this.config.host,
|
||||
// 空文字列の場合右辺を使いたいため
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
'name': instance.name || this.config.host,
|
||||
'name': this.meta.name || this.config.host,
|
||||
'start_url': '/',
|
||||
'display': 'standalone',
|
||||
'background_color': '#313a42',
|
||||
// 空文字列の場合右辺を使いたいため
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
'theme_color': instance.themeColor || '#86b300',
|
||||
'theme_color': this.meta.themeColor || '#86b300',
|
||||
'icons': [{
|
||||
// 空文字列の場合右辺を使いたいため
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
'src': instance.app192IconUrl || '/static-assets/icons/192.png',
|
||||
'src': this.meta.app192IconUrl || '/static-assets/icons/192.png',
|
||||
'sizes': '192x192',
|
||||
'type': 'image/png',
|
||||
'purpose': 'maskable',
|
||||
}, {
|
||||
// 空文字列の場合右辺を使いたいため
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
'src': instance.app512IconUrl || '/static-assets/icons/512.png',
|
||||
'src': this.meta.app512IconUrl || '/static-assets/icons/512.png',
|
||||
'sizes': '512x512',
|
||||
'type': 'image/png',
|
||||
'purpose': 'maskable',
|
||||
@@ -178,7 +177,7 @@ export class ClientServerService {
|
||||
|
||||
manifest = {
|
||||
...manifest,
|
||||
...JSON.parse(instance.manifestJsonOverride === '' ? '{}' : instance.manifestJsonOverride),
|
||||
...JSON.parse(this.meta.manifestJsonOverride === '' ? '{}' : this.meta.manifestJsonOverride),
|
||||
};
|
||||
|
||||
reply.header('Cache-Control', 'max-age=300');
|
||||
@@ -453,9 +452,7 @@ export class ClientServerService {
|
||||
|
||||
// OpenSearch XML
|
||||
fastify.get('/opensearch.xml', async (request, reply) => {
|
||||
const meta = await this.metaService.fetch();
|
||||
|
||||
const name = meta.name ?? 'Misskey';
|
||||
const name = this.meta.name ?? 'Misskey';
|
||||
let content = '';
|
||||
content += '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">';
|
||||
content += `<ShortName>${name}</ShortName>`;
|
||||
@@ -472,14 +469,13 @@ export class ClientServerService {
|
||||
//#endregion
|
||||
|
||||
const renderBase = async (reply: FastifyReply, data: { [key: string]: any } = {}) => {
|
||||
const meta = await this.metaService.fetch();
|
||||
reply.header('Cache-Control', 'public, max-age=30');
|
||||
return await reply.view('base', {
|
||||
img: meta.bannerUrl,
|
||||
img: this.meta.bannerUrl,
|
||||
url: this.config.url,
|
||||
title: meta.name ?? 'Misskey',
|
||||
desc: meta.description,
|
||||
...await this.generateCommonPugData(meta),
|
||||
title: this.meta.name ?? 'Misskey',
|
||||
desc: this.meta.description,
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
...data,
|
||||
});
|
||||
};
|
||||
@@ -557,7 +553,6 @@ export class ClientServerService {
|
||||
|
||||
if (user != null) {
|
||||
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id });
|
||||
const meta = await this.metaService.fetch();
|
||||
const me = profile.fields
|
||||
? profile.fields
|
||||
.filter(filed => filed.value != null && filed.value.match(/^https?:/))
|
||||
@@ -573,7 +568,7 @@ export class ClientServerService {
|
||||
user, profile, me,
|
||||
avatarUrl: user.avatarUrl ?? this.userEntityService.getIdenticonUrl(user),
|
||||
sub: request.params.sub,
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
// リモートユーザーなので
|
||||
@@ -611,7 +606,6 @@ 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');
|
||||
@@ -623,7 +617,7 @@ export class ClientServerService {
|
||||
avatarUrl: _note.user.avatarUrl,
|
||||
// TODO: Let locale changeable by instance setting
|
||||
summary: getNoteSummary(_note),
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
return await renderBase(reply);
|
||||
@@ -648,7 +642,6 @@ 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 {
|
||||
@@ -662,7 +655,7 @@ export class ClientServerService {
|
||||
page: _page,
|
||||
profile,
|
||||
avatarUrl: _page.user.avatarUrl,
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
return await renderBase(reply);
|
||||
@@ -678,7 +671,6 @@ 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');
|
||||
@@ -688,7 +680,7 @@ export class ClientServerService {
|
||||
flash: _flash,
|
||||
profile,
|
||||
avatarUrl: _flash.user.avatarUrl,
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
return await renderBase(reply);
|
||||
@@ -704,7 +696,6 @@ 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');
|
||||
@@ -714,7 +705,7 @@ export class ClientServerService {
|
||||
clip: _clip,
|
||||
profile,
|
||||
avatarUrl: _clip.user.avatarUrl,
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
return await renderBase(reply);
|
||||
@@ -728,7 +719,6 @@ export class ClientServerService {
|
||||
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');
|
||||
@@ -738,7 +728,7 @@ export class ClientServerService {
|
||||
post: _post,
|
||||
profile,
|
||||
avatarUrl: _post.user.avatarUrl,
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
return await renderBase(reply);
|
||||
@@ -753,11 +743,10 @@ export class ClientServerService {
|
||||
|
||||
if (channel) {
|
||||
const _channel = await this.channelEntityService.pack(channel);
|
||||
const meta = await this.metaService.fetch();
|
||||
reply.header('Cache-Control', 'public, max-age=15');
|
||||
return await reply.view('channel', {
|
||||
channel: _channel,
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
return await renderBase(reply);
|
||||
@@ -772,11 +761,10 @@ export class ClientServerService {
|
||||
|
||||
if (game) {
|
||||
const _game = await this.reversiGameEntityService.packDetail(game);
|
||||
const meta = await this.metaService.fetch();
|
||||
reply.header('Cache-Control', 'public, max-age=3600');
|
||||
return await reply.view('reversi-game', {
|
||||
game: _game,
|
||||
...await this.generateCommonPugData(meta),
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
} else {
|
||||
return await renderBase(reply);
|
||||
@@ -798,26 +786,22 @@ export class ClientServerService {
|
||||
|
||||
//#region embed pages
|
||||
fastify.get('/embed/*', async (request, reply) => {
|
||||
const meta = await this.metaService.fetch();
|
||||
|
||||
reply.removeHeader('X-Frame-Options');
|
||||
|
||||
reply.header('Cache-Control', 'public, max-age=3600');
|
||||
return await reply.view('base-embed', {
|
||||
title: meta.name ?? 'Misskey',
|
||||
...await this.generateCommonPugData(meta),
|
||||
title: this.meta.name ?? 'Misskey',
|
||||
...await this.generateCommonPugData(this.meta),
|
||||
});
|
||||
});
|
||||
|
||||
fastify.get('/_info_card_', async (request, reply) => {
|
||||
const meta = await this.metaService.fetch(true);
|
||||
|
||||
reply.removeHeader('X-Frame-Options');
|
||||
|
||||
return await reply.view('info-card', {
|
||||
version: this.config.version,
|
||||
host: this.config.host,
|
||||
meta: meta,
|
||||
meta: this.meta,
|
||||
originalUsersCount: await this.usersRepository.countBy({ host: IsNull() }),
|
||||
originalNotesCount: await this.notesRepository.countBy({ userHost: IsNull() }),
|
||||
});
|
||||
|
@@ -8,7 +8,6 @@ import { summaly } from '@misskey-dev/summaly';
|
||||
import { SummalyResult } from '@misskey-dev/summaly/built/summary.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { MetaService } from '@/core/MetaService.js';
|
||||
import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import { query } from '@/misc/prelude/url.js';
|
||||
@@ -26,7 +25,9 @@ export class UrlPreviewService {
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
private metaService: MetaService,
|
||||
@Inject(DI.meta)
|
||||
private meta: MiMeta,
|
||||
|
||||
private httpRequestService: HttpRequestService,
|
||||
private loggerService: LoggerService,
|
||||
) {
|
||||
@@ -62,9 +63,7 @@ export class UrlPreviewService {
|
||||
return;
|
||||
}
|
||||
|
||||
const meta = await this.metaService.fetch();
|
||||
|
||||
if (!meta.urlPreviewEnabled) {
|
||||
if (!this.meta.urlPreviewEnabled) {
|
||||
reply.code(403);
|
||||
return {
|
||||
error: new ApiError({
|
||||
@@ -75,14 +74,14 @@ export class UrlPreviewService {
|
||||
};
|
||||
}
|
||||
|
||||
this.logger.info(meta.urlPreviewSummaryProxyUrl
|
||||
this.logger.info(this.meta.urlPreviewSummaryProxyUrl
|
||||
? `(Proxy) Getting preview of ${url}@${lang} ...`
|
||||
: `Getting preview of ${url}@${lang} ...`);
|
||||
|
||||
try {
|
||||
const summary = meta.urlPreviewSummaryProxyUrl
|
||||
? await this.fetchSummaryFromProxy(url, meta, lang)
|
||||
: await this.fetchSummary(url, meta, lang);
|
||||
const summary = this.meta.urlPreviewSummaryProxyUrl
|
||||
? await this.fetchSummaryFromProxy(url, this.meta, lang)
|
||||
: await this.fetchSummary(url, this.meta, lang);
|
||||
|
||||
this.logger.succ(`Got preview of ${url}: ${summary.title}`);
|
||||
|
||||
|
Reference in New Issue
Block a user