enhance(dev): non-production環境でhttpサーバー間でもユーザー、ノートの連合が可能なように (#10717)
* enhance(dev): non-production環境でhttpサーバー間でもユーザー、ノートの連合が可能なように * refactor (use checkHttps) * MISSKEY_WEBFINGER_USE_HTTP * Environment Variable readme * NEVER USE IN PRODUCTION * fix punyHost
This commit is contained in:
		| @@ -43,7 +43,8 @@ export class WebfingerService { | ||||
| 		const m = query.match(/^([^@]+)@(.*)/); | ||||
| 		if (m) { | ||||
| 			const hostname = m[2]; | ||||
| 			return `https://${hostname}/.well-known/webfinger?` + urlQuery({ resource: `acct:${query}` }); | ||||
| 			const useHttp = process.env.MISSKEY_WEBFINGER_USE_HTTP && process.env.MISSKEY_WEBFINGER_USE_HTTP.toLowerCase() === 'true'; | ||||
| 			return `http${useHttp ? '' : 's'}://${hostname}/.well-known/webfinger?${urlQuery({ resource: `acct:${query}` })}`; | ||||
| 		} | ||||
|  | ||||
| 		throw new Error(`Invalid query (${query})`); | ||||
|   | ||||
| @@ -12,6 +12,7 @@ import type Logger from '@/logger.js'; | ||||
| import { bindThis } from '@/decorators.js'; | ||||
| import { ApResolverService } from '../ApResolverService.js'; | ||||
| import { ApLoggerService } from '../ApLoggerService.js'; | ||||
| import { checkHttps } from '@/misc/check-https.js'; | ||||
|  | ||||
| @Injectable() | ||||
| export class ApImageService { | ||||
| @@ -48,8 +49,8 @@ export class ApImageService { | ||||
| 			throw new Error('invalid image: url not privided'); | ||||
| 		} | ||||
|  | ||||
| 		if (!image.url.startsWith('https://')) { | ||||
| 			throw new Error('invalid image: unexpected shcema of url: ' + image.url); | ||||
| 		if (!checkHttps(image.url)) { | ||||
| 			throw new Error('invalid image: unexpected schema of url: ' + image.url); | ||||
| 		} | ||||
|  | ||||
| 		this.logger.info(`Creating the Image: ${image.url}`); | ||||
|   | ||||
| @@ -32,6 +32,7 @@ import { ApQuestionService } from './ApQuestionService.js'; | ||||
| import { ApImageService } from './ApImageService.js'; | ||||
| import type { Resolver } from '../ApResolverService.js'; | ||||
| import type { IObject, IPost } from '../type.js'; | ||||
| import { checkHttps } from '@/misc/check-https.js'; | ||||
|  | ||||
| @Injectable() | ||||
| export class ApNoteService { | ||||
| @@ -130,13 +131,13 @@ export class ApNoteService { | ||||
| 	 | ||||
| 		this.logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); | ||||
|  | ||||
| 		if (note.id && !note.id.startsWith('https://')) { | ||||
| 		if (note.id && !checkHttps(note.id)) { | ||||
| 			throw new Error('unexpected shcema of note.id: ' + note.id); | ||||
| 		} | ||||
|  | ||||
| 		const url = getOneApHrefNullable(note.url); | ||||
|  | ||||
| 		if (url && !url.startsWith('https://')) { | ||||
| 		if (url && !checkHttps(url)) { | ||||
| 			throw new Error('unexpected shcema of note url: ' + url); | ||||
| 		} | ||||
| 	 | ||||
|   | ||||
| @@ -42,6 +42,7 @@ import type { ApLoggerService } from '../ApLoggerService.js'; | ||||
| // eslint-disable-next-line @typescript-eslint/consistent-type-imports | ||||
| import type { ApImageService } from './ApImageService.js'; | ||||
| import type { IActor, IObject } from '../type.js'; | ||||
| import { checkHttps } from '@/misc/check-https.js'; | ||||
|  | ||||
| const nameLength = 128; | ||||
| const summaryLength = 2048; | ||||
| @@ -134,6 +135,12 @@ export class ApPersonService implements OnModuleInit { | ||||
| 		this.logger = this.apLoggerService.logger; | ||||
| 	} | ||||
|  | ||||
| 	private punyHost(url: string): string { | ||||
| 		const urlObj = new URL(url); | ||||
| 		const host = `${this.utilityService.toPuny(urlObj.hostname)}${urlObj.port.length > 0 ? ':' + urlObj.port : ''}`; | ||||
| 		return host; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Validate and convert to actor object | ||||
| 	 * @param x Fetched object | ||||
| @@ -141,7 +148,7 @@ export class ApPersonService implements OnModuleInit { | ||||
| 	 */ | ||||
| 	@bindThis | ||||
| 	private validateActor(x: IObject, uri: string): IActor { | ||||
| 		const expectHost = this.utilityService.toPuny(new URL(uri).hostname); | ||||
| 		const expectHost = this.punyHost(uri); | ||||
|  | ||||
| 		if (x == null) { | ||||
| 			throw new Error('invalid Actor: object is null'); | ||||
| @@ -182,7 +189,7 @@ export class ApPersonService implements OnModuleInit { | ||||
| 			x.summary = truncate(x.summary, summaryLength); | ||||
| 		} | ||||
|  | ||||
| 		const idHost = this.utilityService.toPuny(new URL(x.id!).hostname); | ||||
| 		const idHost = this.punyHost(x.id); | ||||
| 		if (idHost !== expectHost) { | ||||
| 			throw new Error('invalid Actor: id has different host'); | ||||
| 		} | ||||
| @@ -192,7 +199,7 @@ export class ApPersonService implements OnModuleInit { | ||||
| 				throw new Error('invalid Actor: publicKey.id is not a string'); | ||||
| 			} | ||||
|  | ||||
| 			const publicKeyIdHost = this.utilityService.toPuny(new URL(x.publicKey.id).hostname); | ||||
| 			const publicKeyIdHost = this.punyHost(x.publicKey.id); | ||||
| 			if (publicKeyIdHost !== expectHost) { | ||||
| 				throw new Error('invalid Actor: publicKey.id has different host'); | ||||
| 			} | ||||
| @@ -252,7 +259,7 @@ export class ApPersonService implements OnModuleInit { | ||||
|  | ||||
| 		this.logger.info(`Creating the Person: ${person.id}`); | ||||
|  | ||||
| 		const host = this.utilityService.toPuny(new URL(object.id).hostname); | ||||
| 		const host = this.punyHost(object.id); | ||||
|  | ||||
| 		const { fields } = this.analyzeAttachments(person.attachment ?? []); | ||||
|  | ||||
| @@ -264,8 +271,8 @@ export class ApPersonService implements OnModuleInit { | ||||
|  | ||||
| 		const url = getOneApHrefNullable(person.url); | ||||
|  | ||||
| 		if (url && !url.startsWith('https://')) { | ||||
| 			throw new Error('unexpected shcema of person url: ' + url); | ||||
| 		if (url && !checkHttps(url)) { | ||||
| 			throw new Error('unexpected schema of person url: ' + url); | ||||
| 		} | ||||
|  | ||||
| 		// Create user | ||||
| @@ -459,8 +466,8 @@ export class ApPersonService implements OnModuleInit { | ||||
|  | ||||
| 		const url = getOneApHrefNullable(person.url); | ||||
|  | ||||
| 		if (url && !url.startsWith('https://')) { | ||||
| 			throw new Error('unexpected shcema of person url: ' + url); | ||||
| 		if (url && !checkHttps(url)) { | ||||
| 			throw new Error('unexpected schema of person url: ' + url); | ||||
| 		} | ||||
|  | ||||
| 		const updates = { | ||||
|   | ||||
							
								
								
									
										4
									
								
								packages/backend/src/misc/check-https.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/backend/src/misc/check-https.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| export function checkHttps(url: string) { | ||||
|     return url.startsWith('https://') || | ||||
|         (url.startsWith('http://') && process.env.NODE_ENV !== 'production'); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 tamaina
					tamaina