diff --git a/src/claim.js b/src/claim.js index 5b2c1ef..f8298e2 100644 --- a/src/claim.js +++ b/src/claim.js @@ -234,7 +234,7 @@ class Claim { if (proofData) { // Run the verification process - verificationResult = verifications.run( + verificationResult = await verifications.run( proofData.result, claimData, this._fingerprint diff --git a/src/verifications.js b/src/verifications.js index c0e3789..3f9835b 100644 --- a/src/verifications.js +++ b/src/verifications.js @@ -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 limitations under the License. */ +const axios = require('axios') +const { URL } = require('node:url') const utils = require('./utils') const E = require('./enums') @@ -21,40 +23,80 @@ const E = require('./enums') * @ignore */ -const runJSON = (proofData, checkPath, checkClaim, checkRelation) => { - let re +const containsProof = async (data, target) => { + 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) { return false } if (Array.isArray(proofData)) { let result = false - proofData.forEach((item, i) => { + + for (let index = 0; index < proofData.length; index++) { + const item = proofData[index] + if (result) { - return + continue } - result = runJSON(item, checkPath, checkClaim, checkRelation) - }) + + result = await runJSON(item, checkPath, checkClaim, checkRelation) + } + return result } if (checkPath.length === 0) { switch (checkRelation) { - case E.ClaimRelation.EQUALS: - return ( - proofData.replace(/\r?\n|\r|\\/g, '').toLowerCase() === - checkClaim.toLowerCase() - ) - case E.ClaimRelation.ONEOF: - re = new RegExp(checkClaim, 'gi') - return re.test(proofData.join('|')) + return await containsProof(proofData.join('|'), checkClaim) case E.ClaimRelation.CONTAINS: + case E.ClaimRelation.EQUALS: default: - re = new RegExp(checkClaim, 'gi') - return re.test(proofData.replace(/\r?\n|\r|\\/g, '')) + return await containsProof(proofData, checkClaim) } } @@ -62,7 +104,7 @@ const runJSON = (proofData, checkPath, checkClaim, checkRelation) => { throw new Error('err_json_structure_incorrect') } - return runJSON( + return await runJSON( proofData[checkPath[0]], checkPath.slice(1), checkClaim, @@ -72,12 +114,13 @@ const runJSON = (proofData, checkPath, checkClaim, checkRelation) => { /** * Run the verification by finding the formatted fingerprint in the proof + * @async * @param {object} proofData - The proof data * @param {object} claimData - The claim data * @param {string} fingerprint - The fingerprint * @returns {object} */ -const run = (proofData, claimData, fingerprint) => { +const run = async (proofData, claimData, fingerprint) => { const res = { result: false, completed: false, @@ -87,7 +130,7 @@ const run = (proofData, claimData, fingerprint) => { switch (claimData.proof.request.format) { case E.ProofFormat.JSON: try { - res.result = runJSON( + res.result = await runJSON( proofData, claimData.claim.path, utils.generateClaim(fingerprint, claimData.claim.format), @@ -100,14 +143,8 @@ const run = (proofData, claimData, fingerprint) => { break case E.ProofFormat.TEXT: try { - const re = new RegExp( - utils - .generateClaim(fingerprint, claimData.claim.format) - .replace('[', '\\[') - .replace(']', '\\]'), - 'gi' - ) - res.result = re.test(proofData.replace(/\r?\n|\r/, '')) + res.result = await containsProof(proofData, + utils.generateClaim(fingerprint, claimData.claim.format)) res.completed = true } catch (error) { res.errors.push('err_unknown_text_verification')