forked from Mirrors/doipjs
Compare commits
2 commits
dev
...
matrix-roo
Author | SHA1 | Date | |
---|---|---|---|
|
c5a1b2104d | ||
|
5258da3353 |
8 changed files with 209 additions and 24 deletions
32
src/claim.js
32
src/claim.js
|
@ -169,6 +169,13 @@ class Claim {
|
|||
}
|
||||
|
||||
const candidate = def.processURI(this._uri)
|
||||
|
||||
// If the candidate is valid but the URI could not be processed,
|
||||
// continue matching
|
||||
if (!candidate) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (candidate.match.isAmbiguous) {
|
||||
// Add to the possible candidates
|
||||
this._matches.push(candidate)
|
||||
|
@ -239,10 +246,23 @@ class Claim {
|
|||
claimData,
|
||||
this._fingerprint
|
||||
)
|
||||
|
||||
if (verificationResult.completed) {
|
||||
if (!verificationResult.result && this.isAmbiguous()) {
|
||||
// Assume a wrong match and continue
|
||||
continue
|
||||
}
|
||||
|
||||
verificationResult.proof = {
|
||||
fetcher: proofData.fetcher,
|
||||
viaProxy: proofData.viaProxy
|
||||
}
|
||||
|
||||
// Store the result, keep a single match and stop verifying
|
||||
this._verification = verificationResult
|
||||
this._matches = [claimData]
|
||||
index = this._matches.length
|
||||
}
|
||||
} else {
|
||||
// Consider the proof completed but with a negative result
|
||||
verificationResult = verificationResult || {
|
||||
|
@ -251,18 +271,6 @@ class Claim {
|
|||
proof: {},
|
||||
errors: [proofFetchError]
|
||||
}
|
||||
|
||||
if (this.isAmbiguous()) {
|
||||
// Assume a wrong match and continue
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (verificationResult.completed) {
|
||||
// Store the result, keep a single match and stop verifying
|
||||
this._verification = verificationResult
|
||||
this._matches = [claimData]
|
||||
index = this._matches.length
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ const list = [
|
|||
'irc',
|
||||
'xmpp',
|
||||
'matrix',
|
||||
'matrix_legacy',
|
||||
'telegram',
|
||||
'twitter',
|
||||
'reddit',
|
||||
|
@ -41,6 +42,7 @@ const data = {
|
|||
irc: require('./irc'),
|
||||
xmpp: require('./xmpp'),
|
||||
matrix: require('./matrix'),
|
||||
matrix_legacy: require('./matrix_legacy'),
|
||||
telegram: require('./telegram'),
|
||||
twitter: require('./twitter'),
|
||||
reddit: require('./reddit'),
|
||||
|
|
|
@ -27,12 +27,12 @@ const processURI = (uri) => {
|
|||
|
||||
const params = queryString.parse(match[2])
|
||||
|
||||
if (!('org.keyoxide.e' in params && 'org.keyoxide.r' in params)) {
|
||||
if (!('org.keyoxide.r' in params)) {
|
||||
return null
|
||||
}
|
||||
|
||||
const profileUrl = `https://matrix.to/#/@${match[1]}`
|
||||
const eventUrl = `https://matrix.to/#/${params['org.keyoxide.r']}/${params['org.keyoxide.e']}`
|
||||
const eventUrl = `https://matrix.to/#/${params['org.keyoxide.r']}`
|
||||
|
||||
return {
|
||||
serviceprovider: {
|
||||
|
@ -41,7 +41,7 @@ const processURI = (uri) => {
|
|||
},
|
||||
match: {
|
||||
regularExpression: reURI,
|
||||
isAmbiguous: false
|
||||
isAmbiguous: true
|
||||
},
|
||||
profile: {
|
||||
display: `@${match[1]}`,
|
||||
|
@ -55,7 +55,6 @@ const processURI = (uri) => {
|
|||
access: E.ProofAccess.GRANTED,
|
||||
format: E.ProofFormat.JSON,
|
||||
data: {
|
||||
eventId: params['org.keyoxide.e'],
|
||||
roomId: params['org.keyoxide.r']
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +62,7 @@ const processURI = (uri) => {
|
|||
claim: {
|
||||
format: E.ClaimFormat.URI,
|
||||
relation: E.ClaimRelation.CONTAINS,
|
||||
path: ['content', 'body']
|
||||
path: ['chunk', 'content', 'topic']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +70,7 @@ const processURI = (uri) => {
|
|||
const tests = [
|
||||
{
|
||||
uri:
|
||||
'matrix:u/alice:matrix.domain.org?org.keyoxide.r=!123:domain.org&org.keyoxide.e=$123',
|
||||
'matrix:u/alice:matrix.domain.org?org.keyoxide.r=!123:domain.org',
|
||||
shouldMatch: true
|
||||
},
|
||||
{
|
||||
|
|
93
src/claimDefinitions/matrix_legacy.js
Normal file
93
src/claimDefinitions/matrix_legacy.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2021 Yarmo Mackenbach
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
const E = require('../enums')
|
||||
const queryString = require('query-string')
|
||||
|
||||
const reURI = /^matrix:u\/(?:@)?([^@:]*:[^?]*)(\?.*)?/
|
||||
|
||||
const processURI = (uri) => {
|
||||
const match = uri.match(reURI)
|
||||
|
||||
if (!match[2]) {
|
||||
return null
|
||||
}
|
||||
|
||||
const params = queryString.parse(match[2])
|
||||
|
||||
if (!('org.keyoxide.e' in params && 'org.keyoxide.r' in params)) {
|
||||
return null
|
||||
}
|
||||
|
||||
const profileUrl = `https://matrix.to/#/@${match[1]}`
|
||||
const eventUrl = `https://matrix.to/#/${params['org.keyoxide.r']}/${params['org.keyoxide.e']}`
|
||||
|
||||
return {
|
||||
serviceprovider: {
|
||||
type: 'communication',
|
||||
name: 'matrix'
|
||||
},
|
||||
match: {
|
||||
regularExpression: reURI,
|
||||
isAmbiguous: true
|
||||
},
|
||||
profile: {
|
||||
display: `@${match[1]}`,
|
||||
uri: profileUrl,
|
||||
qr: null
|
||||
},
|
||||
proof: {
|
||||
uri: eventUrl,
|
||||
request: {
|
||||
fetcher: E.Fetcher.MATRIX_LEGACY,
|
||||
access: E.ProofAccess.GRANTED,
|
||||
format: E.ProofFormat.JSON,
|
||||
data: {
|
||||
eventId: params['org.keyoxide.e'],
|
||||
roomId: params['org.keyoxide.r']
|
||||
}
|
||||
}
|
||||
},
|
||||
claim: {
|
||||
format: E.ClaimFormat.URI,
|
||||
relation: E.ClaimRelation.CONTAINS,
|
||||
path: ['content', 'body']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tests = [
|
||||
{
|
||||
uri:
|
||||
'matrix:u/alice:matrix.domain.org?org.keyoxide.r=!123:domain.org&org.keyoxide.e=$123',
|
||||
shouldMatch: true
|
||||
},
|
||||
{
|
||||
uri: 'matrix:u/alice:matrix.domain.org',
|
||||
shouldMatch: true
|
||||
},
|
||||
{
|
||||
uri: 'xmpp:alice@domain.org',
|
||||
shouldMatch: false
|
||||
},
|
||||
{
|
||||
uri: 'https://domain.org/@alice',
|
||||
shouldMatch: false
|
||||
}
|
||||
]
|
||||
|
||||
exports.reURI = reURI
|
||||
exports.processURI = processURI
|
||||
exports.tests = tests
|
|
@ -49,6 +49,8 @@ const Fetcher = {
|
|||
XMPP: 'xmpp',
|
||||
/** HTTP request to Matrix API */
|
||||
MATRIX: 'matrix',
|
||||
/** HTTP request to Matrix API (legacy method) */
|
||||
MATRIX_LEGACY: 'matrix_legacy',
|
||||
/** HTTP request to Telegram API */
|
||||
TELEGRAM: 'telegram',
|
||||
/** HTTP request to Twitter API */
|
||||
|
|
|
@ -18,6 +18,7 @@ exports.dns = require('./dns')
|
|||
exports.http = require('./http')
|
||||
exports.irc = require('./irc')
|
||||
exports.matrix = require('./matrix')
|
||||
exports.matrix_legacy = require('./matrix_legacy')
|
||||
exports.telegram = require('./telegram')
|
||||
exports.twitter = require('./twitter')
|
||||
exports.xmpp = require('./xmpp')
|
||||
|
|
|
@ -31,8 +31,7 @@ module.exports.timeout = 5000
|
|||
* @function
|
||||
* @async
|
||||
* @param {object} data - Data used in the request
|
||||
* @param {string} data.eventId - The identifier of the targeted post
|
||||
* @param {string} data.roomId - The identifier of the room containing the targeted post
|
||||
* @param {string} data.roomId - The identifier of the room containing the proof
|
||||
* @param {object} opts - Options used to enable the request
|
||||
* @param {string} opts.claims.matrix.instance - The server hostname on which the library can log in
|
||||
* @param {string} opts.claims.matrix.accessToken - The access token required to identify the library ({@link https://www.matrix.org/docs/guides/client-server-api|Matrix docs})
|
||||
|
@ -55,7 +54,10 @@ module.exports.fn = async (data, opts) => {
|
|||
throw new Error(`Matrix fetcher was not set up properly (${err.message})`)
|
||||
}
|
||||
|
||||
const url = `https://${opts.claims.matrix.instance}/_matrix/client/r0/rooms/${data.roomId}/event/${data.eventId}?access_token=${opts.claims.matrix.accessToken}`
|
||||
const urlFilter = encodeURI('{"limit": 1,"types": ["m.room.topic"]}')
|
||||
const url = `https://${opts.claims.matrix.instance}` +
|
||||
`/_matrix/client/v3/rooms/${data.roomId}/messages` +
|
||||
`?access_token=${opts.claims.matrix.accessToken}&dir=b&filter=${urlFilter}`
|
||||
axios.get(url,
|
||||
{
|
||||
headers: { Accept: 'application/json' }
|
||||
|
|
78
src/fetcher/matrix_legacy.js
Normal file
78
src/fetcher/matrix_legacy.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2021 Yarmo Mackenbach
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
const axios = require('axios')
|
||||
const validator = require('validator')
|
||||
|
||||
/**
|
||||
* @module fetcher/matrix_legacy
|
||||
*/
|
||||
|
||||
/**
|
||||
* The request's timeout value in milliseconds
|
||||
* @constant {number} timeout
|
||||
*/
|
||||
module.exports.timeout = 5000
|
||||
|
||||
/**
|
||||
* Execute a fetch request
|
||||
* @function
|
||||
* @async
|
||||
* @param {object} data - Data used in the request
|
||||
* @param {string} data.eventId - The identifier of the targeted post
|
||||
* @param {string} data.roomId - The identifier of the room containing the targeted post
|
||||
* @param {object} opts - Options used to enable the request
|
||||
* @param {string} opts.claims.matrix.instance - The server hostname on which the library can log in
|
||||
* @param {string} opts.claims.matrix.accessToken - The access token required to identify the library ({@link https://www.matrix.org/docs/guides/client-server-api|Matrix docs})
|
||||
* @returns {object}
|
||||
*/
|
||||
module.exports.fn = async (data, opts) => {
|
||||
let timeoutHandle
|
||||
const timeoutPromise = new Promise((resolve, reject) => {
|
||||
timeoutHandle = setTimeout(
|
||||
() => reject(new Error('Request was timed out')),
|
||||
data.fetcherTimeout ? data.fetcherTimeout : module.exports.timeout
|
||||
)
|
||||
})
|
||||
|
||||
const fetchPromise = new Promise((resolve, reject) => {
|
||||
try {
|
||||
validator.isFQDN(opts.claims.matrix.instance)
|
||||
validator.isAscii(opts.claims.matrix.accessToken)
|
||||
} catch (err) {
|
||||
throw new Error(`Matrix_legacy fetcher was not set up properly (${err.message})`)
|
||||
}
|
||||
|
||||
const url = `https://${opts.claims.matrix.instance}/_matrix/client/r0/rooms/${data.roomId}/event/${data.eventId}?access_token=${opts.claims.matrix.accessToken}`
|
||||
axios.get(url,
|
||||
{
|
||||
headers: { Accept: 'application/json' }
|
||||
})
|
||||
.then(res => {
|
||||
return res.data
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
|
||||
return Promise.race([fetchPromise, timeoutPromise]).then((result) => {
|
||||
clearTimeout(timeoutHandle)
|
||||
return result
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue