forked from Mirrors/doipjs
Fix JavaScript Standard Style issues
This commit is contained in:
parent
5b7bdcad76
commit
3676023df1
35 changed files with 665 additions and 704 deletions
35
src/claim.js
35
src/claim.js
|
@ -58,7 +58,6 @@ class Claim {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid claim version')
|
throw new Error('Invalid claim version')
|
||||||
break
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -73,12 +72,12 @@ class Claim {
|
||||||
try {
|
try {
|
||||||
validator.isAlphanumeric(fingerprint)
|
validator.isAlphanumeric(fingerprint)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(`Invalid fingerprint`)
|
throw new Error('Invalid fingerprint')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._uri = uri ? uri : null
|
this._uri = uri || null
|
||||||
this._fingerprint = fingerprint ? fingerprint : null
|
this._fingerprint = fingerprint || null
|
||||||
this._status = E.ClaimStatus.INIT
|
this._status = E.ClaimStatus.INIT
|
||||||
this._matches = null
|
this._matches = null
|
||||||
this._verification = null
|
this._verification = null
|
||||||
|
@ -207,7 +206,7 @@ class Claim {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle options
|
// Handle options
|
||||||
opts = mergeOptions(defaults.opts, opts ? opts : {})
|
opts = mergeOptions(defaults.opts, opts || {})
|
||||||
|
|
||||||
// If there are no matches
|
// If there are no matches
|
||||||
if (this._matches.length === 0) {
|
if (this._matches.length === 0) {
|
||||||
|
@ -215,7 +214,7 @@ class Claim {
|
||||||
result: false,
|
result: false,
|
||||||
completed: true,
|
completed: true,
|
||||||
proof: {},
|
proof: {},
|
||||||
errors: ['No matches for claim'],
|
errors: ['No matches for claim']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,9 +222,9 @@ class Claim {
|
||||||
for (let index = 0; index < this._matches.length; index++) {
|
for (let index = 0; index < this._matches.length; index++) {
|
||||||
const claimData = this._matches[index]
|
const claimData = this._matches[index]
|
||||||
|
|
||||||
let verificationResult = null,
|
let verificationResult = null
|
||||||
proofData = null,
|
let proofData = null
|
||||||
proofFetchError
|
let proofFetchError
|
||||||
|
|
||||||
try {
|
try {
|
||||||
proofData = await proofs.fetch(claimData, opts)
|
proofData = await proofs.fetch(claimData, opts)
|
||||||
|
@ -242,15 +241,15 @@ class Claim {
|
||||||
)
|
)
|
||||||
verificationResult.proof = {
|
verificationResult.proof = {
|
||||||
fetcher: proofData.fetcher,
|
fetcher: proofData.fetcher,
|
||||||
viaProxy: proofData.viaProxy,
|
viaProxy: proofData.viaProxy
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Consider the proof completed but with a negative result
|
// Consider the proof completed but with a negative result
|
||||||
verificationResult = verificationResult ? verificationResult : {
|
verificationResult = verificationResult || {
|
||||||
result: false,
|
result: false,
|
||||||
completed: true,
|
completed: true,
|
||||||
proof: {},
|
proof: {},
|
||||||
errors: [proofFetchError],
|
errors: [proofFetchError]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isAmbiguous()) {
|
if (this.isAmbiguous()) {
|
||||||
|
@ -268,11 +267,13 @@ class Claim {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail safe verification result
|
// Fail safe verification result
|
||||||
this._verification = this._verification ? this._verification : {
|
this._verification = this._verification
|
||||||
|
? this._verification
|
||||||
|
: {
|
||||||
result: false,
|
result: false,
|
||||||
completed: true,
|
completed: true,
|
||||||
proof: {},
|
proof: {},
|
||||||
errors: ['Unknown error'],
|
errors: ['Unknown error']
|
||||||
}
|
}
|
||||||
|
|
||||||
this._status = E.ClaimStatus.VERIFIED
|
this._status = E.ClaimStatus.VERIFIED
|
||||||
|
@ -292,9 +293,7 @@ class Claim {
|
||||||
if (this._matches.length === 0) {
|
if (this._matches.length === 0) {
|
||||||
throw new Error('The claim has no matches')
|
throw new Error('The claim has no matches')
|
||||||
}
|
}
|
||||||
return (
|
return this._matches.length > 1 || this._matches[0].match.isAmbiguous
|
||||||
this._matches.length > 1 || this._matches[0].match.isAmbiguous
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -310,7 +309,7 @@ class Claim {
|
||||||
fingerprint: this._fingerprint,
|
fingerprint: this._fingerprint,
|
||||||
status: this._status,
|
status: this._status,
|
||||||
matches: this._matches,
|
matches: this._matches,
|
||||||
verification: this._verification,
|
verification: this._verification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'devto',
|
name: 'devto'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: `https://dev.to/${match[1]}`,
|
uri: `https://dev.to/${match[1]}`,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://dev.to/api/articles/${match[1]}/${match[2]}`,
|
url: `https://dev.to/api/articles/${match[1]}/${match[2]}`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['body_markdown'],
|
path: ['body_markdown']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://dev.to/alice/post',
|
uri: 'https://dev.to/alice/post',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://dev.to/alice/post/',
|
uri: 'https://dev.to/alice/post/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice/post',
|
uri: 'https://domain.org/alice/post',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'discourse',
|
name: 'discourse'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: true,
|
isAmbiguous: true
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `${match[2]}@${match[1]}`,
|
display: `${match[2]}@${match[1]}`,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://${match[1]}/u/${match[2]}.json`,
|
url: `https://${match[1]}/u/${match[2]}.json`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['user', 'bio_raw'],
|
path: ['user', 'bio_raw']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/u/alice',
|
uri: 'https://domain.org/u/alice',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/u/alice/',
|
uri: 'https://domain.org/u/alice/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice',
|
uri: 'https://domain.org/alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
const E = require('../enums')
|
const E = require('../enums')
|
||||||
|
|
||||||
const reURI = /^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
|
const reURI = /^dns:([a-zA-Z0-9.\-_]*)(?:\?(.*))?/
|
||||||
|
|
||||||
const processURI = (uri) => {
|
const processURI = (uri) => {
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'dns',
|
name: 'dns'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: `https://${match[1]}`,
|
uri: `https://${match[1]}`,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: null,
|
uri: null,
|
||||||
|
@ -41,31 +41,31 @@ const processURI = (uri) => {
|
||||||
access: E.ProofAccess.SERVER,
|
access: E.ProofAccess.SERVER,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
domain: match[1],
|
domain: match[1]
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.URI,
|
format: E.ClaimFormat.URI,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['records', 'txt'],
|
path: ['records', 'txt']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'dns:domain.org',
|
uri: 'dns:domain.org',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'dns:domain.org?type=TXT',
|
uri: 'dns:domain.org?type=TXT',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org',
|
uri: 'https://domain.org',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'fediverse',
|
name: 'fediverse'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: true,
|
isAmbiguous: true
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `@${match[2]}@${match[1]}`,
|
display: `@${match[2]}@${match[1]}`,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: uri,
|
url: uri,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.FINGERPRINT,
|
format: E.ClaimFormat.FINGERPRINT,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['summary'],
|
path: ['summary']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/users/alice',
|
uri: 'https://domain.org/users/alice',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/users/alice/',
|
uri: 'https://domain.org/users/alice/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice',
|
uri: 'https://domain.org/alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'gitea',
|
name: 'gitea'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: true,
|
isAmbiguous: true
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `${match[2]}@${match[1]}`,
|
display: `${match[2]}@${match[1]}`,
|
||||||
uri: `https://${match[1]}/${match[2]}`,
|
uri: `https://${match[1]}/${match[2]}`,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://${match[1]}/api/v1/repos/${match[2]}/gitea_proof`,
|
url: `https://${match[1]}/api/v1/repos/${match[2]}/gitea_proof`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.EQUALS,
|
relation: E.ClaimRelation.EQUALS,
|
||||||
path: ['description'],
|
path: ['description']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice/gitea_proof',
|
uri: 'https://domain.org/alice/gitea_proof',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice/gitea_proof/',
|
uri: 'https://domain.org/alice/gitea_proof/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice/other_proof',
|
uri: 'https://domain.org/alice/other_proof',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'github',
|
name: 'github'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: `https://github.com/${match[1]}`,
|
uri: `https://github.com/${match[1]}`,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://api.github.com/gists/${match[2]}`,
|
url: `https://api.github.com/gists/${match[2]}`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['files', 'openpgp.md', 'content'],
|
path: ['files', 'openpgp.md', 'content']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://gist.github.com/Alice/123456789',
|
uri: 'https://gist.github.com/Alice/123456789',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://gist.github.com/Alice/123456789/',
|
uri: 'https://gist.github.com/Alice/123456789/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/Alice/123456789',
|
uri: 'https://domain.org/Alice/123456789',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'gitlab',
|
name: 'gitlab'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: true,
|
isAmbiguous: true
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `${match[2]}@${match[1]}`,
|
display: `${match[2]}@${match[1]}`,
|
||||||
uri: `https://${match[1]}/${match[2]}`,
|
uri: `https://${match[1]}/${match[2]}`,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
domain: match[1],
|
domain: match[1],
|
||||||
username: match[2],
|
username: match[2]
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.EQUALS,
|
relation: E.ClaimRelation.EQUALS,
|
||||||
path: ['description'],
|
path: ['description']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://gitlab.domain.org/alice/gitlab_proof',
|
uri: 'https://gitlab.domain.org/alice/gitlab_proof',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://gitlab.domain.org/alice/gitlab_proof/',
|
uri: 'https://gitlab.domain.org/alice/gitlab_proof/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice/other_proof',
|
uri: 'https://domain.org/alice/other_proof',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'hackernews',
|
name: 'hackernews'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: `https://hacker-news.firebaseio.com/v0/user/${match[1]}.json`,
|
uri: `https://hacker-news.firebaseio.com/v0/user/${match[1]}.json`,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://hacker-news.firebaseio.com/v0/user/${match[1]}.json`,
|
url: `https://hacker-news.firebaseio.com/v0/user/${match[1]}.json`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.URI,
|
format: E.ClaimFormat.URI,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['about'],
|
path: ['about']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://news.ycombinator.com/user?id=Alice',
|
uri: 'https://news.ycombinator.com/user?id=Alice',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://news.ycombinator.com/user?id=Alice/',
|
uri: 'https://news.ycombinator.com/user?id=Alice/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/user?id=Alice',
|
uri: 'https://domain.org/user?id=Alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -30,7 +30,7 @@ const list = [
|
||||||
'mastodon',
|
'mastodon',
|
||||||
'fediverse',
|
'fediverse',
|
||||||
'discourse',
|
'discourse',
|
||||||
'owncast',
|
'owncast'
|
||||||
]
|
]
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
|
@ -50,7 +50,7 @@ const data = {
|
||||||
mastodon: require('./mastodon'),
|
mastodon: require('./mastodon'),
|
||||||
fediverse: require('./fediverse'),
|
fediverse: require('./fediverse'),
|
||||||
discourse: require('./discourse'),
|
discourse: require('./discourse'),
|
||||||
owncast: require('./owncast'),
|
owncast: require('./owncast')
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.list = list
|
exports.list = list
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
const E = require('../enums')
|
const E = require('../enums')
|
||||||
|
|
||||||
const reURI = /^irc\:\/\/(.*)\/([a-zA-Z0-9\-\[\]\\\`\_\^\{\|\}]*)/
|
const reURI = /^irc:\/\/(.*)\/([a-zA-Z0-9\-[\]\\`_^{|}]*)/
|
||||||
|
|
||||||
const processURI = (uri) => {
|
const processURI = (uri) => {
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'communication',
|
type: 'communication',
|
||||||
name: 'irc',
|
name: 'irc'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `irc://${match[1]}/${match[2]}`,
|
display: `irc://${match[1]}/${match[2]}`,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: null,
|
uri: null,
|
||||||
|
@ -42,35 +42,35 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
domain: match[1],
|
domain: match[1],
|
||||||
nick: match[2],
|
nick: match[2]
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.URI,
|
format: E.ClaimFormat.URI,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: [],
|
path: []
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'irc://chat.ircserver.org/Alice1',
|
uri: 'irc://chat.ircserver.org/Alice1',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'irc://chat.ircserver.org/alice?param=123',
|
uri: 'irc://chat.ircserver.org/alice?param=123',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'irc://chat.ircserver.org/alice_bob',
|
uri: 'irc://chat.ircserver.org/alice_bob',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://chat.ircserver.org/alice',
|
uri: 'https://chat.ircserver.org/alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'liberapay',
|
name: 'liberapay'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://liberapay.com/${match[1]}/public.json`,
|
url: `https://liberapay.com/${match[1]}/public.json`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['statements', 'content'],
|
path: ['statements', 'content']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://liberapay.com/alice',
|
uri: 'https://liberapay.com/alice',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://liberapay.com/alice/',
|
uri: 'https://liberapay.com/alice/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice',
|
uri: 'https://domain.org/alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'lobsters',
|
name: 'lobsters'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: `https://lobste.rs/u/${match[1]}.json`,
|
uri: `https://lobste.rs/u/${match[1]}.json`,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://lobste.rs/u/${match[1]}.json`,
|
url: `https://lobste.rs/u/${match[1]}.json`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['about'],
|
path: ['about']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://lobste.rs/u/Alice',
|
uri: 'https://lobste.rs/u/Alice',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://lobste.rs/u/Alice/',
|
uri: 'https://lobste.rs/u/Alice/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/u/Alice',
|
uri: 'https://domain.org/u/Alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'mastodon',
|
name: 'mastodon'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: true,
|
isAmbiguous: true
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `@${match[2]}@${match[1]}`,
|
display: `@${match[2]}@${match[1]}`,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: uri,
|
url: uri,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.FINGERPRINT,
|
format: E.ClaimFormat.FINGERPRINT,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['attachment', 'value'],
|
path: ['attachment', 'value']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/@alice',
|
uri: 'https://domain.org/@alice',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/@alice/',
|
uri: 'https://domain.org/@alice/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice',
|
uri: 'https://domain.org/alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
const E = require('../enums')
|
const E = require('../enums')
|
||||||
const queryString = require('query-string')
|
const queryString = require('query-string')
|
||||||
|
|
||||||
const reURI = /^matrix\:u\/(?:\@)?([^@:]*\:[^?]*)(\?.*)?/
|
const reURI = /^matrix:u\/(?:@)?([^@:]*:[^?]*)(\?.*)?/
|
||||||
|
|
||||||
const processURI = (uri) => {
|
const processURI = (uri) => {
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
@ -37,16 +37,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'communication',
|
type: 'communication',
|
||||||
name: 'matrix',
|
name: 'matrix'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `@${match[1]}`,
|
display: `@${match[1]}`,
|
||||||
uri: profileUrl,
|
uri: profileUrl,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: eventUrl,
|
uri: eventUrl,
|
||||||
|
@ -56,15 +56,15 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
eventId: params['org.keyoxide.e'],
|
eventId: params['org.keyoxide.e'],
|
||||||
roomId: params['org.keyoxide.r'],
|
roomId: params['org.keyoxide.r']
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['content', 'body'],
|
path: ['content', 'body']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,20 +72,20 @@ 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&org.keyoxide.e=$123',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'matrix:u/alice:matrix.domain.org',
|
uri: 'matrix:u/alice:matrix.domain.org',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'xmpp:alice@domain.org',
|
uri: 'xmpp:alice@domain.org',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/@alice',
|
uri: 'https://domain.org/@alice',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'owncast',
|
name: 'owncast'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: true,
|
isAmbiguous: true
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: `${uri}/api/config`,
|
uri: `${uri}/api/config`,
|
||||||
|
@ -42,35 +42,35 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `${uri}/api/config`,
|
url: `${uri}/api/config`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.FINGERPRINT,
|
format: E.ClaimFormat.FINGERPRINT,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['socialHandles', 'url'],
|
path: ['socialHandles', 'url']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://live.domain.org',
|
uri: 'https://live.domain.org',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://live.domain.org/',
|
uri: 'https://live.domain.org/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/live',
|
uri: 'https://domain.org/live',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/live/',
|
uri: 'https://domain.org/live/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'reddit',
|
name: 'reddit'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: `https://www.reddit.com/user/${match[1]}`,
|
uri: `https://www.reddit.com/user/${match[1]}`,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -42,39 +42,39 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON,
|
||||||
data: {
|
data: {
|
||||||
url: `https://www.reddit.com/user/${match[1]}/comments/${match[2]}.json`,
|
url: `https://www.reddit.com/user/${match[1]}/comments/${match[2]}.json`,
|
||||||
format: E.ProofFormat.JSON,
|
format: E.ProofFormat.JSON
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: ['data', 'children', 'data', 'selftext'],
|
path: ['data', 'children', 'data', 'selftext']
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://www.reddit.com/user/Alice/comments/123456/post',
|
uri: 'https://www.reddit.com/user/Alice/comments/123456/post',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://www.reddit.com/user/Alice/comments/123456/post/',
|
uri: 'https://www.reddit.com/user/Alice/comments/123456/post/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://reddit.com/user/Alice/comments/123456/post',
|
uri: 'https://reddit.com/user/Alice/comments/123456/post',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://reddit.com/user/Alice/comments/123456/post/',
|
uri: 'https://reddit.com/user/Alice/comments/123456/post/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/user/Alice/comments/123456/post',
|
uri: 'https://domain.org/user/Alice/comments/123456/post',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'twitter',
|
name: 'twitter'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `@${match[1]}`,
|
display: `@${match[1]}`,
|
||||||
uri: `https://twitter.com/${match[1]}`,
|
uri: `https://twitter.com/${match[1]}`,
|
||||||
qr: null,
|
qr: null
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
|
@ -41,31 +41,31 @@ const processURI = (uri) => {
|
||||||
access: E.ProofAccess.GRANTED,
|
access: E.ProofAccess.GRANTED,
|
||||||
format: E.ProofFormat.TEXT,
|
format: E.ProofFormat.TEXT,
|
||||||
data: {
|
data: {
|
||||||
tweetId: match[2],
|
tweetId: match[2]
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: [],
|
path: []
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'https://twitter.com/alice/status/1234567890123456789',
|
uri: 'https://twitter.com/alice/status/1234567890123456789',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://twitter.com/alice/status/1234567890123456789/',
|
uri: 'https://twitter.com/alice/status/1234567890123456789/',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org/alice/status/1234567890123456789',
|
uri: 'https://domain.org/alice/status/1234567890123456789',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
const E = require('../enums')
|
const E = require('../enums')
|
||||||
|
|
||||||
const reURI = /^xmpp:([a-zA-Z0-9\.\-\_]*)@([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
|
const reURI = /^xmpp:([a-zA-Z0-9.\-_]*)@([a-zA-Z0-9.\-_]*)(?:\?(.*))?/
|
||||||
|
|
||||||
const processURI = (uri) => {
|
const processURI = (uri) => {
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
@ -23,16 +23,16 @@ const processURI = (uri) => {
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'communication',
|
type: 'communication',
|
||||||
name: 'xmpp',
|
name: 'xmpp'
|
||||||
},
|
},
|
||||||
match: {
|
match: {
|
||||||
regularExpression: reURI,
|
regularExpression: reURI,
|
||||||
isAmbiguous: false,
|
isAmbiguous: false
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `${match[1]}@${match[2]}`,
|
display: `${match[1]}@${match[2]}`,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: uri,
|
qr: uri
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: null,
|
uri: null,
|
||||||
|
@ -42,31 +42,31 @@ const processURI = (uri) => {
|
||||||
format: E.ProofFormat.TEXT,
|
format: E.ProofFormat.TEXT,
|
||||||
data: {
|
data: {
|
||||||
id: `${match[1]}@${match[2]}`,
|
id: `${match[1]}@${match[2]}`,
|
||||||
field: 'note',
|
field: 'note'
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
format: E.ClaimFormat.MESSAGE,
|
format: E.ClaimFormat.MESSAGE,
|
||||||
relation: E.ClaimRelation.CONTAINS,
|
relation: E.ClaimRelation.CONTAINS,
|
||||||
path: [],
|
path: []
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests = [
|
const tests = [
|
||||||
{
|
{
|
||||||
uri: 'xmpp:alice@domain.org',
|
uri: 'xmpp:alice@domain.org',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9',
|
uri: 'xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9',
|
||||||
shouldMatch: true,
|
shouldMatch: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
uri: 'https://domain.org',
|
uri: 'https://domain.org',
|
||||||
shouldMatch: false,
|
shouldMatch: false
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
exports.reURI = reURI
|
exports.reURI = reURI
|
||||||
|
|
|
@ -42,25 +42,25 @@ const E = require('./enums')
|
||||||
const opts = {
|
const opts = {
|
||||||
proxy: {
|
proxy: {
|
||||||
hostname: null,
|
hostname: null,
|
||||||
policy: E.ProxyPolicy.NEVER,
|
policy: E.ProxyPolicy.NEVER
|
||||||
},
|
},
|
||||||
claims: {
|
claims: {
|
||||||
irc: {
|
irc: {
|
||||||
nick: null,
|
nick: null
|
||||||
},
|
},
|
||||||
matrix: {
|
matrix: {
|
||||||
instance: null,
|
instance: null,
|
||||||
accessToken: null,
|
accessToken: null
|
||||||
},
|
},
|
||||||
xmpp: {
|
xmpp: {
|
||||||
service: null,
|
service: null,
|
||||||
username: null,
|
username: null,
|
||||||
password: null,
|
password: null
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
bearerToken: null,
|
bearerToken: null
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.opts = opts
|
exports.opts = opts
|
||||||
|
|
14
src/enums.js
14
src/enums.js
|
@ -29,7 +29,7 @@ const ProxyPolicy = {
|
||||||
/** Always use a proxy */
|
/** Always use a proxy */
|
||||||
ALWAYS: 'always',
|
ALWAYS: 'always',
|
||||||
/** Never use a proxy, skip a verification if a proxy is inevitable */
|
/** Never use a proxy, skip a verification if a proxy is inevitable */
|
||||||
NEVER: 'never',
|
NEVER: 'never'
|
||||||
}
|
}
|
||||||
Object.freeze(ProxyPolicy)
|
Object.freeze(ProxyPolicy)
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ const Fetcher = {
|
||||||
/** HTTP request to Gitlab API */
|
/** HTTP request to Gitlab API */
|
||||||
GITLAB: 'gitlab',
|
GITLAB: 'gitlab',
|
||||||
/** HTTP request to Twitter API */
|
/** HTTP request to Twitter API */
|
||||||
TWITTER: 'twitter',
|
TWITTER: 'twitter'
|
||||||
}
|
}
|
||||||
Object.freeze(Fetcher)
|
Object.freeze(Fetcher)
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ const ProofAccess = {
|
||||||
/** HTTP requests must contain API or access tokens */
|
/** HTTP requests must contain API or access tokens */
|
||||||
GRANTED: 2,
|
GRANTED: 2,
|
||||||
/** Not accessible by HTTP request, needs server software */
|
/** Not accessible by HTTP request, needs server software */
|
||||||
SERVER: 3,
|
SERVER: 3
|
||||||
}
|
}
|
||||||
Object.freeze(ProofAccess)
|
Object.freeze(ProofAccess)
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ const ProofFormat = {
|
||||||
/** JSON format */
|
/** JSON format */
|
||||||
JSON: 'json',
|
JSON: 'json',
|
||||||
/** Plaintext format */
|
/** Plaintext format */
|
||||||
TEXT: 'text',
|
TEXT: 'text'
|
||||||
}
|
}
|
||||||
Object.freeze(ProofFormat)
|
Object.freeze(ProofFormat)
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ const ClaimFormat = {
|
||||||
/** `123123123` */
|
/** `123123123` */
|
||||||
FINGERPRINT: 1,
|
FINGERPRINT: 1,
|
||||||
/** `[Verifying my OpenPGP key: openpgp4fpr:123123123]` */
|
/** `[Verifying my OpenPGP key: openpgp4fpr:123123123]` */
|
||||||
MESSAGE: 2,
|
MESSAGE: 2
|
||||||
}
|
}
|
||||||
Object.freeze(ClaimFormat)
|
Object.freeze(ClaimFormat)
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ const ClaimRelation = {
|
||||||
/** Claim is equal to the JSON field's textual content */
|
/** Claim is equal to the JSON field's textual content */
|
||||||
EQUALS: 1,
|
EQUALS: 1,
|
||||||
/** Claim is equal to an element of the JSON field's array of strings */
|
/** Claim is equal to an element of the JSON field's array of strings */
|
||||||
ONEOF: 2,
|
ONEOF: 2
|
||||||
}
|
}
|
||||||
Object.freeze(ClaimRelation)
|
Object.freeze(ClaimRelation)
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ const ClaimStatus = {
|
||||||
/** Claim has matched its URI to candidate claim definitions */
|
/** Claim has matched its URI to candidate claim definitions */
|
||||||
MATCHED: 'matched',
|
MATCHED: 'matched',
|
||||||
/** Claim has verified one or multiple candidate claim definitions */
|
/** Claim has verified one or multiple candidate claim definitions */
|
||||||
VERIFIED: 'verified',
|
VERIFIED: 'verified'
|
||||||
}
|
}
|
||||||
Object.freeze(ClaimStatus)
|
Object.freeze(ClaimStatus)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
const jsEnv = require("browser-or-node")
|
const jsEnv = require('browser-or-node')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module fetcher/dns
|
* @module fetcher/dns
|
||||||
|
@ -55,8 +55,8 @@ if (jsEnv.isNode) {
|
||||||
resolve({
|
resolve({
|
||||||
domain: data.domain,
|
domain: data.domain,
|
||||||
records: {
|
records: {
|
||||||
txt: records,
|
txt: records
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -44,28 +44,45 @@ module.exports.fn = async (data, opts) => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const fetchPromise = new Promise(async (resolve, reject) => {
|
const fetchPromise = new Promise((resolve, reject) => {
|
||||||
const urlUser = `https://${data.domain}/api/v4/users?username=${data.username}`
|
const urlUser = `https://${data.domain}/api/v4/users?username=${data.username}`
|
||||||
const resUser = await req(urlUser, null, { Accept: 'application/json' })
|
// const resUser = await req(urlUser, null, { Accept: 'application/json' })
|
||||||
const jsonUser = await resUser.json()
|
const res = req(urlUser, null, { Accept: 'application/json' })
|
||||||
|
.then(resUser => {
|
||||||
const user = jsonUser.find((user) => user.username === data.username)
|
return resUser.json()
|
||||||
if (!user) {
|
|
||||||
reject(`No user with username ${data.username}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const urlProject = `https://${data.domain}/api/v4/users/${user.id}/projects`
|
|
||||||
const resProject = await req(urlProject, null, {
|
|
||||||
Accept: 'application/json',
|
|
||||||
})
|
})
|
||||||
const jsonProject = await resProject.json()
|
.then(jsonUser => {
|
||||||
|
return jsonUser.find((user) => user.username === data.username)
|
||||||
const project = jsonProject.find((proj) => proj.path === 'gitlab_proof')
|
})
|
||||||
if (!project) {
|
.then(user => {
|
||||||
reject(`No project found`)
|
if (!user) {
|
||||||
|
throw new Error(`No user with username ${data.username}`)
|
||||||
}
|
}
|
||||||
|
return user
|
||||||
|
})
|
||||||
|
.then(user => {
|
||||||
|
const urlProject = `https://${data.domain}/api/v4/users/${user.id}/projects`
|
||||||
|
return req(urlProject, null, {
|
||||||
|
Accept: 'application/json'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(resProject => {
|
||||||
|
return resProject.json()
|
||||||
|
})
|
||||||
|
.then(jsonProject => {
|
||||||
|
return jsonProject.find((proj) => proj.path === 'gitlab_proof')
|
||||||
|
})
|
||||||
|
.then(project => {
|
||||||
|
if (!project) {
|
||||||
|
throw new Error('No project found')
|
||||||
|
}
|
||||||
|
return project
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error)
|
||||||
|
})
|
||||||
|
|
||||||
resolve(project)
|
resolve(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
return Promise.race([fetchPromise, timeoutPromise]).then((result) => {
|
return Promise.race([fetchPromise, timeoutPromise]).then((result) => {
|
||||||
|
|
|
@ -47,7 +47,7 @@ module.exports.fn = async (data, opts) => {
|
||||||
|
|
||||||
const fetchPromise = new Promise((resolve, reject) => {
|
const fetchPromise = new Promise((resolve, reject) => {
|
||||||
if (!data.url) {
|
if (!data.url) {
|
||||||
reject('No valid URI provided')
|
reject(new Error('No valid URI provided'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ module.exports.fn = async (data, opts) => {
|
||||||
case E.ProofFormat.JSON:
|
case E.ProofFormat.JSON:
|
||||||
req(data.url, null, {
|
req(data.url, null, {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
'User-Agent': `doipjs/${require('../../package.json').version}`,
|
'User-Agent': `doipjs/${require('../../package.json').version}`
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
return await res.json()
|
return await res.json()
|
||||||
|
@ -80,7 +80,7 @@ module.exports.fn = async (data, opts) => {
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
reject('No specified data format')
|
reject(new Error('No specified data format'))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
const jsEnv = require("browser-or-node")
|
const jsEnv = require('browser-or-node')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module fetcher/irc
|
* @module fetcher/irc
|
||||||
|
@ -64,9 +64,9 @@ if (jsEnv.isNode) {
|
||||||
showErrors: false,
|
showErrors: false,
|
||||||
debug: false
|
debug: false
|
||||||
})
|
})
|
||||||
const reKey = /[a-zA-Z0-9\-\_]+\s+:\s(openpgp4fpr\:.*)/
|
const reKey = /[a-zA-Z0-9\-_]+\s+:\s(openpgp4fpr:.*)/
|
||||||
const reEnd = /End\sof\s.*\staxonomy./
|
const reEnd = /End\sof\s.*\staxonomy./
|
||||||
let keys = []
|
const keys = []
|
||||||
|
|
||||||
client.addListener('registered', (message) => {
|
client.addListener('registered', (message) => {
|
||||||
client.send(`PRIVMSG NickServ TAXONOMY ${data.nick}`)
|
client.send(`PRIVMSG NickServ TAXONOMY ${data.nick}`)
|
||||||
|
|
|
@ -58,7 +58,7 @@ module.exports.fn = async (data, opts) => {
|
||||||
|
|
||||||
const url = `https://${opts.claims.matrix.instance}/_matrix/client/r0/rooms/${data.roomId}/event/${data.eventId}?access_token=${opts.claims.matrix.accessToken}`
|
const url = `https://${opts.claims.matrix.instance}/_matrix/client/r0/rooms/${data.roomId}/event/${data.eventId}?access_token=${opts.claims.matrix.accessToken}`
|
||||||
bentReq(url, null, {
|
bentReq(url, null, {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json'
|
||||||
})
|
})
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
return await res.json()
|
return await res.json()
|
||||||
|
|
|
@ -60,7 +60,7 @@ module.exports.fn = async (data, opts) => {
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
Authorization: `Bearer ${opts.claims.twitter.bearerToken}`,
|
Authorization: `Bearer ${opts.claims.twitter.bearerToken}`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then(async (data) => {
|
.then(async (data) => {
|
||||||
|
|
|
@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
const jsEnv = require("browser-or-node")
|
const jsEnv = require('browser-or-node')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module fetcher/xmpp
|
* @module fetcher/xmpp
|
||||||
|
@ -31,15 +31,15 @@ if (jsEnv.isNode) {
|
||||||
const debug = require('@xmpp/debug')
|
const debug = require('@xmpp/debug')
|
||||||
const validator = require('validator')
|
const validator = require('validator')
|
||||||
|
|
||||||
let xmpp = null,
|
let xmpp = null
|
||||||
iqCaller = null
|
let iqCaller = null
|
||||||
|
|
||||||
const xmppStart = async (service, username, password) => {
|
const xmppStart = async (service, username, password) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const xmpp = client({
|
const xmpp = client({
|
||||||
service: service,
|
service: service,
|
||||||
username: username,
|
username: username,
|
||||||
password: password,
|
password: password
|
||||||
})
|
})
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
debug(xmpp, true)
|
debug(xmpp, true)
|
||||||
|
@ -69,15 +69,6 @@ if (jsEnv.isNode) {
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
module.exports.fn = async (data, opts) => {
|
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(async (resolve, reject) => {
|
|
||||||
try {
|
try {
|
||||||
validator.isFQDN(opts.claims.xmpp.service)
|
validator.isFQDN(opts.claims.xmpp.service)
|
||||||
validator.isAscii(opts.claims.xmpp.username)
|
validator.isAscii(opts.claims.xmpp.username)
|
||||||
|
@ -104,6 +95,15 @@ if (jsEnv.isNode) {
|
||||||
const vcardRow = response.getChild('vCard', 'vcard-temp').toString()
|
const vcardRow = response.getChild('vCard', 'vcard-temp').toString()
|
||||||
const dom = new jsdom.JSDOM(vcardRow)
|
const dom = new jsdom.JSDOM(vcardRow)
|
||||||
|
|
||||||
|
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 {
|
try {
|
||||||
let vcard
|
let vcard
|
||||||
|
|
||||||
|
|
122
src/keys.js
122
src/keys.js
|
@ -34,35 +34,31 @@ const Claim = require('./claim')
|
||||||
* const key1 = doip.keys.fetchHKP('alice@domain.tld');
|
* const key1 = doip.keys.fetchHKP('alice@domain.tld');
|
||||||
* const key2 = doip.keys.fetchHKP('123abc123abc');
|
* const key2 = doip.keys.fetchHKP('123abc123abc');
|
||||||
*/
|
*/
|
||||||
exports.fetchHKP = (identifier, keyserverDomain) => {
|
exports.fetchHKP = async (identifier, keyserverDomain) => {
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
const keyserverBaseUrl = keyserverDomain
|
const keyserverBaseUrl = keyserverDomain
|
||||||
? `https://${keyserverDomain}`
|
? `https://${keyserverDomain}`
|
||||||
: 'https://keys.openpgp.org'
|
: 'https://keys.openpgp.org'
|
||||||
|
|
||||||
const hkp = new openpgp.HKP(keyserverBaseUrl)
|
const hkp = new openpgp.HKP(keyserverBaseUrl)
|
||||||
const lookupOpts = {
|
const lookupOpts = {
|
||||||
query: identifier,
|
query: identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
let publicKey = await hkp.lookup(lookupOpts).catch((error) => {
|
const publicKey = await hkp.lookup(lookupOpts).catch((error) => {
|
||||||
reject('Key does not exist or could not be fetched')
|
throw new Error(`Key does not exist or could not be fetched (${error})`)
|
||||||
})
|
})
|
||||||
|
|
||||||
publicKey = await openpgp.key
|
if (!publicKey) {
|
||||||
|
throw new Error('Key does not exist or could not be fetched')
|
||||||
|
}
|
||||||
|
|
||||||
|
return await openpgp.key
|
||||||
.readArmored(publicKey)
|
.readArmored(publicKey)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
return result.keys[0]
|
return result.keys[0]
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
return null
|
throw new Error(`Key does not exist or could not be fetched (${error})`)
|
||||||
})
|
|
||||||
|
|
||||||
if (publicKey) {
|
|
||||||
resolve(publicKey)
|
|
||||||
} else {
|
|
||||||
reject('Key does not exist or could not be fetched')
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,27 +70,19 @@ exports.fetchHKP = (identifier, keyserverDomain) => {
|
||||||
* @example
|
* @example
|
||||||
* const key = doip.keys.fetchWKD('alice@domain.tld');
|
* const key = doip.keys.fetchWKD('alice@domain.tld');
|
||||||
*/
|
*/
|
||||||
exports.fetchWKD = (identifier) => {
|
exports.fetchWKD = async (identifier) => {
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
const wkd = new openpgp.WKD()
|
const wkd = new openpgp.WKD()
|
||||||
const lookupOpts = {
|
const lookupOpts = {
|
||||||
email: identifier,
|
email: identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
const publicKey = await wkd
|
return await wkd
|
||||||
.lookup(lookupOpts)
|
.lookup(lookupOpts)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
return result.keys[0]
|
return result.keys[0]
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
return null
|
throw new Error(`Key does not exist or could not be fetched (${error})`)
|
||||||
})
|
|
||||||
|
|
||||||
if (publicKey) {
|
|
||||||
resolve(publicKey)
|
|
||||||
} else {
|
|
||||||
reject('Key does not exist or could not be fetched')
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,8 +95,7 @@ exports.fetchWKD = (identifier) => {
|
||||||
* @example
|
* @example
|
||||||
* const key = doip.keys.fetchKeybase('alice', '123abc123abc');
|
* const key = doip.keys.fetchKeybase('alice', '123abc123abc');
|
||||||
*/
|
*/
|
||||||
exports.fetchKeybase = (username, fingerprint) => {
|
exports.fetchKeybase = async (username, fingerprint) => {
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}`
|
const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}`
|
||||||
let rawKeyContent
|
let rawKeyContent
|
||||||
try {
|
try {
|
||||||
|
@ -120,23 +107,16 @@ exports.fetchKeybase = (username, fingerprint) => {
|
||||||
})
|
})
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject(`Error fetching Keybase key: ${e.message}`)
|
throw new Error(`Error fetching Keybase key: ${e.message}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const publicKey = await openpgp.key
|
return await openpgp.key
|
||||||
.readArmored(rawKeyContent)
|
.readArmored(rawKeyContent)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
return result.keys[0]
|
return result.keys[0]
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
return null
|
throw new Error(`Key does not exist or could not be fetched (${error})`)
|
||||||
})
|
|
||||||
|
|
||||||
if (publicKey) {
|
|
||||||
resolve(publicKey)
|
|
||||||
} else {
|
|
||||||
reject('Key does not exist or could not be fetched')
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,12 +134,9 @@ exports.fetchKeybase = (username, fingerprint) => {
|
||||||
* -----END PGP PUBLIC KEY BLOCK-----`
|
* -----END PGP PUBLIC KEY BLOCK-----`
|
||||||
* const key = doip.keys.fetchPlaintext(plainkey);
|
* const key = doip.keys.fetchPlaintext(plainkey);
|
||||||
*/
|
*/
|
||||||
exports.fetchPlaintext = (rawKeyContent) => {
|
exports.fetchPlaintext = async (rawKeyContent) => {
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0]
|
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0]
|
||||||
|
return publicKey
|
||||||
resolve(publicKey)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,41 +149,34 @@ exports.fetchPlaintext = (rawKeyContent) => {
|
||||||
* const key2 = doip.keys.fetchURI('hkp:123abc123abc');
|
* const key2 = doip.keys.fetchURI('hkp:123abc123abc');
|
||||||
* const key3 = doip.keys.fetchURI('wkd:alice@domain.tld');
|
* const key3 = doip.keys.fetchURI('wkd:alice@domain.tld');
|
||||||
*/
|
*/
|
||||||
exports.fetchURI = (uri) => {
|
exports.fetchURI = async (uri) => {
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
if (!validUrl.isUri(uri)) {
|
if (!validUrl.isUri(uri)) {
|
||||||
reject('Invalid URI')
|
throw new Error('Invalid URI')
|
||||||
}
|
}
|
||||||
|
|
||||||
const re = /([a-zA-Z0-9]*):([a-zA-Z0-9@._=+\-]*)(?:\:([a-zA-Z0-9@._=+\-]*))?/
|
const re = /([a-zA-Z0-9]*):([a-zA-Z0-9@._=+-]*)(?::([a-zA-Z0-9@._=+-]*))?/
|
||||||
const match = uri.match(re)
|
const match = uri.match(re)
|
||||||
|
|
||||||
if (!match[1]) {
|
if (!match[1]) {
|
||||||
reject('Invalid URI')
|
throw new Error('Invalid URI')
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (match[1]) {
|
switch (match[1]) {
|
||||||
case 'hkp':
|
case 'hkp':
|
||||||
resolve(
|
return exports.fetchHKP(
|
||||||
exports.fetchHKP(
|
|
||||||
match[3] ? match[3] : match[2],
|
match[3] ? match[3] : match[2],
|
||||||
match[3] ? match[2] : null
|
match[3] ? match[2] : null
|
||||||
)
|
)
|
||||||
)
|
|
||||||
break
|
|
||||||
case 'wkd':
|
case 'wkd':
|
||||||
resolve(exports.fetchWKD(match[2]))
|
return exports.fetchWKD(match[2])
|
||||||
break
|
|
||||||
case 'kb':
|
case 'kb':
|
||||||
resolve(
|
return exports.fetchKeybase(match[2], match.length >= 4 ? match[3] : null)
|
||||||
exports.fetchKeybase(match[2], match.length >= 4 ? match[3] : null)
|
|
||||||
)
|
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
reject('Invalid URI protocol')
|
throw new Error('Invalid URI protocol')
|
||||||
break
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,16 +191,15 @@ exports.fetchURI = (uri) => {
|
||||||
* console.log(claim.uri);
|
* console.log(claim.uri);
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
exports.process = (publicKey) => {
|
exports.process = async (publicKey) => {
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
if (!publicKey || !(publicKey instanceof openpgp.key.Key)) {
|
if (!publicKey || !(publicKey instanceof openpgp.key.Key)) {
|
||||||
reject('Invalid public key')
|
throw new Error('Invalid public key')
|
||||||
}
|
}
|
||||||
|
|
||||||
const fingerprint = await publicKey.primaryKey.getFingerprint()
|
const fingerprint = await publicKey.primaryKey.getFingerprint()
|
||||||
const primaryUser = await publicKey.getPrimaryUser()
|
const primaryUser = await publicKey.getPrimaryUser()
|
||||||
const users = publicKey.users
|
const users = publicKey.users
|
||||||
let usersOutput = []
|
const usersOutput = []
|
||||||
|
|
||||||
users.forEach((user, i) => {
|
users.forEach((user, i) => {
|
||||||
usersOutput[i] = {
|
usersOutput[i] = {
|
||||||
|
@ -240,9 +209,9 @@ exports.process = (publicKey) => {
|
||||||
email: user.userId ? user.userId.email : null,
|
email: user.userId ? user.userId.email : null,
|
||||||
comment: user.userId ? user.userId.comment : null,
|
comment: user.userId ? user.userId.comment : null,
|
||||||
isPrimary: primaryUser.index === i,
|
isPrimary: primaryUser.index === i,
|
||||||
isRevoked: false,
|
isRevoked: false
|
||||||
},
|
},
|
||||||
claims: [],
|
claims: []
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('selfCertifications' in user && user.selfCertifications.length > 0) {
|
if ('selfCertifications' in user && user.selfCertifications.length > 0) {
|
||||||
|
@ -250,22 +219,27 @@ exports.process = (publicKey) => {
|
||||||
|
|
||||||
const notations = selfCertification.rawNotations
|
const notations = selfCertification.rawNotations
|
||||||
usersOutput[i].claims = notations
|
usersOutput[i].claims = notations
|
||||||
.filter(({ name, humanReadable }) => humanReadable && name === 'proof@metacode.biz')
|
.filter(
|
||||||
.map(({ value }) => new Claim(openpgp.util.decode_utf8(value), fingerprint))
|
({ name, humanReadable }) =>
|
||||||
|
humanReadable && name === 'proof@metacode.biz'
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
({ value }) =>
|
||||||
|
new Claim(openpgp.util.decode_utf8(value), fingerprint)
|
||||||
|
)
|
||||||
|
|
||||||
usersOutput[i].userData.isRevoked = selfCertification.revoked
|
usersOutput[i].userData.isRevoked = selfCertification.revoked
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
resolve({
|
return {
|
||||||
fingerprint: fingerprint,
|
fingerprint: fingerprint,
|
||||||
users: usersOutput,
|
users: usersOutput,
|
||||||
primaryUserIndex: primaryUser.index,
|
primaryUserIndex: primaryUser.index,
|
||||||
key: {
|
key: {
|
||||||
data: publicKey,
|
data: publicKey,
|
||||||
fetchMethod: null,
|
fetchMethod: null,
|
||||||
uri: null,
|
uri: null
|
||||||
},
|
}
|
||||||
})
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,49 +54,37 @@ const handleBrowserRequests = (data, opts) => {
|
||||||
switch (opts.proxy.policy) {
|
switch (opts.proxy.policy) {
|
||||||
case E.ProxyPolicy.ALWAYS:
|
case E.ProxyPolicy.ALWAYS:
|
||||||
return createProxyRequestPromise(data, opts)
|
return createProxyRequestPromise(data, opts)
|
||||||
break
|
|
||||||
|
|
||||||
case E.ProxyPolicy.NEVER:
|
case E.ProxyPolicy.NEVER:
|
||||||
switch (data.proof.request.access) {
|
switch (data.proof.request.access) {
|
||||||
case E.ProofAccess.GENERIC:
|
case E.ProofAccess.GENERIC:
|
||||||
case E.ProofAccess.GRANTED:
|
case E.ProofAccess.GRANTED:
|
||||||
return createDefaultRequestPromise(data, opts)
|
return createDefaultRequestPromise(data, opts)
|
||||||
break
|
|
||||||
case E.ProofAccess.NOCORS:
|
case E.ProofAccess.NOCORS:
|
||||||
case E.ProofAccess.SERVER:
|
case E.ProofAccess.SERVER:
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Impossible to fetch proof (bad combination of service access and proxy policy)'
|
'Impossible to fetch proof (bad combination of service access and proxy policy)'
|
||||||
)
|
)
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid proof access value')
|
throw new Error('Invalid proof access value')
|
||||||
break
|
|
||||||
}
|
}
|
||||||
break
|
|
||||||
|
|
||||||
case E.ProxyPolicy.ADAPTIVE:
|
case E.ProxyPolicy.ADAPTIVE:
|
||||||
switch (data.proof.request.access) {
|
switch (data.proof.request.access) {
|
||||||
case E.ProofAccess.GENERIC:
|
case E.ProofAccess.GENERIC:
|
||||||
return createFallbackRequestPromise(data, opts)
|
return createFallbackRequestPromise(data, opts)
|
||||||
break
|
|
||||||
case E.ProofAccess.NOCORS:
|
case E.ProofAccess.NOCORS:
|
||||||
return createProxyRequestPromise(data, opts)
|
return createProxyRequestPromise(data, opts)
|
||||||
break
|
|
||||||
case E.ProofAccess.GRANTED:
|
case E.ProofAccess.GRANTED:
|
||||||
return createFallbackRequestPromise(data, opts)
|
return createFallbackRequestPromise(data, opts)
|
||||||
break
|
|
||||||
case E.ProofAccess.SERVER:
|
case E.ProofAccess.SERVER:
|
||||||
return createProxyRequestPromise(data, opts)
|
return createProxyRequestPromise(data, opts)
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid proof access value')
|
throw new Error('Invalid proof access value')
|
||||||
break
|
|
||||||
}
|
}
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid proxy policy')
|
throw new Error('Invalid proxy policy')
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,19 +92,15 @@ const handleNodeRequests = (data, opts) => {
|
||||||
switch (opts.proxy.policy) {
|
switch (opts.proxy.policy) {
|
||||||
case E.ProxyPolicy.ALWAYS:
|
case E.ProxyPolicy.ALWAYS:
|
||||||
return createProxyRequestPromise(data, opts)
|
return createProxyRequestPromise(data, opts)
|
||||||
break
|
|
||||||
|
|
||||||
case E.ProxyPolicy.NEVER:
|
case E.ProxyPolicy.NEVER:
|
||||||
return createDefaultRequestPromise(data, opts)
|
return createDefaultRequestPromise(data, opts)
|
||||||
break
|
|
||||||
|
|
||||||
case E.ProxyPolicy.ADAPTIVE:
|
case E.ProxyPolicy.ADAPTIVE:
|
||||||
return createFallbackRequestPromise(data, opts)
|
return createFallbackRequestPromise(data, opts)
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error('Invalid proxy policy')
|
throw new Error('Invalid proxy policy')
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +113,7 @@ const createDefaultRequestPromise = (data, opts) => {
|
||||||
fetcher: data.proof.request.fetcher,
|
fetcher: data.proof.request.fetcher,
|
||||||
data: data,
|
data: data,
|
||||||
viaProxy: false,
|
viaProxy: false,
|
||||||
result: res,
|
result: res
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -154,7 +138,7 @@ const createProxyRequestPromise = (data, opts) => {
|
||||||
const requestData = {
|
const requestData = {
|
||||||
url: proxyUrl,
|
url: proxyUrl,
|
||||||
format: data.proof.request.format,
|
format: data.proof.request.format,
|
||||||
fetcherTimeout: fetcher[data.proof.request.fetcher].timeout,
|
fetcherTimeout: fetcher[data.proof.request.fetcher].timeout
|
||||||
}
|
}
|
||||||
fetcher.http
|
fetcher.http
|
||||||
.fn(requestData, opts)
|
.fn(requestData, opts)
|
||||||
|
@ -163,7 +147,7 @@ const createProxyRequestPromise = (data, opts) => {
|
||||||
fetcher: 'http',
|
fetcher: 'http',
|
||||||
data: data,
|
data: data,
|
||||||
viaProxy: true,
|
viaProxy: true,
|
||||||
result: res,
|
result: res
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -184,7 +168,7 @@ const createFallbackRequestPromise = (data, opts) => {
|
||||||
return resolve(res)
|
return resolve(res)
|
||||||
})
|
})
|
||||||
.catch((err2) => {
|
.catch((err2) => {
|
||||||
return reject([err1, err2])
|
return reject(err2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,40 +24,40 @@ const debug = require('@xmpp/debug')
|
||||||
const irc = require('irc-upd')
|
const irc = require('irc-upd')
|
||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
const xmpp_service = process.env.XMPP_SERVICE || null
|
const xmppService = process.env.XMPP_SERVICE || null
|
||||||
const xmpp_username = process.env.XMPP_USERNAME || null
|
const xmppUsername = process.env.XMPP_USERNAME || null
|
||||||
const xmpp_password = process.env.XMPP_PASSWORD || null
|
const xmppPassword = process.env.XMPP_PASSWORD || null
|
||||||
const twitter_bearer_token = process.env.TWITTER_BEARER_TOKEN || null
|
const twitterBearerToken = process.env.TWITTER_BEARER_TOKEN || null
|
||||||
const matrix_instance = process.env.MATRIX_INSTANCE || null
|
const matrixInstance = process.env.MATRIX_INSTANCE || null
|
||||||
const matrix_access_token = process.env.MATRIX_ACCESS_TOKEN || null
|
const matrixAccessToken = process.env.MATRIX_ACCESS_TOKEN || null
|
||||||
const irc_nick = process.env.IRC_NICK || null
|
const ircNick = process.env.IRC_NICK || null
|
||||||
|
|
||||||
let xmpp = null,
|
let xmpp = null
|
||||||
iqCaller = null,
|
let iqCaller = null
|
||||||
xmpp_enabled = true,
|
let xmppEnabled = true
|
||||||
twitter_enabled = false,
|
let twitterEnabled = false
|
||||||
matrix_enabled = false,
|
let matrixEnabled = false
|
||||||
irc_enabled = false
|
let ircEnabled = false
|
||||||
|
|
||||||
if (!xmpp_service || !xmpp_username || !xmpp_password) {
|
if (!xmppService || !xmppUsername || !xmppPassword) {
|
||||||
xmpp_enabled = false
|
xmppEnabled = false
|
||||||
}
|
}
|
||||||
if (twitter_bearer_token) {
|
if (twitterBearerToken) {
|
||||||
twitter_enabled = true
|
twitterEnabled = true
|
||||||
}
|
}
|
||||||
if (matrix_instance && matrix_access_token) {
|
if (matrixInstance && matrixAccessToken) {
|
||||||
matrix_enabled = true
|
matrixEnabled = true
|
||||||
}
|
}
|
||||||
if (irc_nick) {
|
if (ircNick) {
|
||||||
irc_enabled = true
|
ircEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const xmppStart = async (xmpp_service, xmpp_username, xmpp_password) => {
|
const xmppStart = async (xmppService, xmppUsername, xmppPassword) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const xmpp = client({
|
const xmpp = client({
|
||||||
service: xmpp_service,
|
service: xmppService,
|
||||||
username: xmpp_username,
|
username: xmppUsername,
|
||||||
password: xmpp_password,
|
password: xmppPassword
|
||||||
})
|
})
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
debug(xmpp, true)
|
debug(xmpp, true)
|
||||||
|
@ -77,7 +77,7 @@ const xmppStart = async (xmpp_service, xmpp_username, xmpp_password) => {
|
||||||
router.get('/', async (req, res) => {
|
router.get('/', async (req, res) => {
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
message:
|
message:
|
||||||
'Available endpoints: /json/:url, /text/:url, /dns/:hostname, /xmpp/:xmppid, /twitter/:tweetid, /matrix/:roomid/:eventid, /irc/:ircserver/:ircnick',
|
'Available endpoints: /json/:url, /text/:url, /dns/:hostname, /xmpp/:xmppid, /twitter/:tweetid, /matrix/:roomid/:eventid, /irc/:ircserver/:ircnick'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ router.param('url', async (req, res, next, url) => {
|
||||||
router.param('xmppid', async (req, res, next, xmppid) => {
|
router.param('xmppid', async (req, res, next, xmppid) => {
|
||||||
req.params.xmppid = xmppid
|
req.params.xmppid = xmppid
|
||||||
|
|
||||||
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/.test(req.params.xmppid)) {
|
if (/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,})+$/.test(req.params.xmppid)) {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
return res.status(400).json({ message: 'XMPP_ID was not valid' })
|
return res.status(400).json({ message: 'XMPP_ID was not valid' })
|
||||||
|
@ -112,13 +112,13 @@ router.param('xmppdata', async (req, res, next, xmppdata) => {
|
||||||
'BDAY',
|
'BDAY',
|
||||||
'NICKNAME',
|
'NICKNAME',
|
||||||
'NOTE',
|
'NOTE',
|
||||||
'DESC',
|
'DESC'
|
||||||
]
|
]
|
||||||
|
|
||||||
if (!allowedData.includes(req.params.xmppdata)) {
|
if (!allowedData.includes(req.params.xmppdata)) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
message:
|
message:
|
||||||
'Allowed data are: FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC',
|
'Allowed data are: FN, NUMBER, USERID, URL, BDAY, NICKNAME, NOTE, DESC'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ router.param('xmppdata', async (req, res, next, xmppdata) => {
|
||||||
|
|
||||||
router.get('/get/json/:url', (req, res) => {
|
router.get('/get/json/:url', (req, res) => {
|
||||||
bentReq(req.params.url, 'json', {
|
bentReq(req.params.url, 'json', {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json'
|
||||||
})
|
})
|
||||||
.then(async (result) => {
|
.then(async (result) => {
|
||||||
return await result.json()
|
return await result.json()
|
||||||
|
@ -155,11 +155,14 @@ router.get('/get/text/:url', (req, res) => {
|
||||||
|
|
||||||
router.get('/get/dns/:hostname', async (req, res) => {
|
router.get('/get/dns/:hostname', async (req, res) => {
|
||||||
dns.resolveTxt(req.params.hostname, (err, records) => {
|
dns.resolveTxt(req.params.hostname, (err, records) => {
|
||||||
|
if (err) {
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
const out = {
|
const out = {
|
||||||
hostname: req.params.hostname,
|
hostname: req.params.hostname,
|
||||||
records: {
|
records: {
|
||||||
txt: records,
|
txt: records
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
return res.status(200).json(out)
|
return res.status(200).json(out)
|
||||||
})
|
})
|
||||||
|
@ -174,14 +177,14 @@ router.get('/get/xmpp/:xmppid', async (req, res) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get('/get/xmpp/:xmppid/:xmppdata', async (req, res) => {
|
router.get('/get/xmpp/:xmppid/:xmppdata', async (req, res) => {
|
||||||
if (!xmpp_enabled) {
|
if (!xmppEnabled) {
|
||||||
return res.status(500).json('XMPP not enabled on server')
|
return res.status(500).json('XMPP not enabled on server')
|
||||||
}
|
}
|
||||||
if (!xmpp) {
|
if (!xmpp) {
|
||||||
const xmppStartRes = await xmppStart(
|
const xmppStartRes = await xmppStart(
|
||||||
xmpp_service,
|
xmppService,
|
||||||
xmpp_username,
|
xmppUsername,
|
||||||
xmpp_password
|
xmppPassword
|
||||||
)
|
)
|
||||||
xmpp = xmppStartRes.xmpp
|
xmpp = xmppStartRes.xmpp
|
||||||
iqCaller = xmppStartRes.iqCaller
|
iqCaller = xmppStartRes.iqCaller
|
||||||
|
@ -231,7 +234,7 @@ router.get('/get/xmpp/:xmppid/:xmppdata', async (req, res) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get('/get/twitter/:tweetid', async (req, res) => {
|
router.get('/get/twitter/:tweetid', async (req, res) => {
|
||||||
if (!twitter_enabled) {
|
if (!twitterEnabled) {
|
||||||
return res.status(500).json('Twitter not enabled on server')
|
return res.status(500).json('Twitter not enabled on server')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +243,7 @@ router.get('/get/twitter/:tweetid', async (req, res) => {
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
Authorization: `Bearer ${twitter_bearer_token}`,
|
Authorization: `Bearer ${twitterBearerToken}`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then(async (data) => {
|
.then(async (data) => {
|
||||||
|
@ -253,20 +256,20 @@ router.get('/get/twitter/:tweetid', async (req, res) => {
|
||||||
return res.status(error.statusCode || 400).json({
|
return res.status(error.statusCode || 400).json({
|
||||||
data: [],
|
data: [],
|
||||||
message: 'Request could not be fulfilled',
|
message: 'Request could not be fulfilled',
|
||||||
error: error,
|
error: error
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get('/get/matrix/:matrixroomid/:matrixeventid', async (req, res) => {
|
router.get('/get/matrix/:matrixroomid/:matrixeventid', async (req, res) => {
|
||||||
if (!matrix_enabled) {
|
if (!matrixEnabled) {
|
||||||
return res.status(500).json('Matrix not enabled on server')
|
return res.status(500).json('Matrix not enabled on server')
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `https://${matrix_instance}/_matrix/client/r0/rooms/${req.params.matrixroomid}/event/${req.params.matrixeventid}?access_token=${matrix_access_token}`
|
const url = `https://${matrixInstance}/_matrix/client/r0/rooms/${req.params.matrixroomid}/event/${req.params.matrixeventid}?access_token=${matrixAccessToken}`
|
||||||
|
|
||||||
bentReq(url, null, {
|
bentReq(url, null, {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json'
|
||||||
})
|
})
|
||||||
.then(async (data) => {
|
.then(async (data) => {
|
||||||
return await data.json()
|
return await data.json()
|
||||||
|
@ -278,25 +281,25 @@ router.get('/get/matrix/:matrixroomid/:matrixeventid', async (req, res) => {
|
||||||
return res.status(error.statusCode || 400).json({
|
return res.status(error.statusCode || 400).json({
|
||||||
data: [],
|
data: [],
|
||||||
message: 'Request could not be fulfilled',
|
message: 'Request could not be fulfilled',
|
||||||
error: error,
|
error: error
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get('/get/irc/:ircserver/:ircnick', async (req, res) => {
|
router.get('/get/irc/:ircserver/:ircnick', async (req, res) => {
|
||||||
if (!irc_enabled) {
|
if (!ircEnabled) {
|
||||||
return res.status(500).json('IRC not enabled on server')
|
return res.status(500).json('IRC not enabled on server')
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const client = new irc.Client(req.params.ircserver, irc_nick, {
|
const client = new irc.Client(req.params.ircserver, ircNick, {
|
||||||
port: 6697,
|
port: 6697,
|
||||||
secure: true,
|
secure: true,
|
||||||
channels: [],
|
channels: []
|
||||||
})
|
})
|
||||||
const reKey = /[a-zA-Z0-9\-\_]+\s+:\s(openpgp4fpr\:.*)/
|
const reKey = /[a-zA-Z0-9\-_]+\s+:\s(openpgp4fpr:.*)/
|
||||||
const reEnd = /End\sof\s.*\staxonomy./
|
const reEnd = /End\sof\s.*\staxonomy./
|
||||||
let keys = []
|
const keys = []
|
||||||
|
|
||||||
client.addListener('registered', (message) => {
|
client.addListener('registered', (message) => {
|
||||||
client.send(`PRIVMSG NickServ :TAXONOMY ${req.params.ircnick}`)
|
client.send(`PRIVMSG NickServ :TAXONOMY ${req.params.ircnick}`)
|
||||||
|
@ -317,7 +320,7 @@ router.get('/get/irc/:ircserver/:ircnick', async (req, res) => {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
data: [],
|
data: [],
|
||||||
message: 'Request could not be fulfilled',
|
message: 'Request could not be fulfilled',
|
||||||
error: error,
|
error: error
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,21 +22,21 @@ require('dotenv').config()
|
||||||
const opts = {
|
const opts = {
|
||||||
claims: {
|
claims: {
|
||||||
irc: {
|
irc: {
|
||||||
nick: process.env.IRC_NICK || null,
|
nick: process.env.IRC_NICK || null
|
||||||
},
|
},
|
||||||
matrix: {
|
matrix: {
|
||||||
instance: process.env.MATRIX_INSTANCE || null,
|
instance: process.env.MATRIX_INSTANCE || null,
|
||||||
accessToken: process.env.MATRIX_ACCESS_TOKEN || null,
|
accessToken: process.env.MATRIX_ACCESS_TOKEN || null
|
||||||
},
|
},
|
||||||
xmpp: {
|
xmpp: {
|
||||||
service: process.env.XMPP_SERVICE || null,
|
service: process.env.XMPP_SERVICE || null,
|
||||||
username: process.env.XMPP_USERNAME || null,
|
username: process.env.XMPP_USERNAME || null,
|
||||||
password: process.env.XMPP_PASSWORD || null,
|
password: process.env.XMPP_PASSWORD || null
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
bearerToken: process.env.TWITTER_BEARER_TOKEN || null,
|
bearerToken: process.env.TWITTER_BEARER_TOKEN || null
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root route
|
// Root route
|
||||||
|
@ -61,11 +61,9 @@ router.get(
|
||||||
switch (req.query.format) {
|
switch (req.query.format) {
|
||||||
case E.ProofFormat.JSON:
|
case E.ProofFormat.JSON:
|
||||||
return res.status(200).json(result)
|
return res.status(200).json(result)
|
||||||
break
|
|
||||||
|
|
||||||
case E.ProofFormat.TEXT:
|
case E.ProofFormat.TEXT:
|
||||||
return res.status(200).send(result)
|
return res.status(200).send(result)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -103,7 +101,7 @@ router.get(
|
||||||
'bday',
|
'bday',
|
||||||
'nickname',
|
'nickname',
|
||||||
'note',
|
'note',
|
||||||
'desc',
|
'desc'
|
||||||
]),
|
]),
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -27,30 +27,28 @@ const keys = require('./keys')
|
||||||
* @param {string} signature - The plaintext signature to process
|
* @param {string} signature - The plaintext signature to process
|
||||||
* @returns {Promise<object>}
|
* @returns {Promise<object>}
|
||||||
*/
|
*/
|
||||||
const process = (signature) => {
|
const process = async (signature) => {
|
||||||
return new Promise(async (resolve, reject) => {
|
let sigData
|
||||||
let sigData,
|
const result = {
|
||||||
result = {
|
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
users: [
|
users: [
|
||||||
{
|
{
|
||||||
userData: {},
|
userData: {},
|
||||||
claims: [],
|
claims: []
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
primaryUserIndex: null,
|
primaryUserIndex: null,
|
||||||
key: {
|
key: {
|
||||||
data: null,
|
data: null,
|
||||||
fetchMethod: null,
|
fetchMethod: null,
|
||||||
uri: null,
|
uri: null
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sigData = await openpgp.cleartext.readArmored(signature)
|
sigData = await openpgp.cleartext.readArmored(signature)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(new Error('invalid_signature'))
|
throw new Error('invalid_signature')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const issuerKeyId = sigData.signature.packets[0].issuerKeyId.toHex()
|
const issuerKeyId = sigData.signature.packets[0].issuerKeyId.toHex()
|
||||||
|
@ -59,10 +57,10 @@ const process = (signature) => {
|
||||||
sigData.signature.packets[0].preferredKeyServer ||
|
sigData.signature.packets[0].preferredKeyServer ||
|
||||||
'https://keys.openpgp.org/'
|
'https://keys.openpgp.org/'
|
||||||
const text = sigData.getText()
|
const text = sigData.getText()
|
||||||
let sigKeys = []
|
const sigKeys = []
|
||||||
|
|
||||||
text.split('\n').forEach((line, i) => {
|
text.split('\n').forEach((line, i) => {
|
||||||
const match = line.match(/^([a-zA-Z0-9]*)\=(.*)$/i)
|
const match = line.match(/^([a-zA-Z0-9]*)=(.*)$/i)
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -99,15 +97,12 @@ const process = (signature) => {
|
||||||
// Try HKP
|
// Try HKP
|
||||||
if (!result.key.data) {
|
if (!result.key.data) {
|
||||||
try {
|
try {
|
||||||
const match = preferredKeyServer.match(/^(.*\:\/\/)?([^/]*)(?:\/)?$/i)
|
const match = preferredKeyServer.match(/^(.*:\/\/)?([^/]*)(?:\/)?$/i)
|
||||||
result.key.uri = `hkp:${match[2]}:${
|
result.key.uri = `hkp:${match[2]}:${issuerKeyId || signersUserId}`
|
||||||
issuerKeyId ? issuerKeyId : signersUserId
|
|
||||||
}`
|
|
||||||
result.key.data = await keys.fetchURI(result.key.uri)
|
result.key.data = await keys.fetchURI(result.key.uri)
|
||||||
result.key.fetchMethod = 'hkp'
|
result.key.fetchMethod = 'hkp'
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject(new Error('key_not_found'))
|
throw new Error('key_not_found')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +117,7 @@ const process = (signature) => {
|
||||||
|
|
||||||
if (signersUserId) {
|
if (signersUserId) {
|
||||||
result.key.data.users.forEach((user) => {
|
result.key.data.users.forEach((user) => {
|
||||||
if (user.userId.email == signersUserId) {
|
if (user.userId.email === signersUserId) {
|
||||||
userData = user
|
userData = user
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -136,13 +131,12 @@ const process = (signature) => {
|
||||||
name: userData.userId ? userData.userId.name : null,
|
name: userData.userId ? userData.userId.name : null,
|
||||||
email: userData.userId ? userData.userId.email : null,
|
email: userData.userId ? userData.userId.email : null,
|
||||||
comment: userData.userId ? userData.userId.comment : null,
|
comment: userData.userId ? userData.userId.comment : null,
|
||||||
isPrimary: primaryUserData.user.userId.userid === userData.userId.userid,
|
isPrimary: primaryUserData.user.userId.userid === userData.userId.userid
|
||||||
}
|
}
|
||||||
|
|
||||||
result.primaryUserIndex = result.users[0].userData.isPrimary ? 0 : null
|
result.primaryUserIndex = result.users[0].userData.isPrimary ? 0 : null
|
||||||
|
|
||||||
resolve(result)
|
return result
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.process = process
|
exports.process = process
|
||||||
|
|
|
@ -32,10 +32,10 @@ const generateProxyURL = (type, data, opts) => {
|
||||||
try {
|
try {
|
||||||
validator.isFQDN(opts.proxy.hostname)
|
validator.isFQDN(opts.proxy.hostname)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(`Invalid proxy hostname`)
|
throw new Error('Invalid proxy hostname')
|
||||||
}
|
}
|
||||||
|
|
||||||
let queryStrings = []
|
const queryStrings = []
|
||||||
|
|
||||||
Object.keys(data).forEach((key) => {
|
Object.keys(data).forEach((key) => {
|
||||||
queryStrings.push(`${key}=${encodeURIComponent(data[key])}`)
|
queryStrings.push(`${key}=${encodeURIComponent(data[key])}`)
|
||||||
|
@ -56,13 +56,10 @@ const generateClaim = (fingerprint, format) => {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case E.ClaimFormat.URI:
|
case E.ClaimFormat.URI:
|
||||||
return `openpgp4fpr:${fingerprint}`
|
return `openpgp4fpr:${fingerprint}`
|
||||||
break
|
|
||||||
case E.ClaimFormat.MESSAGE:
|
case E.ClaimFormat.MESSAGE:
|
||||||
return `[Verifying my OpenPGP key: openpgp4fpr:${fingerprint}]`
|
return `[Verifying my OpenPGP key: openpgp4fpr:${fingerprint}]`
|
||||||
break
|
|
||||||
case E.ClaimFormat.FINGERPRINT:
|
case E.ClaimFormat.FINGERPRINT:
|
||||||
return fingerprint
|
return fingerprint
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
throw new Error('No valid claim format')
|
throw new Error('No valid claim format')
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,31 +39,26 @@ const runJSON = (proofData, checkPath, checkClaim, checkRelation) => {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkPath.length == 0) {
|
if (checkPath.length === 0) {
|
||||||
switch (checkRelation) {
|
switch (checkRelation) {
|
||||||
default:
|
|
||||||
case E.ClaimRelation.CONTAINS:
|
|
||||||
re = new RegExp(checkClaim, 'gi')
|
|
||||||
return re.test(proofData.replace(/\r?\n|\r|\\/g, ''))
|
|
||||||
break
|
|
||||||
|
|
||||||
case E.ClaimRelation.EQUALS:
|
case E.ClaimRelation.EQUALS:
|
||||||
return (
|
return (
|
||||||
proofData.replace(/\r?\n|\r|\\/g, '').toLowerCase() ==
|
proofData.replace(/\r?\n|\r|\\/g, '').toLowerCase() ===
|
||||||
checkClaim.toLowerCase()
|
checkClaim.toLowerCase()
|
||||||
)
|
)
|
||||||
break
|
|
||||||
|
|
||||||
case E.ClaimRelation.ONEOF:
|
case E.ClaimRelation.ONEOF:
|
||||||
re = new RegExp(checkClaim, 'gi')
|
re = new RegExp(checkClaim, 'gi')
|
||||||
return re.test(proofData.join('|'))
|
return re.test(proofData.join('|'))
|
||||||
break
|
|
||||||
|
case E.ClaimRelation.CONTAINS:
|
||||||
|
default:
|
||||||
|
re = new RegExp(checkClaim, 'gi')
|
||||||
|
return re.test(proofData.replace(/\r?\n|\r|\\/g, ''))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (!(checkPath[0] in proofData)) {
|
||||||
checkPath[0] in proofData
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('err_json_structure_incorrect')
|
throw new Error('err_json_structure_incorrect')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +78,10 @@ const runJSON = (proofData, checkPath, checkClaim, checkRelation) => {
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
const run = (proofData, claimData, fingerprint) => {
|
const run = (proofData, claimData, fingerprint) => {
|
||||||
let res = {
|
const res = {
|
||||||
result: false,
|
result: false,
|
||||||
completed: false,
|
completed: false,
|
||||||
errors: [],
|
errors: []
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (claimData.proof.request.format) {
|
switch (claimData.proof.request.format) {
|
||||||
|
|
Loading…
Reference in a new issue