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)
|
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) {
|
if (candidate.match.isAmbiguous) {
|
||||||
// Add to the possible candidates
|
// Add to the possible candidates
|
||||||
this._matches.push(candidate)
|
this._matches.push(candidate)
|
||||||
|
@ -239,10 +246,23 @@ class Claim {
|
||||||
claimData,
|
claimData,
|
||||||
this._fingerprint
|
this._fingerprint
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (verificationResult.completed) {
|
||||||
|
if (!verificationResult.result && this.isAmbiguous()) {
|
||||||
|
// Assume a wrong match and continue
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
verificationResult.proof = {
|
verificationResult.proof = {
|
||||||
fetcher: proofData.fetcher,
|
fetcher: proofData.fetcher,
|
||||||
viaProxy: proofData.viaProxy
|
viaProxy: proofData.viaProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store the result, keep a single match and stop verifying
|
||||||
|
this._verification = verificationResult
|
||||||
|
this._matches = [claimData]
|
||||||
|
index = this._matches.length
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Consider the proof completed but with a negative result
|
// Consider the proof completed but with a negative result
|
||||||
verificationResult = verificationResult || {
|
verificationResult = verificationResult || {
|
||||||
|
@ -251,18 +271,6 @@ class Claim {
|
||||||
proof: {},
|
proof: {},
|
||||||
errors: [proofFetchError]
|
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',
|
'irc',
|
||||||
'xmpp',
|
'xmpp',
|
||||||
'matrix',
|
'matrix',
|
||||||
|
'matrix_legacy',
|
||||||
'telegram',
|
'telegram',
|
||||||
'twitter',
|
'twitter',
|
||||||
'reddit',
|
'reddit',
|
||||||
|
@ -41,6 +42,7 @@ const data = {
|
||||||
irc: require('./irc'),
|
irc: require('./irc'),
|
||||||
xmpp: require('./xmpp'),
|
xmpp: require('./xmpp'),
|
||||||
matrix: require('./matrix'),
|
matrix: require('./matrix'),
|
||||||
|
matrix_legacy: require('./matrix_legacy'),
|
||||||
telegram: require('./telegram'),
|
telegram: require('./telegram'),
|
||||||
twitter: require('./twitter'),
|
twitter: require('./twitter'),
|
||||||
reddit: require('./reddit'),
|
reddit: require('./reddit'),
|
||||||
|
|
|
@ -27,12 +27,12 @@ const processURI = (uri) => {
|
||||||
|
|
||||||
const params = queryString.parse(match[2])
|
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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const profileUrl = `https://matrix.to/#/@${match[1]}`
|
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 {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
|
@ -41,7 +41,7 @@ const processURI = (uri) => {
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false
|
isAmbiguous: true
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `@${match[1]}`,
|
display: `@${match[1]}`,
|
||||||
|
@ -55,7 +55,6 @@ const processURI = (uri) => {
|
||||||
access: E.ProofAccess.GRANTED,
|
access: E.ProofAccess.GRANTED,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
eventId: params['org.keyoxide.e'],
|
|
||||||
roomId: params['org.keyoxide.r']
|
roomId: params['org.keyoxide.r']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +62,7 @@ const processURI = (uri) => {
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.URI,
|
format: E.ClaimFormat.URI,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['content', 'body']
|
path: ['chunk', 'content', 'topic']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +70,7 @@ const processURI = (uri) => {
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri:
|
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
|
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',
|
XMPP: 'xmpp',
|
||||||
/** HTTP request to Matrix API */
|
/** HTTP request to Matrix API */
|
||||||
MATRIX: 'matrix',
|
MATRIX: 'matrix',
|
||||||
|
/** HTTP request to Matrix API (legacy method) */
|
||||||
|
MATRIX_LEGACY: 'matrix_legacy',
|
||||||
/** HTTP request to Telegram API */
|
/** HTTP request to Telegram API */
|
||||||
TELEGRAM: 'telegram',
|
TELEGRAM: 'telegram',
|
||||||
/** HTTP request to Twitter API */
|
/** HTTP request to Twitter API */
|
||||||
|
|
|
@ -18,6 +18,7 @@ exports.dns = require('./dns')
|
||||||
exports.http = require('./http')
|
exports.http = require('./http')
|
||||||
exports.irc = require('./irc')
|
exports.irc = require('./irc')
|
||||||
exports.matrix = require('./matrix')
|
exports.matrix = require('./matrix')
|
||||||
|
exports.matrix_legacy = require('./matrix_legacy')
|
||||||
exports.telegram = require('./telegram')
|
exports.telegram = require('./telegram')
|
||||||
exports.twitter = require('./twitter')
|
exports.twitter = require('./twitter')
|
||||||
exports.xmpp = require('./xmpp')
|
exports.xmpp = require('./xmpp')
|
||||||
|
|
|
@ -31,8 +31,7 @@ module.exports.timeout = 5000
|
||||||
* @function
|
* @function
|
||||||
* @async
|
* @async
|
||||||
* @param {object} data - Data used in the request
|
* @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 proof
|
||||||
* @param {string} data.roomId - The identifier of the room containing the targeted post
|
|
||||||
* @param {object} opts - Options used to enable the request
|
* @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.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})
|
* @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})`)
|
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,
|
axios.get(url,
|
||||||
{
|
{
|
||||||
headers: { Accept: 'application/json' }
|
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