Merge branch 'develop' into pr/ThatOneCalculator/8764
This commit is contained in:
		
						commit
						088d66a252
					
				
					 120 changed files with 501 additions and 365 deletions
				
			
		
							
								
								
									
										11
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								CHANGELOG.md
									
										
									
									
									
								
							|  | @ -9,6 +9,17 @@ | ||||||
| You should also include the user name that made the change. | You should also include the user name that made the change. | ||||||
| --> | --> | ||||||
| 
 | 
 | ||||||
|  | ## 12.x.x (unreleased) | ||||||
|  | 
 | ||||||
|  | ### Changes | ||||||
|  | - Elasticsearchのサポートが削除されました | ||||||
|  | 	- 代わりに今後任意の検索プロバイダを設定できる仕組みを構想しています。その仕組みを使えば今まで通りElasticsearchも利用できます | ||||||
|  | - ノートのウォッチ機能が削除されました | ||||||
|  | 
 | ||||||
|  | ### Improvements | ||||||
|  | 
 | ||||||
|  | ### Bugfixes | ||||||
|  | 
 | ||||||
| ## 12.119.0 (2022/09/10) | ## 12.119.0 (2022/09/10) | ||||||
| 
 | 
 | ||||||
| ### Improvements | ### Improvements | ||||||
|  |  | ||||||
|  | @ -349,6 +349,10 @@ recaptcha: "reCAPTCHA" | ||||||
| enableRecaptcha: "reCAPTCHAを有効にする" | enableRecaptcha: "reCAPTCHAを有効にする" | ||||||
| recaptchaSiteKey: "サイトキー" | recaptchaSiteKey: "サイトキー" | ||||||
| recaptchaSecretKey: "シークレットキー" | recaptchaSecretKey: "シークレットキー" | ||||||
|  | turnstile: "Turnstile" | ||||||
|  | enableTurnstile: "Turnstileを有効にする" | ||||||
|  | turnstileSiteKey: "サイトキー" | ||||||
|  | turnstileSecretKey: "シークレットキー" | ||||||
| avoidMultiCaptchaConfirm: "複数のCaptchaを使用すると干渉を起こす可能性があります。他のCaptchaを無効にしますか?キャンセルして複数のCaptchaを有効化したままにすることも可能です。" | avoidMultiCaptchaConfirm: "複数のCaptchaを使用すると干渉を起こす可能性があります。他のCaptchaを無効にしますか?キャンセルして複数のCaptchaを有効化したままにすることも可能です。" | ||||||
| antennas: "アンテナ" | antennas: "アンテナ" | ||||||
| manageAntennas: "アンテナの管理" | manageAntennas: "アンテナの管理" | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| { | { | ||||||
| 	"name": "misskey", | 	"name": "misskey", | ||||||
| 	"version": "12.120.0-alpha.5", | 	"version": "12.120.0-alpha.6", | ||||||
| 	"codename": "indigo", | 	"codename": "indigo", | ||||||
| 	"repository": { | 	"repository": { | ||||||
| 		"type": "git", | 		"type": "git", | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								packages/backend/migration/1664694635394-turnstile.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								packages/backend/migration/1664694635394-turnstile.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | export class turnstile1664694635394 { | ||||||
|  |     name = 'turnstile1664694635394' | ||||||
|  | 
 | ||||||
|  |     async up(queryRunner) { | ||||||
|  |         await queryRunner.query(`ALTER TABLE "meta" ADD "enableTurnstile" boolean NOT NULL DEFAULT false`); | ||||||
|  |         await queryRunner.query(`ALTER TABLE "meta" ADD "turnstileSiteKey" character varying(64)`); | ||||||
|  |         await queryRunner.query(`ALTER TABLE "meta" ADD "turnstileSecretKey" character varying(64)`); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async down(queryRunner) { | ||||||
|  |         await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "turnstileSecretKey"`); | ||||||
|  |         await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "turnstileSiteKey"`); | ||||||
|  |         await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableTurnstile"`); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -35,7 +35,6 @@ | ||||||
| 		"@peertube/http-signature": "1.7.0", | 		"@peertube/http-signature": "1.7.0", | ||||||
| 		"@sinonjs/fake-timers": "9.1.2", | 		"@sinonjs/fake-timers": "9.1.2", | ||||||
| 		"@syuilo/aiscript": "0.11.1", | 		"@syuilo/aiscript": "0.11.1", | ||||||
| 		"@types/pg": "8.6.5", |  | ||||||
| 		"ajv": "8.11.0", | 		"ajv": "8.11.0", | ||||||
| 		"archiver": "5.3.1", | 		"archiver": "5.3.1", | ||||||
| 		"autobind-decorator": "2.4.0", | 		"autobind-decorator": "2.4.0", | ||||||
|  | @ -140,6 +139,7 @@ | ||||||
| 		"@redocly/openapi-core": "1.0.0-beta.108", | 		"@redocly/openapi-core": "1.0.0-beta.108", | ||||||
| 		"@swc/core": "1.3.2", | 		"@swc/core": "1.3.2", | ||||||
| 		"@swc/jest": "0.2.22", | 		"@swc/jest": "0.2.22", | ||||||
|  | 		"@types/archiver": "5.3.1", | ||||||
| 		"@types/bcryptjs": "2.4.2", | 		"@types/bcryptjs": "2.4.2", | ||||||
| 		"@types/bull": "3.15.9", | 		"@types/bull": "3.15.9", | ||||||
| 		"@types/cbor": "6.0.0", | 		"@types/cbor": "6.0.0", | ||||||
|  | @ -161,10 +161,12 @@ | ||||||
| 		"@types/koa__cors": "3.3.0", | 		"@types/koa__cors": "3.3.0", | ||||||
| 		"@types/koa__multer": "2.0.4", | 		"@types/koa__multer": "2.0.4", | ||||||
| 		"@types/koa__router": "8.0.11", | 		"@types/koa__router": "8.0.11", | ||||||
|  | 		"@types/mime-types": "2.1.1", | ||||||
| 		"@types/node": "18.7.18", | 		"@types/node": "18.7.18", | ||||||
| 		"@types/node-fetch": "3.0.3", | 		"@types/node-fetch": "3.0.3", | ||||||
| 		"@types/nodemailer": "6.4.6", | 		"@types/nodemailer": "6.4.6", | ||||||
| 		"@types/oauth": "0.9.1", | 		"@types/oauth": "0.9.1", | ||||||
|  | 		"@types/pg": "8.6.5", | ||||||
| 		"@types/pug": "2.0.6", | 		"@types/pug": "2.0.6", | ||||||
| 		"@types/punycode": "2.1.0", | 		"@types/punycode": "2.1.0", | ||||||
| 		"@types/qrcode": "1.5.0", | 		"@types/qrcode": "1.5.0", | ||||||
|  | @ -179,6 +181,7 @@ | ||||||
| 		"@types/speakeasy": "2.0.7", | 		"@types/speakeasy": "2.0.7", | ||||||
| 		"@types/tinycolor2": "1.4.3", | 		"@types/tinycolor2": "1.4.3", | ||||||
| 		"@types/tmp": "0.2.3", | 		"@types/tmp": "0.2.3", | ||||||
|  | 		"@types/unzipper": "0.10.5", | ||||||
| 		"@types/uuid": "8.3.4", | 		"@types/uuid": "8.3.4", | ||||||
| 		"@types/web-push": "3.3.2", | 		"@types/web-push": "3.3.2", | ||||||
| 		"@types/websocket": "1.0.5", | 		"@types/websocket": "1.0.5", | ||||||
|  |  | ||||||
|  | @ -119,8 +119,7 @@ function loadConfigBoot(): Config { | ||||||
| 		if (typeof exception === 'string') { | 		if (typeof exception === 'string') { | ||||||
| 			configLogger.error(exception); | 			configLogger.error(exception); | ||||||
| 			process.exit(1); | 			process.exit(1); | ||||||
| 		} | 		} else if ((exception as any).code === 'ENOENT') { | ||||||
| 		if (exception.code === 'ENOENT') { |  | ||||||
| 			configLogger.error('Configuration file not found', null, true); | 			configLogger.error('Configuration file not found', null, true); | ||||||
| 			process.exit(1); | 			process.exit(1); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -60,7 +60,7 @@ export class AntennaService implements OnApplicationShutdown { | ||||||
| 		this.redisSubscriber.off('message', this.onRedisMessage); | 		this.redisSubscriber.off('message', this.onRedisMessage); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private async onRedisMessage(_, data) { | 	private async onRedisMessage(_: string, data: string): Promise<void> { | ||||||
| 		const obj = JSON.parse(data); | 		const obj = JSON.parse(data); | ||||||
| 
 | 
 | ||||||
| 		if (obj.channel === 'internal') { | 		if (obj.channel === 'internal') { | ||||||
|  |  | ||||||
|  | @ -66,5 +66,16 @@ export class CaptchaService { | ||||||
| 			throw `hcaptcha-failed: ${errorCodes}`; | 			throw `hcaptcha-failed: ${errorCodes}`; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	public async verifyTurnstile(secret: string, response: string): Promise<void> { | ||||||
|  | 		const result = await this.getCaptchaResponse('https://challenges.cloudflare.com/turnstile/v0/siteverify', secret, response).catch(e => { | ||||||
|  | 			throw `turnstile-request-failed: ${e}`; | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		if (result.success !== true) { | ||||||
|  | 			const errorCodes = result['error-codes'] ? result['error-codes'].join(', ') : ''; | ||||||
|  | 			throw `turnstile-failed: ${errorCodes}`; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -61,7 +61,7 @@ type AddFileArgs = { | ||||||
| 
 | 
 | ||||||
| type UploadFromUrlArgs = { | type UploadFromUrlArgs = { | ||||||
| 	url: string; | 	url: string; | ||||||
| 	user: { id: User['id']; host: User['host'] } | null; | 	user: { id: User['id']; host: User['host']; driveCapacityOverrideMb: User['driveCapacityOverrideMb'] } | null; | ||||||
| 	folderId?: DriveFolder['id'] | null; | 	folderId?: DriveFolder['id'] | null; | ||||||
| 	uri?: string | null; | 	uri?: string | null; | ||||||
| 	sensitive?: boolean; | 	sensitive?: boolean; | ||||||
|  |  | ||||||
|  | @ -159,7 +159,7 @@ export class EmailService { | ||||||
| 			validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
 | 			validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
 | ||||||
| 			validateDisposable: true, // 捨てアドかどうかチェック
 | 			validateDisposable: true, // 捨てアドかどうかチェック
 | ||||||
| 			validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
 | 			validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
 | ||||||
| 		}) : { valid: true }; | 		}) : { valid: true, reason: null }; | ||||||
| 	 | 	 | ||||||
| 		const available = exist === 0 && validated.valid; | 		const available = exist === 0 && validated.valid; | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
|  | @ -13,20 +13,21 @@ import { HttpRequestService } from './HttpRequestService.js'; | ||||||
| import type { DOMWindow } from 'jsdom'; | import type { DOMWindow } from 'jsdom'; | ||||||
| 
 | 
 | ||||||
| type NodeInfo = { | type NodeInfo = { | ||||||
| 	openRegistrations?: any; | 	openRegistrations?: unknown; | ||||||
| 	software?: { | 	software?: { | ||||||
| 		name?: any; | 		name?: unknown; | ||||||
| 		version?: any; | 		version?: unknown; | ||||||
| 	}; | 	}; | ||||||
| 	metadata?: { | 	metadata?: { | ||||||
| 		name?: any; | 		name?: unknown; | ||||||
| 		nodeName?: any; | 		nodeName?: unknown; | ||||||
| 		nodeDescription?: any; | 		nodeDescription?: unknown; | ||||||
| 		description?: any; | 		description?: unknown; | ||||||
| 		maintainer?: { | 		maintainer?: { | ||||||
| 			name?: any; | 			name?: unknown; | ||||||
| 			email?: any; | 			email?: unknown; | ||||||
| 		}; | 		}; | ||||||
|  | 		themeColor?: unknown; | ||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -81,7 +82,7 @@ export class FetchInstanceMetadataService { | ||||||
| 			} as Record<string, any>; | 			} as Record<string, any>; | ||||||
| 	 | 	 | ||||||
| 			if (info) { | 			if (info) { | ||||||
| 				updates.softwareName = info.software?.name.toLowerCase(); | 				updates.softwareName = typeof info.software?.name === 'string' ? info.software.name.toLowerCase() : '?'; | ||||||
| 				updates.softwareVersion = info.software?.version; | 				updates.softwareVersion = info.software?.version; | ||||||
| 				updates.openRegistrations = info.openRegistrations; | 				updates.openRegistrations = info.openRegistrations; | ||||||
| 				updates.maintainerName = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name ?? null) : null : null; | 				updates.maintainerName = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name ?? null) : null : null; | ||||||
|  | @ -238,8 +239,10 @@ export class FetchInstanceMetadataService { | ||||||
| 
 | 
 | ||||||
| 	private async getSiteName(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> { | 	private async getSiteName(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> { | ||||||
| 		if (info && info.metadata) { | 		if (info && info.metadata) { | ||||||
| 			if (info.metadata.nodeName || info.metadata.name) { | 			if (typeof info.metadata.nodeName === 'string') { | ||||||
| 				return info.metadata.nodeName ?? info.metadata.name; | 				return info.metadata.nodeName; | ||||||
|  | 			} else if (typeof info.metadata.name === 'string') { | ||||||
|  | 				return info.metadata.name; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	 | 	 | ||||||
|  | @ -260,8 +263,10 @@ export class FetchInstanceMetadataService { | ||||||
| 
 | 
 | ||||||
| 	private async getDescription(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> { | 	private async getDescription(info: NodeInfo | null, doc: DOMWindow['document'] | null, manifest: Record<string, any> | null): Promise<string | null> { | ||||||
| 		if (info && info.metadata) { | 		if (info && info.metadata) { | ||||||
| 			if (info.metadata.nodeDescription || info.metadata.description) { | 			if (typeof info.metadata.nodeDescription === 'string') { | ||||||
| 				return info.metadata.nodeDescription ?? info.metadata.description; | 				return info.metadata.nodeDescription; | ||||||
|  | 			} else if (typeof info.metadata.description === 'string') { | ||||||
|  | 				return info.metadata.description; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ export class MetaService implements OnApplicationShutdown { | ||||||
| 		this.redisSubscriber.on('message', this.onMessage); | 		this.redisSubscriber.on('message', this.onMessage); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private async onMessage(_, data): Promise<void> { | 	private async onMessage(_: string, data: string): Promise<void> { | ||||||
| 		const obj = JSON.parse(data); | 		const obj = JSON.parse(data); | ||||||
| 
 | 
 | ||||||
| 		if (obj.channel === 'internal') { | 		if (obj.channel === 'internal') { | ||||||
|  |  | ||||||
|  | @ -534,7 +534,6 @@ export class NoteCreateService { | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
| 			const nm = new NotificationManager(this.mutingsRepository, this.createNotificationService, user, note); | 			const nm = new NotificationManager(this.mutingsRepository, this.createNotificationService, user, note); | ||||||
| 			const nmRelatedPromises = []; |  | ||||||
| 
 | 
 | ||||||
| 			await this.createMentionedEvents(mentionedUsers, note, nm); | 			await this.createMentionedEvents(mentionedUsers, note, nm); | ||||||
| 
 | 
 | ||||||
|  | @ -583,9 +582,7 @@ export class NoteCreateService { | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			Promise.all(nmRelatedPromises).then(() => { | 			nm.deliver(); | ||||||
| 				nm.deliver(); |  | ||||||
| 			}); |  | ||||||
| 
 | 
 | ||||||
| 			//#region AP deliver
 | 			//#region AP deliver
 | ||||||
| 			if (this.userEntityService.isLocalUser(user)) { | 			if (this.userEntityService.isLocalUser(user)) { | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import bcrypt from 'bcryptjs'; | import bcrypt from 'bcryptjs'; | ||||||
| import { DataSource, IsNull } from 'typeorm'; | import { DataSource, IsNull } from 'typeorm'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import type { UsedUsernamesRepository } from '@/models/index.js'; | import type { UsedUsernamesRepository, UsersRepository } from '@/models/index.js'; | ||||||
| import type { Config } from '@/config.js'; | import type { Config } from '@/config.js'; | ||||||
| import { User } from '@/models/entities/User.js'; | import { User } from '@/models/entities/User.js'; | ||||||
| import { UserProfile } from '@/models/entities/UserProfile.js'; | import { UserProfile } from '@/models/entities/UserProfile.js'; | ||||||
|  |  | ||||||
|  | @ -67,6 +67,8 @@ function verifyCertificateChain(certificates: string[]) { | ||||||
| 		const CACert = i + 1 >= certificates.length ? Cert : certificates[i + 1]; | 		const CACert = i + 1 >= certificates.length ? Cert : certificates[i + 1]; | ||||||
| 
 | 
 | ||||||
| 		const certStruct = jsrsasign.ASN1HEX.getTLVbyList(certificate.hex!, 0, [0]); | 		const certStruct = jsrsasign.ASN1HEX.getTLVbyList(certificate.hex!, 0, [0]); | ||||||
|  | 		if (certStruct == null) throw new Error('certStruct is null'); | ||||||
|  | 		 | ||||||
| 		const algorithm = certificate.getSignatureAlgorithmField(); | 		const algorithm = certificate.getSignatureAlgorithmField(); | ||||||
| 		const signatureHex = certificate.getSignatureValueHex(); | 		const signatureHex = certificate.getSignatureValueHex(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,12 +9,16 @@ import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import logger from '@/logger.js'; | import logger from '@/logger.js'; | ||||||
| import type { UsersRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, UserListsRepository, UserListJoiningsRepository } from '@/models/index.js'; | import type { UsersRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, UserListsRepository, UserListJoiningsRepository } from '@/models/index.js'; | ||||||
|  | import Logger from '@/logger.js'; | ||||||
| import { UserEntityService } from './entities/UserEntityService.js'; | import { UserEntityService } from './entities/UserEntityService.js'; | ||||||
| import { WebhookService } from './WebhookService.js'; | import { WebhookService } from './WebhookService.js'; | ||||||
| import { ApRendererService } from './remote/activitypub/ApRendererService.js'; | import { ApRendererService } from './remote/activitypub/ApRendererService.js'; | ||||||
|  | import { LoggerService } from './LoggerService.js'; | ||||||
| 
 | 
 | ||||||
| @Injectable() | @Injectable() | ||||||
| export class UserBlockingService { | export class UserBlockingService { | ||||||
|  | 	private logger: Logger; | ||||||
|  | 
 | ||||||
| 	constructor( | 	constructor( | ||||||
| 		@Inject(DI.usersRepository) | 		@Inject(DI.usersRepository) | ||||||
| 		private usersRepository: UsersRepository, | 		private usersRepository: UsersRepository, | ||||||
|  | @ -41,7 +45,9 @@ export class UserBlockingService { | ||||||
| 		private webhookService: WebhookService, | 		private webhookService: WebhookService, | ||||||
| 		private apRendererService: ApRendererService, | 		private apRendererService: ApRendererService, | ||||||
| 		private perUserFollowingChart: PerUserFollowingChart, | 		private perUserFollowingChart: PerUserFollowingChart, | ||||||
|  | 		private loggerService: LoggerService, | ||||||
| 	) { | 	) { | ||||||
|  | 		this.logger = this.loggerService.getLogger('user-block'); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public async block(blocker: User, blockee: User) { | 	public async block(blocker: User, blockee: User) { | ||||||
|  | @ -181,7 +187,7 @@ export class UserBlockingService { | ||||||
| 		}); | 		}); | ||||||
| 	 | 	 | ||||||
| 		if (blocking == null) { | 		if (blocking == null) { | ||||||
| 			logger.warn('ブロック解除がリクエストされましたがブロックしていませんでした'); | 			this.logger.warn('ブロック解除がリクエストされましたがブロックしていませんでした'); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
|  | @ -33,7 +33,7 @@ export class UserCacheService implements OnApplicationShutdown { | ||||||
| 		this.redisSubscriber.on('message', this.onMessage); | 		this.redisSubscriber.on('message', this.onMessage); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private async onMessage(_, data) { | 	private async onMessage(_: string, data: string): Promise<void> { | ||||||
| 		const obj = JSON.parse(data); | 		const obj = JSON.parse(data); | ||||||
| 
 | 
 | ||||||
| 		if (obj.channel === 'internal') { | 		if (obj.channel === 'internal') { | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ export class WebhookService implements OnApplicationShutdown { | ||||||
| 		return this.webhooks; | 		return this.webhooks; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private async onMessage(_, data) { | 	private async onMessage(_: string, data: string): Promise<void> { | ||||||
| 		const obj = JSON.parse(data); | 		const obj = JSON.parse(data); | ||||||
| 
 | 
 | ||||||
| 		if (obj.channel === 'internal') { | 		if (obj.channel === 'internal') { | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ export default class TestGroupedChart extends Chart<typeof schema> { | ||||||
| 		private db: DataSource, | 		private db: DataSource, | ||||||
| 
 | 
 | ||||||
| 		private appLockService: AppLockService, | 		private appLockService: AppLockService, | ||||||
| 		private logger: Logger, | 		logger: Logger, | ||||||
| 	) { | 	) { | ||||||
| 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema, true); | 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema, true); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ export default class TestIntersectionChart extends Chart<typeof schema> { | ||||||
| 		private db: DataSource, | 		private db: DataSource, | ||||||
| 
 | 
 | ||||||
| 		private appLockService: AppLockService, | 		private appLockService: AppLockService, | ||||||
| 		private logger: Logger, | 		logger: Logger, | ||||||
| 	) { | 	) { | ||||||
| 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema); | 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ export default class TestUniqueChart extends Chart<typeof schema> { | ||||||
| 		private db: DataSource, | 		private db: DataSource, | ||||||
| 
 | 
 | ||||||
| 		private appLockService: AppLockService, | 		private appLockService: AppLockService, | ||||||
| 		private logger: Logger, | 		logger: Logger, | ||||||
| 	) { | 	) { | ||||||
| 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema); | 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ export default class TestChart extends Chart<typeof schema> { | ||||||
| 		private db: DataSource, | 		private db: DataSource, | ||||||
| 
 | 
 | ||||||
| 		private appLockService: AppLockService, | 		private appLockService: AppLockService, | ||||||
| 		private logger: Logger, | 		logger: Logger, | ||||||
| 	) { | 	) { | ||||||
| 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema); | 		super(db, (k) => appLockService.getChartInsertLock(k), logger, name, schema); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import type { GalleryPosts, GalleryLikesRepository } from '@/models/index.js'; | import type { GalleryLikesRepository } from '@/models/index.js'; | ||||||
| import { awaitAll } from '@/misc/prelude/await-all.js'; | import { awaitAll } from '@/misc/prelude/await-all.js'; | ||||||
| import type { Packed } from '@/misc/schema.js'; | import type { Packed } from '@/misc/schema.js'; | ||||||
| import type { } from '@/models/entities/Blocking.js'; | import type { } from '@/models/entities/Blocking.js'; | ||||||
|  |  | ||||||
|  | @ -295,8 +295,9 @@ export class ApInboxService { | ||||||
| 			let renote; | 			let renote; | ||||||
| 			try { | 			try { | ||||||
| 				renote = await this.apNoteService.resolveNote(targetUri); | 				renote = await this.apNoteService.resolveNote(targetUri); | ||||||
|  | 				if (renote == null) throw new Error('announce target is null'); | ||||||
| 			} catch (err) { | 			} catch (err) { | ||||||
| 			// 対象が4xxならスキップ
 | 				// 対象が4xxならスキップ
 | ||||||
| 				if (err instanceof StatusError) { | 				if (err instanceof StatusError) { | ||||||
| 					if (err.isClientError) { | 					if (err.isClientError) { | ||||||
| 						this.logger.warn(`Ignored announce target ${targetUri} - ${err.statusCode}`); | 						this.logger.warn(`Ignored announce target ${targetUri} - ${err.statusCode}`); | ||||||
|  | @ -308,7 +309,10 @@ export class ApInboxService { | ||||||
| 				throw err; | 				throw err; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (!await this.noteEntityService.isVisibleForMe(renote, actor.id)) return 'skip: invalid actor for this activity'; | 			if (!await this.noteEntityService.isVisibleForMe(renote, actor.id)) { | ||||||
|  | 				this.logger.warn('skip: invalid actor for this activity'); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 			this.logger.info(`Creating the (Re)Note: ${uri}`); | 			this.logger.info(`Creating the (Re)Note: ${uri}`); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ import type { UserKeypair } from '@/models/entities/UserKeypair.js'; | ||||||
| import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, EmojisRepository, PollsRepository } from '@/models/index.js'; | import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, EmojisRepository, PollsRepository } from '@/models/index.js'; | ||||||
| import { LdSignatureService } from './LdSignatureService.js'; | import { LdSignatureService } from './LdSignatureService.js'; | ||||||
| import { ApMfmService } from './ApMfmService.js'; | import { ApMfmService } from './ApMfmService.js'; | ||||||
| import type { IActivity } from './type.js'; | import type { IActivity, IObject } from './type.js'; | ||||||
| import type { IIdentifier } from './models/identifier.js'; | import type { IIdentifier } from './models/identifier.js'; | ||||||
| 
 | 
 | ||||||
| @Injectable() | @Injectable() | ||||||
|  | @ -243,7 +243,7 @@ export class ApRendererService { | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public async renderLike(noteReaction: NoteReaction, note: Note) { | 	public async renderLike(noteReaction: NoteReaction, note: { uri: string | null }) { | ||||||
| 		const reaction = noteReaction.reaction; | 		const reaction = noteReaction.reaction; | ||||||
| 
 | 
 | ||||||
| 		const object = { | 		const object = { | ||||||
|  | @ -276,7 +276,7 @@ export class ApRendererService { | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public async renderNote(note: Note, dive = true, isTalk = false): Promise<Record<string, unknown>> { | 	public async renderNote(note: Note, dive = true, isTalk = false): Promise<IObject> { | ||||||
| 		const getPromisedFiles = async (ids: string[]) => { | 		const getPromisedFiles = async (ids: string[]) => { | ||||||
| 			if (!ids || ids.length === 0) return []; | 			if (!ids || ids.length === 0) return []; | ||||||
| 			const items = await this.driveFilesRepository.findBy({ id: In(ids) }); | 			const items = await this.driveFilesRepository.findBy({ id: In(ids) }); | ||||||
|  | @ -399,8 +399,8 @@ export class ApRendererService { | ||||||
| 			id: `${this.config.url}/notes/${note.id}`, | 			id: `${this.config.url}/notes/${note.id}`, | ||||||
| 			type: 'Note', | 			type: 'Note', | ||||||
| 			attributedTo, | 			attributedTo, | ||||||
| 			summary, | 			summary: summary ?? undefined, | ||||||
| 			content, | 			content: content ?? undefined, | ||||||
| 			_misskey_content: text, | 			_misskey_content: text, | ||||||
| 			source: { | 			source: { | ||||||
| 				content: text, | 				content: text, | ||||||
|  |  | ||||||
|  | @ -156,8 +156,8 @@ export class Resolver { | ||||||
| 				return this.notesRepository.findOneByOrFail({ id: parsed.id }) | 				return this.notesRepository.findOneByOrFail({ id: parsed.id }) | ||||||
| 					.then(note => { | 					.then(note => { | ||||||
| 						if (parsed.rest === 'activity') { | 						if (parsed.rest === 'activity') { | ||||||
| 						// this refers to the create activity and not the note itself
 | 							// this refers to the create activity and not the note itself
 | ||||||
| 							return this.apRendererService.renderActivity(this.apRendererService.renderCreate(this.apRendererService.renderNote(note))); | 							return this.apRendererService.renderActivity(this.apRendererService.renderCreate(this.apRendererService.renderNote(note), note)); | ||||||
| 						} else { | 						} else { | ||||||
| 							return this.apRendererService.renderNote(note); | 							return this.apRendererService.renderNote(note); | ||||||
| 						} | 						} | ||||||
|  | @ -174,7 +174,7 @@ export class Resolver { | ||||||
| 					.then(([note, poll]) => this.apRendererService.renderQuestion({ id: note.userId }, note, poll)); | 					.then(([note, poll]) => this.apRendererService.renderQuestion({ id: note.userId }, note, poll)); | ||||||
| 			case 'likes': | 			case 'likes': | ||||||
| 				return this.noteReactionsRepository.findOneByOrFail({ id: parsed.id }).then(reaction => | 				return this.noteReactionsRepository.findOneByOrFail({ id: parsed.id }).then(reaction => | ||||||
| 					this.apRendererService.renderActivity(this.apRendererService.renderLike(reaction, { uri: null }))); | 					this.apRendererService.renderActivity(this.apRendererService.renderLike(reaction, { uri: null }))!); | ||||||
| 			case 'follows': | 			case 'follows': | ||||||
| 				// rest should be <followee id>
 | 				// rest should be <followee id>
 | ||||||
| 				if (parsed.rest == null || !/^\w+$/.test(parsed.rest)) throw new Error('resolveLocal: invalid follow URI'); | 				if (parsed.rest == null || !/^\w+$/.test(parsed.rest)) throw new Error('resolveLocal: invalid follow URI'); | ||||||
|  | @ -184,7 +184,7 @@ export class Resolver { | ||||||
| 				) | 				) | ||||||
| 					.then(([follower, followee]) => this.apRendererService.renderActivity(this.apRendererService.renderFollow(follower, followee, url))); | 					.then(([follower, followee]) => this.apRendererService.renderActivity(this.apRendererService.renderFollow(follower, followee, url))); | ||||||
| 			default: | 			default: | ||||||
| 				throw new Error(`resolveLocal: type ${type} unhandled`); | 				throw new Error(`resolveLocal: type ${parsed.type} unhandled`); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| import * as crypto from 'node:crypto'; | import * as crypto from 'node:crypto'; | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import jsonld from 'jsonld'; |  | ||||||
| import fetch from 'node-fetch'; | import fetch from 'node-fetch'; | ||||||
| import { HttpRequestService } from '@/core/HttpRequestService.js'; | import { HttpRequestService } from '@/core/HttpRequestService.js'; | ||||||
| import { CONTEXTS } from './misc/contexts.js'; | import { CONTEXTS } from './misc/contexts.js'; | ||||||
|  | @ -93,9 +92,7 @@ class LdSignature { | ||||||
| 
 | 
 | ||||||
| 	public async normalize(data: any) { | 	public async normalize(data: any) { | ||||||
| 		const customLoader = this.getLoader(); | 		const customLoader = this.getLoader(); | ||||||
| 		return await jsonld.normalize(data, { | 		return 42; | ||||||
| 			documentLoader: customLoader, |  | ||||||
| 		}); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private getLoader() { | 	private getLoader() { | ||||||
|  |  | ||||||
|  | @ -111,8 +111,9 @@ export interface IPost extends IObject { | ||||||
| 		mediaType: string; | 		mediaType: string; | ||||||
| 	}; | 	}; | ||||||
| 	_misskey_quote?: string; | 	_misskey_quote?: string; | ||||||
|  | 	_misskey_content?: string; | ||||||
| 	quoteUrl?: string; | 	quoteUrl?: string; | ||||||
| 	_misskey_talk: boolean; | 	_misskey_talk?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface IQuestion extends IObject { | export interface IQuestion extends IObject { | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ import type { User } from '@/models/entities/User.js'; | ||||||
| type NoteLike = { | type NoteLike = { | ||||||
| 	userId: Note['userId']; | 	userId: Note['userId']; | ||||||
| 	text: Note['text']; | 	text: Note['text']; | ||||||
|  | 	cw?: Note['cw']; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| type UserLike = { | type UserLike = { | ||||||
|  |  | ||||||
|  | @ -188,6 +188,23 @@ export class Meta { | ||||||
| 	}) | 	}) | ||||||
| 	public recaptchaSecretKey: string | null; | 	public recaptchaSecretKey: string | null; | ||||||
| 
 | 
 | ||||||
|  | 	@Column('boolean', { | ||||||
|  | 		default: false, | ||||||
|  | 	}) | ||||||
|  | 	public enableTurnstile: boolean; | ||||||
|  | 
 | ||||||
|  | 	@Column('varchar', { | ||||||
|  | 		length: 64, | ||||||
|  | 		nullable: true, | ||||||
|  | 	}) | ||||||
|  | 	public turnstileSiteKey: string | null; | ||||||
|  | 
 | ||||||
|  | 	@Column('varchar', { | ||||||
|  | 		length: 64, | ||||||
|  | 		nullable: true, | ||||||
|  | 	}) | ||||||
|  | 	public turnstileSecretKey: string | null; | ||||||
|  | 
 | ||||||
| 	@Column('enum', { | 	@Column('enum', { | ||||||
| 		enum: ['none', 'all', 'local', 'remote'], | 		enum: ['none', 'all', 'local', 'remote'], | ||||||
| 		default: 'none', | 		default: 'none', | ||||||
|  |  | ||||||
|  | @ -12,6 +12,11 @@ export const packedNoteSchema = { | ||||||
| 			optional: false, nullable: false, | 			optional: false, nullable: false, | ||||||
| 			format: 'date-time', | 			format: 'date-time', | ||||||
| 		}, | 		}, | ||||||
|  | 		deletedAt: { | ||||||
|  | 			type: 'string', | ||||||
|  | 			optional: true, nullable: true, | ||||||
|  | 			format: 'date-time', | ||||||
|  | 		}, | ||||||
| 		text: { | 		text: { | ||||||
| 			type: 'string', | 			type: 'string', | ||||||
| 			optional: false, nullable: true, | 			optional: false, nullable: true, | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| import pg from 'pg'; | import pg from 'pg'; | ||||||
| pg.types.setTypeParser(20, Number); | pg.types.setTypeParser(20, Number); | ||||||
| 
 | 
 | ||||||
| import { DataSource } from 'typeorm'; | import { DataSource, Logger } from 'typeorm'; | ||||||
| import * as highlight from 'cli-highlight'; | import * as highlight from 'cli-highlight'; | ||||||
| import { entities as charts } from '@/core/chart/entities.js'; | import { entities as charts } from '@/core/chart/entities.js'; | ||||||
| 
 | 
 | ||||||
|  | @ -71,10 +71,10 @@ import { Webhook } from '@/models/entities/Webhook.js'; | ||||||
| import { Channel } from '@/models/entities/Channel.js'; | import { Channel } from '@/models/entities/Channel.js'; | ||||||
| 
 | 
 | ||||||
| import { Config } from '@/config.js'; | import { Config } from '@/config.js'; | ||||||
| import Logger from '@/logger.js'; | import MisskeyLogger from '@/logger.js'; | ||||||
| import { envOption } from './env.js'; | import { envOption } from './env.js'; | ||||||
| 
 | 
 | ||||||
| export const dbLogger = new Logger('db'); | export const dbLogger = new MisskeyLogger('db'); | ||||||
| 
 | 
 | ||||||
| const sqlLogger = dbLogger.createSubLogger('sql', 'gray', false); | const sqlLogger = dbLogger.createSubLogger('sql', 'gray', false); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -39,25 +39,19 @@ export class DbQueueProcessorsService { | ||||||
| 	) { | 	) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public start(dbQueue: Bull.Queue<DbJobData>) { | 	public start(q: Bull.Queue): void { | ||||||
| 		const jobs = { | 		q.process('deleteDriveFiles', (job, done) => this.deleteDriveFilesProcessorService.process(job, done)); | ||||||
| 			deleteDriveFiles: (job, done) => this.deleteDriveFilesProcessorService.process(job, done), | 		q.process('exportCustomEmojis', (job, done) => this.exportCustomEmojisProcessorService.process(job, done)); | ||||||
| 			exportCustomEmojis: (job, done) => this.exportCustomEmojisProcessorService.process(job, done), | 		q.process('exportNotes', (job, done) => this.exportNotesProcessorService.process(job, done)); | ||||||
| 			exportNotes: (job, done) => this.exportNotesProcessorService.process(job, done), | 		q.process('exportFollowing', (job, done) => this.exportFollowingProcessorService.process(job, done)); | ||||||
| 			exportFollowing: (job, done) => this.exportFollowingProcessorService.process(job, done), | 		q.process('exportMuting', (job, done) => this.exportMutingProcessorService.process(job, done)); | ||||||
| 			exportMuting: (job, done) => this.exportMutingProcessorService.process(job, done), | 		q.process('exportBlocking', (job, done) => this.exportBlockingProcessorService.process(job, done)); | ||||||
| 			exportBlocking: (job, done) => this.exportBlockingProcessorService.process(job, done), | 		q.process('exportUserLists', (job, done) => this.exportUserListsProcessorService.process(job, done)); | ||||||
| 			exportUserLists: (job, done) => this.exportUserListsProcessorService.process(job, done), | 		q.process('importFollowing', (job, done) => this.importFollowingProcessorService.process(job, done)); | ||||||
| 			importFollowing: (job, done) => this.importFollowingProcessorService.process(job, done), | 		q.process('importMuting', (job, done) => this.importMutingProcessorService.process(job, done)); | ||||||
| 			importMuting: (job, done) => this.importMutingProcessorService.process(job, done), | 		q.process('importBlocking', (job, done) => this.importBlockingProcessorService.process(job, done)); | ||||||
| 			importBlocking: (job, done) => this.importBlockingProcessorService.process(job, done), | 		q.process('importUserLists', (job, done) => this.importUserListsProcessorService.process(job, done)); | ||||||
| 			importUserLists: (job, done) => this.importUserListsProcessorService.process(job, done), | 		q.process('importCustomEmojis', (job, done) => this.importCustomEmojisProcessorService.process(job, done)); | ||||||
| 			importCustomEmojis: (job, done) => this.importCustomEmojisProcessorService.process(job, done), | 		q.process('deleteAccount', (job) => this.deleteAccountProcessorService.process(job)); | ||||||
| 			deleteAccount: (job) => this.deleteAccountProcessorService.process(job), |  | ||||||
| 		} as Record<string, Bull.ProcessCallbackFunction<DbJobData | Bull.ProcessPromiseFunction<DbJobData>>>; |  | ||||||
| 		 |  | ||||||
| 		for (const [k, v] of Object.entries(jobs)) { |  | ||||||
| 			dbQueue.process(k, v); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,14 +17,8 @@ export class ObjectStorageQueueProcessorsService { | ||||||
| 	) { | 	) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public start(q: Bull.Queue) { | 	public start(q: Bull.Queue): void { | ||||||
| 		const jobs = { | 		q.process('deleteFile', 16, (job) => this.deleteFileProcessorService.process(job)); | ||||||
| 			deleteFile: (job) => this.deleteFileProcessorService.process(job), | 		q.process('cleanRemoteFiles', 16, (job, done) => this.cleanRemoteFilesProcessorService.process(job, done)); | ||||||
| 			cleanRemoteFiles: (job) => this.cleanRemoteFilesProcessorService.process(job), |  | ||||||
| 		} as Record<string, Bull.ProcessCallbackFunction<ObjectStorageJobData | Bull.ProcessPromiseFunction<ObjectStorageJobData>>>; |  | ||||||
| 		 |  | ||||||
| 		for (const [k, v] of Object.entries(jobs)) { |  | ||||||
| 			q.process(k, 16, v); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,17 +22,11 @@ export class SystemQueueProcessorsService { | ||||||
| 	) { | 	) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public start(dbQueue: Bull.Queue<Record<string, unknown>>) { | 	public start(q: Bull.Queue): void { | ||||||
| 		const jobs = { | 		q.process('tickCharts', (job, done) => this.tickChartsProcessorService.process(job, done)); | ||||||
| 			tickCharts: (job, done) => this.tickChartsProcessorService.process(job, done), | 		q.process('resyncCharts', (job, done) => this.resyncChartsProcessorService.process(job, done)); | ||||||
| 			resyncCharts: (job, done) => this.resyncChartsProcessorService.process(job, done), | 		q.process('cleanCharts', (job, done) => this.cleanChartsProcessorService.process(job, done)); | ||||||
| 			cleanCharts: (job, done) => this.cleanChartsProcessorService.process(job, done), | 		q.process('checkExpiredMutings', (job, done) => this.checkExpiredMutingsProcessorService.process(job, done)); | ||||||
| 			checkExpiredMutings: (job, done) => this.checkExpiredMutingsProcessorService.process(job, done), | 		q.process('clean', (job, done) => this.cleanProcessorService.process(job, done)); | ||||||
| 			clean: (job, done) => this.cleanProcessorService.process(job, done), |  | ||||||
| 		} as Record<string, Bull.ProcessCallbackFunction<Record<string, unknown>> | Bull.ProcessPromiseFunction<Record<string, unknown>>>; |  | ||||||
| 		 |  | ||||||
| 		for (const [k, v] of Object.entries(jobs)) { |  | ||||||
| 			dbQueue.process(k, v); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -80,7 +80,7 @@ export class ExportCustomEmojisProcessorService { | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		for (const emoji of customEmojis) { | 		for (const emoji of customEmojis) { | ||||||
| 			const ext = mime.extension(emoji.type); | 			const ext = mime.extension(emoji.type ?? 'image/png'); | ||||||
| 			const fileName = emoji.name + (ext ? '.' + ext : ''); | 			const fileName = emoji.name + (ext ? '.' + ext : ''); | ||||||
| 			const emojiPath = path + '/' + fileName; | 			const emojiPath = path + '/' + fileName; | ||||||
| 			fs.writeFileSync(emojiPath, '', 'binary'); | 			fs.writeFileSync(emojiPath, '', 'binary'); | ||||||
|  |  | ||||||
|  | @ -118,7 +118,7 @@ export class NodeinfoServerService { | ||||||
| 		router.get(nodeinfo2_0path, async ctx => { | 		router.get(nodeinfo2_0path, async ctx => { | ||||||
| 			const base = await cache.fetch(null, () => nodeinfo2()); | 			const base = await cache.fetch(null, () => nodeinfo2()); | ||||||
| 
 | 
 | ||||||
| 			delete base.software.repository; | 			delete (base as any).software.repository; | ||||||
| 
 | 
 | ||||||
| 			ctx.body = { version: '2.0', ...base }; | 			ctx.body = { version: '2.0', ...base }; | ||||||
| 			ctx.set('Cache-Control', 'public, max-age=600'); | 			ctx.set('Cache-Control', 'public, max-age=600'); | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ import { MediaProxyServerService } from './MediaProxyServerService.js'; | ||||||
| import { NodeinfoServerService } from './NodeinfoServerService.js'; | import { NodeinfoServerService } from './NodeinfoServerService.js'; | ||||||
| import { ServerService } from './ServerService.js'; | import { ServerService } from './ServerService.js'; | ||||||
| import { WellKnownServerService } from './WellKnownServerService.js'; | import { WellKnownServerService } from './WellKnownServerService.js'; | ||||||
| import { GetterService } from './api/common/GetterService.js'; | import { GetterService } from './api/GetterService.js'; | ||||||
| import { DiscordServerService } from './api/integration/DiscordServerService.js'; | import { DiscordServerService } from './api/integration/DiscordServerService.js'; | ||||||
| import { GithubServerService } from './api/integration/GithubServerService.js'; | import { GithubServerService } from './api/integration/GithubServerService.js'; | ||||||
| import { TwitterServerService } from './api/integration/TwitterServerService.js'; | import { TwitterServerService } from './api/integration/TwitterServerService.js'; | ||||||
|  |  | ||||||
|  | @ -313,7 +313,7 @@ import * as ep___users_show from './endpoints/users/show.js'; | ||||||
| import * as ep___users_stats from './endpoints/users/stats.js'; | import * as ep___users_stats from './endpoints/users/stats.js'; | ||||||
| import * as ep___fetchRss from './endpoints/fetch-rss.js'; | import * as ep___fetchRss from './endpoints/fetch-rss.js'; | ||||||
| import * as ep___admin_driveCapOverride from './endpoints/admin/drive-capacity-override.js'; | import * as ep___admin_driveCapOverride from './endpoints/admin/drive-capacity-override.js'; | ||||||
| import { GetterService } from './common/GetterService.js'; | import { GetterService } from './GetterService.js'; | ||||||
| import { ApiLoggerService } from './ApiLoggerService.js'; | import { ApiLoggerService } from './ApiLoggerService.js'; | ||||||
| import type { Provider } from '@nestjs/common'; | import type { Provider } from '@nestjs/common'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ import { IdService } from '@/core/IdService.js'; | ||||||
| import { SignupService } from '@/core/SignupService.js'; | import { SignupService } from '@/core/SignupService.js'; | ||||||
| import { UserEntityService } from '@/core/entities/UserEntityService.js'; | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { EmailService } from '@/core/EmailService.js'; | import { EmailService } from '@/core/EmailService.js'; | ||||||
|  | import { ILocalUser } from '@/models/entities/User.js'; | ||||||
| import { SigninService } from './SigninService.js'; | import { SigninService } from './SigninService.js'; | ||||||
| import type Koa from 'koa'; | import type Koa from 'koa'; | ||||||
| 
 | 
 | ||||||
|  | @ -60,6 +61,12 @@ export class SignupApiService { | ||||||
| 					ctx.throw(400, e); | 					ctx.throw(400, e); | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			if (instance.enableTurnstile && instance.turnstileSecretKey) { | ||||||
|  | 				await this.captchaService.verifyTurnstile(instance.turnstileSecretKey, body['turnstile-response']).catch(e => { | ||||||
|  | 					ctx.throw(400, e); | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	 | 	 | ||||||
| 		const username = body['username']; | 		const username = body['username']; | ||||||
|  | @ -117,7 +124,7 @@ export class SignupApiService { | ||||||
| 	 | 	 | ||||||
| 			const link = `${this.config.url}/signup-complete/${code}`; | 			const link = `${this.config.url}/signup-complete/${code}`; | ||||||
| 	 | 	 | ||||||
| 			sendEmail(emailAddress, 'Signup', | 			this.emailService.sendEmail(emailAddress, 'Signup', | ||||||
| 				`To complete signup, please click this link:<br><a href="${link}">${link}</a>`, | 				`To complete signup, please click this link:<br><a href="${link}">${link}</a>`, | ||||||
| 				`To complete signup, please click this link: ${link}`); | 				`To complete signup, please click this link: ${link}`); | ||||||
| 	 | 	 | ||||||
|  | @ -167,7 +174,7 @@ export class SignupApiService { | ||||||
| 				emailVerifyCode: null, | 				emailVerifyCode: null, | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
| 			this.signinService.signin(ctx, account); | 			this.signinService.signin(ctx, account as ILocalUser); | ||||||
| 		} catch (e) { | 		} catch (e) { | ||||||
| 			ctx.throw(400, e); | 			ctx.throw(400, e); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -72,7 +72,7 @@ export class StreamingApiServerService { | ||||||
| 
 | 
 | ||||||
| 			const ev = new EventEmitter(); | 			const ev = new EventEmitter(); | ||||||
| 
 | 
 | ||||||
| 			async function onRedisMessage(_: string, data: string) { | 			async function onRedisMessage(_: string, data: string): Promise<void> { | ||||||
| 				const parsed = JSON.parse(data); | 				const parsed = JSON.parse(data); | ||||||
| 				ev.emit(parsed.channel, parsed.message); | 				ev.emit(parsed.channel, parsed.message); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -1,53 +0,0 @@ | ||||||
| import rndstr from 'rndstr'; |  | ||||||
| import type { Note } from '@/models/entities/Note.js'; |  | ||||||
| import type { User } from '@/models/entities/User.js'; |  | ||||||
| 
 |  | ||||||
| // TODO: リアクション、Renote、返信などをしたノートは除外する
 |  | ||||||
| 
 |  | ||||||
| export async function injectFeatured(timeline: Note[], user?: User | null) { |  | ||||||
| 	if (timeline.length < 5) return; |  | ||||||
| 
 |  | ||||||
| 	if (user) { |  | ||||||
| 		const profile = await UserProfiles.findOneByOrFail({ userId: user.id }); |  | ||||||
| 		if (!profile.injectFeaturedNote) return; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	const max = 30; |  | ||||||
| 	const day = 1000 * 60 * 60 * 24 * 3; // 3日前まで
 |  | ||||||
| 
 |  | ||||||
| 	const query = Notes.createQueryBuilder('note') |  | ||||||
| 		.addSelect('note.score') |  | ||||||
| 		.where('note.userHost IS NULL') |  | ||||||
| 		.andWhere('note.score > 0') |  | ||||||
| 		.andWhere('note.createdAt > :date', { date: new Date(Date.now() - day) }) |  | ||||||
| 		.andWhere('note.visibility = \'public\'') |  | ||||||
| 		.innerJoinAndSelect('note.user', 'user'); |  | ||||||
| 
 |  | ||||||
| 	if (user) { |  | ||||||
| 		query.andWhere('note.userId != :userId', { userId: user.id }); |  | ||||||
| 
 |  | ||||||
| 		generateMutedUserQuery(query, user); |  | ||||||
| 		generateBlockedUserQuery(query, user); |  | ||||||
| 
 |  | ||||||
| 		const reactionQuery = NoteReactions.createQueryBuilder('reaction') |  | ||||||
| 			.select('reaction.noteId') |  | ||||||
| 			.where('reaction.userId = :userId', { userId: user.id }); |  | ||||||
| 
 |  | ||||||
| 		query.andWhere(`note.id NOT IN (${ reactionQuery.getQuery() })`); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	const notes = await query |  | ||||||
| 		.orderBy('note.score', 'DESC') |  | ||||||
| 		.take(max) |  | ||||||
| 		.getMany(); |  | ||||||
| 
 |  | ||||||
| 	if (notes.length === 0) return; |  | ||||||
| 
 |  | ||||||
| 	// Pick random one
 |  | ||||||
| 	const featured = notes[Math.floor(Math.random() * notes.length)]; |  | ||||||
| 
 |  | ||||||
| 	(featured as any)._featuredId_ = rndstr('a-z0-9', 8); |  | ||||||
| 
 |  | ||||||
| 	// Inject featured
 |  | ||||||
| 	timeline.splice(3, 0, featured); |  | ||||||
| } |  | ||||||
|  | @ -1,33 +0,0 @@ | ||||||
| import rndstr from 'rndstr'; |  | ||||||
| import type { Note } from '@/models/entities/Note.js'; |  | ||||||
| import type { User } from '@/models/entities/User.js'; |  | ||||||
| 
 |  | ||||||
| export async function injectPromo(timeline: Note[], user?: User | null) { |  | ||||||
| 	if (timeline.length < 5) return; |  | ||||||
| 
 |  | ||||||
| 	// TODO: readやexpireフィルタはクエリ側でやる
 |  | ||||||
| 
 |  | ||||||
| 	const reads = user ? await PromoReads.findBy({ |  | ||||||
| 		userId: user.id, |  | ||||||
| 	}) : []; |  | ||||||
| 
 |  | ||||||
| 	let promos = await PromoNotes.find(); |  | ||||||
| 
 |  | ||||||
| 	promos = promos.filter(n => n.expiresAt.getTime() > Date.now()); |  | ||||||
| 	promos = promos.filter(n => !reads.map(r => r.noteId).includes(n.noteId)); |  | ||||||
| 
 |  | ||||||
| 	if (promos.length === 0) return; |  | ||||||
| 
 |  | ||||||
| 	// Pick random promo
 |  | ||||||
| 	const promo = promos[Math.floor(Math.random() * promos.length)]; |  | ||||||
| 
 |  | ||||||
| 	const note = await Notes.findOneByOrFail({ id: promo.noteId }); |  | ||||||
| 
 |  | ||||||
| 	// Join
 |  | ||||||
| 	note.user = await Users.findOneByOrFail({ id: note.userId }); |  | ||||||
| 
 |  | ||||||
| 	(note as any)._prId_ = rndstr('a-z0-9', 8); |  | ||||||
| 
 |  | ||||||
| 	// Inject promo
 |  | ||||||
| 	timeline.splice(3, 0, note); |  | ||||||
| } |  | ||||||
|  | @ -725,10 +725,10 @@ export interface IEndpoint { | ||||||
| 	params: Schema; | 	params: Schema; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const endpoints: IEndpoint[] = eps.map(([name, ep]) => { | const endpoints: IEndpoint[] = (eps as [string, any]).map(([name, ep]) => { | ||||||
| 	return { | 	return { | ||||||
| 		name: name, | 		name: name, | ||||||
| 		meta: ep.meta || {}, | 		meta: ep.meta ?? {}, | ||||||
| 		params: ep.paramDef, | 		params: ep.paramDef, | ||||||
| 	}; | 	}; | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { AbuseUserReportsRepository } from '@/models/index.js'; | import type { AbuseUserReportsRepository } from '@/models/index.js'; | ||||||
| import { QueryService } from '@/core/QueryService.js'; | import { QueryService } from '@/core/QueryService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  | import { AbuseUserReportEntityService } from '@/core/entities/AbuseUserReportEntityService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  | @ -93,6 +94,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		@Inject(DI.abuseUserReportsRepository) | 		@Inject(DI.abuseUserReportsRepository) | ||||||
| 		private abuseUserReportsRepository: AbuseUserReportsRepository, | 		private abuseUserReportsRepository: AbuseUserReportsRepository, | ||||||
| 
 | 
 | ||||||
|  | 		private abuseUserReportEntityService: AbuseUserReportEntityService, | ||||||
| 		private queryService: QueryService, | 		private queryService: QueryService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(meta, paramDef, async (ps, me) => { | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ import { QueueService } from '@/core/QueueService.js'; | ||||||
| import { GlobalEventService } from '@/core/GlobalEventService.js'; | import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||||||
| import { UserSuspendService } from '@/core/UserSuspendService.js'; | import { UserSuspendService } from '@/core/UserSuspendService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  | @ -28,6 +29,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		@Inject(DI.usersRepository) | 		@Inject(DI.usersRepository) | ||||||
| 		private usersRepository: UsersRepository, | 		private usersRepository: UsersRepository, | ||||||
| 
 | 
 | ||||||
|  | 		private userEntityService: UserEntityService, | ||||||
| 		private queueService: QueueService, | 		private queueService: QueueService, | ||||||
| 		private globalEventService: GlobalEventService, | 		private globalEventService: GlobalEventService, | ||||||
| 		private userSuspendService: UserSuspendService, | 		private userSuspendService: UserSuspendService, | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { UsersRepository } from '@/models/index.js'; | import type { UsersRepository } from '@/models/index.js'; | ||||||
| import { ModerationLogService } from '@/core/ModerationLogService.js'; | import { ModerationLogService } from '@/core/ModerationLogService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  | @ -27,6 +28,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		@Inject(DI.usersRepository) | 		@Inject(DI.usersRepository) | ||||||
| 		private usersRepository: UsersRepository, | 		private usersRepository: UsersRepository, | ||||||
| 
 | 
 | ||||||
|  | 		private userEntityService: UserEntityService, | ||||||
| 		private moderationLogService: ModerationLogService, | 		private moderationLogService: ModerationLogService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(meta, paramDef, async (ps, me) => { | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ import type { DriveFilesRepository } from '@/models/index.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { QueryService } from '@/core/QueryService.js'; | import { QueryService } from '@/core/QueryService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  | import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  | @ -47,6 +48,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		@Inject(DI.driveFilesRepository) | 		@Inject(DI.driveFilesRepository) | ||||||
| 		private driveFilesRepository: DriveFilesRepository, | 		private driveFilesRepository: DriveFilesRepository, | ||||||
| 
 | 
 | ||||||
|  | 		private driveFileEntityService: DriveFileEntityService, | ||||||
| 		private queryService: QueryService, | 		private queryService: QueryService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(meta, paramDef, async (ps, me) => { | ||||||
|  |  | ||||||
|  | @ -76,23 +76,6 @@ export const meta = { | ||||||
| 			properties: { | 			properties: { | ||||||
| 				type: 'object', | 				type: 'object', | ||||||
| 				optional: false, nullable: false, | 				optional: false, nullable: false, | ||||||
| 				properties: { |  | ||||||
| 					width: { |  | ||||||
| 						type: 'number', |  | ||||||
| 						optional: false, nullable: false, |  | ||||||
| 						example: 1280, |  | ||||||
| 					}, |  | ||||||
| 					height: { |  | ||||||
| 						type: 'number', |  | ||||||
| 						optional: false, nullable: false, |  | ||||||
| 						example: 720, |  | ||||||
| 					}, |  | ||||||
| 					avgColor: { |  | ||||||
| 						type: 'string', |  | ||||||
| 						optional: true, nullable: false, |  | ||||||
| 						example: 'rgb(40,65,87)', |  | ||||||
| 					}, |  | ||||||
| 				}, |  | ||||||
| 			}, | 			}, | ||||||
| 			storedInternal: { | 			storedInternal: { | ||||||
| 				type: 'boolean', | 				type: 'boolean', | ||||||
|  | @ -116,15 +99,15 @@ export const meta = { | ||||||
| 			}, | 			}, | ||||||
| 			accessKey: { | 			accessKey: { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: false, nullable: false, | 				optional: false, nullable: true, | ||||||
| 			}, | 			}, | ||||||
| 			thumbnailAccessKey: { | 			thumbnailAccessKey: { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: false, nullable: false, | 				optional: false, nullable: true, | ||||||
| 			}, | 			}, | ||||||
| 			webpublicAccessKey: { | 			webpublicAccessKey: { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: false, nullable: false, | 				optional: false, nullable: true, | ||||||
| 			}, | 			}, | ||||||
| 			uri: { | 			uri: { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
|  | @ -192,12 +175,36 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 				throw new ApiError(meta.errors.noSuchFile); | 				throw new ApiError(meta.errors.noSuchFile); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (!me.isAdmin) { | 			return { | ||||||
| 				delete file.requestIp; | 				id: file.id, | ||||||
| 				delete file.requestHeaders; | 				userId: file.userId, | ||||||
| 			} | 				userHost: file.userHost, | ||||||
| 
 | 				isLink: file.isLink, | ||||||
| 			return file; | 				maybePorn: file.maybePorn, | ||||||
|  | 				maybeSensitive: file.maybeSensitive, | ||||||
|  | 				isSensitive: file.isSensitive, | ||||||
|  | 				folderId: file.folderId, | ||||||
|  | 				src: file.src, | ||||||
|  | 				uri: file.uri, | ||||||
|  | 				webpublicAccessKey: file.webpublicAccessKey, | ||||||
|  | 				thumbnailAccessKey: file.thumbnailAccessKey, | ||||||
|  | 				accessKey: file.accessKey, | ||||||
|  | 				webpublicType: file.webpublicType, | ||||||
|  | 				webpublicUrl: file.webpublicUrl, | ||||||
|  | 				thumbnailUrl: file.thumbnailUrl, | ||||||
|  | 				url: file.url, | ||||||
|  | 				storedInternal: file.storedInternal, | ||||||
|  | 				properties: file.properties, | ||||||
|  | 				blurhash: file.blurhash, | ||||||
|  | 				comment: file.comment, | ||||||
|  | 				size: file.size, | ||||||
|  | 				type: file.type, | ||||||
|  | 				name: file.name, | ||||||
|  | 				md5: file.md5, | ||||||
|  | 				createdAt: file.createdAt.toISOString(), | ||||||
|  | 				requestIp: me.isAdmin ? file.requestIp : null, | ||||||
|  | 				requestHeaders: me.isAdmin ? file.requestHeaders : null, | ||||||
|  | 			}; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ import type { EmojisRepository } from '@/models/index.js'; | ||||||
| import type { Emoji } from '@/models/entities/Emoji.js'; | import type { Emoji } from '@/models/entities/Emoji.js'; | ||||||
| import { QueryService } from '@/core/QueryService.js'; | import { QueryService } from '@/core/QueryService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  | import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  | @ -40,8 +41,8 @@ export const meta = { | ||||||
| 					optional: false, nullable: true, | 					optional: false, nullable: true, | ||||||
| 				}, | 				}, | ||||||
| 				host: { | 				host: { | ||||||
| 					type: 'null', | 					type: 'string', | ||||||
| 					optional: false, | 					optional: false, nullable: true, | ||||||
| 					description: 'The local host is represented with `null`. The field exists for compatibility with other API endpoints that return files.', | 					description: 'The local host is represented with `null`. The field exists for compatibility with other API endpoints that return files.', | ||||||
| 				}, | 				}, | ||||||
| 				url: { | 				url: { | ||||||
|  | @ -71,6 +72,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		@Inject(DI.emojisRepository) | 		@Inject(DI.emojisRepository) | ||||||
| 		private emojisRepository: EmojisRepository, | 		private emojisRepository: EmojisRepository, | ||||||
| 
 | 
 | ||||||
|  | 		private emojiEntityService: EmojiEntityService, | ||||||
| 		private queryService: QueryService, | 		private queryService: QueryService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(meta, paramDef, async (ps, me) => { | ||||||
|  |  | ||||||
|  | @ -47,6 +47,14 @@ export const meta = { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: false, nullable: true, | 				optional: false, nullable: true, | ||||||
| 			}, | 			}, | ||||||
|  | 			enableTurnstile: { | ||||||
|  | 				type: 'boolean', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			turnstileSiteKey: { | ||||||
|  | 				type: 'string', | ||||||
|  | 				optional: false, nullable: true, | ||||||
|  | 			}, | ||||||
| 			swPublickey: { | 			swPublickey: { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: false, nullable: true, | 				optional: false, nullable: true, | ||||||
|  | @ -197,6 +205,10 @@ export const meta = { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: true, nullable: true, | 				optional: true, nullable: true, | ||||||
| 			}, | 			}, | ||||||
|  | 			turnstileSecretKey: { | ||||||
|  | 				type: 'string', | ||||||
|  | 				optional: true, nullable: true, | ||||||
|  | 			} | ||||||
| 			sensitiveMediaDetection: { | 			sensitiveMediaDetection: { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: true, nullable: false, | 				optional: true, nullable: false, | ||||||
|  | @ -374,6 +386,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 				hcaptchaSiteKey: instance.hcaptchaSiteKey, | 				hcaptchaSiteKey: instance.hcaptchaSiteKey, | ||||||
| 				enableRecaptcha: instance.enableRecaptcha, | 				enableRecaptcha: instance.enableRecaptcha, | ||||||
| 				recaptchaSiteKey: instance.recaptchaSiteKey, | 				recaptchaSiteKey: instance.recaptchaSiteKey, | ||||||
|  | 				enableTurnstile: instance.enableTurnstile, | ||||||
|  | 				turnstileSiteKey: instance.turnstileSiteKey, | ||||||
| 				swPublickey: instance.swPublicKey, | 				swPublickey: instance.swPublicKey, | ||||||
| 				themeColor: instance.themeColor, | 				themeColor: instance.themeColor, | ||||||
| 				mascotImageUrl: instance.mascotImageUrl, | 				mascotImageUrl: instance.mascotImageUrl, | ||||||
|  | @ -400,6 +414,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 				blockedHosts: instance.blockedHosts, | 				blockedHosts: instance.blockedHosts, | ||||||
| 				hcaptchaSecretKey: instance.hcaptchaSecretKey, | 				hcaptchaSecretKey: instance.hcaptchaSecretKey, | ||||||
| 				recaptchaSecretKey: instance.recaptchaSecretKey, | 				recaptchaSecretKey: instance.recaptchaSecretKey, | ||||||
|  | 				turnstileSecretKey: instance.turnstileSecretKey, | ||||||
| 				sensitiveMediaDetection: instance.sensitiveMediaDetection, | 				sensitiveMediaDetection: instance.sensitiveMediaDetection, | ||||||
| 				sensitiveMediaDetectionSensitivity: instance.sensitiveMediaDetectionSensitivity, | 				sensitiveMediaDetectionSensitivity: instance.sensitiveMediaDetectionSensitivity, | ||||||
| 				setSensitiveFlagAutomatically: instance.setSensitiveFlagAutomatically, | 				setSensitiveFlagAutomatically: instance.setSensitiveFlagAutomatically, | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { PromoNotesRepository } from '@/models/index.js'; | import type { PromoNotesRepository } from '@/models/index.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { URL } from 'node:url'; | import { URL } from 'node:url'; | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { DeliverQueue } from '@/core/queue/QueueModule.js'; | import type { DeliverQueue } from '@/core/queue/QueueModule.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { URL } from 'node:url'; | import { URL } from 'node:url'; | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { InboxQueue } from '@/core/queue/QueueModule.js'; | import type { InboxQueue } from '@/core/queue/QueueModule.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, WebhookDeliverQueue } from '@/core/queue/QueueModule.js'; | import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, WebhookDeliverQueue } from '@/core/queue/QueueModule.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { ModerationLogsRepository } from '@/models/index.js'; | import type { ModerationLogsRepository } from '@/models/index.js'; | ||||||
| import { QueryService } from '@/core/QueryService.js'; | import { QueryService } from '@/core/QueryService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  | import { ModerationLogEntityService } from '@/core/entities/ModerationLogEntityService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  | @ -67,6 +68,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		@Inject(DI.moderationLogsRepository) | 		@Inject(DI.moderationLogsRepository) | ||||||
| 		private moderationLogsRepository: ModerationLogsRepository, | 		private moderationLogsRepository: ModerationLogsRepository, | ||||||
| 
 | 
 | ||||||
|  | 		private moderationLogEntityService: ModerationLogEntityService, | ||||||
| 		private queryService: QueryService, | 		private queryService: QueryService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(meta, paramDef, async (ps, me) => { | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ import { ModerationLogService } from '@/core/ModerationLogService.js'; | ||||||
| import { UserSuspendService } from '@/core/UserSuspendService.js'; | import { UserSuspendService } from '@/core/UserSuspendService.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['admin'], | 	tags: ['admin'], | ||||||
|  | @ -36,6 +37,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		@Inject(DI.notificationsRepository) | 		@Inject(DI.notificationsRepository) | ||||||
| 		private notificationsRepository: NotificationsRepository, | 		private notificationsRepository: NotificationsRepository, | ||||||
| 
 | 
 | ||||||
|  | 		private userEntityService: UserEntityService, | ||||||
| 		private userFollowingService: UserFollowingService, | 		private userFollowingService: UserFollowingService, | ||||||
| 		private userSuspendService: UserSuspendService, | 		private userSuspendService: UserSuspendService, | ||||||
| 		private moderationLogService: ModerationLogService, | 		private moderationLogService: ModerationLogService, | ||||||
|  |  | ||||||
|  | @ -52,6 +52,9 @@ export const paramDef = { | ||||||
| 		enableRecaptcha: { type: 'boolean' }, | 		enableRecaptcha: { type: 'boolean' }, | ||||||
| 		recaptchaSiteKey: { type: 'string', nullable: true }, | 		recaptchaSiteKey: { type: 'string', nullable: true }, | ||||||
| 		recaptchaSecretKey: { type: 'string', nullable: true }, | 		recaptchaSecretKey: { type: 'string', nullable: true }, | ||||||
|  | 		enableTurnstile: { type: 'boolean' }, | ||||||
|  | 		turnstileSiteKey: { type: 'string', nullable: true }, | ||||||
|  | 		turnstileSecretKey: { type: 'string', nullable: true }, | ||||||
| 		sensitiveMediaDetection: { type: 'string', enum: ['none', 'all', 'local', 'remote'] }, | 		sensitiveMediaDetection: { type: 'string', enum: ['none', 'all', 'local', 'remote'] }, | ||||||
| 		sensitiveMediaDetectionSensitivity: { type: 'string', enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'] }, | 		sensitiveMediaDetectionSensitivity: { type: 'string', enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'] }, | ||||||
| 		setSensitiveFlagAutomatically: { type: 'boolean' }, | 		setSensitiveFlagAutomatically: { type: 'boolean' }, | ||||||
|  | @ -231,6 +234,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 				set.recaptchaSecretKey = ps.recaptchaSecretKey; | 				set.recaptchaSecretKey = ps.recaptchaSecretKey; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			if (ps.enableTurnstile !== undefined) { | ||||||
|  | 				set.enableTurnstile = ps.enableTurnstile; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (ps.turnstileSiteKey !== undefined) { | ||||||
|  | 				set.turnstileSiteKey = ps.turnstileSiteKey; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (ps.turnstileSecretKey !== undefined) { | ||||||
|  | 				set.turnstileSecretKey = ps.turnstileSecretKey; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			if (ps.sensitiveMediaDetection !== undefined) { | 			if (ps.sensitiveMediaDetection !== undefined) { | ||||||
| 				set.sensitiveMediaDetection = ps.sensitiveMediaDetection; | 				set.sensitiveMediaDetection = ps.sensitiveMediaDetection; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { NotesRepository, AntennaNotesRepository } from '@/models/index.js'; | import type { NotesRepository, AntennaNotesRepository, AntennasRepository } from '@/models/index.js'; | ||||||
| import { QueryService } from '@/core/QueryService.js'; | import { QueryService } from '@/core/QueryService.js'; | ||||||
| import { NoteReadService } from '@/core/NoteReadService.js'; | import { NoteReadService } from '@/core/NoteReadService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { UserBlockingService } from '@/core/UserBlockingService.js'; | import { UserBlockingService } from '@/core/UserBlockingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['account'], | 	tags: ['account'], | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { UserBlockingService } from '@/core/UserBlockingService.js'; | import { UserBlockingService } from '@/core/UserBlockingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['account'], | 	tags: ['account'], | ||||||
|  |  | ||||||
|  | @ -44,7 +44,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 		private globalEventService: GlobalEventService, | 		private globalEventService: GlobalEventService, | ||||||
| 	) { | 	) { | ||||||
| 		super(meta, paramDef, async (ps, me) => { | 		super(meta, paramDef, async (ps, me) => { | ||||||
| 			const channel = await Channels.findOneBy({ | 			const channel = await this.channelsRepository.findOneBy({ | ||||||
| 				id: ps.channelId, | 				id: ps.channelId, | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import { IdService } from '@/core/IdService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js'; | import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['account', 'notes', 'clips'], | 	tags: ['account', 'notes', 'clips'], | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js'; | import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['account', 'notes', 'clips'], | 	tags: ['account', 'notes', 'clips'], | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { ApPersonService } from '@/core/remote/activitypub/models/ApPersonService.js'; | import { ApPersonService } from '@/core/remote/activitypub/models/ApPersonService.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['federation'], | 	tags: ['federation'], | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['following', 'users'], | 	tags: ['following', 'users'], | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['following', 'users'], | 	tags: ['following', 'users'], | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['following', 'users'], | 	tags: ['following', 'users'], | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,10 +1,9 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { FollowingsRepository } from '@/models/index.js'; | import type { FollowingsRepository, UsersRepository } from '@/models/index.js'; | ||||||
| import type { UsersRepository } from '@/models/index.js'; |  | ||||||
| import { IdentifiableError } from '@/misc/identifiable-error.js'; | import { IdentifiableError } from '@/misc/identifiable-error.js'; | ||||||
| import { UserEntityService } from '@/core/entities/UserEntityService.js'; | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { UserFollowingService } from '@/core/UserFollowingService.js'; | import { UserFollowingService } from '@/core/UserFollowingService.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
|  | import { IsNull, Not } from 'typeorm'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { AccessTokensRepository } from '@/models/index.js'; | import type { AccessTokensRepository } from '@/models/index.js'; | ||||||
| import { AppEntityService } from '@/core/entities/AppEntityService.js'; | import { AppEntityService } from '@/core/entities/AppEntityService.js'; | ||||||
|  | @ -34,6 +35,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 			const tokens = await this.accessTokensRepository.find({ | 			const tokens = await this.accessTokensRepository.find({ | ||||||
| 				where: { | 				where: { | ||||||
| 					userId: me.id, | 					userId: me.id, | ||||||
|  | 					appId: Not(IsNull()), | ||||||
| 				}, | 				}, | ||||||
| 				take: ps.limit, | 				take: ps.limit, | ||||||
| 				skip: ps.offset, | 				skip: ps.offset, | ||||||
|  | @ -42,7 +44,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 				}, | 				}, | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
| 			return await Promise.all(tokens.map(token => this.appEntityService.pack(token.appId, me, { | 			return await Promise.all(tokens.map(token => this.appEntityService.pack(token.appId!, me, { | ||||||
| 				detail: true, | 				detail: true, | ||||||
| 			}))); | 			}))); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
|  | @ -78,7 +78,7 @@ export const paramDef = { | ||||||
| 		description: { ...descriptionSchema, nullable: true }, | 		description: { ...descriptionSchema, nullable: true }, | ||||||
| 		location: { ...locationSchema, nullable: true }, | 		location: { ...locationSchema, nullable: true }, | ||||||
| 		birthday: { ...birthdaySchema, nullable: true }, | 		birthday: { ...birthdaySchema, nullable: true }, | ||||||
| 		lang: { type: 'string', enum: [null, ...Object.keys(langmap)], nullable: true }, | 		lang: { type: 'string', enum: [null, ...Object.keys(langmap)] as string[], nullable: true }, | ||||||
| 		avatarId: { type: 'string', format: 'misskey:id', nullable: true }, | 		avatarId: { type: 'string', format: 'misskey:id', nullable: true }, | ||||||
| 		bannerId: { type: 'string', format: 'misskey:id', nullable: true }, | 		bannerId: { type: 'string', format: 'misskey:id', nullable: true }, | ||||||
| 		fields: { | 		fields: { | ||||||
|  | @ -109,9 +109,7 @@ export const paramDef = { | ||||||
| 		alwaysMarkNsfw: { type: 'boolean' }, | 		alwaysMarkNsfw: { type: 'boolean' }, | ||||||
| 		autoSensitive: { type: 'boolean' }, | 		autoSensitive: { type: 'boolean' }, | ||||||
| 		ffVisibility: { type: 'string', enum: ['public', 'followers', 'private'] }, | 		ffVisibility: { type: 'string', enum: ['public', 'followers', 'private'] }, | ||||||
| 		pinnedPageId: { type: 'array', items: { | 		pinnedPageId: { type: 'string', format: 'misskey:id' }, | ||||||
| 			type: 'string', format: 'misskey:id', |  | ||||||
| 		} }, |  | ||||||
| 		mutedWords: { type: 'array' }, | 		mutedWords: { type: 'array' }, | ||||||
| 		mutedInstances: { type: 'array', items: { | 		mutedInstances: { type: 'array', items: { | ||||||
| 			type: 'string', | 			type: 'string', | ||||||
|  | @ -266,7 +264,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 
 | 
 | ||||||
| 			// Publish meUpdated event
 | 			// Publish meUpdated event
 | ||||||
| 			this.globalEventService.publishMainStream(user.id, 'meUpdated', iObj); | 			this.globalEventService.publishMainStream(user.id, 'meUpdated', iObj); | ||||||
| 			this.globalEventService.publishUserEvent(user.id, 'updateUserProfile', await this.userProfilesRepository.findOneBy({ userId: user.id })); | 			this.globalEventService.publishUserEvent(user.id, 'updateUserProfile', await this.userProfilesRepository.findOneByOrFail({ userId: user.id })); | ||||||
| 
 | 
 | ||||||
| 			// 鍵垢を解除したとき、溜まっていたフォローリクエストがあるならすべて承認
 | 			// 鍵垢を解除したとき、溜まっていたフォローリクエストがあるならすべて承認
 | ||||||
| 			if (user.isLocked && ps.isLocked === false) { | 			if (user.isLocked && ps.isLocked === false) { | ||||||
|  |  | ||||||
|  | @ -1,15 +1,14 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Brackets } from 'typeorm'; | import { Brackets } from 'typeorm'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { UsersRepository } from '@/models/index.js'; | import type { UsersRepository, UserGroupsRepository, MessagingMessagesRepository, UserGroupJoiningsRepository } from '@/models/index.js'; | ||||||
| import type { UserGroupsRepository, MessagingMessagesRepository, UserGroupJoiningsRepository } from '@/models/index.js'; |  | ||||||
| import { QueryService } from '@/core/QueryService.js'; | import { QueryService } from '@/core/QueryService.js'; | ||||||
| import { UserEntityService } from '@/core/entities/UserEntityService.js'; | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { MessagingMessageEntityService } from '@/core/entities/MessagingMessageEntityService.js'; | import { MessagingMessageEntityService } from '@/core/entities/MessagingMessageEntityService.js'; | ||||||
| import { MessagingService } from '@/core/MessagingService.js'; | import { MessagingService } from '@/core/MessagingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['messaging'], | 	tags: ['messaging'], | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import type { BlockingsRepository, UserGroupJoiningsRepository, DriveFilesRepository, UserGroupsRepository } from '@/models/index.js'; | import type { BlockingsRepository, UserGroupJoiningsRepository, DriveFilesRepository, UserGroupsRepository } from '@/models/index.js'; | ||||||
| import type { User } from '@/models/entities/User.js'; | import type { User } from '@/models/entities/User.js'; | ||||||
| import type { UserGroup } from '@/models/entities/UserGroup.js'; | import type { UserGroup } from '@/models/entities/UserGroup.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { MessagingService } from '@/core/MessagingService.js'; | import { MessagingService } from '@/core/MessagingService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
|  |  | ||||||
|  | @ -119,6 +119,14 @@ export const meta = { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: false, nullable: true, | 				optional: false, nullable: true, | ||||||
| 			}, | 			}, | ||||||
|  | 			enableTurnstile: { | ||||||
|  | 				type: 'boolean', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			turnstileSiteKey: { | ||||||
|  | 				type: 'string', | ||||||
|  | 				optional: false, nullable: true, | ||||||
|  | 			}, | ||||||
| 			swPublickey: { | 			swPublickey: { | ||||||
| 				type: 'string', | 				type: 'string', | ||||||
| 				optional: false, nullable: true, | 				optional: false, nullable: true, | ||||||
|  | @ -372,6 +380,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 				hcaptchaSiteKey: instance.hcaptchaSiteKey, | 				hcaptchaSiteKey: instance.hcaptchaSiteKey, | ||||||
| 				enableRecaptcha: instance.enableRecaptcha, | 				enableRecaptcha: instance.enableRecaptcha, | ||||||
| 				recaptchaSiteKey: instance.recaptchaSiteKey, | 				recaptchaSiteKey: instance.recaptchaSiteKey, | ||||||
|  | 				enableTurnstile: instance.enableTurnstile, | ||||||
|  | 				turnstileSiteKey: instance.turnstileSiteKey, | ||||||
| 				swPublickey: instance.swPublicKey, | 				swPublickey: instance.swPublicKey, | ||||||
| 				themeColor: instance.themeColor, | 				themeColor: instance.themeColor, | ||||||
| 				mascotImageUrl: instance.mascotImageUrl, | 				mascotImageUrl: instance.mascotImageUrl, | ||||||
|  | @ -423,6 +433,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 					elasticsearch: this.config.elasticsearch ? true : false, | 					elasticsearch: this.config.elasticsearch ? true : false, | ||||||
| 					hcaptcha: instance.enableHcaptcha, | 					hcaptcha: instance.enableHcaptcha, | ||||||
| 					recaptcha: instance.enableRecaptcha, | 					recaptcha: instance.enableRecaptcha, | ||||||
|  | 					turnstile: instance.enableTurnstile, | ||||||
| 					objectStorage: instance.useObjectStorage, | 					objectStorage: instance.useObjectStorage, | ||||||
| 					twitter: instance.enableTwitterIntegration, | 					twitter: instance.enableTwitterIntegration, | ||||||
| 					github: instance.enableGithubIntegration, | 					github: instance.enableGithubIntegration, | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ import type { Muting } from '@/models/entities/Muting.js'; | ||||||
| import { GlobalEventService } from '@/core/GlobalEventService.js'; | import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['account'], | 	tags: ['account'], | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import type { MutingsRepository } from '@/models/index.js'; | ||||||
| import { GlobalEventService } from '@/core/GlobalEventService.js'; | import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['account'], | 	tags: ['account'], | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; | import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['clips', 'notes'], | 	tags: ['clips', 'notes'], | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['notes'], | 	tags: ['notes'], | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { NoteDeleteService } from '@/core/NoteDeleteService.js'; | import { NoteDeleteService } from '@/core/NoteDeleteService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['notes'], | 	tags: ['notes'], | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import type { NoteFavoritesRepository } from '@/models/index.js'; | import type { NoteFavoritesRepository } from '@/models/index.js'; | ||||||
| import { IdService } from '@/core/IdService.js'; | import { IdService } from '@/core/IdService.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import type { NoteFavoritesRepository } from '@/models/index.js'; | import type { NoteFavoritesRepository } from '@/models/index.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import type { UsersRepository, BlockingsRepository, PollsRepository, PollVotesRe | ||||||
| import type { IRemoteUser } from '@/models/entities/User.js'; | import type { IRemoteUser } from '@/models/entities/User.js'; | ||||||
| import { IdService } from '@/core/IdService.js'; | import { IdService } from '@/core/IdService.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { QueueService } from '@/core/QueueService.js'; | import { QueueService } from '@/core/QueueService.js'; | ||||||
| import { PollService } from '@/core/PollService.js'; | import { PollService } from '@/core/PollService.js'; | ||||||
| import { ApRendererService } from '@/core/remote/activitypub/ApRendererService.js'; | import { ApRendererService } from '@/core/remote/activitypub/ApRendererService.js'; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { ReactionService } from '@/core/ReactionService.js'; | import { ReactionService } from '@/core/ReactionService.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import ms from 'ms'; | import ms from 'ms'; | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { ReactionService } from '@/core/ReactionService.js'; | import { ReactionService } from '@/core/ReactionService.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import { QueryService } from '@/core/QueryService.js'; | ||||||
| import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['notes'], | 	tags: ['notes'], | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['notes'], | 	tags: ['notes'], | ||||||
|  |  | ||||||
|  | @ -16,10 +16,6 @@ export const meta = { | ||||||
| 				type: 'boolean', | 				type: 'boolean', | ||||||
| 				optional: false, nullable: false, | 				optional: false, nullable: false, | ||||||
| 			}, | 			}, | ||||||
| 			isWatching: { |  | ||||||
| 				type: 'boolean', |  | ||||||
| 				optional: false, nullable: false, |  | ||||||
| 			}, |  | ||||||
| 			isMutedThread: { | 			isMutedThread: { | ||||||
| 				type: 'boolean', | 				type: 'boolean', | ||||||
| 				optional: false, nullable: false, | 				optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import type { NotesRepository, NoteThreadMutingsRepository } from '@/models/index.js'; | import type { NotesRepository, NoteThreadMutingsRepository } from '@/models/index.js'; | ||||||
| import { IdService } from '@/core/IdService.js'; | import { IdService } from '@/core/IdService.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { NoteReadService } from '@/core/NoteReadService.js'; | import { NoteReadService } from '@/core/NoteReadService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import type { NoteThreadMutingsRepository } from '@/models/index.js'; | import type { NoteThreadMutingsRepository } from '@/models/index.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; | ||||||
| import { MetaService } from '@/core/MetaService.js'; | import { MetaService } from '@/core/MetaService.js'; | ||||||
| import { HttpRequestService } from '@/core/HttpRequestService.js'; | import { HttpRequestService } from '@/core/HttpRequestService.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['notes'], | 	tags: ['notes'], | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { NoteDeleteService } from '@/core/NoteDeleteService.js'; | import { NoteDeleteService } from '@/core/NoteDeleteService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['notes'], | 	tags: ['notes'], | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import { IdService } from '@/core/IdService.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['notes'], | 	tags: ['notes'], | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { IsNull } from 'typeorm'; | import { IsNull } from 'typeorm'; | ||||||
| import type { InstancesRepository, NotesRepository, UsersRepository } from '@/models/index.js'; | import type { InstancesRepository, NoteReactionsRepository, NotesRepository, UsersRepository } from '@/models/index.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { UserEntityService } from '@/core/entities/UserEntityService.js'; | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../error.js'; | import { ApiError } from '../../error.js'; | ||||||
| import { GetterService } from '../../common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['users'], | 	tags: ['users'], | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import type { UserGroupsRepository, UserGroupJoiningsRepository, UserGroupInvita | ||||||
| import { IdService } from '@/core/IdService.js'; | import { IdService } from '@/core/IdService.js'; | ||||||
| import type { UserGroupInvitation } from '@/models/entities/UserGroupInvitation.js'; | import type { UserGroupInvitation } from '@/models/entities/UserGroupInvitation.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { CreateNotificationService } from '@/core/CreateNotificationService.js'; | import { CreateNotificationService } from '@/core/CreateNotificationService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js'; | import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js'; | import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js'; | ||||||
| import { Endpoint } from '@/server/api/endpoint-base.js'; | import { Endpoint } from '@/server/api/endpoint-base.js'; | ||||||
| import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js'; | import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js'; | ||||||
| import { GetterService } from '@/server/api/common/GetterService.js'; | import { GetterService } from '@/server/api/GetterService.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { ApiError } from '../../../error.js'; | import { ApiError } from '../../../error.js'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue