Remove webfinger from activitypub

This commit is contained in:
Yarmo Mackenbach 2022-10-03 22:32:46 +02:00
parent 1710195211
commit 2a29832110
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1
5 changed files with 44 additions and 44 deletions

View file

@ -220,7 +220,7 @@ class Claim {
// For each match
for (let index = 0; index < this._matches.length; index++) {
const claimData = this._matches[index]
let claimData = this._matches[index]
let verificationResult = null
let proofData = null
@ -243,6 +243,11 @@ class Claim {
fetcher: proofData.fetcher,
viaProxy: proofData.viaProxy
}
// Post process the data
if (claimData.functions && claimData.functions.postprocess) {
({ claimData, proofData } = claimData.functions.postprocess(claimData, proofData))
}
} else {
// Consider the proof completed but with a negative result
verificationResult = verificationResult || {

View file

@ -15,11 +15,9 @@ limitations under the License.
*/
const E = require('../enums')
const reURI = /^acct:(.*)@(.*)\/?/
const reURI = /^https:\/\/(.*)\/?/
const processURI = (uri) => {
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
@ -30,7 +28,7 @@ const processURI = (uri) => {
isAmbiguous: false
},
profile: {
display: `${match[1]}@${match[2]}`,
display: uri,
uri: uri,
qr: null
},
@ -41,8 +39,7 @@ const processURI = (uri) => {
access: E.ProofAccess.GENERIC,
format: E.ProofFormat.JSON,
data: {
username: match[1],
domain: match[2]
url: uri
}
}
},
@ -57,25 +54,39 @@ const processURI = (uri) => {
relation: E.ClaimRelation.CONTAINS,
path: ['attachment', 'value']
}
]
],
functions: {
postprocess: (claimData, proofData) => {
claimData.profile.display = `${proofData.result.preferredUsername}@${new URL(proofData.result.url).hostname}`
return { claimData, proofData }
}
}
}
}
const tests = [
{
uri: 'acct:alice@domain.org',
uri: 'https://domain.org',
shouldMatch: true
},
{
uri: 'acct:alice',
shouldMatch: false
uri: 'https://domain.org/@/alice/',
shouldMatch: true
},
{
uri: 'https://domain.org/@alice/',
shouldMatch: false
uri: 'https://domain.org/@alice',
shouldMatch: true
},
{
uri: 'https://domain.org/alice',
uri: 'https://domain.org/u/alice/',
shouldMatch: true
},
{
uri: 'https://domain.org/users/alice/',
shouldMatch: true
},
{
uri: 'http://domain.org/alice',
shouldMatch: false
}
]

View file

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const axios = require('axios')
const validator = require('validator')
const jsEnv = require('browser-or-node')
/**
@ -31,10 +32,9 @@ module.exports.timeout = 5000
* @function
* @async
* @param {object} data - Data used in the request
* @param {string} data.username - The username of the account to verify
* @param {string} data.domain - The domain of the ActivityPub instance
* @param {string} data.url - The URL of the account to verify
* @param {object} opts - Options used to enable the request
* @param {string} opts.claims.activitypub.acct - The identifier of the verifier account
* @param {string} opts.claims.activitypub.url - The URL of the verifier account
* @param {string} opts.claims.activitypub.privateKey - The private key to sign the request
* @returns {object}
*/
@ -54,33 +54,15 @@ module.exports.fn = async (data, opts) => {
const fetchPromise = new Promise((resolve, reject) => {
(async () => {
if (!opts.claims.activitypub.acct.match(/acct:(.*)@(.*)/)) {
reject(new Error('ActivityPub fetcher was not set up properly'))
try {
validator.isURL(opts.claims.activitypub.url)
} catch (err) {
throw new Error(`ActivityPub fetcher was not set up properly (${err.message})`)
}
const urlWebfinger = `https://${data.domain}/.well-known/webfinger?resource=acct:${data.username}@${data.domain}`
const webfinger = await axios.get(urlWebfinger,
{
headers: { Accept: 'application/json' }
})
.then(res => {
return res.data
})
.catch(error => {
reject(error)
})
let urlActivitypub = null
webfinger.links.forEach(element => {
if (element.type === 'application/activity+json') {
urlActivitypub = element.href
}
})
// Prepare the signature
const matchAcct = opts.claims.activitypub.acct.match(/acct:(.*)@(.*)/)
const now = new Date()
const { host, pathname, search } = new URL(urlActivitypub)
const { host, pathname, search } = new URL(data.url)
const signedString = `(request-target): get ${pathname}${search}\nhost: ${host}\ndate: ${now.toUTCString()}`
const headers = {
@ -95,10 +77,10 @@ module.exports.fn = async (data, opts) => {
sign.write(signedString)
sign.end()
const signatureSig = sign.sign(opts.claims.activitypub.privateKey, 'base64')
headers.signature = `keyId="https://${matchAcct[2]}/${matchAcct[1]}#main-key",headers="(request-target) host date",signature="${signatureSig}",algorithm="rsa-sha256"`
headers.signature = `keyId="${opts.claims.activitypub.url}#main-key",headers="(request-target) host date",signature="${signatureSig}",algorithm="rsa-sha256"`
}
axios.get(urlActivitypub,
axios.get(data.url,
{
headers
})

View file

@ -249,8 +249,7 @@ router.get(
// ActivityPub route
router.get(
'/get/activitypub',
query('username').isString(),
query('domain').isFQDN(),
query('url').isURL(),
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {

View file

@ -52,6 +52,9 @@ const pattern = {
claim: (x) => {
return _.isObject(x) || _.isArray(x)
},
functions: (x) => {
return _.isObject(x) || _.isUndefined(x)
},
}
doipjs.claimDefinitions.list.forEach((claimDefName, i) => {