2017-04-28 18:40:37 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								'use strict' ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  oauth3  =  require ( './oauth3.js' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  defaults  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  main :  'oauth3' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								,  provider :  'oauth3.org'  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  parseArgs ( argv ,  opts )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  args  =  Array . prototype . slice . call ( argv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  sep  =  /[:\.\-]/ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  args . shift ( ) ;  // node
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  args . shift ( ) ;  // oauth3.js
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  command  =  args . shift ( )  ||  'help' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  cmdpair  =  command . split ( sep ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  cmd  =  cmdpair [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  sub  =  cmdpair [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  COMMAND  =  'COMMAND' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  maxCmdLen  =  COMMAND . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  maxPairLen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  cmds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  arg1  =  args [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // build commands list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  pairsMap  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cmds  =  opts . commands . filter ( function  ( desc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var  pair  =  desc [ 0 ] . split ( /\s+/ ) [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var  psub  =  pair . split ( sep ) [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pairsMap [ pair ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    maxPairLen  =  Math . max ( maxPairLen ,  pair . length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( pair  ===  psub )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      maxCmdLen  =  Math . max ( maxCmdLen ,  psub . length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( - 1  ===  Object . keys ( pairsMap ) . indexOf ( cmd ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    console . log ( 'fail' ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    arg1  =  cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    cmd  =  'help' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    help ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  rpad ( str ,  len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( str . length  <  len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      str  +=  ' ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function  help ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var  status  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    function  helpMain ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( 'Here are all the top-level commands:' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( '\t'  +  defaults . main  +  ' '  +  rpad ( COMMAND ,  maxCmdLen ) ,  ' # description' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( '\t'  +  '------------------------------' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cmds . forEach ( function  ( desc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var  pcmd  =  rpad ( desc [ 0 ] . split ( /\s+/ ) [ 0 ] ,  maxCmdLen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var  pdesc  =  desc [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console . log ( '\t'  +  defaults . main  +  ' '  +  pcmd ,  ' # '  +  pdesc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( arg1  &&  - 1  ===  Object . keys ( pairsMap ) . indexOf ( arg1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( defaults . main  +  ": Unknown command '"  +  arg1  +  "'" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      arg1  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! arg1  ||  '-'  ===  arg1 [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      helpMain ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      process . exit ( status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( 'help'  ===  arg1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      helpMain ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      console . log ( "no more help available for 'help'" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      process . exit ( status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( - 1  !==  [  'help' ,  '-h' ,  '--help'  ] . indexOf ( command )  ||  - 1  !==  args . indexOf ( '-h' )  ||  - 1  !==  args . indexOf ( '--help' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    help ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								parseArgs ( process . argv ,  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // CLI goals:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // whoami / login: you are now logged in as
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //   * john@example.com [current] (just now)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //   * john@work.net (2 minutes ago)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //   * john@family.me (2 weeks ago)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  commands :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [  'login [email or cloud address]' ,  'alias of session:attach' ,  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "--auto, create a new account without asking if none exists" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      //, "--exclusive, logout all other ids, removing access to their accounts"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ,  "--provider, specify an authentication provider (default: :provider)" . replace ( /\b:provider\b/ ,  defaults . provider ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      //, "--email [addr], use the given id as an email address, even if it works as a cloud address"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      //, "--cloud [addr], use the given id as a cloud address or fail (don't fallback to email)"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'logout' ,  'alias of session:detach'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'whoami' ,  'show current account(s) and login(s) and device(s)'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // authn
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'session' ,  'Manage your ids (credentials / logins)'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'session:new' ,  'alias of `login --exclusive`'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'session:attach' ,  'Create a session (and account if needed) for a given email address or cloud address'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'session:detach' ,  'remove login from session'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'session:list' ,  'show all of the ids in the current session'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // authz
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts' ,  'Manage your accounts (authorization / profiles)'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:new' ,  'create a new account attached to the credentials of the current session'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:set' ,  'change account details'  ]  // todo changing the name should be restricted john@provider.net -> jonathan@provider.net would be bad
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:list' ,  'show all of the accounts in the current session'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:attach' ,  'attach an account to an id'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:detach' ,  'detach an account from an id'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:select' ,  'select an account to use as the primary account for this session'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:update' ,  '(deprecated) alias of set'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:login' ,  '(deprecated) alias of login'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'accounts:whoami' ,  '(deprecated) alias of whoami'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // authn / authz
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'devices' ,  'manages devices for your account(s)'  ] 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-15 20:21:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ,  [  'devices:new' ,  'create a new device (default name is hostname, default ip is the result of :provider/api/tunnel@oauth3.org/checkip)' . replace ( /\b:provider\b/ ,  defaults . provider )  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'devices:set' ,  'set the ip address of the device (defaults ip is the result of :provider/api/tunnel@oauth3.org/checkip)' . replace ( /\b:provider\b/ ,  defaults . provider )  ] 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-28 18:40:37 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  ,  [  'devices:attach' ,  "attach a device to a domain's DNS record"  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'devices:detach' ,  "detach an account from a domain's DNS record"  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'devices:select' ,  '(re)claim the specified device as this device (i.e. you re-installed your OS or deleted your ~/.oauth3)'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'devices:list' ,  'show all devices for your account(s)'  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // help
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  [  'help' ,  "show this menu; use '"  +  defaults . main  +  " help COMMAND' (even 'help') for options and sub-commands"  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ) ;