diff --git a/bundle/doip.js b/bundle/doip.js new file mode 100644 index 0000000..8df33a8 --- /dev/null +++ b/bundle/doip.js @@ -0,0 +1,371 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.doip = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i= 0)) return; + + // if authority is present, the path must be empty or begin with a / + if (authority && authority.length) { + if (!(path.length === 0 || /^\//.test(path))) return; + } else { + // if authority is not present, the path must not start with // + if (/^\/\//.test(path)) return; + } + + // scheme must begin with a letter, then consist of letters, digits, +, ., or - + if (!/^[a-z][a-z0-9\+\-\.]*$/.test(scheme.toLowerCase())) return; + + // re-assemble the URL per section 5.3 in RFC 3986 + out += scheme + ':'; + if (authority && authority.length) { + out += '//' + authority; + } + + out += path; + + if (query && query.length) { + out += '?' + query; + } + + if (fragment && fragment.length) { + out += '#' + fragment; + } + + return out; + } + + function is_http_iri(value, allowHttps) { + if (!is_iri(value)) { + return; + } + + var splitted = []; + var scheme = ''; + var authority = ''; + var path = ''; + var port = ''; + var query = ''; + var fragment = ''; + var out = ''; + + // from RFC 3986 + splitted = splitUri(value); + scheme = splitted[1]; + authority = splitted[2]; + path = splitted[3]; + query = splitted[4]; + fragment = splitted[5]; + + if (!scheme) return; + + if(allowHttps) { + if (scheme.toLowerCase() != 'https') return; + } else { + if (scheme.toLowerCase() != 'http') return; + } + + // fully-qualified URIs must have an authority section that is + // a valid host + if (!authority) { + return; + } + + // enable port component + if (/:(\d+)$/.test(authority)) { + port = authority.match(/:(\d+)$/)[0]; + authority = authority.replace(/:\d+$/, ''); + } + + out += scheme + ':'; + out += '//' + authority; + + if (port) { + out += port; + } + + out += path; + + if(query && query.length){ + out += '?' + query; + } + + if(fragment && fragment.length){ + out += '#' + fragment; + } + + return out; + } + + function is_https_iri(value) { + return is_http_iri(value, true); + } + + function is_web_iri(value) { + return (is_http_iri(value) || is_https_iri(value)); + } + +})(module); + +},{}],2:[function(require,module,exports){ +/* +Copyright (C) 2020 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 validUrl = require('valid-url') +const { serviceprovidersList, serviceproviders } = require('./serviceproviders') + +const matchSp = (uri) => { + let matches = [], sp + + serviceprovidersList.forEach((spName, i) => { + sp = serviceproviders[spName] + if (sp.reURI.test(uri)) { + matches.push(sp.processURI(uri)) + } + }) + + return matches +} + +const verify = (uri, fingerprint, opts) => { + if (!opts) { opts = {} } + + if (!validUrl.isUri(uri)) { + throw new Error('Not a valid URI') + } + + const spMatches = matchSp(uri) + + if ('returnMatchesOnly' in opts && opts.returnMatchesOnly) { + return spMatches + } +} + +exports.verify = verify +exports.serviceproviders = serviceproviders +exports.serviceprovidersList = serviceprovidersList + +},{"./serviceproviders":3,"valid-url":1}],3:[function(require,module,exports){ +exports.serviceprovidersList = [ + 'dns', + 'xmpp', +] + +exports.serviceproviders = { + dns: require('./serviceproviders/dns'), + xmpp: require('./serviceproviders/xmpp') +} + +},{"./serviceproviders/dns":4,"./serviceproviders/xmpp":5}],4:[function(require,module,exports){ +/* +Copyright (C) 2020 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 reURI = /^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/ + +const processURI = (uri, opts) => { + const match = uri.match(reURI) + + return { + type: "domain", + profile: { + display: match[1], + uri: `https://${match[1]}` + }, + proof: { + uri: `https://dns.shivering-isles.com/dns-query?name=${match[1]}&type=TXT`, + fetch: null + }, + qr: null + } +} + +const tests = [ + { + uri: 'dns:domain.org', + shouldMatch: true + }, + { + uri: 'dns:domain.org?type=TXT', + shouldMatch: true + }, + { + uri: 'https://domain.org', + shouldMatch: false + } +] + +exports.reURI = reURI +exports.processURI = processURI +exports.tests = tests + +},{}],5:[function(require,module,exports){ +/* +Copyright (C) 2020 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 reURI = /^xmpp:([a-zA-Z0-9\.\-\_]*)@([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/ + +const processURI = (uri, opts) => { + if (!opts) { opts = {} } + const match = uri.match(reURI) + + return { + type: "xmpp", + profile: { + display: `${match[1]}@${match[2]}`, + uri: uri + }, + proof: { + uri: 'XMPP_VCARD_SERVER_DOMAIN' in opts + ? `https://${opts.XMPP_VCARD_SERVER_DOMAIN}/api/vcard/${output.display}/DESC` + : null, + fetch: null + }, + qr: null + } +} + +const tests = [ + { + uri: 'xmpp:alice@domain.org', + shouldMatch: true + }, + { + uri: 'xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9', + shouldMatch: true + }, + { + uri: 'https://domain.org', + shouldMatch: false + } +] + +exports.reURI = reURI +exports.processURI = processURI +exports.tests = tests + +},{}]},{},[2])(2) +}); diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..39d3b7a --- /dev/null +++ b/demo/index.html @@ -0,0 +1,14 @@ + + + + + doip.js browser demo + + + + + + +