Merge branch 'master' of git.daplie.com:OAuth3/oauth3.js
This commit is contained in:
		
						commit
						672662271d
					
				
							
								
								
									
										144
									
								
								bin/cli.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								bin/cli.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,144 @@
 | 
			
		||||
'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)' ]
 | 
			
		||||
  , [ 'devices:new', 'create a new device (default name is hostname, default ip is the result of :provider/api/org.oauth3.tunnel/checkip)'.replace(/\b:provider\b/, defaults.provider) ]
 | 
			
		||||
  , [ 'devices:set', 'set the ip address of the device (defaults ip is the result of :provider/api/org.oauth3.tunnel/checkip)'.replace(/\b:provider\b/, defaults.provider) ]
 | 
			
		||||
  , [ '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" ]
 | 
			
		||||
  ]
 | 
			
		||||
});
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user