Support HTTP proofs

This commit is contained in:
Yarmo Mackenbach 2022-09-10 12:16:50 +02:00
parent 9f0a61a3f0
commit 4e0a86343a
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1
2 changed files with 65 additions and 28 deletions

View file

@ -234,7 +234,7 @@ class Claim {
if (proofData) { if (proofData) {
// Run the verification process // Run the verification process
verificationResult = verifications.run( verificationResult = await verifications.run(
proofData.result, proofData.result,
claimData, claimData,
this._fingerprint this._fingerprint

View file

@ -13,6 +13,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const axios = require('axios')
const { URL } = require('node:url')
const utils = require('./utils') const utils = require('./utils')
const E = require('./enums') const E = require('./enums')
@ -21,40 +23,80 @@ const E = require('./enums')
* @ignore * @ignore
*/ */
const runJSON = (proofData, checkPath, checkClaim, checkRelation) => { const containsProof = async (data, target) => {
let re let result = false
// Check for plaintext proof
result = data.replace(/\r?\n|\r/g, '')
.toLowerCase()
.indexOf(target.toLowerCase()) !== -1
// Check for HTTP proof if plaintext not found
if (!result) {
const uris = utils.getUriFromString(data)
for (let index = 0; index < uris.length; index++) {
if (result) continue
const candidate = uris[index]
let candidateURL
try {
candidateURL = new URL(candidate)
} catch (_) {
continue
}
if (candidateURL.protocol !== 'https:') {
continue
}
const response = await axios.head(candidate, {
maxRedirects: 1
})
if (response.status !== 200) continue
if (!response.headers['ariadne-identity-proof']) continue
result = response.headers['ariadne-identity-proof']
.toLowerCase()
.indexOf(target.toLowerCase()) !== -1
}
}
return result
}
const runJSON = async (proofData, checkPath, checkClaim, checkRelation) => {
if (!proofData) { if (!proofData) {
return false return false
} }
if (Array.isArray(proofData)) { if (Array.isArray(proofData)) {
let result = false let result = false
proofData.forEach((item, i) => {
for (let index = 0; index < proofData.length; index++) {
const item = proofData[index]
if (result) { if (result) {
return continue
} }
result = runJSON(item, checkPath, checkClaim, checkRelation)
}) result = await runJSON(item, checkPath, checkClaim, checkRelation)
}
return result return result
} }
if (checkPath.length === 0) { if (checkPath.length === 0) {
switch (checkRelation) { switch (checkRelation) {
case E.ClaimRelation.EQUALS:
return (
proofData.replace(/\r?\n|\r|\\/g, '').toLowerCase() ===
checkClaim.toLowerCase()
)
case E.ClaimRelation.ONEOF: case E.ClaimRelation.ONEOF:
re = new RegExp(checkClaim, 'gi') return await containsProof(proofData.join('|'), checkClaim)
return re.test(proofData.join('|'))
case E.ClaimRelation.CONTAINS: case E.ClaimRelation.CONTAINS:
case E.ClaimRelation.EQUALS:
default: default:
re = new RegExp(checkClaim, 'gi') return await containsProof(proofData, checkClaim)
return re.test(proofData.replace(/\r?\n|\r|\\/g, ''))
} }
} }
@ -62,7 +104,7 @@ const runJSON = (proofData, checkPath, checkClaim, checkRelation) => {
throw new Error('err_json_structure_incorrect') throw new Error('err_json_structure_incorrect')
} }
return runJSON( return await runJSON(
proofData[checkPath[0]], proofData[checkPath[0]],
checkPath.slice(1), checkPath.slice(1),
checkClaim, checkClaim,
@ -72,12 +114,13 @@ const runJSON = (proofData, checkPath, checkClaim, checkRelation) => {
/** /**
* Run the verification by finding the formatted fingerprint in the proof * Run the verification by finding the formatted fingerprint in the proof
* @async
* @param {object} proofData - The proof data * @param {object} proofData - The proof data
* @param {object} claimData - The claim data * @param {object} claimData - The claim data
* @param {string} fingerprint - The fingerprint * @param {string} fingerprint - The fingerprint
* @returns {object} * @returns {object}
*/ */
const run = (proofData, claimData, fingerprint) => { const run = async (proofData, claimData, fingerprint) => {
const res = { const res = {
result: false, result: false,
completed: false, completed: false,
@ -87,7 +130,7 @@ const run = (proofData, claimData, fingerprint) => {
switch (claimData.proof.request.format) { switch (claimData.proof.request.format) {
case E.ProofFormat.JSON: case E.ProofFormat.JSON:
try { try {
res.result = runJSON( res.result = await runJSON(
proofData, proofData,
claimData.claim.path, claimData.claim.path,
utils.generateClaim(fingerprint, claimData.claim.format), utils.generateClaim(fingerprint, claimData.claim.format),
@ -100,14 +143,8 @@ const run = (proofData, claimData, fingerprint) => {
break break
case E.ProofFormat.TEXT: case E.ProofFormat.TEXT:
try { try {
const re = new RegExp( res.result = await containsProof(proofData,
utils utils.generateClaim(fingerprint, claimData.claim.format))
.generateClaim(fingerprint, claimData.claim.format)
.replace('[', '\\[')
.replace(']', '\\]'),
'gi'
)
res.result = re.test(proofData.replace(/\r?\n|\r/, ''))
res.completed = true res.completed = true
} catch (error) { } catch (error) {
res.errors.push('err_unknown_text_verification') res.errors.push('err_unknown_text_verification')