decentralized-internet
Version:
An NPM library of programs to create decentralized web and distributed computing projects
1 lines • 12.8 kB
JavaScript
"use strict";const Dns=require("dns"),internals={hasOwn:Object.prototype.hasOwnProperty,indexOf:Array.prototype.indexOf,defaultThreshold:16,maxIPv6Groups:8,categories:{valid:1,dnsWarn:7,rfc5321:15,cfws:31,deprecated:63,rfc5322:127,error:255},diagnoses:{valid:0,dnsWarnNoMXRecord:5,dnsWarnNoRecord:6,rfc5321TLD:9,rfc5321TLDNumeric:10,rfc5321QuotedString:11,rfc5321AddressLiteral:12,cfwsComment:17,cfwsFWS:18,deprecatedLocalPart:33,deprecatedFWS:34,deprecatedQTEXT:35,deprecatedQP:36,deprecatedComment:37,deprecatedCTEXT:38,deprecatedIPv6:39,deprecatedCFWSNearAt:49,rfc5322Domain:65,rfc5322TooLong:66,rfc5322LocalTooLong:67,rfc5322DomainTooLong:68,rfc5322LabelTooLong:69,rfc5322DomainLiteral:70,rfc5322DomainLiteralOBSDText:71,rfc5322IPv6GroupCount:72,rfc5322IPv62x2xColon:73,rfc5322IPv6BadCharacter:74,rfc5322IPv6MaxGroups:75,rfc5322IPv6ColonStart:76,rfc5322IPv6ColonEnd:77,errExpectingDTEXT:129,errNoLocalPart:130,errNoDomain:131,errConsecutiveDots:132,errATEXTAfterCFWS:133,errATEXTAfterQS:134,errATEXTAfterDomainLiteral:135,errExpectingQPair:136,errExpectingATEXT:137,errExpectingQTEXT:138,errExpectingCTEXT:139,errBackslashEnd:140,errDotStart:141,errDotEnd:142,errDomainHyphenStart:143,errDomainHyphenEnd:144,errUnclosedQuotedString:145,errUnclosedComment:146,errUnclosedDomainLiteral:147,errFWSCRLFx2:148,errFWSCRLFEnd:149,errCRNoLF:150,errUnknownTLD:160,errDomainTooShort:161},components:{localpart:0,domain:1,literal:2,contextComment:3,contextFWS:4,contextQuotedString:5,contextQuotedPair:6}};internals.defer="undefined"!=typeof process&&process&&"function"==typeof process.nextTick?process.nextTick.bind(process):function(e){return setTimeout(e,0)},internals.specials=function(){const e=new Array(256);for(let n=255;n>=0;--n)e[n]=!1;for(let n=0;n<'()<>[]:;@\\,."'.length;++n)e['()<>[]:;@\\,."'.charCodeAt(n)]=!0;return function(n){return e[n]}}(),internals.regex={ipV4:/\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipV6:/^[a-fA-F\d]{0,4}$/},internals.checkIpV6=function(e){return e.every(e=>internals.regex.ipV6.test(e))},internals.validDomain=function(e,n){return n.tldBlacklist?Array.isArray(n.tldBlacklist)?-1===internals.indexOf.call(n.tldBlacklist,e):!internals.hasOwn.call(n.tldBlacklist,e):Array.isArray(n.tldWhitelist)?-1!==internals.indexOf.call(n.tldWhitelist,e):internals.hasOwn.call(n.tldWhitelist,e)},exports.validate=internals.validate=function(e,n,t){if("function"==typeof(n=n||{})&&(t=n,n={}),"function"!=typeof t){if(n.checkDNS)throw new TypeError("expected callback function for checkDNS option");t=null}let r,s;if("number"==typeof n.errorLevel?(r=!0,s=n.errorLevel):(r=!!n.errorLevel,s=internals.diagnoses.valid),n.tldWhitelist)if("string"==typeof n.tldWhitelist)n.tldWhitelist=[n.tldWhitelist];else if("object"!=typeof n.tldWhitelist)throw new TypeError("expected array or object tldWhitelist");if(n.tldBlacklist)if("string"==typeof n.tldBlacklist)n.tldBlacklist=[n.tldBlacklist];else if("object"!=typeof n.tldBlacklist)throw new TypeError("expected array or object tldBlacklist");if(n.minDomainAtoms&&(n.minDomainAtoms!==(0|+n.minDomainAtoms)||n.minDomainAtoms<0))throw new TypeError("expected positive integer minDomainAtoms");let a=internals.diagnoses.valid;const o=e=>{e>a&&(a=e)},i={now:internals.components.localpart,prev:internals.components.localpart,stack:[internals.components.localpart]};let l="";const c={local:"",domain:""},d={locals:[""],domains:[""]};let p,m=0,g=0,f=0,w=!1,h=!1;const k=e.length;let u;for(let n=0;n<k;++n){switch(u=e[n],i.now){case internals.components.localpart:switch(u){case"(":0===g?o(0===m?internals.diagnoses.cfwsComment:internals.diagnoses.deprecatedComment):(o(internals.diagnoses.cfwsComment),h=!0),i.stack.push(i.now),i.now=internals.components.contextComment;break;case".":0===g?o(0===m?internals.diagnoses.errDotStart:internals.diagnoses.errConsecutiveDots):(h&&o(internals.diagnoses.deprecatedLocalPart),h=!1,g=0,++m,c.local+=u,d.locals[m]="");break;case'"':0===g?(o(0===m?internals.diagnoses.rfc5321QuotedString:internals.diagnoses.deprecatedLocalPart),c.local+=u,d.locals[m]+=u,++g,h=!0,i.stack.push(i.now),i.now=internals.components.contextQuotedString):o(internals.diagnoses.errExpectingATEXT);break;case"\r":if(k===++n||"\n"!==e[n]){o(internals.diagnoses.errCRNoLF);break}case" ":case"\t":0===g?o(0===m?internals.diagnoses.cfwsFWS:internals.diagnoses.deprecatedFWS):h=!0,i.stack.push(i.now),i.now=internals.components.contextFWS,l=u;break;case"@":if(1!==i.stack.length)throw new Error("unexpected item on context stack");0===c.local.length?o(internals.diagnoses.errNoLocalPart):0===g?o(internals.diagnoses.errDotEnd):c.local.length>64?o(internals.diagnoses.rfc5322LocalTooLong):i.prev!==internals.components.contextComment&&i.prev!==internals.components.contextFWS||o(internals.diagnoses.deprecatedCFWSNearAt),i.now=internals.components.domain,i.stack[0]=internals.components.domain,m=0,g=0,h=!1;break;default:if(h)switch(i.prev){case internals.components.contextComment:case internals.components.contextFWS:o(internals.diagnoses.errATEXTAfterCFWS);break;case internals.components.contextQuotedString:o(internals.diagnoses.errATEXTAfterQS);break;default:throw new Error("more atext found where none is allowed, but unrecognized prev context: "+i.prev)}else i.prev=i.now,((p=u.charCodeAt(0))<33||p>126||internals.specials(p))&&o(internals.diagnoses.errExpectingATEXT),c.local+=u,d.locals[m]+=u,++g}break;case internals.components.domain:switch(u){case"(":0===g?o(0===m?internals.diagnoses.deprecatedCFWSNearAt:internals.diagnoses.deprecatedComment):(h=!0,o(internals.diagnoses.cfwsComment)),i.stack.push(i.now),i.now=internals.components.contextComment;break;case".":0===g?o(0===m?internals.diagnoses.errDotStart:internals.diagnoses.errConsecutiveDots):w?o(internals.diagnoses.errDomainHyphenEnd):g>63&&o(internals.diagnoses.rfc5322LabelTooLong),h=!1,g=0,++m,d.domains[m]="",c.domain+=u;break;case"[":0===c.domain.length?(h=!0,++g,i.stack.push(i.now),i.now=internals.components.literal,c.domain+=u,d.domains[m]+=u,c.literal=""):o(internals.diagnoses.errExpectingATEXT);break;case"\r":if(k===++n||"\n"!==e[n]){o(internals.diagnoses.errCRNoLF);break}case" ":case"\t":0===g?o(0===m?internals.diagnoses.deprecatedCFWSNearAt:internals.diagnoses.deprecatedFWS):(o(internals.diagnoses.cfwsFWS),h=!0),i.stack.push(i.now),i.now=internals.components.contextFWS,l=u;break;default:if(h)switch(i.prev){case internals.components.contextComment:case internals.components.contextFWS:o(internals.diagnoses.errATEXTAfterCFWS);break;case internals.components.literal:o(internals.diagnoses.errATEXTAfterDomainLiteral);break;default:throw new Error("more atext found where none is allowed, but unrecognized prev context: "+i.prev)}w=!1,(p=u.charCodeAt(0))<33||p>126||internals.specials(p)?o(internals.diagnoses.errExpectingATEXT):"-"===u?(0===g&&o(internals.diagnoses.errDomainHyphenStart),w=!0):(p<48||p>122||p>57&&p<65||p>90&&p<97)&&o(internals.diagnoses.rfc5322Domain),c.domain+=u,d.domains[m]+=u,++g}break;case internals.components.literal:switch(u){case"]":if(a<internals.categories.deprecated){let e=-1,n=c.literal;const t=internals.regex.ipV4.exec(n);if(t&&0!==(e=t.index)&&(n=n.slice(0,e)+"0:0"),0===e)o(internals.diagnoses.rfc5321AddressLiteral);else if("ipv6:"!==n.slice(0,5).toLowerCase())o(internals.diagnoses.rfc5322DomainLiteral);else{const t=n.slice(5);let r=internals.maxIPv6Groups;const s=t.split(":");~(e=t.indexOf("::"))?e!==t.lastIndexOf("::")?o(internals.diagnoses.rfc5322IPv62x2xColon):(0!==e&&e!==t.length-2||++r,s.length>r?o(internals.diagnoses.rfc5322IPv6MaxGroups):s.length===r&&o(internals.diagnoses.deprecatedIPv6)):s.length!==r&&o(internals.diagnoses.rfc5322IPv6GroupCount),":"===t[0]&&":"!==t[1]?o(internals.diagnoses.rfc5322IPv6ColonStart):":"===t[t.length-1]&&":"!==t[t.length-2]?o(internals.diagnoses.rfc5322IPv6ColonEnd):internals.checkIpV6(s)?o(internals.diagnoses.rfc5321AddressLiteral):o(internals.diagnoses.rfc5322IPv6BadCharacter)}}else o(internals.diagnoses.rfc5322DomainLiteral);c.domain+=u,d.domains[m]+=u,++g,i.prev=i.now,i.now=i.stack.pop();break;case"\\":o(internals.diagnoses.rfc5322DomainLiteralOBSDText),i.stack.push(i.now),i.now=internals.components.contextQuotedPair;break;case"\r":if(k===++n||"\n"!==e[n]){o(internals.diagnoses.errCRNoLF);break}case" ":case"\t":o(internals.diagnoses.cfwsFWS),i.stack.push(i.now),i.now=internals.components.contextFWS,l=u;break;default:if((p=u.charCodeAt(0))>127||0===p||"["===u){o(internals.diagnoses.errExpectingDTEXT);break}(p<33||127===p)&&o(internals.diagnoses.rfc5322DomainLiteralOBSDText),c.literal+=u,c.domain+=u,d.domains[m]+=u,++g}break;case internals.components.contextQuotedString:switch(u){case"\\":i.stack.push(i.now),i.now=internals.components.contextQuotedPair;break;case"\r":if(k===++n||"\n"!==e[n]){o(internals.diagnoses.errCRNoLF);break}case"\t":c.local+=" ",d.locals[m]+=" ",++g,o(internals.diagnoses.cfwsFWS),i.stack.push(i.now),i.now=internals.components.contextFWS,l=u;break;case'"':c.local+=u,d.locals[m]+=u,++g,i.prev=i.now,i.now=i.stack.pop();break;default:(p=u.charCodeAt(0))>127||0===p||10===p?o(internals.diagnoses.errExpectingQTEXT):(p<32||127===p)&&o(internals.diagnoses.deprecatedQTEXT),c.local+=u,d.locals[m]+=u,++g}break;case internals.components.contextQuotedPair:switch((p=u.charCodeAt(0))>127?o(internals.diagnoses.errExpectingQPair):(p<31&&9!==p||127===p)&&o(internals.diagnoses.deprecatedQP),i.prev=i.now,i.now=i.stack.pop(),u="\\"+u,i.now){case internals.components.contextComment:break;case internals.components.contextQuotedString:c.local+=u,d.locals[m]+=u,g+=2;break;case internals.components.literal:c.domain+=u,d.domains[m]+=u,g+=2;break;default:throw new Error("quoted pair logic invoked in an invalid context: "+i.now)}break;case internals.components.contextComment:switch(u){case"(":i.stack.push(i.now),i.now=internals.components.contextComment;break;case")":i.prev=i.now,i.now=i.stack.pop();break;case"\\":i.stack.push(i.now),i.now=internals.components.contextQuotedPair;break;case"\r":if(k===++n||"\n"!==e[n]){o(internals.diagnoses.errCRNoLF);break}case" ":case"\t":o(internals.diagnoses.cfwsFWS),i.stack.push(i.now),i.now=internals.components.contextFWS,l=u;break;default:if((p=u.charCodeAt(0))>127||0===p||10===p){o(internals.diagnoses.errExpectingCTEXT);break}(p<32||127===p)&&o(internals.diagnoses.deprecatedCTEXT)}break;case internals.components.contextFWS:if("\r"===l){if("\r"===u){o(internals.diagnoses.errFWSCRLFx2);break}++f>1?o(internals.diagnoses.deprecatedFWS):f=1}switch(u){case"\r":k!==++n&&"\n"===e[n]||o(internals.diagnoses.errCRNoLF);break;case" ":case"\t":break;default:"\r"===l&&o(internals.diagnoses.errFWSCRLFEnd),f=0,i.prev=i.now,i.now=i.stack.pop(),--n}l=u;break;default:throw new Error("unknown context: "+i.now)}if(a>internals.categories.rfc5322)break}if(a<internals.categories.rfc5322)if(i.now===internals.components.contextQuotedString)o(internals.diagnoses.errUnclosedQuotedString);else if(i.now===internals.components.contextQuotedPair)o(internals.diagnoses.errBackslashEnd);else if(i.now===internals.components.contextComment)o(internals.diagnoses.errUnclosedComment);else if(i.now===internals.components.literal)o(internals.diagnoses.errUnclosedDomainLiteral);else if("\r"===u)o(internals.diagnoses.errFWSCRLFEnd);else if(0===c.domain.length)o(internals.diagnoses.errNoDomain);else if(0===g)o(internals.diagnoses.errDotEnd);else if(w)o(internals.diagnoses.errDomainHyphenEnd);else if(c.domain.length>255)o(internals.diagnoses.rfc5322DomainTooLong);else if(c.local.length+c.domain.length+1>254)o(internals.diagnoses.rfc5322TooLong);else if(g>63)o(internals.diagnoses.rfc5322LabelTooLong);else if(n.minDomainAtoms&&d.domains.length<n.minDomainAtoms)o(internals.diagnoses.errDomainTooShort);else if(n.tldWhitelist||n.tldBlacklist){const e=d.domains[m];internals.validDomain(e,n)||o(internals.diagnoses.errUnknownTLD)}let x=!1,T=!1;const C=()=>{if(!x&&a<internals.categories.dnsWarn){d.domains[m].charCodeAt(0)<=57?o(internals.diagnoses.rfc5321TLDNumeric):0===m&&o(internals.diagnoses.rfc5321TLD)}a<s&&(a=internals.diagnoses.valid);const e=r?a:a<internals.defaultThreshold;return t&&(T?t(e):internals.defer(t.bind(null,e))),e};if(!(n.checkDNS&&a<internals.categories.dnsWarn)){const e=C();return T=!0,e}{0===m&&(c.domain+=".");const e=c.domain;Dns.resolveMx(e,(n,t)=>{if(n&&n.code!==Dns.NODATA)return o(internals.diagnoses.dnsWarnNoRecord),C();if(t&&t.length)return x=!0,C();let r=3,s=!1;o(internals.diagnoses.dnsWarnNoMXRecord);const a=(e,n)=>{if(!s){if(--r,n&&n.length)return s=!0,C();0===r&&(o(internals.diagnoses.dnsWarnNoRecord),s=!0,C())}};Dns.resolveCname(e,a),Dns.resolve4(e,a),Dns.resolve6(e,a)}),T=!0}},exports.diagnoses=internals.validate.diagnoses=function(){const e={},n=Object.keys(internals.diagnoses);for(let t=0;t<n.length;++t){const r=n[t];e[r]=internals.diagnoses[r]}return e}();