mirror of
https://framagit.org/les/gancio.git
synced 2025-01-31 16:42:22 +01:00
correctly verify http-signature
This commit is contained in:
parent
40f7ffa99e
commit
9b2015f46f
5 changed files with 39 additions and 51 deletions
|
@ -56,7 +56,7 @@
|
||||||
"email-templates": "^6.0.0",
|
"email-templates": "^6.0.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-jwt": "^5.3.1",
|
"express-jwt": "^5.3.1",
|
||||||
"fetch": "^1.1.0",
|
"http-signature": "^1.2.0",
|
||||||
"ics": "^2.15.1",
|
"ics": "^2.15.1",
|
||||||
"inquirer": "^6.5.0",
|
"inquirer": "^6.5.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
|
@ -65,6 +65,7 @@
|
||||||
"mastodon-api": "lesion/mastodon-api",
|
"mastodon-api": "lesion/mastodon-api",
|
||||||
"morgan": "^1.9.1",
|
"morgan": "^1.9.1",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
|
"node-fetch": "^2.6.0",
|
||||||
"nuxt": "^2.8.1",
|
"nuxt": "^2.8.1",
|
||||||
"pg": "^7.11.0",
|
"pg": "^7.11.0",
|
||||||
"sass-loader": "^7.1.0",
|
"sass-loader": "^7.1.0",
|
||||||
|
|
|
@ -103,12 +103,12 @@ api.get('/event/:month/:year', eventController.getAll)
|
||||||
|
|
||||||
// Handle 404
|
// Handle 404
|
||||||
api.use(function(req, res) {
|
api.use(function(req, res) {
|
||||||
res.send('404: Page not Found', 404)
|
res.status(404).send('404: Page not Found')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Handle 500
|
// Handle 500
|
||||||
api.use(function(error, req, res, next) {
|
api.use(function(error, req, res, next) {
|
||||||
res.send('500: Internal Server Error', 500)
|
res.status(500).send('500: Internal Server Error')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
const fetch = require('fetch')
|
const fetch = require('node-fetch')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const config = require('config')
|
const config = require('config')
|
||||||
|
const httpSignature = require('http-signature')
|
||||||
|
|
||||||
|
const actorCache = []
|
||||||
|
|
||||||
const Helpers = {
|
const Helpers = {
|
||||||
async signAndSend(message, user, to) {//, domain, req, res, targetOrigin) {
|
async signAndSend(message, user, to) {//, domain, req, res, targetOrigin) {
|
||||||
|
@ -57,24 +60,38 @@ const Helpers = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: cache
|
|
||||||
// user: les@mastodon.cisti.org
|
|
||||||
async getFederatedUser(address) {
|
async getFederatedUser(address) {
|
||||||
address = address.trim()
|
address = address.trim()
|
||||||
let [ user, host ] = address.split('@')
|
const [ username, host ] = address.split('@')
|
||||||
const url = `https://${host}/.well-known/webfinger?resource=acct:${user}@${host}`
|
const url = `https://${host}/.well-known/webfinger?resource=acct:${username}@${host}`
|
||||||
console.error('get federated user at => ', address, url)
|
return Helpers.getActor(url)
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: cache
|
||||||
|
async getActor(url, force=false) {
|
||||||
|
// try with cache first if not forced
|
||||||
|
if (!force && actorCache[url]) return actorCache[url]
|
||||||
const user = await fetch(url, { headers: {'Accept': 'application/jrd+json, application/json'} })
|
const user = await fetch(url, { headers: {'Accept': 'application/jrd+json, application/json'} })
|
||||||
|
.then(res => res.json())
|
||||||
|
actorCache[url] = user
|
||||||
return user
|
return user
|
||||||
},
|
},
|
||||||
|
|
||||||
async verifySignature(req, res) {
|
// ref: https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/
|
||||||
console.error(req.headers['signature'])
|
async verifySignature(req, res, next) {
|
||||||
// https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/
|
let user = Helpers.getActor(req.body.actor)
|
||||||
const signature_header = req.headers['signature'].split(',')
|
|
||||||
.map(pair => pair.split('='))
|
// little hack -> https://github.com/joyent/node-http-signature/pull/83
|
||||||
console.error(signature_header)
|
req.headers.authorization = 'Signature ' + req.headers.signature
|
||||||
return true
|
const parsed = httpSignature.parseRequest(req)
|
||||||
|
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) return next()
|
||||||
|
|
||||||
|
// signature not valid, try without cache
|
||||||
|
user = Helpers.getActor(req.body.actor, true)
|
||||||
|
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) return next()
|
||||||
|
|
||||||
|
// still not valid
|
||||||
|
res.send('Request signature could not be verified', 401)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,7 @@ router.get('/m/:event_id', async (req, res) => {
|
||||||
|
|
||||||
// get any message coming from federation
|
// get any message coming from federation
|
||||||
// Federation is calling!
|
// Federation is calling!
|
||||||
router.post('/u/:name/inbox', async (req, res) => {
|
router.post('/u/:name/inbox', Helpers.verifySignature, async (req, res) => {
|
||||||
|
|
||||||
if (!Helpers.verifySignature(req, res)) {
|
|
||||||
res.send('Request signature could not be verified', 401)
|
|
||||||
}
|
|
||||||
|
|
||||||
const b = req.body
|
const b = req.body
|
||||||
console.error('> INBOX ', b.type, b)
|
console.error('> INBOX ', b.type, b)
|
||||||
|
@ -55,28 +51,24 @@ router.post('/u/:name/inbox', async (req, res) => {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'Announce':
|
case 'Announce':
|
||||||
console.error('This is a boost ?')
|
|
||||||
Ego.boost(req, res)
|
Ego.boost(req, res)
|
||||||
break
|
break
|
||||||
case 'Note':
|
case 'Note':
|
||||||
console.error('This is a note ! I probably should not receive this')
|
console.error('This is a note ! I probably should not receive this')
|
||||||
break
|
break
|
||||||
case 'Like':
|
case 'Like':
|
||||||
console.error('This is a like!')
|
|
||||||
Ego.like(req, res)
|
Ego.like(req, res)
|
||||||
break
|
break
|
||||||
case 'Delete':
|
case 'Delete':
|
||||||
console.error('Delete a comment ?!?!')
|
console.error('Delete ?!?!')
|
||||||
break
|
break
|
||||||
case 'Create':
|
case 'Create':
|
||||||
// this is a reply
|
// this is a reply
|
||||||
if (b.object.type === 'Note' && b.object.inReplyTo) {
|
if (b.object.type === 'Note' && b.object.inReplyTo) {
|
||||||
console.error('this is a reply to an event')
|
|
||||||
Comments.create(b)
|
Comments.create(b)
|
||||||
} else {
|
} else {
|
||||||
console.error('Create what? ', b.object.type)
|
console.error('Create what? ', b.object.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
28
yarn.lock
28
yarn.lock
|
@ -1953,13 +1953,6 @@ binary-extensions@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
|
||||||
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
|
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
|
||||||
|
|
||||||
biskviit@1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/biskviit/-/biskviit-1.0.1.tgz#037a0cd4b71b9e331fd90a1122de17dc49e420a7"
|
|
||||||
integrity sha1-A3oM1LcbnjMf2QoRIt4X3EnkIKc=
|
|
||||||
dependencies:
|
|
||||||
psl "^1.1.7"
|
|
||||||
|
|
||||||
bl@^1.0.0:
|
bl@^1.0.0:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
|
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
|
||||||
|
@ -3688,13 +3681,6 @@ encodeurl@~1.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||||
|
|
||||||
encoding@0.1.12:
|
|
||||||
version "0.1.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
|
||||||
integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
|
|
||||||
dependencies:
|
|
||||||
iconv-lite "~0.4.13"
|
|
||||||
|
|
||||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
|
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
|
||||||
|
@ -4436,14 +4422,6 @@ fast-levenshtein@~2.0.4:
|
||||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||||
|
|
||||||
fetch@^1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/fetch/-/fetch-1.1.0.tgz#0a8279f06be37f9f0ebb567560a30a480da59a2e"
|
|
||||||
integrity sha1-CoJ58Gvjf58Ou1Z1YKMKSA2lmi4=
|
|
||||||
dependencies:
|
|
||||||
biskviit "1.0.1"
|
|
||||||
encoding "0.1.12"
|
|
||||||
|
|
||||||
figgy-pudding@^3.5.1:
|
figgy-pudding@^3.5.1:
|
||||||
version "3.5.1"
|
version "3.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
||||||
|
@ -5306,7 +5284,7 @@ http-proxy@^1.17.0:
|
||||||
follow-redirects "^1.0.0"
|
follow-redirects "^1.0.0"
|
||||||
requires-port "^1.0.0"
|
requires-port "^1.0.0"
|
||||||
|
|
||||||
http-signature@~1.2.0:
|
http-signature@^1.2.0, http-signature@~1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
||||||
|
@ -5337,7 +5315,7 @@ i18n@^0.8.3:
|
||||||
mustache "*"
|
mustache "*"
|
||||||
sprintf-js ">=1.0.3"
|
sprintf-js ">=1.0.3"
|
||||||
|
|
||||||
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
|
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
|
||||||
version "0.4.24"
|
version "0.4.24"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||||
|
@ -8642,7 +8620,7 @@ pseudomap@^1.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
|
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
|
||||||
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
|
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
|
||||||
|
|
||||||
psl@^1.1.24, psl@^1.1.7:
|
psl@^1.1.24:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6"
|
resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6"
|
||||||
integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==
|
integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==
|
||||||
|
|
Loading…
Reference in a new issue