2015-12-16 11:01:10 +00:00
#!/usr/bin/env node
'use strict' ;
var cli = require ( 'cli' ) ;
2015-12-16 12:27:23 +00:00
var mkdirp = require ( 'mkdirp' ) ;
2015-12-16 11:01:10 +00:00
cli . parse ( {
email : [ false , " Email used for registration and recovery contact. (default: null)" , 'email' ]
, domains : [ false , " Domain names to apply. For multiple domains you can enter a comma separated list of domains as a parameter. (default: [])" , 'string' ]
, duplicate : [ false , " Allow getting a certificate that duplicates an existing one" , 'boolean' , false ]
, 'agree-tos' : [ false , " Agree to the Let's Encrypt Subscriber Agreement" , 'boolean' , false ]
, debug : [ false , " show traces and logs" , 'boolean' , false ]
2015-12-28 15:56:46 +00:00
, 'tls-sni-01-port' : [ false , " Port number to perform tls-sni-01 challenge. Boulder in testing mode defaults to 5001. (default: 443,5001)" , 'string' ]
, 'http-01-port' : [ false , " Port used in the SimpleHttp challenge. (default: 80)" , 'string' ]
2015-12-16 11:01:10 +00:00
, 'rsa-key-size' : [ false , " Size (in bits) of the RSA key." , 'int' , 2048 ]
2015-12-20 03:21:53 +00:00
, 'cert-path' : [ false , " Path to where new cert.pem is saved" , 'string' , ':config/live/:hostname/cert.pem' ]
, 'fullchain-path' : [ false , " Path to where new fullchain.pem (cert + chain) is saved" , 'string' , ':config/live/:hostname/fullchain.pem' ]
, 'chain-path' : [ false , " Path to where new chain.pem is saved" , 'string' , ':config/live/:hostname/chain.pem' ]
2015-12-16 11:01:10 +00:00
, 'domain-key-path' : [ false , " Path to privkey.pem to use for domain (default: generate new)" , 'string' ]
2015-12-16 11:21:14 +00:00
, 'config-dir' : [ false , " Configuration directory." , 'string' , '~/letsencrypt/etc/' ]
2015-12-16 11:01:10 +00:00
, server : [ false , " ACME Directory Resource URI." , 'string' , 'https://acme-v01.api.letsencrypt.org/directory)' ]
2015-12-16 12:51:14 +00:00
, standalone : [ false , " Obtain certs using a \"standalone\" webserver." , 'boolean' , false ]
2015-12-16 11:01:10 +00:00
//, manual: [ false, " Provide laborious manual instructions for obtaining a cert (default: false)", 'boolean', false ]
, webroot : [ false , " Obtain certs by placing files in a webroot directory." , 'boolean' , false ]
, 'webroot-path' : [ false , " public_html / webroot path." , 'string' ]
//, 'standalone-supported-challenges': [ false, " Supported challenges, order preferences are randomly chosen. (default: http-01,tls-sni-01)", 'string', 'http-01,tls-sni-01']
2015-12-16 11:21:14 +00:00
, 'work-dir' : [ false , "(ignored)" , 'string' , '~/letsencrypt/var/lib/' ]
, 'logs-dir' : [ false , "(ignored)" , 'string' , '~/letsencrypt/var/log/' ]
2015-12-16 11:01:10 +00:00
} ) ;
2015-12-16 11:43:30 +00:00
// ignore certonly and extraneous arguments
cli . main ( function ( _ , options ) {
2015-12-17 09:16:43 +00:00
console . log ( '' ) ;
2015-12-16 11:43:30 +00:00
var args = { } ;
2015-12-20 03:21:53 +00:00
var homedir = require ( 'homedir' ) ( ) ;
2015-12-16 11:43:30 +00:00
Object . keys ( options ) . forEach ( function ( key ) {
var val = options [ key ] ;
if ( 'string' === typeof val ) {
val = val . replace ( /^~/ , homedir ) ;
}
key = key . replace ( /\-([a-z0-9A-Z])/g , function ( c ) { return c [ 1 ] . toUpperCase ( ) ; } ) ;
args [ key ] = val ;
} ) ;
Object . keys ( args ) . forEach ( function ( key ) {
var val = args [ key ] ;
if ( 'string' === typeof val ) {
2015-12-20 03:21:53 +00:00
val = val . replace ( /\:config/ , args . configDir ) ;
2015-12-16 11:43:30 +00:00
}
args [ key ] = val ;
} ) ;
2015-12-16 12:27:23 +00:00
if ( args . domains ) {
args . domains = args . domains . split ( ',' ) ;
2015-12-16 11:43:30 +00:00
}
2015-12-16 12:27:23 +00:00
2015-12-17 09:14:33 +00:00
if ( ! ( Array . isArray ( args . domains ) && args . domains . length ) || ! args . email || ! args . agreeTos ) {
console . error ( "\nUsage: letsencrypt certonly --standalone --domains example.com --email user@example.com --agree-tos" ) ;
console . error ( "\nSee letsencrypt --help for more details\n" ) ;
return ;
}
2015-12-16 12:27:23 +00:00
if ( args . tlsSni01Port ) {
2015-12-28 15:56:46 +00:00
// [@agnat]: Coerce to string. cli returns a number although we request a string.
args . tlsSni01Port = "" + args . tlsSni01Port ;
2015-12-16 12:27:23 +00:00
args . tlsSni01Port = args . tlsSni01Port . split ( ',' ) . map ( function ( port ) {
return parseInt ( port , 10 ) ;
} ) ;
}
if ( args . http01Port ) {
2015-12-28 15:56:46 +00:00
// [@agnat]: Coerce to string. cli returns a number although we request a string.
args . http01Port = "" + args . http01Port ;
2015-12-16 12:27:23 +00:00
args . http01Port = args . http01Port . split ( ',' ) . map ( function ( port ) {
return parseInt ( port , 10 ) ;
} ) ;
2015-12-16 11:43:30 +00:00
}
2015-12-16 12:27:23 +00:00
mkdirp ( args . configDir , function ( err ) {
2015-12-16 11:43:30 +00:00
if ( err ) {
2015-12-16 12:27:23 +00:00
console . error ( "Could not create --config-dir '" + args . configDir + "':" , err . code ) ;
console . error ( "Try setting --config-dir '/tmp'" ) ;
2015-12-16 11:43:30 +00:00
return ;
}
2015-12-16 12:27:23 +00:00
var LE = require ( 'letsencrypt' ) ;
var handlers ;
2015-12-16 12:51:14 +00:00
if ( args . webrootPath ) {
handlers = require ( '../lib/webroot' ) . create ( args ) ;
}
else /*if (args.standalone)*/ {
2015-12-16 12:42:04 +00:00
handlers = require ( '../lib/standalone' ) . create ( ) ;
2015-12-28 15:56:46 +00:00
handlers . startServers ( args . http01Port || [ 80 ] , args . tlsSni01Port || [ 443 , 5001 ] ) ;
2015-12-16 12:27:23 +00:00
}
2015-12-16 12:51:14 +00:00
// let LE know that we're handling standalone / webroot here
2015-12-17 09:14:33 +00:00
LE . create ( {
manual : true
2016-03-17 23:27:03 +00:00
, server : args . server
2015-12-17 09:14:33 +00:00
, debug : args . debug
, configDir : args . configDir
2015-12-20 03:21:53 +00:00
, privkeyPath : ':config/live/:hostname/privkey.pem' //args.privkeyPath
2015-12-17 09:14:33 +00:00
, fullchainPath : args . fullchainPath
, certPath : args . certPath
, chainPath : args . chainPath
} , handlers ) . register ( args , function ( err , results ) {
2015-12-16 12:27:23 +00:00
if ( err ) {
2015-12-19 22:26:46 +00:00
console . error ( '[Error]: letsencrypt-cli' ) ;
console . error ( err . stack || err ) ;
2015-12-16 12:27:23 +00:00
return ;
}
2016-01-01 22:15:24 +00:00
if ( ! results || ( 'object' !== typeof results ) ) {
console . error ( "Error: An unknown error occurred. My best guess is that we got an error that we're not used to from the ACME server and accidentally interpretted it as a success... or forgot to expose the error." ) ;
console . error ( results ) ;
err = new Error ( "Here's a stack trace, in case it helps:" ) ;
console . error ( err . stack ) ;
return ;
}
2015-12-16 12:27:23 +00:00
if ( handlers . closeServers ) {
handlers . closeServers ( ) ;
}
// should get back account, path to certs, pems, etc?
2015-12-17 09:14:33 +00:00
console . log ( '\nCertificates installed at:' ) ;
console . log ( Object . keys ( results ) . filter ( function ( key ) {
return /Path/ . test ( key ) ;
} ) . map ( function ( key ) {
return results [ key ] ;
} ) . join ( '\n' ) ) ;
process . exit ( 0 ) ;
2015-12-16 12:27:23 +00:00
} ) ;
2015-12-16 11:43:30 +00:00
} ) ;
2015-12-16 11:01:10 +00:00
} ) ;