forked from Mirrors/doipjs
Run prettier on code
This commit is contained in:
parent
1a2c6b7b84
commit
4c6715ddb4
22 changed files with 306 additions and 204 deletions
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"ignore": ".licenseignore",
|
"ignore": ".licenseignore",
|
||||||
"license": "LICENSE.HEADER",
|
"license": "LICENSE.HEADER",
|
||||||
"licenseFormats": {
|
"licenseFormats": {
|
||||||
"dotfile|licenseignore|gitignore|yml": {
|
"dotfile|licenseignore|gitignore|yml": {
|
||||||
"eachLine": {
|
"eachLine": {
|
||||||
"prepend": "# "
|
"prepend": "# "
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,15 +18,20 @@ const runOnJson = (res, proofData, checkPath, checkClaim, checkRelation) => {
|
||||||
switch (checkRelation) {
|
switch (checkRelation) {
|
||||||
default:
|
default:
|
||||||
case 'contains':
|
case 'contains':
|
||||||
re = new RegExp(checkClaim.replace('[', '\\[').replace(']', '\\]'), "gi")
|
re = new RegExp(
|
||||||
|
checkClaim.replace('[', '\\[').replace(']', '\\]'),
|
||||||
|
'gi'
|
||||||
|
)
|
||||||
res.isVerified = re.test(proofData.replace(/\r?\n|\r/, ''))
|
res.isVerified = re.test(proofData.replace(/\r?\n|\r/, ''))
|
||||||
break
|
break
|
||||||
case 'equals':
|
case 'equals':
|
||||||
res.isVerified = proofData.replace(/\r?\n|\r/, '').toLowerCase() == checkClaim.toLowerCase()
|
res.isVerified =
|
||||||
|
proofData.replace(/\r?\n|\r/, '').toLowerCase() ==
|
||||||
|
checkClaim.toLowerCase()
|
||||||
break
|
break
|
||||||
case 'oneOf':
|
case 'oneOf':
|
||||||
re = new RegExp(checkClaim, "gi")
|
re = new RegExp(checkClaim, 'gi')
|
||||||
res.isVerified = re.test(proofData.join("|"))
|
res.isVerified = re.test(proofData.join('|'))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
@ -34,27 +39,42 @@ const runOnJson = (res, proofData, checkPath, checkClaim, checkRelation) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkPath[0] in proofData
|
checkPath[0] in proofData
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
res.errors.push('err_data_structure_incorrect')
|
res.errors.push('err_data_structure_incorrect')
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
res = runOnJson(res, proofData[checkPath[0]], checkPath.slice(1), checkClaim, checkRelation)
|
res = runOnJson(
|
||||||
|
res,
|
||||||
|
proofData[checkPath[0]],
|
||||||
|
checkPath.slice(1),
|
||||||
|
checkClaim,
|
||||||
|
checkRelation
|
||||||
|
)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
const run = (proofData, spData) => {
|
const run = (proofData, spData) => {
|
||||||
let res = {
|
let res = {
|
||||||
isVerified: false,
|
isVerified: false,
|
||||||
errors: []
|
errors: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (spData.proof.format) {
|
switch (spData.proof.format) {
|
||||||
case 'json':
|
case 'json':
|
||||||
res = runOnJson(res, proofData, spData.claim.path, utils.generateClaim(spData.claim.fingerprint, spData.claim.format), spData.claim.relation)
|
res = runOnJson(
|
||||||
|
res,
|
||||||
|
proofData,
|
||||||
|
spData.claim.path,
|
||||||
|
utils.generateClaim(spData.claim.fingerprint, spData.claim.format),
|
||||||
|
spData.claim.relation
|
||||||
|
)
|
||||||
break
|
break
|
||||||
case 'text':
|
case 'text':
|
||||||
re = new RegExp(utils.generateClaim(spData.claim.fingerprint, spData.claim.format), "gi")
|
re = new RegExp(
|
||||||
|
utils.generateClaim(spData.claim.fingerprint, spData.claim.format),
|
||||||
|
'gi'
|
||||||
|
)
|
||||||
res = re.test(proofData.replace(/\r?\n|\r/, ''))
|
res = re.test(proofData.replace(/\r?\n|\r/, ''))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
27
src/index.js
27
src/index.js
|
@ -20,13 +20,17 @@ const claimVerification = require('./claimVerification')
|
||||||
const utils = require('./utils')
|
const utils = require('./utils')
|
||||||
|
|
||||||
const verify = async (uri, fingerprint, opts) => {
|
const verify = async (uri, fingerprint, opts) => {
|
||||||
if (!fingerprint) { fingerprint = null }
|
if (!fingerprint) {
|
||||||
if (!opts) { opts = {} }
|
fingerprint = null
|
||||||
|
}
|
||||||
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
|
|
||||||
const defaultOpts = {
|
const defaultOpts = {
|
||||||
returnMatchesOnly: false,
|
returnMatchesOnly: false,
|
||||||
proxyPolicy: 'adaptive',
|
proxyPolicy: 'adaptive',
|
||||||
doipProxyHostname: 'proxy.keyoxide.org'
|
doipProxyHostname: 'proxy.keyoxide.org',
|
||||||
}
|
}
|
||||||
opts = mergeOptions(defaultOpts, opts)
|
opts = mergeOptions(defaultOpts, opts)
|
||||||
|
|
||||||
|
@ -39,7 +43,13 @@ const verify = async (uri, fingerprint, opts) => {
|
||||||
if ('returnMatchesOnly' in opts && opts.returnMatchesOnly) {
|
if ('returnMatchesOnly' in opts && opts.returnMatchesOnly) {
|
||||||
return spMatches
|
return spMatches
|
||||||
}
|
}
|
||||||
let claimVerificationDone = false, claimVerificationResult, sp, iSp = 0, res, proofData, spData
|
let claimVerificationDone = false,
|
||||||
|
claimVerificationResult,
|
||||||
|
sp,
|
||||||
|
iSp = 0,
|
||||||
|
res,
|
||||||
|
proofData,
|
||||||
|
spData
|
||||||
while (!claimVerificationDone && iSp < spMatches.length) {
|
while (!claimVerificationDone && iSp < spMatches.length) {
|
||||||
spData = spMatches[iSp]
|
spData = spMatches[iSp]
|
||||||
spData.claim.fingerprint = fingerprint
|
spData.claim.fingerprint = fingerprint
|
||||||
|
@ -48,7 +58,10 @@ const verify = async (uri, fingerprint, opts) => {
|
||||||
|
|
||||||
if (spData.customRequestHandler instanceof Function) {
|
if (spData.customRequestHandler instanceof Function) {
|
||||||
proofData = await spData.customRequestHandler(spData, opts)
|
proofData = await spData.customRequestHandler(spData, opts)
|
||||||
} else if (!spData.proof.useProxy || 'proxyPolicy' in opts && !opts.useProxyWhenNeeded) {
|
} else if (
|
||||||
|
!spData.proof.useProxy ||
|
||||||
|
('proxyPolicy' in opts && !opts.useProxyWhenNeeded)
|
||||||
|
) {
|
||||||
proofData = await serviceproviders.directRequestHandler(spData, opts)
|
proofData = await serviceproviders.directRequestHandler(spData, opts)
|
||||||
} else {
|
} else {
|
||||||
proofData = await serviceproviders.proxyRequestHandler(spData, opts)
|
proofData = await serviceproviders.proxyRequestHandler(spData, opts)
|
||||||
|
@ -67,13 +80,13 @@ const verify = async (uri, fingerprint, opts) => {
|
||||||
|
|
||||||
if (!claimVerificationResult) {
|
if (!claimVerificationResult) {
|
||||||
claimVerificationResult = {
|
claimVerificationResult = {
|
||||||
isVerified: false
|
isVerified: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isVerified: claimVerificationResult.isVerified,
|
isVerified: claimVerificationResult.isVerified,
|
||||||
serviceproviderData: spData
|
serviceproviderData: spData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,8 @@ const data = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = (uri, opts) => {
|
const match = (uri, opts) => {
|
||||||
let matches = [], sp
|
let matches = [],
|
||||||
|
sp
|
||||||
|
|
||||||
list.forEach((spName, i) => {
|
list.forEach((spName, i) => {
|
||||||
sp = data[spName]
|
sp = data[spName]
|
||||||
|
@ -65,7 +66,11 @@ const match = (uri, opts) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const directRequestHandler = async (spData, opts) => {
|
const directRequestHandler = async (spData, opts) => {
|
||||||
const res = await req(spData.proof.fetch ? spData.proof.fetch : spData.proof.uri, null, { Accept: 'application/json' })
|
const res = await req(
|
||||||
|
spData.proof.fetch ? spData.proof.fetch : spData.proof.uri,
|
||||||
|
null,
|
||||||
|
{ Accept: 'application/json' }
|
||||||
|
)
|
||||||
|
|
||||||
switch (spData.proof.format) {
|
switch (spData.proof.format) {
|
||||||
case 'json':
|
case 'json':
|
||||||
|
@ -82,7 +87,11 @@ const directRequestHandler = async (spData, opts) => {
|
||||||
|
|
||||||
const proxyRequestHandler = async (spData, opts) => {
|
const proxyRequestHandler = async (spData, opts) => {
|
||||||
const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri
|
const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri
|
||||||
const res = await req(utils.generateProxyURL(spData.proof.format, url, opts), null, { Accept: 'application/json' })
|
const res = await req(
|
||||||
|
utils.generateProxyURL(spData.proof.format, url, opts),
|
||||||
|
null,
|
||||||
|
{ Accept: 'application/json' }
|
||||||
|
)
|
||||||
const json = await res.json()
|
const json = await res.json()
|
||||||
return json.content
|
return json.content
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/dev\.to\/(.*)\/(.*)\/?/
|
const reURI = /^https:\/\/dev\.to\/(.*)\/(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'devto'
|
name: 'devto',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: `https://dev.to/api/articles/${match[1]}/${match[2]}`,
|
fetch: `https://dev.to/api/articles/${match[1]}/${match[2]}`,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['body_markdown'],
|
path: ['body_markdown'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/(.*)\/u\/(.*)\/?/
|
const reURI = /^https:\/\/(.*)\/u\/(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'discourse'
|
name: 'discourse',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: `https://${match[1]}/u/${match[2]}.json`,
|
fetch: `https://${match[1]}/u/${match[2]}.json`,
|
||||||
useProxy: true,
|
useProxy: true,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['user', 'bio_raw'],
|
path: ['user', 'bio_raw'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -20,7 +20,7 @@ const utils = require('../utils')
|
||||||
const reURI = /^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
|
const reURI = /^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
|
||||||
|
|
||||||
const customRequestHandler = async (spData, opts) => {
|
const customRequestHandler = async (spData, opts) => {
|
||||||
if (('resolveTxt' in dns)) {
|
if ('resolveTxt' in dns) {
|
||||||
const prom = async () => {
|
const prom = async () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
dns.resolveTxt(spData.profile.display, (err, records) => {
|
dns.resolveTxt(spData.profile.display, (err, records) => {
|
||||||
|
@ -32,59 +32,63 @@ const customRequestHandler = async (spData, opts) => {
|
||||||
return {
|
return {
|
||||||
hostname: spData.profile.display,
|
hostname: spData.profile.display,
|
||||||
records: {
|
records: {
|
||||||
txt: await prom()
|
txt: await prom(),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const res = await req(spData.proof.uri, null, { Accept: 'application/json' })
|
const res = await req(spData.proof.uri, null, {
|
||||||
|
Accept: 'application/json',
|
||||||
|
})
|
||||||
const json = await res.json()
|
const json = await res.json()
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'dns'
|
name: 'dns',
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: `https://${match[1]}`,
|
uri: `https://${match[1]}`,
|
||||||
qr: null
|
qr: null,
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: utils.generateProxyURL('dns', match[1]),
|
uri: utils.generateProxyURL('dns', match[1]),
|
||||||
fetch: null,
|
fetch: null,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'uri',
|
format: 'uri',
|
||||||
path: ['records', 'txt'],
|
path: ['records', 'txt'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: customRequestHandler
|
customRequestHandler: customRequestHandler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/(.*)\/users\/(.*)\/?/
|
const reURI = /^https:\/\/(.*)\/users\/(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'fediverse'
|
name: 'fediverse',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: null,
|
fetch: null,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'fingerprint',
|
format: 'fingerprint',
|
||||||
path: ['summary'],
|
path: ['summary'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/(.*)\/(.*)\/gitea_proof\/?/
|
const reURI = /^https:\/\/(.*)\/(.*)\/gitea_proof\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'gitea'
|
name: 'gitea',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: `https://${match[1]}/api/v1/repos/${match[2]}/gitea_proof`,
|
fetch: `https://${match[1]}/api/v1/repos/${match[2]}/gitea_proof`,
|
||||||
useProxy: true,
|
useProxy: true,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['description'],
|
path: ['description'],
|
||||||
relation: 'equals'
|
relation: 'equals',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/gist\.github\.com\/(.*)\/(.*)\/?/
|
const reURI = /^https:\/\/gist\.github\.com\/(.*)\/(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'github'
|
name: 'github',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: `https://api.github.com/gists/${match[2]}`,
|
fetch: `https://api.github.com/gists/${match[2]}`,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['files', 'openpgp.md', 'content'],
|
path: ['files', 'openpgp.md', 'content'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -25,66 +25,68 @@ const customRequestHandler = async (spData, opts) => {
|
||||||
const resUser = await req(urlUser, 'json', { Accept: 'application/json' })
|
const resUser = await req(urlUser, 'json', { Accept: 'application/json' })
|
||||||
const jsonUser = await resUser.json()
|
const jsonUser = await resUser.json()
|
||||||
|
|
||||||
const user = jsonUser.find(user => user.username === match[2])
|
const user = jsonUser.find((user) => user.username === match[2])
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new Error(`No user with username ${match[2]}`);
|
throw new Error(`No user with username ${match[2]}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const urlProject = `https://${match[1]}/api/v4/users/${user.id}/projects`
|
const urlProject = `https://${match[1]}/api/v4/users/${user.id}/projects`
|
||||||
const resProject = await req(urlProject, {}, { Accept: 'application/json' })
|
const resProject = await req(urlProject, {}, { Accept: 'application/json' })
|
||||||
const jsonProject = await resProject.json()
|
const jsonProject = await resProject.json()
|
||||||
|
|
||||||
const project = jsonProject.find(proj => proj.path === 'gitlab_proof')
|
const project = jsonProject.find((proj) => proj.path === 'gitlab_proof')
|
||||||
if (!project) {
|
if (!project) {
|
||||||
throw new Error(`No project at ${spData.proof.uri}`);
|
throw new Error(`No project at ${spData.proof.uri}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return project
|
return project
|
||||||
}
|
}
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'gitlab'
|
name: 'gitlab',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: null,
|
fetch: null,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['description'],
|
path: ['description'],
|
||||||
relation: 'equals'
|
relation: 'equals',
|
||||||
},
|
},
|
||||||
customRequestHandler: customRequestHandler
|
customRequestHandler: customRequestHandler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/news\.ycombinator\.com\/user\?id=(.*)\/?/
|
const reURI = /^https:\/\/news\.ycombinator\.com\/user\?id=(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'hackernews'
|
name: 'hackernews',
|
||||||
},
|
},
|
||||||
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`,
|
||||||
fetch: null,
|
fetch: null,
|
||||||
useProxy: true,
|
useProxy: true,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'uri',
|
format: 'uri',
|
||||||
path: ['about'],
|
path: ['about'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/liberapay\.com\/(.*)\/?/
|
const reURI = /^https:\/\/liberapay\.com\/(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'liberapay'
|
name: 'liberapay',
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: match[1],
|
display: match[1],
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: null
|
qr: null,
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: uri,
|
uri: uri,
|
||||||
fetch: `https://liberapay.com/${match[1]}/public.json`,
|
fetch: `https://liberapay.com/${match[1]}/public.json`,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['statements', 'content'],
|
path: ['statements', 'content'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/lobste\.rs\/u\/(.*)\/?/
|
const reURI = /^https:\/\/lobste\.rs\/u\/(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'lobsters'
|
name: 'lobsters',
|
||||||
},
|
},
|
||||||
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`,
|
||||||
fetch: null,
|
fetch: null,
|
||||||
useProxy: true,
|
useProxy: true,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['about'],
|
path: ['about'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/(.*)\/@(.*)\/?/
|
const reURI = /^https:\/\/(.*)\/@(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'mastodon'
|
name: 'mastodon',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: null,
|
fetch: null,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'fingerprint',
|
format: 'fingerprint',
|
||||||
path: ['attachment', 'value'],
|
path: ['attachment', 'value'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,56 +16,58 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/(?:www\.)?reddit\.com\/user\/(.*)\/comments\/(.*)\/(.*)\/?/
|
const reURI = /^https:\/\/(?:www\.)?reddit\.com\/user\/(.*)\/comments\/(.*)\/(.*)\/?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'reddit'
|
name: 'reddit',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: `https://www.reddit.com/user/${match[1]}/comments/${match[2]}.json`,
|
fetch: `https://www.reddit.com/user/${match[1]}/comments/${match[2]}.json`,
|
||||||
useProxy: true,
|
useProxy: true,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: ['data', 'children', 'data', 'selftext'],
|
path: ['data', 'children', 'data', 'selftext'],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,48 +16,50 @@ limitations under the License.
|
||||||
const reURI = /^https:\/\/twitter\.com\/(.*)\/status\/([0-9]*)(?:\?.*)?/
|
const reURI = /^https:\/\/twitter\.com\/(.*)\/status\/([0-9]*)(?:\?.*)?/
|
||||||
|
|
||||||
const processURI = (uri, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'web',
|
type: 'web',
|
||||||
name: 'twitter'
|
name: 'twitter',
|
||||||
},
|
},
|
||||||
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,
|
||||||
fetch: `https://mobile.twitter.com/${match[1]}/status/${match[2]}`,
|
fetch: `https://mobile.twitter.com/${match[1]}/status/${match[2]}`,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'text'
|
format: 'text',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: [],
|
path: [],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -16,50 +16,53 @@ limitations under the License.
|
||||||
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, opts) => {
|
const processURI = (uri, opts) => {
|
||||||
if (!opts) { opts = {} }
|
if (!opts) {
|
||||||
|
opts = {}
|
||||||
|
}
|
||||||
const match = uri.match(reURI)
|
const match = uri.match(reURI)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: 'communication',
|
type: 'communication',
|
||||||
name: 'xmpp'
|
name: 'xmpp',
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: `${match[1]}@${match[2]}`,
|
display: `${match[1]}@${match[2]}`,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
qr: uri
|
qr: uri,
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: 'xmppVcardServerDomain' in opts
|
uri:
|
||||||
? `https://${opts.xmppVcardServerDomain}/api/vcard/${match[1]}@${match[2]}/DESC`
|
'xmppVcardServerDomain' in opts
|
||||||
: null,
|
? `https://${opts.xmppVcardServerDomain}/api/vcard/${match[1]}@${match[2]}/DESC`
|
||||||
|
: null,
|
||||||
fetch: null,
|
fetch: null,
|
||||||
useProxy: false,
|
useProxy: false,
|
||||||
format: 'json'
|
format: 'json',
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: null,
|
fingerprint: null,
|
||||||
format: 'message',
|
format: 'message',
|
||||||
path: [],
|
path: [],
|
||||||
relation: 'contains'
|
relation: 'contains',
|
||||||
},
|
},
|
||||||
customRequestHandler: null
|
customRequestHandler: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
14
src/utils.js
14
src/utils.js
|
@ -1,19 +1,23 @@
|
||||||
const generateProxyURL = (type, url, opts) => {
|
const generateProxyURL = (type, url, opts) => {
|
||||||
if (!opts || !opts.doipProxyHostname) { return null }
|
if (!opts || !opts.doipProxyHostname) {
|
||||||
return `https://${opts.doipProxyHostname}/api/1/get/${type}/${encodeURIComponent(url)}`
|
return null
|
||||||
|
}
|
||||||
|
return `https://${
|
||||||
|
opts.doipProxyHostname
|
||||||
|
}/api/1/get/${type}/${encodeURIComponent(url)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateClaim = (fingerprint, format) => {
|
const generateClaim = (fingerprint, format) => {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 'uri':
|
case 'uri':
|
||||||
return `openpgp4fpr:${fingerprint}`
|
return `openpgp4fpr:${fingerprint}`
|
||||||
break;
|
break
|
||||||
case 'message':
|
case 'message':
|
||||||
return `[Verifying my OpenPGP key: openpgp4fpr:${fingerprint}]`
|
return `[Verifying my OpenPGP key: openpgp4fpr:${fingerprint}]`
|
||||||
break;
|
break
|
||||||
case 'fingerprint':
|
case 'fingerprint':
|
||||||
return fingerprint
|
return fingerprint
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
throw new Error('No valid claim format')
|
throw new Error('No valid claim format')
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,14 +37,15 @@ doipjs.serviceproviders.list.forEach((sp, i) => {
|
||||||
doipjs.serviceproviders.data[sp].tests.forEach((test, j) => {
|
doipjs.serviceproviders.data[sp].tests.forEach((test, j) => {
|
||||||
if (test.shouldMatch) {
|
if (test.shouldMatch) {
|
||||||
it(`should match "${test.uri}"`, () => {
|
it(`should match "${test.uri}"`, () => {
|
||||||
expect(doipjs.serviceproviders.data[sp].reURI.test(test.uri)).to.be.true
|
expect(doipjs.serviceproviders.data[sp].reURI.test(test.uri)).to.be
|
||||||
|
.true
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
it(`should not match "${test.uri}"`, () => {
|
it(`should not match "${test.uri}"`, () => {
|
||||||
expect(doipjs.serviceproviders.data[sp].reURI.test(test.uri)).to.be.false
|
expect(doipjs.serviceproviders.data[sp].reURI.test(test.uri)).to.be
|
||||||
|
.false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,12 +24,18 @@ describe('utils.generateClaim', () => {
|
||||||
expect(doipjs.utils.generateClaim).to.have.length(2)
|
expect(doipjs.utils.generateClaim).to.have.length(2)
|
||||||
})
|
})
|
||||||
it('should generate a correct "uri" claim', () => {
|
it('should generate a correct "uri" claim', () => {
|
||||||
expect(doipjs.utils.generateClaim('123456789', 'uri')).to.equal('openpgp4fpr:123456789')
|
expect(doipjs.utils.generateClaim('123456789', 'uri')).to.equal(
|
||||||
|
'openpgp4fpr:123456789'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
it('should generate a correct "message" claim', () => {
|
it('should generate a correct "message" claim', () => {
|
||||||
expect(doipjs.utils.generateClaim('123456789', 'message')).to.equal('[Verifying my OpenPGP key: openpgp4fpr:123456789]')
|
expect(doipjs.utils.generateClaim('123456789', 'message')).to.equal(
|
||||||
|
'[Verifying my OpenPGP key: openpgp4fpr:123456789]'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
it('should generate a correct "fingerprint" claim', () => {
|
it('should generate a correct "fingerprint" claim', () => {
|
||||||
expect(doipjs.utils.generateClaim('123456789', 'fingerprint')).to.equal('123456789')
|
expect(doipjs.utils.generateClaim('123456789', 'fingerprint')).to.equal(
|
||||||
|
'123456789'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -17,7 +17,7 @@ const chai = require('chai')
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
const chaiMatchPattern = require('chai-match-pattern')
|
const chaiMatchPattern = require('chai-match-pattern')
|
||||||
chai.use(chaiMatchPattern)
|
chai.use(chaiMatchPattern)
|
||||||
chai.use(require("chai-as-promised"))
|
chai.use(require('chai-as-promised'))
|
||||||
|
|
||||||
const _ = chaiMatchPattern.getLodashModule()
|
const _ = chaiMatchPattern.getLodashModule()
|
||||||
const doipjs = require('../src')
|
const doipjs = require('../src')
|
||||||
|
@ -25,26 +25,36 @@ const doipjs = require('../src')
|
||||||
const pattern = {
|
const pattern = {
|
||||||
serviceprovider: {
|
serviceprovider: {
|
||||||
type: _.isString,
|
type: _.isString,
|
||||||
name: _.isString
|
name: _.isString,
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
display: _.isString,
|
display: _.isString,
|
||||||
uri: _.isString,
|
uri: _.isString,
|
||||||
qr: (x) => { return _.isString(x) || _.isNull(x) }
|
qr: (x) => {
|
||||||
|
return _.isString(x) || _.isNull(x)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
proof: {
|
proof: {
|
||||||
uri: (x) => { return _.isString(x) || _.isNull(x) },
|
uri: (x) => {
|
||||||
fetch: (x) => { return _.isString(x) || _.isNull(x) },
|
return _.isString(x) || _.isNull(x)
|
||||||
|
},
|
||||||
|
fetch: (x) => {
|
||||||
|
return _.isString(x) || _.isNull(x)
|
||||||
|
},
|
||||||
useProxy: _.isBoolean,
|
useProxy: _.isBoolean,
|
||||||
format: _.isString
|
format: _.isString,
|
||||||
},
|
},
|
||||||
claim: {
|
claim: {
|
||||||
fingerprint: (x) => { return _.isString(x) || _.isNull(x) },
|
fingerprint: (x) => {
|
||||||
|
return _.isString(x) || _.isNull(x)
|
||||||
|
},
|
||||||
format: _.isString,
|
format: _.isString,
|
||||||
path: _.isArray,
|
path: _.isArray,
|
||||||
relation: _.isString
|
relation: _.isString,
|
||||||
|
},
|
||||||
|
customRequestHandler: (x) => {
|
||||||
|
return _.isFunction(x) || _.isNull(x) || _.isUndefined(x)
|
||||||
},
|
},
|
||||||
customRequestHandler: (x) => { return _.isFunction(x) || _.isNull(x) || _.isUndefined(x) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('verify', () => {
|
describe('verify', () => {
|
||||||
|
@ -53,17 +63,25 @@ describe('verify', () => {
|
||||||
expect(doipjs.verify).to.have.length(3)
|
expect(doipjs.verify).to.have.length(3)
|
||||||
})
|
})
|
||||||
it('should throw an error for non-valid URIs', () => {
|
it('should throw an error for non-valid URIs', () => {
|
||||||
return expect(doipjs.verify('noURI')).to.eventually.be.rejectedWith('Not a valid URI')
|
return expect(doipjs.verify('noURI')).to.eventually.be.rejectedWith(
|
||||||
return expect(doipjs.verify('domain.org')).to.eventually.be.rejectedWith('Not a valid URI')
|
'Not a valid URI'
|
||||||
|
)
|
||||||
|
return expect(doipjs.verify('domain.org')).to.eventually.be.rejectedWith(
|
||||||
|
'Not a valid URI'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
doipjs.serviceproviders.list.forEach((spName, i) => {
|
doipjs.serviceproviders.list.forEach((spName, i) => {
|
||||||
const sp = doipjs.serviceproviders.data[spName]
|
const sp = doipjs.serviceproviders.data[spName]
|
||||||
|
|
||||||
if (sp.tests.length == 0) { return }
|
if (sp.tests.length == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
it(`should return a valid object for the "${spName}" service provider`, async () => {
|
it(`should return a valid object for the "${spName}" service provider`, async () => {
|
||||||
const matches = await doipjs.verify(sp.tests[0].uri, null, {returnMatchesOnly: true})
|
const matches = await doipjs.verify(sp.tests[0].uri, null, {
|
||||||
|
returnMatchesOnly: true,
|
||||||
|
})
|
||||||
expect(matches).to.be.a('array')
|
expect(matches).to.be.a('array')
|
||||||
expect(matches).to.be.length.above(0)
|
expect(matches).to.be.length.above(0)
|
||||||
expect(matches[0].serviceprovider.name).to.be.equal(spName)
|
expect(matches[0].serviceprovider.name).to.be.equal(spName)
|
||||||
|
|
Loading…
Reference in a new issue