wip
This commit is contained in:
		@@ -14,10 +14,10 @@ import type {
 | 
			
		||||
	AbuseReportNotificationRecipientRepository,
 | 
			
		||||
	MiAbuseReportNotificationRecipient,
 | 
			
		||||
	MiAbuseUserReport,
 | 
			
		||||
	MiMeta,
 | 
			
		||||
	MiUser,
 | 
			
		||||
} from '@/models/_.js';
 | 
			
		||||
import { EmailService } from '@/core/EmailService.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { RoleService } from '@/core/RoleService.js';
 | 
			
		||||
import { RecipientMethod } from '@/models/AbuseReportNotificationRecipient.js';
 | 
			
		||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
 | 
			
		||||
@@ -27,15 +27,19 @@ import { IdService } from './IdService.js';
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class AbuseReportNotificationService implements OnApplicationShutdown {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.abuseReportNotificationRecipientRepository)
 | 
			
		||||
		private abuseReportNotificationRecipientRepository: AbuseReportNotificationRecipientRepository,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.redisForSub)
 | 
			
		||||
		private redisForSub: Redis.Redis,
 | 
			
		||||
 | 
			
		||||
		private idService: IdService,
 | 
			
		||||
		private roleService: RoleService,
 | 
			
		||||
		private systemWebhookService: SystemWebhookService,
 | 
			
		||||
		private emailService: EmailService,
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private moderationLogService: ModerationLogService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
	) {
 | 
			
		||||
@@ -93,10 +97,8 @@ export class AbuseReportNotificationService implements OnApplicationShutdown {
 | 
			
		||||
			.filter(x => x != null),
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		// 送信先の鮮度を保つため、毎回取得する
 | 
			
		||||
		const meta = await this.metaService.fetch(true);
 | 
			
		||||
		recipientEMailAddresses.push(
 | 
			
		||||
			...(meta.email ? [meta.email] : []),
 | 
			
		||||
			...(this.meta.email ? [this.meta.email] : []),
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		if (recipientEMailAddresses.length <= 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ import { IsNull, In, MoreThan, Not } from 'typeorm';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js';
 | 
			
		||||
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, MutingsRepository, UserListMembershipsRepository, UsersRepository } from '@/models/_.js';
 | 
			
		||||
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, MiMeta, MutingsRepository, UserListMembershipsRepository, UsersRepository } from '@/models/_.js';
 | 
			
		||||
import type { RelationshipJobData, ThinUser } from '@/queue/types.js';
 | 
			
		||||
 | 
			
		||||
import { IdService } from '@/core/IdService.js';
 | 
			
		||||
@@ -22,13 +22,15 @@ import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
 | 
			
		||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
 | 
			
		||||
import { ProxyAccountService } from '@/core/ProxyAccountService.js';
 | 
			
		||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import InstanceChart from '@/core/chart/charts/instance.js';
 | 
			
		||||
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class AccountMoveService {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.usersRepository)
 | 
			
		||||
		private usersRepository: UsersRepository,
 | 
			
		||||
 | 
			
		||||
@@ -57,7 +59,6 @@ export class AccountMoveService {
 | 
			
		||||
		private perUserFollowingChart: PerUserFollowingChart,
 | 
			
		||||
		private federatedInstanceService: FederatedInstanceService,
 | 
			
		||||
		private instanceChart: InstanceChart,
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private relayService: RelayService,
 | 
			
		||||
		private queueService: QueueService,
 | 
			
		||||
	) {
 | 
			
		||||
@@ -276,7 +277,7 @@ export class AccountMoveService {
 | 
			
		||||
		if (this.userEntityService.isRemoteUser(oldAccount)) {
 | 
			
		||||
			this.federatedInstanceService.fetch(oldAccount.host).then(async i => {
 | 
			
		||||
				this.instancesRepository.decrement({ id: i.id }, 'followersCount', localFollowerIds.length);
 | 
			
		||||
				if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
 | 
			
		||||
				if (this.meta.enableChartsForFederatedInstances) {
 | 
			
		||||
					this.instanceChart.updateFollowers(i.host, false);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import { Brackets, In } from 'typeorm';
 | 
			
		||||
import { Injectable, Inject } from '@nestjs/common';
 | 
			
		||||
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/User.js';
 | 
			
		||||
import type { MiNote, IMentionedRemoteUsers } from '@/models/Note.js';
 | 
			
		||||
import type { InstancesRepository, NotesRepository, UsersRepository } from '@/models/_.js';
 | 
			
		||||
import type { InstancesRepository, MiMeta, NotesRepository, UsersRepository } from '@/models/_.js';
 | 
			
		||||
import { RelayService } from '@/core/RelayService.js';
 | 
			
		||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
@@ -19,9 +19,7 @@ import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
 | 
			
		||||
import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js';
 | 
			
		||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
 | 
			
		||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { SearchService } from '@/core/SearchService.js';
 | 
			
		||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
 | 
			
		||||
import { isQuote, isRenote } from '@/misc/is-renote.js';
 | 
			
		||||
@@ -32,6 +30,9 @@ export class NoteDeleteService {
 | 
			
		||||
		@Inject(DI.config)
 | 
			
		||||
		private config: Config,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.usersRepository)
 | 
			
		||||
		private usersRepository: UsersRepository,
 | 
			
		||||
 | 
			
		||||
@@ -42,13 +43,11 @@ export class NoteDeleteService {
 | 
			
		||||
		private instancesRepository: InstancesRepository,
 | 
			
		||||
 | 
			
		||||
		private userEntityService: UserEntityService,
 | 
			
		||||
		private noteEntityService: NoteEntityService,
 | 
			
		||||
		private globalEventService: GlobalEventService,
 | 
			
		||||
		private relayService: RelayService,
 | 
			
		||||
		private federatedInstanceService: FederatedInstanceService,
 | 
			
		||||
		private apRendererService: ApRendererService,
 | 
			
		||||
		private apDeliverManagerService: ApDeliverManagerService,
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private searchService: SearchService,
 | 
			
		||||
		private moderationLogService: ModerationLogService,
 | 
			
		||||
		private notesChart: NotesChart,
 | 
			
		||||
@@ -102,17 +101,15 @@ export class NoteDeleteService {
 | 
			
		||||
			}
 | 
			
		||||
			//#endregion
 | 
			
		||||
 | 
			
		||||
			const meta = await this.metaService.fetch();
 | 
			
		||||
 | 
			
		||||
			this.notesChart.update(note, false);
 | 
			
		||||
			if (meta.enableChartsForRemoteUser || (user.host == null)) {
 | 
			
		||||
			if (this.meta.enableChartsForRemoteUser || (user.host == null)) {
 | 
			
		||||
				this.perUserNotesChart.update(user, note, false);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (this.userEntityService.isRemoteUser(user)) {
 | 
			
		||||
				this.federatedInstanceService.fetch(user.host).then(async i => {
 | 
			
		||||
					this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1);
 | 
			
		||||
					if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
 | 
			
		||||
					if (this.meta.enableChartsForFederatedInstances) {
 | 
			
		||||
						this.instanceChart.updateNote(i.host, note, false);
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
 
 | 
			
		||||
@@ -4,26 +4,25 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import type { UsersRepository } from '@/models/_.js';
 | 
			
		||||
import type { MiMeta, UsersRepository } from '@/models/_.js';
 | 
			
		||||
import type { MiLocalUser } from '@/models/User.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class ProxyAccountService {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.usersRepository)
 | 
			
		||||
		private usersRepository: UsersRepository,
 | 
			
		||||
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
	) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
	public async fetch(): Promise<MiLocalUser | null> {
 | 
			
		||||
		const meta = await this.metaService.fetch();
 | 
			
		||||
		if (meta.proxyAccountId == null) return null;
 | 
			
		||||
		return await this.usersRepository.findOneByOrFail({ id: meta.proxyAccountId }) as MiLocalUser;
 | 
			
		||||
		if (this.meta.proxyAccountId == null) return null;
 | 
			
		||||
		return await this.usersRepository.findOneByOrFail({ id: this.meta.proxyAccountId }) as MiLocalUser;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import bcrypt from 'bcryptjs';
 | 
			
		||||
import { DataSource, IsNull } from 'typeorm';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import type { UsedUsernamesRepository, UsersRepository } from '@/models/_.js';
 | 
			
		||||
import type { MiMeta, UsedUsernamesRepository, UsersRepository } from '@/models/_.js';
 | 
			
		||||
import { MiUser } from '@/models/User.js';
 | 
			
		||||
import { MiUserProfile } from '@/models/UserProfile.js';
 | 
			
		||||
import { IdService } from '@/core/IdService.js';
 | 
			
		||||
@@ -20,7 +20,6 @@ import { InstanceActorService } from '@/core/InstanceActorService.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import UsersChart from '@/core/chart/charts/users.js';
 | 
			
		||||
import { UtilityService } from '@/core/UtilityService.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { UserService } from '@/core/UserService.js';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
@@ -29,6 +28,9 @@ export class SignupService {
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.usersRepository)
 | 
			
		||||
		private usersRepository: UsersRepository,
 | 
			
		||||
 | 
			
		||||
@@ -39,7 +41,6 @@ export class SignupService {
 | 
			
		||||
		private userService: UserService,
 | 
			
		||||
		private userEntityService: UserEntityService,
 | 
			
		||||
		private idService: IdService,
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private instanceActorService: InstanceActorService,
 | 
			
		||||
		private usersChart: UsersChart,
 | 
			
		||||
	) {
 | 
			
		||||
@@ -88,8 +89,7 @@ export class SignupService {
 | 
			
		||||
		const isTheFirstUser = !await this.instanceActorService.realLocalUsersPresent();
 | 
			
		||||
 | 
			
		||||
		if (!opts.ignorePreservedUsernames && !isTheFirstUser) {
 | 
			
		||||
			const instance = await this.metaService.fetch(true);
 | 
			
		||||
			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 Error('USED_USERNAME');
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,10 +12,9 @@ import {
 | 
			
		||||
} from '@simplewebauthn/server';
 | 
			
		||||
import { AttestationFormat, isoCBOR, isoUint8Array } from '@simplewebauthn/server/helpers';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import type { UserSecurityKeysRepository } from '@/models/_.js';
 | 
			
		||||
import type { MiMeta, UserSecurityKeysRepository } from '@/models/_.js';
 | 
			
		||||
import type { Config } from '@/config.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { MiUser } from '@/models/_.js';
 | 
			
		||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
 | 
			
		||||
import type {
 | 
			
		||||
@@ -23,7 +22,6 @@ import type {
 | 
			
		||||
	AuthenticatorTransportFuture,
 | 
			
		||||
	CredentialDeviceType,
 | 
			
		||||
	PublicKeyCredentialCreationOptionsJSON,
 | 
			
		||||
	PublicKeyCredentialDescriptorFuture,
 | 
			
		||||
	PublicKeyCredentialRequestOptionsJSON,
 | 
			
		||||
	RegistrationResponseJSON,
 | 
			
		||||
} from '@simplewebauthn/types';
 | 
			
		||||
@@ -31,33 +29,33 @@ import type {
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class WebAuthnService {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.redis)
 | 
			
		||||
		private redisClient: Redis.Redis,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.config)
 | 
			
		||||
		private config: Config,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.redis)
 | 
			
		||||
		private redisClient: Redis.Redis,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.userSecurityKeysRepository)
 | 
			
		||||
		private userSecurityKeysRepository: UserSecurityKeysRepository,
 | 
			
		||||
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
	) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
	public async getRelyingParty(): Promise<{ origin: string; rpId: string; rpName: string; rpIcon?: string; }> {
 | 
			
		||||
		const instance = await this.metaService.fetch();
 | 
			
		||||
	public getRelyingParty(): { origin: string; rpId: string; rpName: string; rpIcon?: string; } {
 | 
			
		||||
		return {
 | 
			
		||||
			origin: this.config.url,
 | 
			
		||||
			rpId: this.config.hostname,
 | 
			
		||||
			rpName: instance.name ?? this.config.host,
 | 
			
		||||
			rpIcon: instance.iconUrl ?? undefined,
 | 
			
		||||
			rpName: this.meta.name ?? this.config.host,
 | 
			
		||||
			rpIcon: this.meta.iconUrl ?? undefined,
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
	public async initiateRegistration(userId: MiUser['id'], userName: string, userDisplayName?: string): Promise<PublicKeyCredentialCreationOptionsJSON> {
 | 
			
		||||
		const relyingParty = await this.getRelyingParty();
 | 
			
		||||
		const relyingParty = this.getRelyingParty();
 | 
			
		||||
		const keys = await this.userSecurityKeysRepository.findBy({
 | 
			
		||||
			userId: userId,
 | 
			
		||||
		});
 | 
			
		||||
@@ -104,7 +102,7 @@ export class WebAuthnService {
 | 
			
		||||
 | 
			
		||||
		await this.redisClient.del(`webauthn:challenge:${userId}`);
 | 
			
		||||
 | 
			
		||||
		const relyingParty = await this.getRelyingParty();
 | 
			
		||||
		const relyingParty = this.getRelyingParty();
 | 
			
		||||
 | 
			
		||||
		let verification;
 | 
			
		||||
		try {
 | 
			
		||||
@@ -143,7 +141,7 @@ export class WebAuthnService {
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
	public async initiateAuthentication(userId: MiUser['id']): Promise<PublicKeyCredentialRequestOptionsJSON> {
 | 
			
		||||
		const relyingParty = await this.getRelyingParty();
 | 
			
		||||
		const relyingParty = this.getRelyingParty();
 | 
			
		||||
		const keys = await this.userSecurityKeysRepository.findBy({
 | 
			
		||||
			userId: userId,
 | 
			
		||||
		});
 | 
			
		||||
@@ -209,7 +207,7 @@ export class WebAuthnService {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const relyingParty = await this.getRelyingParty();
 | 
			
		||||
		const relyingParty = this.getRelyingParty();
 | 
			
		||||
 | 
			
		||||
		let verification;
 | 
			
		||||
		try {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,9 @@
 | 
			
		||||
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import type { DriveFilesRepository } from '@/models/_.js';
 | 
			
		||||
import type { DriveFilesRepository, MiMeta } from '@/models/_.js';
 | 
			
		||||
import type { MiRemoteUser } from '@/models/User.js';
 | 
			
		||||
import type { MiDriveFile } from '@/models/DriveFile.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { truncate } from '@/misc/truncate.js';
 | 
			
		||||
import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/const.js';
 | 
			
		||||
import { DriveService } from '@/core/DriveService.js';
 | 
			
		||||
@@ -24,10 +23,12 @@ export class ApImageService {
 | 
			
		||||
	private logger: Logger;
 | 
			
		||||
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.driveFilesRepository)
 | 
			
		||||
		private driveFilesRepository: DriveFilesRepository,
 | 
			
		||||
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private apResolverService: ApResolverService,
 | 
			
		||||
		private driveService: DriveService,
 | 
			
		||||
		private apLoggerService: ApLoggerService,
 | 
			
		||||
@@ -63,12 +64,10 @@ export class ApImageService {
 | 
			
		||||
 | 
			
		||||
		this.logger.info(`Creating the Image: ${image.url}`);
 | 
			
		||||
 | 
			
		||||
		const instance = await this.metaService.fetch();
 | 
			
		||||
 | 
			
		||||
		// Cache if remote file cache is on AND either
 | 
			
		||||
		// 1. remote sensitive file is also on
 | 
			
		||||
		// 2. or the image is not sensitive
 | 
			
		||||
		const shouldBeCached = instance.cacheRemoteFiles && (instance.cacheRemoteSensitiveFiles || !image.sensitive);
 | 
			
		||||
		const shouldBeCached = this.meta.cacheRemoteFiles && (this.meta.cacheRemoteSensitiveFiles || !image.sensitive);
 | 
			
		||||
 | 
			
		||||
		const file = await this.driveService.uploadFromUrl({
 | 
			
		||||
			url: image.url,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,9 @@
 | 
			
		||||
 | 
			
		||||
import { Injectable, Inject } from '@nestjs/common';
 | 
			
		||||
import { DataSource } from 'typeorm';
 | 
			
		||||
import type { FollowingsRepository, InstancesRepository } from '@/models/_.js';
 | 
			
		||||
import type { FollowingsRepository, InstancesRepository, MiMeta } from '@/models/_.js';
 | 
			
		||||
import { AppLockService } from '@/core/AppLockService.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import Chart from '../core.js';
 | 
			
		||||
import { ChartLoggerService } from '../ChartLoggerService.js';
 | 
			
		||||
@@ -24,13 +23,15 @@ export default class FederationChart extends Chart<typeof schema> { // eslint-di
 | 
			
		||||
		@Inject(DI.db)
 | 
			
		||||
		private db: DataSource,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.followingsRepository)
 | 
			
		||||
		private followingsRepository: FollowingsRepository,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.instancesRepository)
 | 
			
		||||
		private instancesRepository: InstancesRepository,
 | 
			
		||||
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private appLockService: AppLockService,
 | 
			
		||||
		private chartLoggerService: ChartLoggerService,
 | 
			
		||||
	) {
 | 
			
		||||
@@ -43,8 +44,6 @@ export default class FederationChart extends Chart<typeof schema> { // eslint-di
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
 | 
			
		||||
		const meta = await this.metaService.fetch();
 | 
			
		||||
 | 
			
		||||
		const suspendedInstancesQuery = this.instancesRepository.createQueryBuilder('instance')
 | 
			
		||||
			.select('instance.host')
 | 
			
		||||
			.where('instance.suspensionState != \'none\'');
 | 
			
		||||
@@ -65,21 +64,21 @@ export default class FederationChart extends Chart<typeof schema> { // eslint-di
 | 
			
		||||
			this.followingsRepository.createQueryBuilder('following')
 | 
			
		||||
				.select('COUNT(DISTINCT following.followeeHost)')
 | 
			
		||||
				.where('following.followeeHost IS NOT NULL')
 | 
			
		||||
				.andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(this.meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(`following.followeeHost NOT IN (${ suspendedInstancesQuery.getQuery() })`)
 | 
			
		||||
				.getRawOne()
 | 
			
		||||
				.then(x => parseInt(x.count, 10)),
 | 
			
		||||
			this.followingsRepository.createQueryBuilder('following')
 | 
			
		||||
				.select('COUNT(DISTINCT following.followerHost)')
 | 
			
		||||
				.where('following.followerHost IS NOT NULL')
 | 
			
		||||
				.andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followerHost NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(this.meta.blockedHosts.length === 0 ? '1=1' : 'following.followerHost NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(`following.followerHost NOT IN (${ suspendedInstancesQuery.getQuery() })`)
 | 
			
		||||
				.getRawOne()
 | 
			
		||||
				.then(x => parseInt(x.count, 10)),
 | 
			
		||||
			this.followingsRepository.createQueryBuilder('following')
 | 
			
		||||
				.select('COUNT(DISTINCT following.followeeHost)')
 | 
			
		||||
				.where('following.followeeHost IS NOT NULL')
 | 
			
		||||
				.andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(this.meta.blockedHosts.length === 0 ? '1=1' : 'following.followeeHost NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(`following.followeeHost NOT IN (${ suspendedInstancesQuery.getQuery() })`)
 | 
			
		||||
				.andWhere(`following.followeeHost IN (${ pubsubSubQuery.getQuery() })`)
 | 
			
		||||
				.setParameters(pubsubSubQuery.getParameters())
 | 
			
		||||
@@ -88,7 +87,7 @@ export default class FederationChart extends Chart<typeof schema> { // eslint-di
 | 
			
		||||
			this.instancesRepository.createQueryBuilder('instance')
 | 
			
		||||
				.select('COUNT(instance.id)')
 | 
			
		||||
				.where(`instance.host IN (${ subInstancesQuery.getQuery() })`)
 | 
			
		||||
				.andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(this.meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere('instance.suspensionState = \'none\'')
 | 
			
		||||
				.andWhere('instance.isNotResponding = false')
 | 
			
		||||
				.getRawOne()
 | 
			
		||||
@@ -96,7 +95,7 @@ export default class FederationChart extends Chart<typeof schema> { // eslint-di
 | 
			
		||||
			this.instancesRepository.createQueryBuilder('instance')
 | 
			
		||||
				.select('COUNT(instance.id)')
 | 
			
		||||
				.where(`instance.host IN (${ pubInstancesQuery.getQuery() })`)
 | 
			
		||||
				.andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere(this.meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) })
 | 
			
		||||
				.andWhere('instance.suspensionState = \'none\'')
 | 
			
		||||
				.andWhere('instance.isNotResponding = false')
 | 
			
		||||
				.getRawOne()
 | 
			
		||||
 
 | 
			
		||||
@@ -3,19 +3,22 @@
 | 
			
		||||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { Injectable } from '@nestjs/common';
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import type { Packed } from '@/misc/json-schema.js';
 | 
			
		||||
import type { MiInstance } from '@/models/Instance.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { UtilityService } from '@/core/UtilityService.js';
 | 
			
		||||
import { RoleService } from '@/core/RoleService.js';
 | 
			
		||||
import { MiUser } from '@/models/User.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { MiMeta } from '@/models/_.js';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class InstanceEntityService {
 | 
			
		||||
	constructor(
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		private roleService: RoleService,
 | 
			
		||||
 | 
			
		||||
		private utilityService: UtilityService,
 | 
			
		||||
@@ -27,7 +30,6 @@ export class InstanceEntityService {
 | 
			
		||||
		instance: MiInstance,
 | 
			
		||||
		me?: { id: MiUser['id']; } | null | undefined,
 | 
			
		||||
	): Promise<Packed<'FederationInstance'>> {
 | 
			
		||||
		const meta = await this.metaService.fetch();
 | 
			
		||||
		const iAmModerator = me ? await this.roleService.isModerator(me as MiUser) : false;
 | 
			
		||||
 | 
			
		||||
		return {
 | 
			
		||||
@@ -41,7 +43,7 @@ export class InstanceEntityService {
 | 
			
		||||
			isNotResponding: instance.isNotResponding,
 | 
			
		||||
			isSuspended: instance.suspensionState !== 'none',
 | 
			
		||||
			suspensionState: instance.suspensionState,
 | 
			
		||||
			isBlocked: this.utilityService.isBlockedHost(meta.blockedHosts, instance.host),
 | 
			
		||||
			isBlocked: this.utilityService.isBlockedHost(this.meta.blockedHosts, instance.host),
 | 
			
		||||
			softwareName: instance.softwareName,
 | 
			
		||||
			softwareVersion: instance.softwareVersion,
 | 
			
		||||
			openRegistrations: instance.openRegistrations,
 | 
			
		||||
@@ -49,8 +51,8 @@ export class InstanceEntityService {
 | 
			
		||||
			description: instance.description,
 | 
			
		||||
			maintainerName: instance.maintainerName,
 | 
			
		||||
			maintainerEmail: instance.maintainerEmail,
 | 
			
		||||
			isSilenced: this.utilityService.isSilencedHost(meta.silencedHosts, instance.host),
 | 
			
		||||
			isMediaSilenced: this.utilityService.isMediaSilencedHost(meta.mediaSilencedHosts, instance.host),
 | 
			
		||||
			isSilenced: this.utilityService.isSilencedHost(this.meta.silencedHosts, instance.host),
 | 
			
		||||
			isMediaSilenced: this.utilityService.isMediaSilencedHost(this.meta.mediaSilencedHosts, instance.host),
 | 
			
		||||
			iconUrl: instance.iconUrl,
 | 
			
		||||
			faviconUrl: instance.faviconUrl,
 | 
			
		||||
			themeColor: instance.themeColor,
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ import type { Packed } from '@/misc/json-schema.js';
 | 
			
		||||
import type { MiMeta } from '@/models/Meta.js';
 | 
			
		||||
import type { AdsRepository } from '@/models/_.js';
 | 
			
		||||
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
 | 
			
		||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
 | 
			
		||||
@@ -24,11 +23,13 @@ export class MetaEntityService {
 | 
			
		||||
		@Inject(DI.config)
 | 
			
		||||
		private config: Config,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		@Inject(DI.adsRepository)
 | 
			
		||||
		private adsRepository: AdsRepository,
 | 
			
		||||
 | 
			
		||||
		private userEntityService: UserEntityService,
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private instanceActorService: InstanceActorService,
 | 
			
		||||
	) { }
 | 
			
		||||
 | 
			
		||||
@@ -37,7 +38,7 @@ export class MetaEntityService {
 | 
			
		||||
		let instance = meta;
 | 
			
		||||
 | 
			
		||||
		if (!instance) {
 | 
			
		||||
			instance = await this.metaService.fetch();
 | 
			
		||||
			instance = this.meta;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const ads = await this.adsRepository.createQueryBuilder('ads')
 | 
			
		||||
@@ -140,7 +141,7 @@ export class MetaEntityService {
 | 
			
		||||
		let instance = meta;
 | 
			
		||||
 | 
			
		||||
		if (!instance) {
 | 
			
		||||
			instance = await this.metaService.fetch();
 | 
			
		||||
			instance = this.meta;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const packed = await this.pack(instance);
 | 
			
		||||
 
 | 
			
		||||
@@ -3,13 +3,14 @@
 | 
			
		||||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { Injectable } from '@nestjs/common';
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import si from 'systeminformation';
 | 
			
		||||
import Xev from 'xev';
 | 
			
		||||
import * as osUtils from 'os-utils';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import type { OnApplicationShutdown } from '@nestjs/common';
 | 
			
		||||
import { MiMeta } from '@/models/_.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
 | 
			
		||||
const ev = new Xev();
 | 
			
		||||
 | 
			
		||||
@@ -23,7 +24,8 @@ export class ServerStatsService implements OnApplicationShutdown {
 | 
			
		||||
	private intervalId: NodeJS.Timeout | null = null;
 | 
			
		||||
 | 
			
		||||
	constructor(
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
	) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -32,7 +34,7 @@ export class ServerStatsService implements OnApplicationShutdown {
 | 
			
		||||
	 */
 | 
			
		||||
	@bindThis
 | 
			
		||||
	public async start(): Promise<void> {
 | 
			
		||||
		if (!(await this.metaService.fetch(true)).enableServerMachineStats) return;
 | 
			
		||||
		if (!this.meta.enableServerMachineStats) return;
 | 
			
		||||
 | 
			
		||||
		const log = [] as any[];
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,17 +7,20 @@ import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import type Logger from '@/logger.js';
 | 
			
		||||
import { bindThis } from '@/decorators.js';
 | 
			
		||||
import { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js';
 | 
			
		||||
import { MetaService } from '@/core/MetaService.js';
 | 
			
		||||
import { QueueLoggerService } from '../QueueLoggerService.js';
 | 
			
		||||
import type * as Bull from 'bullmq';
 | 
			
		||||
import { MiMeta } from '@/models/_.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class BakeBufferedReactionsProcessorService {
 | 
			
		||||
	private logger: Logger;
 | 
			
		||||
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.meta)
 | 
			
		||||
		private meta: MiMeta,
 | 
			
		||||
 | 
			
		||||
		private reactionsBufferingService: ReactionsBufferingService,
 | 
			
		||||
		private metaService: MetaService,
 | 
			
		||||
		private queueLoggerService: QueueLoggerService,
 | 
			
		||||
	) {
 | 
			
		||||
		this.logger = this.queueLoggerService.logger.createSubLogger('bake-buffered-reactions');
 | 
			
		||||
@@ -25,8 +28,7 @@ export class BakeBufferedReactionsProcessorService {
 | 
			
		||||
 | 
			
		||||
	@bindThis
 | 
			
		||||
	public async process(): Promise<void> {
 | 
			
		||||
		const meta = await this.metaService.fetch();
 | 
			
		||||
		if (!meta.enableReactionsBuffering) {
 | 
			
		||||
		if (!this.meta.enableReactionsBuffering) {
 | 
			
		||||
			this.logger.info('Reactions buffering is disabled. Skipping...');
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -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');
 | 
			
		||||
 
 | 
			
		||||
@@ -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,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);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -130,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',
 | 
			
		||||
@@ -179,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');
 | 
			
		||||
 
 | 
			
		||||
@@ -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