UNPKG

@stacksjs/tlsx

Version:

A TLS/HTTPS library with automation.

14 lines (12 loc) 17.9 kB
import{E as T,b as h,g as B,m as N,r as v,s as H,v as r,w as U,x as L,y as G}from"../chunk-9qdv9bja.js";import"../chunk-0t23af9p.js";import y from"node:os";import b from"node:process";import{EventEmitter as I}from"events";function k(s){return s==null?[]:Array.isArray(s)?s:[s]}function F(s,t,e,n){var i,a=s[t],c=~n.string.indexOf(t)?e==null||e===!0?"":String(e):typeof e==="boolean"?e:~n.boolean.indexOf(t)?e==="false"?!1:e==="true"||(s._.push((i=+e,i*0===0)?i:e),!!e):(i=+e,i*0===0)?i:e;s[t]=a==null?c:Array.isArray(a)?a.concat(c):[a,c]}function W(s,t){s=s||[],t=t||{};var e,n,i,a,c,u={_:[]},o=0,l=0,f=0,m=s.length;let d=t.alias!==void 0,w=t.unknown!==void 0,C=t.default!==void 0;if(t.alias=t.alias||{},t.string=k(t.string),t.boolean=k(t.boolean),d)for(e in t.alias){n=t.alias[e]=k(t.alias[e]);for(o=0;o<n.length;o++)(t.alias[n[o]]=n.concat(e)).splice(o,1)}for(o=t.boolean.length;o-- >0;){n=t.alias[t.boolean[o]]||[];for(l=n.length;l-- >0;)t.boolean.push(n[l])}for(o=t.string.length;o-- >0;){n=t.alias[t.string[o]]||[];for(l=n.length;l-- >0;)t.string.push(n[l])}if(C){for(e in t.default)if(a=typeof t.default[e],n=t.alias[e]=t.alias[e]||[],t[a]!==void 0){t[a].push(e);for(o=0;o<n.length;o++)t[a].push(n[o])}}let j=w?Object.keys(t.alias):[];for(o=0;o<m;o++){if(i=s[o],i==="--"){u._=u._.concat(s.slice(++o));break}for(l=0;l<i.length;l++)if(i.charCodeAt(l)!==45)break;if(l===0)u._.push(i);else if(i.substring(l,l+3)==="no-"){if(a=i.substring(l+3),w&&!~j.indexOf(a))return t.unknown(i);u[a]=!1}else{for(f=l+1;f<i.length;f++)if(i.charCodeAt(f)===61)break;a=i.substring(l,f),c=i.substring(++f)||(o+1===m||(""+s[o+1]).charCodeAt(0)===45||s[++o]),n=l===2?[a]:a;for(f=0;f<n.length;f++){if(a=n[f],w&&!~j.indexOf(a))return t.unknown("-".repeat(l)+a);F(u,a,f+1<n.length||c,t)}}}if(C){for(e in t.default)if(u[e]===void 0)u[e]=t.default[e]}if(d)for(e in u){n=t.alias[e]||[];while(n.length>0)u[n.shift()]=u[e]}return u}var D=(s)=>s.replace(/[<[].+/,"").trim(),K=(s)=>{let t=/<([^>]+)>/g,e=/\[([^\]]+)\]/g,n=[],i=(u)=>{let o=!1,l=u[1];if(l.startsWith("..."))l=l.slice(3),o=!0;return{required:u[0].startsWith("<"),value:l,variadic:o}},a;while(a=t.exec(s))n.push(i(a));let c;while(c=e.exec(s))n.push(i(c));return n},R=(s)=>{let t={alias:{},boolean:[]};for(let[e,n]of s.entries()){if(n.names.length>1)t.alias[n.names[0]]=n.names.slice(1);if(n.isBoolean)if(n.negated){if(!s.some((a,c)=>{return c!==e&&a.names.some((u)=>n.names.includes(u))&&typeof a.required==="boolean"}))t.boolean.push(n.names[0])}else t.boolean.push(n.names[0])}return t},E=(s)=>{return s.sort((t,e)=>{return t.length>e.length?-1:1})[0]},_=(s,t)=>{return s.length>=t?s:`${s}${" ".repeat(t-s.length)}`},S=(s)=>{return s.replace(/([a-z])-([a-z])/g,(t,e,n)=>{return e+n.toUpperCase()})},z=(s,t,e)=>{let n=0,i=t.length,a=s,c;for(;n<i;++n)c=a[t[n]],a=a[t[n]]=n===i-1?e:c!=null?c:!!~t[n+1].indexOf(".")||!(+t[n+1]>-1)?{}:[]},Q=(s,t)=>{for(let e of Object.keys(t)){let n=t[e];if(n.shouldTransform){if(s[e]=Array.prototype.concat.call([],s[e]),typeof n.transformFunction==="function")s[e]=s[e].map(n.transformFunction)}}},J=(s)=>{let t=/([^\\\/]+)$/.exec(s);return t?t[1]:""},V=(s)=>{return s.split(".").map((t,e)=>{return e===0?S(t):t}).join(".")};class x extends Error{constructor(s){super(s);if(this.name=this.constructor.name,typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error(s).stack}}class M{constructor(s,t,e){if(this.rawName=s,this.description=t,this.config=Object.assign({},e),s=s.replace(/\.\*/g,""),this.negated=!1,this.names=D(s).split(",").map((n)=>{let i=n.trim().replace(/^-{1,2}/,"");if(i.startsWith("no-"))this.negated=!0,i=i.replace(/^no-/,"");return V(i)}).sort((n,i)=>n.length>i.length?1:-1),this.name=this.names[this.names.length-1],this.negated&&this.config.default==null)this.config.default=!0;if(s.includes("<"))this.required=!0;else if(s.includes("["))this.required=!1;else this.isBoolean=!0}}var X=process.argv,Y=`${process.platform}-${process.arch} node-${process.version}`;class ${constructor(s,t,e={},n){this.rawName=s,this.description=t,this.config=e,this.cli=n,this.options=[],this.aliasNames=[],this.name=D(s),this.args=K(s),this.examples=[]}usage(s){return this.usageText=s,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(s,t="-v, --version"){return this.versionNumber=s,this.option(t,"Display version number"),this}example(s){return this.examples.push(s),this}option(s,t,e){let n=new M(s,t,e);return this.options.push(n),this}alias(s){return this.aliasNames.push(s),this}action(s){return this.commandAction=s,this}isMatched(s){return this.name===s||this.aliasNames.includes(s)}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof O}hasOption(s){return s=s.split(".")[0],this.options.find((t)=>{return t.names.includes(s)})}outputHelp(){let{name:s,commands:t}=this.cli,{versionNumber:e,options:n,helpCallback:i}=this.cli.globalCommand,a=[{body:`${s}${e?`/${e}`:""}`}];if(a.push({title:"Usage",body:` $ ${s} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let o=E(t.map((l)=>l.rawName));a.push({title:"Commands",body:t.map((l)=>{return` ${_(l.rawName,o.length)} ${l.description}`}).join(` `)}),a.push({title:"For more info, run any command with the `--help` flag",body:t.map((l)=>` $ ${s}${l.name===""?"":` ${l.name}`} --help`).join(` `)})}let u=this.isGlobalCommand?n:[...this.options,...n||[]];if(!this.isGlobalCommand&&!this.isDefaultCommand)u=u.filter((o)=>o.name!=="version");if(u.length>0){let o=E(u.map((l)=>l.rawName));a.push({title:"Options",body:u.map((l)=>{return` ${_(l.rawName,o.length)} ${l.description} ${l.config.default===void 0?"":`(default: ${l.config.default})`}`}).join(` `)})}if(this.examples.length>0)a.push({title:"Examples",body:this.examples.map((o)=>{if(typeof o==="function")return o(s);return o}).join(` `)});if(i)a=i(a)||a;console.log(a.map((o)=>{return o.title?`${o.title}: ${o.body}`:o.body}).join(` `))}outputVersion(){let{name:s}=this.cli,{versionNumber:t}=this.cli.globalCommand;if(t)console.log(`${s}/${t} ${Y}`)}checkRequiredArgs(){let s=this.args.filter((t)=>t.required).length;if(this.cli.args.length<s)throw new x(`missing required args for command \`${this.rawName}\``)}checkUnknownOptions(){let{options:s,globalCommand:t}=this.cli;if(!this.config.allowUnknownOptions){for(let e of Object.keys(s))if(e!=="--"&&!this.hasOption(e)&&!t.hasOption(e))throw new x(`Unknown option \`${e.length>1?`--${e}`:`-${e}`}\``)}}checkOptionValue(){let{options:s,globalCommand:t}=this.cli,e=[...t.options,...this.options];for(let n of e){let i=s[n.name.split(".")[0]];if(n.required){let a=e.some((c)=>c.negated&&c.names.includes(n.name));if(i===!0||i===!1&&!a)throw new x(`option \`${n.rawName}\` value is missing`)}}}}class O extends ${constructor(s){super("@@global@@","",{},s)}}var g=Object.assign;class A extends I{constructor(s=""){super();this.name=s,this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.globalCommand=new O(this),this.globalCommand.usage("<command> [options]")}usage(s){return this.globalCommand.usage(s),this}command(s,t,e){let n=new $(s,t||"",e,this);return n.globalCommand=this.globalCommand,this.commands.push(n),n}option(s,t,e){return this.globalCommand.option(s,t,e),this}help(s){return this.globalCommand.option("-h, --help","Display this message"),this.globalCommand.helpCallback=s,this.showHelpOnExit=!0,this}version(s,t="-v, --version"){return this.globalCommand.version(s,t),this.showVersionOnExit=!0,this}example(s){return this.globalCommand.example(s),this}outputHelp(){if(this.matchedCommand)this.matchedCommand.outputHelp();else this.globalCommand.outputHelp()}outputVersion(){this.globalCommand.outputVersion()}setParsedInfo({args:s,options:t},e,n){if(this.args=s,this.options=t,e)this.matchedCommand=e;if(n)this.matchedCommandName=n;return this}unsetMatchedCommand(){this.matchedCommand=void 0,this.matchedCommandName=void 0}parse(s=X,{run:t=!0}={}){if(this.rawArgs=s,!this.name)this.name=s[1]?J(s[1]):"cli";let e=!0;for(let i of this.commands){let a=this.mri(s.slice(2),i),c=a.args[0];if(i.isMatched(c)){e=!1;let u=g(g({},a),{args:a.args.slice(1)});this.setParsedInfo(u,i,c),this.emit(`command:${c}`,i)}}if(e){for(let i of this.commands)if(i.name===""){e=!1;let a=this.mri(s.slice(2),i);this.setParsedInfo(a,i),this.emit("command:!",i)}}if(e){let i=this.mri(s.slice(2));this.setParsedInfo(i)}if(this.options.help&&this.showHelpOnExit)this.outputHelp(),t=!1,this.unsetMatchedCommand();if(this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null)this.outputVersion(),t=!1,this.unsetMatchedCommand();let n={args:this.args,options:this.options};if(t)this.runMatchedCommand();if(!this.matchedCommand&&this.args[0])this.emit("command:*");return n}mri(s,t){let e=[...this.globalCommand.options,...t?t.options:[]],n=R(e),i=[],a=s.indexOf("--");if(a>-1)i=s.slice(a+1),s=s.slice(0,a);let c=W(s,n);c=Object.keys(c).reduce((m,d)=>{return g(g({},m),{[V(d)]:c[d]})},{_:[]});let u=c._,o={"--":i},l=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,f=Object.create(null);for(let m of e){if(!l&&m.config.default!==void 0)for(let d of m.names)o[d]=m.config.default;if(Array.isArray(m.config.type)){if(f[m.name]===void 0)f[m.name]=Object.create(null),f[m.name].shouldTransform=!0,f[m.name].transformFunction=m.config.type[0]}}for(let m of Object.keys(c))if(m!=="_"){let d=m.split(".");z(o,d,c[m]),Q(o,f)}return{args:u,options:o}}runMatchedCommand(){let{args:s,options:t,matchedCommand:e}=this;if(!e||!e.commandAction)return;e.checkUnknownOptions(),e.checkOptionValue(),e.checkRequiredArgs();let n=[];return e.args.forEach((i,a)=>{if(i.variadic)n.push(s.slice(a));else n.push(s[a])}),n.push(t),e.commandAction.apply(this,n)}}var q="0.13.0";var p=new A("tlsx");p.command("secure [domain]","Auto generate a self-signed SSL certificate for one or multiple domains").option("-k, --key-path <key>","Output key file name",{default:h.keyPath}).option("-c, --cert-path <cert>","Output certificate file name",{default:h.certPath}).option("-ca, --ca-path <ca>","Output CA file name",{default:h.caCertPath}).option("-d, --domains <domains>","Additional domains (comma-separated)").option("--alt-name-ips <ips>","Alternative Name IPs (comma-separated)",{default:h.altNameIPs.join(",")}).option("--alt-name-uris <uris>","Alternative Name URIs (comma-separated)",{default:h.altNameURIs.join(",")}).option("--common-name <name>","Common Name for the certificate",{default:h.commonName}).option("--country-name <name>","Country Name for the certificate",{default:h.countryName}).option("--state-name <name>","State Name for the certificate",{default:h.stateName}).option("--locality-name <name>","Locality Name for the certificate",{default:h.localityName}).option("--organization-name <name>","Organization Name for the certificate",{default:h.organizationName}).option("--validity-days <days>","Validity Days for the certificate",{default:h.validityDays}).option("--verbose","Enable verbose logging",{default:h.verbose}).usage("tlsx secure [domain] [options]").example("tlsx secure example.com --output /etc/ssl").example('tlsx secure example.com -d "api.example.com,*.example.com"').example('tlsx secure -d "example.com,api.example.com"').example('tlsx secure stacks.localhost -d "stacks2.local,stacks3.localhost,stacks4.test"').action(async(s,t)=>{let e=t||{},n=[];if(s)n.push(s);if(e.domains)n.push(...e.domains.split(",").map((o)=>o.trim()));if(n.length===0&&h?.domain)n.push(h.domain);if(n.length===0)throw Error("No domains specified. Use either positional argument or --domains option");let i=e.altNameIPs?e.altNameIPs.split(",").map((o)=>o.trim()):h.altNameIPs,a=e.altNameURIs?e.altNameURIs.split(",").map((o)=>o.trim()):h.altNameURIs;r.info(`Generating a self-signed SSL certificate for: ${n.join(", ")}`),r.debug("Options:",{...e,domains:n});let c=await v(),u=await H({domain:n[0],domains:n,commonName:e.commonName??h.commonName??n[0],altNameIPs:i,altNameURIs:a,countryName:e.countryName||h.countryName,stateName:e.stateName||h.stateName,localityName:e.localityName||h.localityName,organizationName:e.organizationName||h.organizationName,validityDays:Number(e.validityDays)||h.validityDays,rootCA:{certificate:c.certificate,privateKey:c.privateKey}});await U(u,c.certificate),r.success("Certificate generated successfully")});p.command("revoke [domain]","Revoke a certificate for a domain").option("-ca, --ca-path <ca>","CA file path",{default:h.caCertPath}).option("-c, --cert-path <cert>","Certificate file path",{default:h.certPath}).option("-k, --key-path <key>","Key file path",{default:h.keyPath}).option("--cert-name <name>","Specific certificate name to revoke").option("--verbose","Enable verbose logging",{default:h.verbose}).usage("tlsx revoke [domain] [options]").example("tlsx revoke example.com").example("tlsx revoke example.com --ca-path /path/to/ca.crt").example('tlsx revoke example.com --cert-name "My Custom Cert Name"').action(async(s,t)=>{let e=t||{};if(!s&&!h.domain)throw Error("No domain specified. Please provide a domain to revoke.");let n=s||h.domain,i=t?.["cert-name"];r.info(`Revoking certificate for domain: ${n}${i?` with name: ${i}`:""}`),r.debug("Options:",{...e,domain:n,certName:i});try{await L(n,{caCertPath:e.caCertPath||h.caCertPath,certPath:e.certPath||h.certPath,keyPath:e.keyPath||h.keyPath,verbose:e.verbose},i),r.success(`Certificate for ${n}${i?` with name: ${i}`:""} has been revoked`)}catch(a){r.error(`Failed to revoke certificate for ${n}: ${a}`),b.exit(1)}});p.command("list","List all certificates").option("-d, --dir <directory>","Directory to search for certificates").option("--verbose","Enable verbose logging",{default:h.verbose}).usage("tlsx list [options]").example("tlsx list").example("tlsx list -d /etc/ssl/certs").action(async(s)=>{let t=s?.dir;r.info(`Listing certificates${t?` in ${t}`:""}`);try{let e=B(t);if(e.length===0){r.info("No certificates found");return}r.info(`Found ${e.length} certificates:`),e.forEach((n,i)=>{r.info(`${i+1}. ${n}`)})}catch(e){r.error(`Failed to list certificates: ${e}`),b.exit(1)}});p.command("verify [cert-path]","Verify a certificate").option("-ca, --ca-path <ca>","CA certificate path to verify against",{default:h.caCertPath}).option("--verbose","Enable verbose logging",{default:h.verbose}).usage("tlsx verify [cert-path] [options]").example("tlsx verify /path/to/cert.crt").example("tlsx verify /path/to/cert.crt --ca-path /path/to/ca.crt").action(async(s,t)=>{let e=s||h.certPath,n=t?.["ca-path"]||h.caCertPath,i=t?.verbose||h.verbose;if(r.info(`Verifying certificate: ${e}`),n)r.info(`Against CA certificate: ${n}`);try{let a=T(e,n,i);if(a.message)r.error(a.message),b.exit(1);if(r.info("Certificate details:"),r.info(`Subject: ${a.subject}`),r.info(`Issuer: ${a.issuer}`),r.info(`Valid from: ${a.validFrom.toLocaleString()}`),r.info(`Valid to: ${a.validTo.toLocaleString()}`),r.info(`Domains: ${a.domains.join(", ")}`),a.valid)r.success("Certificate is valid");else{if(r.error("Certificate is invalid:"),a.expired)r.error("- Certificate has expired");if(a.notYetValid)r.error("- Certificate is not yet valid");if(!a.issuerValid&&n)r.error("- Certificate was not issued by the provided CA");b.exit(1)}}catch(a){r.error(`Failed to verify certificate: ${a}`),b.exit(1)}});p.command("info","Display system configuration and paths").option("--verbose","Enable verbose logging",{default:h.verbose}).usage("tlsx info [options]").example("tlsx info").example("tlsx info --verbose").action(async(s)=>{let t=s?.verbose||h.verbose;r.info("TLSX Configuration:"),r.info("=================="),r.info(` System Information:`),r.info(`Platform: ${y.platform()}`),r.info(`Architecture: ${y.arch()}`),r.info(`OS Version: ${y.version()}`),r.info(`Hostname: ${y.hostname()}`);let{certPath:e,keyPath:n,caCertPath:i,basePath:a}=N({});if(r.info(` Certificate Configuration:`),r.info(`Domain: ${h.domain}`),r.info(`Common Name: ${h.commonName}`),r.info(`Organization: ${h.organizationName}`),r.info(`Country: ${h.countryName}`),r.info(`State: ${h.stateName}`),r.info(`Locality: ${h.localityName}`),r.info(`Validity Days: ${h.validityDays}`),r.info(` File Paths:`),r.info(`Base Path: ${a}`),r.info(`Certificate Path: ${e}`),r.info(`Private Key Path: ${n}`),r.info(`CA Certificate Path: ${i}`),r.info(` Alternative Names:`),r.info(`Alternative IPs: ${h.altNameIPs.join(", ")}`),r.info(`Alternative URIs: ${h.altNameURIs.join(", ")}`),t)r.info(` Complete Configuration:`),r.info(JSON.stringify(h,null,2))});p.command("cleanup","Clean up all TLSX certificates from the system trust store").option("--force","Skip confirmation prompt",{default:!1}).option("--verbose","Enable verbose logging",{default:h.verbose}).option("--pattern <pattern>","Certificate name pattern to match for cleanup").usage("tlsx cleanup [options]").example("tlsx cleanup").example("tlsx cleanup --force").example('tlsx cleanup --pattern "My Custom Cert"').action(async(s)=>{let t=s?.force||!1,e=s?.verbose||h.verbose,n=s?.pattern;if(!t){r.warn(`This will remove ${n?`certificates matching "${n}"`:"all TLSX certificates"} from your system trust store.`),r.warn("This action cannot be undone."),b.stdout.write("Are you sure you want to continue? (y/N): ");let i=await new Promise((a)=>{b.stdin.once("data",(c)=>{a(c.toString().trim().toLowerCase())})});if(i!=="y"&&i!=="yes"){r.info("Operation cancelled.");return}}r.info(`Cleaning up ${n?`certificates matching "${n}"`:"all TLSX certificates"} from system trust store...`);try{await G({verbose:e},n),r.success(`${n?`Certificates matching "${n}"`:"All TLSX certificates"} have been removed from the system trust store`)}catch(i){r.error(`Failed to clean up certificates: ${i}`),b.exit(1)}});p.version(q);p.help();p.parse();