diff --git a/routes/server.js b/routes/server.js deleted file mode 100644 index d5f7dc6..0000000 --- a/routes/server.js +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright (C) 2021 Yarmo Mackenbach - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU Affero General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -details. - -You should have received a copy of the GNU Affero General Public License along -with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - -If your software can interact with users remotely through a computer network, -you should also make sure that it provides a way for users to get its source. -For example, if your program is a web application, its interface could display -a "Source" link that leads users to an archive of the code. There are many -ways you could offer source, and different solutions will be better for different -programs; see section 13 for the specific requirements. - -You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. For -more information on this, and how to apply and follow the GNU AGPL, see . -*/ -const router = require('express').Router(); -const { check, query, validationResult } = require('express-validator'); -const proofVerification = require('../server/proofVerification'); - -router.get('/verify/proxy', [ - query('url').isURL().exists(), - query('fingerprint').isHexadecimal().exists(), - query('checkClaim').escape(), - query('checkClaimFormat').escape(), - query('checkRelation').escape().exists(), - query('checkPath').escape().exists() -], async function(req, res) { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(400).json({ success: false, errors: errors.array() }); - } - - let params = { - url: req.query.url, - fingerprint: req.query.fingerprint, - checkClaim: req.query.checkClaim ? req.query.checkClaim : null, - checkClaimFormat: req.query.checkClaimFormat ? req.query.checkClaimFormat : "uri", - checkRelation: req.query.checkRelation, - checkPath: req.query.checkPath.split(',') - } - - try { - const proofResult = await proofVerification.Proxy(params); - res.status(200).send(proofResult); - } catch (e) { - console.log(e); - res.status(400).send({ success: false, errors: e }); - } -}); - -router.get('/verify/twitter', [ - query('tweetId').isInt().exists(), - query('account').exists(), - query('fingerprint').isHexadecimal().exists() -], async function(req, res) { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(400).json({ success: false, errors: errors.array() }); - } - - let params = { - tweetId: req.query.tweetId, - account: req.query.account, - fingerprint: req.query.fingerprint - } - - try { - const proofResult = await proofVerification.Twitter(params); - res.status(200).send(proofResult); - } catch (e) { - console.log(e); - res.status(400).send({ success: false, errors: e }); - } -}); - -module.exports = router; diff --git a/server/proofVerification.js b/server/proofVerification.js deleted file mode 100644 index 91c2d72..0000000 --- a/server/proofVerification.js +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright (C) 2021 Yarmo Mackenbach - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU Affero General Public License as published by the Free -Software Foundation, either version 3 of the License, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -details. - -You should have received a copy of the GNU Affero General Public License along -with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - -If your software can interact with users remotely through a computer network, -you should also make sure that it provides a way for users to get its source. -For example, if your program is a web application, its interface could display -a "Source" link that leads users to an archive of the code. There are many -ways you could offer source, and different solutions will be better for different -programs; see section 13 for the specific requirements. - -You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. For -more information on this, and how to apply and follow the GNU AGPL, see . -*/ -const bent = require('bent'); -const getJSON = bent('json'); -require('dotenv').config(); - -const Proxy = async (params) => { - let res = { - success: false, - errors: [], - isVerified: false, - params: params - } - - if (!res.params.checkClaim) { - switch (res.params.checkClaimFormat) { - default: - case "uri": - res.params.checkClaim = `openpgp4fpr:${res.params.fingerprint}`; - break; - case "message": - res.params.checkClaim = `[Verifying my OpenPGP key: openpgp4fpr:${res.params.fingerprint}]`; - break; - case "fingerprint": - res.params.checkClaim = res.params.fingerprint; - break; - } - } - - const obj = await getJSON(res.params.url); - res.isVerified = VerifyJsonProof(obj, res.params.checkPath, res.params.checkClaim, res.params.checkRelation); - res.success = true; - - return res; -}; - -const Twitter = async (params) => { - let res = { - success: false, - errors: [], - isVerified: false, - params: params - } - - let twitter_api_auth = process.env.TWITTER_API_AUTH; - if (!twitter_api_auth) { - let proofUrl = `https://mobile.twitter.com/${res.params.account}/status/${res.params.tweetId}`; - let re = new RegExp(`[Verifying my OpenPGP key: openpgp4fpr:${res.params.fingerprint}]`, "gi"); - const get = bent('GET'); - const obj = await get(proofUrl); - res.isVerified = re.test(obj.data); - return res; - } - - let proofUrl = `https://api.twitter.com/labs/2/tweets/${res.params.tweetId}?tweet.fields=author_id,created_at,id,source,text`; - let re = new RegExp(`[Verifying my OpenPGP key: openpgp4fpr:${res.params.fingerprint}]`, "gi"); - - const get = bent('GET', 'json', {'Content-Type': 'application/json', 'Authorization': `Bearer ${twitter_api_auth}`}); - const obj = await get(proofUrl); - res.isVerified = re.test(obj.data.text); - res.success = true; - - return res; -}; - -const VerifyJsonProof = (data, checkPath, checkClaim, checkRelation) => { - let isVerified = false; - let re; - - if (!data) { - return isVerified; - } - - if (checkPath.length == 0) { - switch (checkRelation) { - default: - case 'contains': - re = new RegExp(checkClaim, "gi"); - return re.test(data); - break; - case 'eq': - return data.replace(/\r?\n|\r/, '').toLowerCase() == checkClaim.toLowerCase(); - break; - case 'oneOf': - re = new RegExp(checkClaim, "gi"); - return re.test(data.join("|")); - break; - } - } - - if (Array.isArray(data)) { - data.forEach((item, i) => { - isVerified = isVerified || VerifyJsonProof(item, checkPath, checkClaim, checkRelation); - }); - } else if (Array.isArray(data[checkPath[0]])) { - data[checkPath[0]].forEach((item, i) => { - isVerified = isVerified || VerifyJsonProof(item, checkPath.slice(1), checkClaim, checkRelation); - }); - } else { - isVerified = isVerified || VerifyJsonProof(data[checkPath[0]], checkPath.slice(1), checkClaim, checkRelation); - } - - return isVerified; -} - -exports.Proxy = Proxy; -exports.Twitter = Twitter;