ActivityPubでリモートのオブジェクトをGETするときのリクエストをHTTP Signatureで署名するオプション (#6731)
* Sign ActivityPub GET * Fix v12, v12.48.0 UI bug
This commit is contained in:
		
							parent
							
								
									ba3c62bf9c
								
							
						
					
					
						commit
						85a0f696bc
					
				
					 10 changed files with 298 additions and 8 deletions
				
			
		|  | @ -154,3 +154,6 @@ id: 'aid' | |||
| 
 | ||||
| # Media Proxy | ||||
| #mediaProxy: https://example.com/proxy | ||||
| 
 | ||||
| # Sign to ActivityPub GET request (default: false) | ||||
| #signToActivityPubGet: true | ||||
|  |  | |||
|  | @ -138,6 +138,7 @@ | |||
| 		"file-type": "15.0.1", | ||||
| 		"fluent-ffmpeg": "2.1.2", | ||||
| 		"glob": "7.1.6", | ||||
| 		"got": "11.7.0", | ||||
| 		"gulp": "4.0.2", | ||||
| 		"gulp-rename": "2.0.0", | ||||
| 		"gulp-replace": "1.0.0", | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ export default defineComponent({ | |||
| 		const acct = new URL(location.href).searchParams.get('acct'); | ||||
| 		if (acct == null) return; | ||||
| 
 | ||||
| 		/* | ||||
| 		const dialog = os.dialog({ | ||||
| 			type: 'waiting', | ||||
| 			text: this.$t('fetchingAsApObject') + '...', | ||||
|  | @ -19,6 +20,7 @@ export default defineComponent({ | |||
| 			showCancelButton: false, | ||||
| 			cancelableByBgClick: false | ||||
| 		}); | ||||
| 		*/ | ||||
| 
 | ||||
| 		if (acct.startsWith('https://')) { | ||||
| 			os.api('ap/show', { | ||||
|  | @ -26,6 +28,8 @@ export default defineComponent({ | |||
| 			}).then(res => { | ||||
| 				if (res.type == 'User') { | ||||
| 					this.follow(res.object); | ||||
| 				} else if (res.type === 'Note') { | ||||
| 					this.$router.push(`/notes/${res.object.id}`); | ||||
| 				} else { | ||||
| 					os.dialog({ | ||||
| 						type: 'error', | ||||
|  | @ -42,7 +46,7 @@ export default defineComponent({ | |||
| 					window.close(); | ||||
| 				}); | ||||
| 			}).finally(() => { | ||||
| 				dialog.close(); | ||||
| 				//dialog.close(); | ||||
| 			}); | ||||
| 		} else { | ||||
| 			os.api('users/show', parseAcct(acct)).then(user => { | ||||
|  | @ -55,7 +59,7 @@ export default defineComponent({ | |||
| 					window.close(); | ||||
| 				}); | ||||
| 			}).finally(() => { | ||||
| 				dialog.close(); | ||||
| 				//dialog.close(); | ||||
| 			}); | ||||
| 		} | ||||
| 	}, | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ export async function search(q?: string | null | undefined) { | |||
| 	} | ||||
| 
 | ||||
| 	if (q.startsWith('https://')) { | ||||
| 		/* | ||||
| 		const dialog = os.dialog({ | ||||
| 			type: 'waiting', | ||||
| 			text: i18n.global.t('fetchingAsApObject') + '...', | ||||
|  | @ -55,19 +56,20 @@ export async function search(q?: string | null | undefined) { | |||
| 			showCancelButton: false, | ||||
| 			cancelableByBgClick: false | ||||
| 		}); | ||||
| 		*/ | ||||
| 
 | ||||
| 		try { | ||||
| 			const res = await os.api('ap/show', { | ||||
| 				uri: q | ||||
| 			}); | ||||
| 			dialog.cancel(); | ||||
| 			//dialog.cancel();
 | ||||
| 			if (res.type === 'User') { | ||||
| 				router.push(`/@${res.object.username}@${res.object.host}`); | ||||
| 			} else if (res.type === 'Note') { | ||||
| 				router.push(`/notes/${res.object.id}`); | ||||
| 			} | ||||
| 		} catch (e) { | ||||
| 			dialog.cancel(); | ||||
| 			//dialog.cancel();
 | ||||
| 			// TODO: Show error
 | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -58,6 +58,8 @@ export type Source = { | |||
| 	}; | ||||
| 
 | ||||
| 	mediaProxy?: string; | ||||
| 
 | ||||
| 	signToActivityPubGet?: boolean; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import fetch, { HeadersInit } from 'node-fetch'; | |||
| import { HttpProxyAgent } from 'http-proxy-agent'; | ||||
| import { HttpsProxyAgent } from 'https-proxy-agent'; | ||||
| import config from '../config'; | ||||
| import { URL } from 'url'; | ||||
| 
 | ||||
| export async function getJson(url: string, accept = 'application/json, */*', timeout = 10000, headers?: HeadersInit) { | ||||
| 	const res = await fetch(url, { | ||||
|  | @ -69,14 +70,14 @@ const _https = new https.Agent({ | |||
|  * Get http proxy or non-proxy agent | ||||
|  */ | ||||
| export const httpAgent = config.proxy | ||||
| 	? new HttpProxyAgent(config.proxy) | ||||
| 	? new HttpProxyAgent(config.proxy) as unknown as http.Agent | ||||
| 	: _http; | ||||
| 
 | ||||
| /** | ||||
|  * Get https proxy or non-proxy agent | ||||
|  */ | ||||
| export const httpsAgent = config.proxy | ||||
| 	? new HttpsProxyAgent(config.proxy) | ||||
| 	? new HttpsProxyAgent(config.proxy) as unknown as https.Agent | ||||
| 	: _https; | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| import * as http from 'http'; | ||||
| import * as https from 'https'; | ||||
| import { sign } from 'http-signature'; | ||||
| import * as crypto from 'crypto'; | ||||
|  | @ -7,6 +8,9 @@ import { ILocalUser } from '../../models/entities/user'; | |||
| import { UserKeypairs } from '../../models'; | ||||
| import { ensure } from '../../prelude/ensure'; | ||||
| import { getAgentByUrl } from '../../misc/fetch'; | ||||
| import { URL } from 'url'; | ||||
| import got from 'got'; | ||||
| import * as Got from 'got'; | ||||
| 
 | ||||
| export default async (user: ILocalUser, url: string, object: any) => { | ||||
| 	const timeout = 10 * 1000; | ||||
|  | @ -62,3 +66,96 @@ export default async (user: ILocalUser, url: string, object: any) => { | |||
| 		req.end(data); | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Get AP object with http-signature | ||||
|  * @param user http-signature user | ||||
|  * @param url URL to fetch | ||||
|  */ | ||||
| export async function signedGet(url: string, user: ILocalUser) { | ||||
| 	const timeout = 10 * 1000; | ||||
| 
 | ||||
| 	const keypair = await UserKeypairs.findOne({ | ||||
| 		userId: user.id | ||||
| 	}).then(ensure); | ||||
| 
 | ||||
| 	const req = got.get<any>(url, { | ||||
| 		headers: { | ||||
| 			'Accept': 'application/activity+json, application/ld+json', | ||||
| 			'User-Agent': config.userAgent, | ||||
| 		}, | ||||
| 		responseType: 'json', | ||||
| 		timeout, | ||||
| 		hooks: { | ||||
| 			beforeRequest: [ | ||||
| 				options => { | ||||
| 					options.request = (url: URL, opt: http.RequestOptions, callback?: (response: any) => void) => { | ||||
| 						// Select custom agent by URL
 | ||||
| 						opt.agent = getAgentByUrl(url, false); | ||||
| 
 | ||||
| 						// Wrap original https?.request
 | ||||
| 						const requestFunc = url.protocol === 'http:' ? http.request : https.request; | ||||
| 						const clientRequest = requestFunc(url, opt, callback) as http.ClientRequest; | ||||
| 
 | ||||
| 						// HTTP-Signature
 | ||||
| 						sign(clientRequest, { | ||||
| 							authorizationHeaderName: 'Signature', | ||||
| 							key: keypair.privateKey, | ||||
| 							keyId: `${config.url}/users/${user.id}#main-key`, | ||||
| 							headers: ['(request-target)', 'host', 'date', 'accept'] | ||||
| 						}); | ||||
| 
 | ||||
| 						return clientRequest; | ||||
| 					}; | ||||
| 				}, | ||||
| 			], | ||||
| 		}, | ||||
| 		retry: 0, | ||||
| 	}); | ||||
| 
 | ||||
| 	const res = await receiveResponce(req, 10 * 1024 * 1024); | ||||
| 
 | ||||
| 	return res.body; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Receive response (with size limit) | ||||
|  * @param req Request | ||||
|  * @param maxSize size limit | ||||
|  */ | ||||
| export async function receiveResponce<T>(req: Got.CancelableRequest<Got.Response<T>>, maxSize: number) { | ||||
| 	// 応答ヘッダでサイズチェック
 | ||||
| 	req.on('response', (res: Got.Response) => { | ||||
| 		const contentLength = res.headers['content-length']; | ||||
| 		if (contentLength != null) { | ||||
| 			const size = Number(contentLength); | ||||
| 			if (size > maxSize) { | ||||
| 				req.cancel(); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	// 受信中のデータでサイズチェック
 | ||||
| 	req.on('downloadProgress', (progress: Got.Progress) => { | ||||
| 		if (progress.transferred > maxSize) { | ||||
| 			req.cancel(); | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	// 応答取得 with ステータスコードエラーの整形
 | ||||
| 	const res = await req.catch(e => { | ||||
| 		if (e.name === 'HTTPError') { | ||||
| 			const statusCode = (e as Got.HTTPError).response.statusCode; | ||||
| 			const statusMessage = (e as Got.HTTPError).response.statusMessage; | ||||
| 			throw { | ||||
| 				name: `StatusError`, | ||||
| 				statusCode, | ||||
| 				message: `${statusCode} ${statusMessage}`, | ||||
| 			}; | ||||
| 		} else { | ||||
| 			throw e; | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	return res; | ||||
| } | ||||
|  |  | |||
|  | @ -1,8 +1,13 @@ | |||
| import config from '../../config'; | ||||
| import { getJson } from '../../misc/fetch'; | ||||
| import { ILocalUser } from '../../models/entities/user'; | ||||
| import { getInstanceActor } from '../../services/instance-actor'; | ||||
| import { signedGet } from './request'; | ||||
| import { IObject, isCollectionOrOrderedCollection, ICollection, IOrderedCollection } from './type'; | ||||
| 
 | ||||
| export default class Resolver { | ||||
| 	private history: Set<string>; | ||||
| 	private user?: ILocalUser; | ||||
| 
 | ||||
| 	constructor() { | ||||
| 		this.history = new Set(); | ||||
|  | @ -39,7 +44,13 @@ export default class Resolver { | |||
| 
 | ||||
| 		this.history.add(value); | ||||
| 
 | ||||
| 		const object = await getJson(value, 'application/activity+json, application/ld+json'); | ||||
| 		if (config.signToActivityPubGet && !this.user) { | ||||
| 			this.user = await getInstanceActor(); | ||||
| 		} | ||||
| 
 | ||||
| 		const object = this.user | ||||
| 			? await signedGet(value, this.user) | ||||
| 			: await getJson(value, 'application/activity+json, application/ld+json'); | ||||
| 
 | ||||
| 		if (object == null || ( | ||||
| 			Array.isArray(object['@context']) ? | ||||
|  |  | |||
							
								
								
									
										17
									
								
								src/services/instance-actor.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/services/instance-actor.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| import { createSystemUser } from './create-system-user'; | ||||
| import { ILocalUser } from '../models/entities/user'; | ||||
| import { Users } from '../models'; | ||||
| 
 | ||||
| const ACTOR_USERNAME = 'instance.actor' as const; | ||||
| 
 | ||||
| export async function getInstanceActor(): Promise<ILocalUser> { | ||||
| 	const user = await Users.findOne({ | ||||
| 		host: null, | ||||
| 		username: ACTOR_USERNAME | ||||
| 	}); | ||||
| 
 | ||||
| 	if (user) return user as ILocalUser; | ||||
| 
 | ||||
| 	const created = await createSystemUser(ACTOR_USERNAME); | ||||
| 	return created as ILocalUser; | ||||
| } | ||||
							
								
								
									
										154
									
								
								yarn.lock
									
										
									
									
									
								
							
							
						
						
									
										154
									
								
								yarn.lock
									
										
									
									
									
								
							|  | @ -236,6 +236,11 @@ | |||
|     "@nodelib/fs.scandir" "2.1.3" | ||||
|     fastq "^1.6.0" | ||||
| 
 | ||||
| "@sindresorhus/is@^3.1.1": | ||||
|   version "3.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-3.1.2.tgz#548650de521b344e3781fbdb0ece4aa6f729afb8" | ||||
|   integrity sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ== | ||||
| 
 | ||||
| "@sinonjs/commons@^1.7.0": | ||||
|   version "1.7.2" | ||||
|   resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.2.tgz#505f55c74e0272b43f6c52d81946bed7058fc0e2" | ||||
|  | @ -266,6 +271,13 @@ | |||
|     stringz "2.1.0" | ||||
|     uuid "7.0.3" | ||||
| 
 | ||||
| "@szmarczak/http-timer@^4.0.5": | ||||
|   version "4.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" | ||||
|   integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== | ||||
|   dependencies: | ||||
|     defer-to-connect "^2.0.0" | ||||
| 
 | ||||
| "@tokenizer/token@^0.1.0", "@tokenizer/token@^0.1.1": | ||||
|   version "0.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3" | ||||
|  | @ -308,6 +320,16 @@ | |||
|   dependencies: | ||||
|     "@types/ioredis" "*" | ||||
| 
 | ||||
| "@types/cacheable-request@^6.0.1": | ||||
|   version "6.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" | ||||
|   integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== | ||||
|   dependencies: | ||||
|     "@types/http-cache-semantics" "*" | ||||
|     "@types/keyv" "*" | ||||
|     "@types/node" "*" | ||||
|     "@types/responselike" "*" | ||||
| 
 | ||||
| "@types/cbor@5.0.1": | ||||
|   version "5.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/cbor/-/cbor-5.0.1.tgz#e147bbe09ada4db7000ec6c23eafb5f67f5422a5" | ||||
|  | @ -488,6 +510,11 @@ | |||
|   resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" | ||||
|   integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== | ||||
| 
 | ||||
| "@types/http-cache-semantics@*": | ||||
|   version "4.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" | ||||
|   integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== | ||||
| 
 | ||||
| "@types/ioredis@*": | ||||
|   version "4.14.9" | ||||
|   resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.14.9.tgz#774387d44d3ad60e1b849044b2b28b96e5813866" | ||||
|  | @ -539,6 +566,13 @@ | |||
|   resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" | ||||
|   integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== | ||||
| 
 | ||||
| "@types/keyv@*": | ||||
|   version "3.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" | ||||
|   integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== | ||||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
| 
 | ||||
| "@types/koa-bodyparser@4.3.0": | ||||
|   version "4.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/koa-bodyparser/-/koa-bodyparser-4.3.0.tgz#54ecd662c45f3a4fa9de849528de5fc8ab269ba5" | ||||
|  | @ -798,6 +832,13 @@ | |||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
| 
 | ||||
| "@types/responselike@*", "@types/responselike@^1.0.0": | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" | ||||
|   integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== | ||||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
| 
 | ||||
| "@types/rimraf@3.0.0": | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f" | ||||
|  | @ -2045,6 +2086,24 @@ cache-content-type@^1.0.0: | |||
|     mime-types "^2.1.18" | ||||
|     ylru "^1.2.0" | ||||
| 
 | ||||
| cacheable-lookup@^5.0.3: | ||||
|   version "5.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" | ||||
|   integrity sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w== | ||||
| 
 | ||||
| cacheable-request@^7.0.1: | ||||
|   version "7.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" | ||||
|   integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== | ||||
|   dependencies: | ||||
|     clone-response "^1.0.2" | ||||
|     get-stream "^5.1.0" | ||||
|     http-cache-semantics "^4.0.0" | ||||
|     keyv "^4.0.0" | ||||
|     lowercase-keys "^2.0.0" | ||||
|     normalize-url "^4.1.0" | ||||
|     responselike "^2.0.0" | ||||
| 
 | ||||
| cafy@15.2.1: | ||||
|   version "15.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/cafy/-/cafy-15.2.1.tgz#5a55eaeb721c604c7dca652f3d555c392e5f995a" | ||||
|  | @ -2415,6 +2474,13 @@ clone-buffer@^1.0.0: | |||
|   resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" | ||||
|   integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= | ||||
| 
 | ||||
| clone-response@^1.0.2: | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" | ||||
|   integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= | ||||
|   dependencies: | ||||
|     mimic-response "^1.0.0" | ||||
| 
 | ||||
| clone-stats@^1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" | ||||
|  | @ -3115,6 +3181,11 @@ default-resolution@^2.0.0: | |||
|   resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" | ||||
|   integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= | ||||
| 
 | ||||
| defer-to-connect@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" | ||||
|   integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== | ||||
| 
 | ||||
| define-properties@^1.1.2, define-properties@^1.1.3: | ||||
|   version "1.1.3" | ||||
|   resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" | ||||
|  | @ -4267,6 +4338,13 @@ get-stream@^4.0.0: | |||
|   dependencies: | ||||
|     pump "^3.0.0" | ||||
| 
 | ||||
| get-stream@^5.1.0: | ||||
|   version "5.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" | ||||
|   integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== | ||||
|   dependencies: | ||||
|     pump "^3.0.0" | ||||
| 
 | ||||
| get-value@^2.0.3, get-value@^2.0.6: | ||||
|   version "2.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" | ||||
|  | @ -4413,6 +4491,23 @@ good-listener@^1.2.2: | |||
|   dependencies: | ||||
|     delegate "^3.1.2" | ||||
| 
 | ||||
| got@11.7.0: | ||||
|   version "11.7.0" | ||||
|   resolved "https://registry.yarnpkg.com/got/-/got-11.7.0.tgz#a386360305571a74548872e674932b4ef70d3b24" | ||||
|   integrity sha512-7en2XwH2MEqOsrK0xaKhbWibBoZqy+f1RSUoIeF1BLcnf+pyQdDsljWMfmOh+QKJwuvDIiKx38GtPh5wFdGGjg== | ||||
|   dependencies: | ||||
|     "@sindresorhus/is" "^3.1.1" | ||||
|     "@szmarczak/http-timer" "^4.0.5" | ||||
|     "@types/cacheable-request" "^6.0.1" | ||||
|     "@types/responselike" "^1.0.0" | ||||
|     cacheable-lookup "^5.0.3" | ||||
|     cacheable-request "^7.0.1" | ||||
|     decompress-response "^6.0.0" | ||||
|     http2-wrapper "^1.0.0-beta.5.2" | ||||
|     lowercase-keys "^2.0.0" | ||||
|     p-cancelable "^2.0.0" | ||||
|     responselike "^2.0.0" | ||||
| 
 | ||||
| graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: | ||||
|   version "4.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" | ||||
|  | @ -4734,6 +4829,11 @@ http-assert@^1.3.0: | |||
|     deep-equal "~1.0.1" | ||||
|     http-errors "~1.7.2" | ||||
| 
 | ||||
| http-cache-semantics@^4.0.0: | ||||
|   version "4.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" | ||||
|   integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== | ||||
| 
 | ||||
| http-errors@1.7.3, http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.7.2: | ||||
|   version "1.7.3" | ||||
|   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" | ||||
|  | @ -4789,6 +4889,14 @@ http-signature@~1.2.0: | |||
|     jsprim "^1.2.2" | ||||
|     sshpk "^1.7.0" | ||||
| 
 | ||||
| http2-wrapper@^1.0.0-beta.5.2: | ||||
|   version "1.0.0-beta.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz#8b923deb90144aea65cf834b016a340fc98556f3" | ||||
|   integrity sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ== | ||||
|   dependencies: | ||||
|     quick-lru "^5.1.1" | ||||
|     resolve-alpn "^1.0.0" | ||||
| 
 | ||||
| http_ece@1.1.0: | ||||
|   version "1.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/http_ece/-/http_ece-1.1.0.tgz#74780c6eb32d8ddfe9e36a83abcd81fe0cd4fb75" | ||||
|  | @ -5478,6 +5586,11 @@ jsdom@16.4.0: | |||
|     ws "^7.2.3" | ||||
|     xml-name-validator "^3.0.0" | ||||
| 
 | ||||
| json-buffer@3.0.1: | ||||
|   version "3.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" | ||||
|   integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== | ||||
| 
 | ||||
| json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" | ||||
|  | @ -5608,6 +5721,13 @@ keygrip@~1.1.0: | |||
|   dependencies: | ||||
|     tsscmp "1.0.6" | ||||
| 
 | ||||
| keyv@^4.0.0: | ||||
|   version "4.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" | ||||
|   integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== | ||||
|   dependencies: | ||||
|     json-buffer "3.0.1" | ||||
| 
 | ||||
| kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: | ||||
|   version "3.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" | ||||
|  | @ -6086,6 +6206,11 @@ lower-case@^1.1.1: | |||
|   resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" | ||||
|   integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= | ||||
| 
 | ||||
| lowercase-keys@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" | ||||
|   integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== | ||||
| 
 | ||||
| lru-cache@^4.1.5: | ||||
|   version "4.1.5" | ||||
|   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" | ||||
|  | @ -6314,6 +6439,11 @@ mimic-fn@^2.0.0: | |||
|   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" | ||||
|   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== | ||||
| 
 | ||||
| mimic-response@^1.0.0: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" | ||||
|   integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== | ||||
| 
 | ||||
| mimic-response@^2.0.0: | ||||
|   version "2.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" | ||||
|  | @ -6656,6 +6786,11 @@ normalize-url@^3.0.0: | |||
|   resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" | ||||
|   integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== | ||||
| 
 | ||||
| normalize-url@^4.1.0: | ||||
|   version "4.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" | ||||
|   integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== | ||||
| 
 | ||||
| now-and-later@^2.0.0: | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" | ||||
|  | @ -6913,7 +7048,7 @@ osenv@^0.1.4: | |||
|     os-homedir "^1.0.0" | ||||
|     os-tmpdir "^1.0.0" | ||||
| 
 | ||||
| p-cancelable@2.0.0: | ||||
| p-cancelable@2.0.0, p-cancelable@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" | ||||
|   integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== | ||||
|  | @ -8048,6 +8183,11 @@ querystring@0.2.0: | |||
|   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" | ||||
|   integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= | ||||
| 
 | ||||
| quick-lru@^5.1.1: | ||||
|   version "5.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" | ||||
|   integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== | ||||
| 
 | ||||
| random-seed@0.3.0: | ||||
|   version "0.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/random-seed/-/random-seed-0.3.0.tgz#d945f2e1f38f49e8d58913431b8bf6bb937556cd" | ||||
|  | @ -8434,6 +8574,11 @@ require-main-filename@^2.0.0: | |||
|   resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" | ||||
|   integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== | ||||
| 
 | ||||
| resolve-alpn@^1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" | ||||
|   integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== | ||||
| 
 | ||||
| resolve-cwd@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" | ||||
|  | @ -8486,6 +8631,13 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.4.0, | |||
|   dependencies: | ||||
|     path-parse "^1.0.6" | ||||
| 
 | ||||
| responselike@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" | ||||
|   integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== | ||||
|   dependencies: | ||||
|     lowercase-keys "^2.0.0" | ||||
| 
 | ||||
| ret@~0.1.10: | ||||
|   version "0.1.15" | ||||
|   resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue