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