mirror of https://github.com/Chocobozzz/PeerTube
Remove old JSON LD signature implementation
Only PeerTube was compatible with it, and the library has moved on RsaSignature2018 and removed RsaSignature2017 support. We had to create a dirty fork of the RsaSignature2017 branch, which is not ideal. Now we use the Mastodon implementation, that most other AP implementations that support JSONLD signatures use.pull/2107/head
parent
f0a47bc92a
commit
ad513607a3
|
@ -128,7 +128,6 @@
|
|||
"iso-639-3": "^1.0.1",
|
||||
"js-yaml": "^3.5.4",
|
||||
"jsonld": "~1.1.0",
|
||||
"jsonld-signatures": "https://github.com/Chocobozzz/jsonld-signatures#rsa2017",
|
||||
"lodash": "^4.17.10",
|
||||
"lru-cache": "^5.1.1",
|
||||
"magnet-uri": "^5.1.4",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import * as AsyncLRU from 'async-lru'
|
||||
import * as jsonld from 'jsonld'
|
||||
import * as jsig from 'jsonld-signatures'
|
||||
import { logger } from './logger'
|
||||
|
||||
const CACHE = {
|
||||
|
@ -79,6 +78,4 @@ jsonld.documentLoader = (url, cb) => {
|
|||
lru.get(url, cb)
|
||||
}
|
||||
|
||||
jsig.use('jsonld', jsonld)
|
||||
|
||||
export { jsig, jsonld }
|
||||
export { jsonld }
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { Request } from 'express'
|
||||
import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants'
|
||||
import { ActorModel } from '../models/activitypub/actor'
|
||||
import { createPrivateKey, getPublicKey, promisify1, promisify2, sha256 } from './core-utils'
|
||||
import { jsig, jsonld } from './custom-jsonld-signature'
|
||||
import { jsonld } from './custom-jsonld-signature'
|
||||
import { logger } from './logger'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { createVerify } from 'crypto'
|
||||
import { createSign, createVerify } from 'crypto'
|
||||
import { buildDigest } from '../lib/job-queue/handlers/utils/activitypub-http-utils'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
import { MActor } from '../typings/models'
|
||||
|
@ -57,70 +56,21 @@ function parseHTTPSignature (req: Request, clockSkew?: number) {
|
|||
|
||||
// JSONLD
|
||||
|
||||
async function isJsonLDSignatureVerified (fromActor: MActor, signedDocument: any): Promise<boolean> {
|
||||
function isJsonLDSignatureVerified (fromActor: MActor, signedDocument: any): Promise<boolean> {
|
||||
if (signedDocument.signature.type === 'RsaSignature2017') {
|
||||
// Mastodon algorithm
|
||||
const res = await isJsonLDRSA2017Verified(fromActor, signedDocument)
|
||||
// Success? If no, try with our library
|
||||
if (res === true) return true
|
||||
return isJsonLDRSA2017Verified(fromActor, signedDocument)
|
||||
}
|
||||
|
||||
const publicKeyObject = {
|
||||
'@context': jsig.SECURITY_CONTEXT_URL,
|
||||
id: fromActor.url,
|
||||
type: 'CryptographicKey',
|
||||
owner: fromActor.url,
|
||||
publicKeyPem: fromActor.publicKey
|
||||
}
|
||||
logger.warn('Unknown JSON LD signature %s.', signedDocument.signature.type, signedDocument)
|
||||
|
||||
const publicKeyOwnerObject = {
|
||||
'@context': jsig.SECURITY_CONTEXT_URL,
|
||||
id: fromActor.url,
|
||||
publicKey: [ publicKeyObject ]
|
||||
}
|
||||
|
||||
const options = {
|
||||
publicKey: publicKeyObject,
|
||||
publicKeyOwner: publicKeyOwnerObject
|
||||
}
|
||||
|
||||
return jsig.promises
|
||||
.verify(signedDocument, options)
|
||||
.then((result: { verified: boolean }) => result.verified)
|
||||
.catch(err => {
|
||||
logger.error('Cannot check signature.', { err })
|
||||
return false
|
||||
})
|
||||
return Promise.resolve(false)
|
||||
}
|
||||
|
||||
// Backward compatibility with "other" implementations
|
||||
async function isJsonLDRSA2017Verified (fromActor: MActor, signedDocument: any) {
|
||||
function hash (obj: any): Promise<any> {
|
||||
return jsonld.promises
|
||||
.normalize(obj, {
|
||||
algorithm: 'URDNA2015',
|
||||
format: 'application/n-quads'
|
||||
})
|
||||
.then(res => sha256(res))
|
||||
}
|
||||
|
||||
const signatureCopy = cloneDeep(signedDocument.signature)
|
||||
Object.assign(signatureCopy, {
|
||||
'@context': [
|
||||
'https://w3id.org/security/v1',
|
||||
{ RsaSignature2017: 'https://w3id.org/security#RsaSignature2017' }
|
||||
]
|
||||
})
|
||||
delete signatureCopy.type
|
||||
delete signatureCopy.id
|
||||
delete signatureCopy.signatureValue
|
||||
|
||||
const docWithoutSignature = cloneDeep(signedDocument)
|
||||
delete docWithoutSignature.signature
|
||||
|
||||
const [ documentHash, optionsHash ] = await Promise.all([
|
||||
hash(docWithoutSignature),
|
||||
hash(signatureCopy)
|
||||
createDocWithoutSignatureHash(signedDocument),
|
||||
createSignatureHash(signedDocument.signature)
|
||||
])
|
||||
|
||||
const toVerify = optionsHash + documentHash
|
||||
|
@ -131,14 +81,27 @@ async function isJsonLDRSA2017Verified (fromActor: MActor, signedDocument: any)
|
|||
return verify.verify(fromActor.publicKey, signedDocument.signature.signatureValue, 'base64')
|
||||
}
|
||||
|
||||
function signJsonLDObject (byActor: MActor, data: any) {
|
||||
const options = {
|
||||
privateKeyPem: byActor.privateKey,
|
||||
async function signJsonLDObject (byActor: MActor, data: any) {
|
||||
const signature = {
|
||||
type: 'RsaSignature2017',
|
||||
creator: byActor.url,
|
||||
algorithm: 'RsaSignature2017'
|
||||
created: new Date().toISOString()
|
||||
}
|
||||
|
||||
return jsig.promises.sign(data, options)
|
||||
const [ documentHash, optionsHash ] = await Promise.all([
|
||||
createDocWithoutSignatureHash(data),
|
||||
createSignatureHash(signature)
|
||||
])
|
||||
|
||||
const toSign = optionsHash + documentHash
|
||||
|
||||
const sign = createSign('RSA-SHA256')
|
||||
sign.update(toSign, 'utf8')
|
||||
|
||||
const signatureValue = sign.sign(byActor.privateKey, 'base64')
|
||||
Object.assign(signature, { signatureValue })
|
||||
|
||||
return Object.assign(data, { signature })
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -155,3 +118,35 @@ export {
|
|||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function hash (obj: any): Promise<any> {
|
||||
return jsonld.promises
|
||||
.normalize(obj, {
|
||||
algorithm: 'URDNA2015',
|
||||
format: 'application/n-quads'
|
||||
})
|
||||
.then(res => sha256(res))
|
||||
}
|
||||
|
||||
function createSignatureHash (signature: any) {
|
||||
const signatureCopy = cloneDeep(signature)
|
||||
Object.assign(signatureCopy, {
|
||||
'@context': [
|
||||
'https://w3id.org/security/v1',
|
||||
{ RsaSignature2017: 'https://w3id.org/security#RsaSignature2017' }
|
||||
]
|
||||
})
|
||||
|
||||
delete signatureCopy.type
|
||||
delete signatureCopy.id
|
||||
delete signatureCopy.signatureValue
|
||||
|
||||
return hash(signatureCopy)
|
||||
}
|
||||
|
||||
function createDocWithoutSignatureHash (doc: any) {
|
||||
const docWithoutSignature = cloneDeep(doc)
|
||||
delete docWithoutSignature.signature
|
||||
|
||||
return hash(docWithoutSignature)
|
||||
}
|
||||
|
|
|
@ -101,6 +101,8 @@ async function checkJsonLDSignature (req: Request, res: Response) {
|
|||
const verified = await isJsonLDSignatureVerified(actor, req.body)
|
||||
|
||||
if (verified !== true) {
|
||||
logger.warn('Signature not verified.', req.body)
|
||||
|
||||
res.sendStatus(403)
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -53,19 +53,6 @@ describe('Test activity pub helpers', function () {
|
|||
expect(result).to.be.false
|
||||
})
|
||||
|
||||
it('Should fail with an invalid PeerTube URL', async function () {
|
||||
const keys = require('./json/peertube/keys.json')
|
||||
const body = require('./json/peertube/announce-without-context.json')
|
||||
|
||||
const actorSignature = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey }
|
||||
const signedBody = await buildSignedActivity(actorSignature as any, body)
|
||||
|
||||
const fromActor = { publicKey: keys.publicKey, url: 'http://localhost:9003/accounts/peertube' }
|
||||
const result = await isJsonLDSignatureVerified(fromActor as any, signedBody)
|
||||
|
||||
expect(result).to.be.false
|
||||
})
|
||||
|
||||
it('Should succeed with a valid PeerTube signature', async function () {
|
||||
const keys = require('./json/peertube/keys.json')
|
||||
const body = require('./json/peertube/announce-without-context.json')
|
||||
|
|
124
yarn.lock
124
yarn.lock
|
@ -828,24 +828,6 @@ bindings@~1.3.0:
|
|||
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5"
|
||||
integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==
|
||||
|
||||
bitcore-lib@^0.13.7:
|
||||
version "0.13.19"
|
||||
resolved "https://registry.yarnpkg.com/bitcore-lib/-/bitcore-lib-0.13.19.tgz#48af1e9bda10067c1ab16263472b5add2000f3dc"
|
||||
integrity sha1-SK8em9oQBnwasWJjRyta3SAA89w=
|
||||
dependencies:
|
||||
bn.js "=2.0.4"
|
||||
bs58 "=2.0.0"
|
||||
buffer-compare "=1.0.0"
|
||||
elliptic "=3.0.3"
|
||||
inherits "=2.0.1"
|
||||
lodash "=3.10.1"
|
||||
|
||||
"bitcore-message@github:CoMakery/bitcore-message#dist":
|
||||
version "1.0.2"
|
||||
resolved "https://codeload.github.com/CoMakery/bitcore-message/tar.gz/8799cc327029c3d34fc725f05b2cf981363f6ebf"
|
||||
dependencies:
|
||||
bitcore-lib "^0.13.7"
|
||||
|
||||
bitfield@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bitfield/-/bitfield-2.0.0.tgz#fbe6767592fe5b4c87ecf1d04126294cc1bfa837"
|
||||
|
@ -968,16 +950,6 @@ bluebird@^3.0.5, bluebird@^3.5.0:
|
|||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
|
||||
integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==
|
||||
|
||||
bn.js@=2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.0.4.tgz#220a7cd677f7f1bfa93627ff4193776fe7819480"
|
||||
integrity sha1-Igp81nf38b+pNif/QZN3b+eBlIA=
|
||||
|
||||
bn.js@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.2.0.tgz#12162bc2ae71fc40a5626c33438f3a875cd37625"
|
||||
integrity sha1-EhYrwq5x/EClYmwzQ486h1zTdiU=
|
||||
|
||||
bn.js@^4.4.0:
|
||||
version "4.11.8"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
|
||||
|
@ -1043,11 +1015,6 @@ braces@^3.0.1:
|
|||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
brorand@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
|
||||
|
||||
browser-stdout@1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
||||
|
@ -1058,11 +1025,6 @@ browserify-package-json@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/browserify-package-json/-/browserify-package-json-1.0.1.tgz#98dde8aa5c561fd6d3fe49bbaa102b74b396fdea"
|
||||
integrity sha1-mN3oqlxWH9bT/km7qhArdLOW/eo=
|
||||
|
||||
bs58@=2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.0.tgz#72b713bed223a0ac518bbda0e3ce3f4817f39eb5"
|
||||
integrity sha1-crcTvtIjoKxRi72g484/SBfznrU=
|
||||
|
||||
buffer-alloc-unsafe@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||
|
@ -1076,16 +1038,6 @@ buffer-alloc@^1.1.0, buffer-alloc@^1.2.0:
|
|||
buffer-alloc-unsafe "^1.1.0"
|
||||
buffer-fill "^1.0.0"
|
||||
|
||||
buffer-compare@=1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-compare/-/buffer-compare-1.0.0.tgz#acaa7a966e98eee9fae14b31c39a5f158fb3c4a2"
|
||||
integrity sha1-rKp6lm6Y7un64Usxw5pfFY+zxKI=
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
||||
|
||||
buffer-equals@^1.0.3, buffer-equals@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equals/-/buffer-equals-1.0.4.tgz#0353b54fd07fd9564170671ae6f66b9cf10d27f5"
|
||||
|
@ -2096,13 +2048,6 @@ ecc-jsbn@~0.1.1:
|
|||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
ecdsa-sig-formatter@1.0.11:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
|
||||
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
|
@ -2113,16 +2058,6 @@ elegant-spinner@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
|
||||
integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=
|
||||
|
||||
elliptic@=3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-3.0.3.tgz#865c9b420bfbe55006b9f969f97a0d2c44966595"
|
||||
integrity sha1-hlybQgv75VAGuflp+XoNLESWZZU=
|
||||
dependencies:
|
||||
bn.js "^2.0.0"
|
||||
brorand "^1.0.1"
|
||||
hash.js "^1.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
emoji-regex@^7.0.1:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
||||
|
@ -3250,14 +3185,6 @@ has@^1.0.1, has@^1.0.3:
|
|||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hash.js@^1.0.0:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
|
||||
integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
minimalistic-assert "^1.0.1"
|
||||
|
||||
hashish@~0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/hashish/-/hashish-0.0.4.tgz#6d60bc6ffaf711b6afd60e426d077988014e6554"
|
||||
|
@ -3481,11 +3408,6 @@ inherits@2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
inherits@=2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
||||
integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
|
||||
|
||||
ini@^1.3.4, ini@~1.3.0:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
|
@ -4028,25 +3950,6 @@ jsonify@~0.0.0:
|
|||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
|
||||
|
||||
"jsonld-signatures@https://github.com/Chocobozzz/jsonld-signatures#rsa2017":
|
||||
version "1.2.2-2"
|
||||
resolved "https://github.com/Chocobozzz/jsonld-signatures#77660963e722eb4541d2d255f9d9d4216329665f"
|
||||
dependencies:
|
||||
bitcore-message "github:CoMakery/bitcore-message#dist"
|
||||
jsonld "^0.5.12"
|
||||
jws "^3.1.4"
|
||||
node-forge "^0.7.1"
|
||||
|
||||
jsonld@^0.5.12:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-0.5.21.tgz#4d5b78d717eb92bcd1ac9d88e34efad95370c0bf"
|
||||
integrity sha512-1dQhaw1Eb3p7Cz5ECE2DNPwLvTmK+f6D45hACBdonJaFKP1bN9zlKLZWbPZQeZtduAc/LNv10J4ML0IiTBVahw==
|
||||
dependencies:
|
||||
rdf-canonize "^0.2.1"
|
||||
request "^2.83.0"
|
||||
semver "^5.5.0"
|
||||
xmldom "0.1.19"
|
||||
|
||||
jsonld@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-1.1.0.tgz#afcb168c44557a7bddead4d4513c3cbcae3bc5b9"
|
||||
|
@ -4082,23 +3985,6 @@ junk@^3.1.0:
|
|||
resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1"
|
||||
integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==
|
||||
|
||||
jwa@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
|
||||
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
|
||||
dependencies:
|
||||
buffer-equal-constant-time "1.0.1"
|
||||
ecdsa-sig-formatter "1.0.11"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
jws@^3.1.4:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
|
||||
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
|
||||
dependencies:
|
||||
jwa "^1.4.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
k-bucket@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/k-bucket/-/k-bucket-4.0.1.tgz#3fc2e5693f0b7bff90d7b6b476edd6087955d542"
|
||||
|
@ -4335,11 +4221,6 @@ lodash@4.17.4:
|
|||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=
|
||||
|
||||
lodash@=3.10.1:
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
|
||||
integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
|
||||
|
||||
lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.3.0, lodash@~4.17.10:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
|
@ -4638,11 +4519,6 @@ mimic-response@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
|
||||
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
|
||||
|
||||
minimalistic-assert@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
||||
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
|
||||
|
||||
minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
|
|
Loading…
Reference in New Issue