MCPcopy
hub / github.com/dthree/vantage

github.com/dthree/vantage @v1.5.0 sqlite

repository ↗ · DeepWiki ↗ · release v1.5.0 ↗
33 symbols 68 edges 26 files 4 documented · 12%
README

vantage

Build Status Gitter

NPM Version Wat: Cheat Sheeted NPM Downloads

Vantage = CLI + SSH + REPL for your live node app. In one line:

require("vantage")().listen(4000);

vantage.js demo

Contents

Introduction

Vantage gives you a new perspective into your live node application not previously available.

An extension of Vorpal, Vantage turns your live Node app into a immersive CLI.Accessible remotely or locally, Vantage lets you build your own API for your application and import community extensions, introducing a new means of live diagnostics and activity for your dev and prod environments.

  • First-class CLI: tab completion, history, you name it.
  • Build your own API with the familiar syntax of commander.js.
  • SSH-like client / server setup for remote access to your live Node app.
  • Production-ready, with authentication middleware and a basic firewall.
  • Built-in REPL.

Unlike any other REPL or CLI module, Vantage allows you to remotely connect to your live app and access the CLI transparently, exactly as you would in an SSH session. Vantage can connect through an unlimited number of live Node instances across multiple machines, piping commands and information to and from your local terminal.

Getting Started

Tour

This Vantage tour will give you a live walk-through of vantage's features.

$ npm install -g vantage
$ vantage tour
Examples
Community
Quick Start

First, install vantage globally:

$ npm install -g vantage

Now, add the following to a file named server.js.

// Create a new instance of vantage.
var vantage = require("vantage")();

// Add the command "foo", which logs "bar".
vantage
  .command("foo")
  .description("Outputs 'bar'.")
  .action(function(args, callback) {
    this.log("bar");
    callback();
  });

// Name your prompt delimiter 
// "websvr~$", listen on port 80 
// and show the Vantage prompt.
vantage
  .delimiter("websvr~$")
  .listen(80)
  .show();

Run server.js. You Node app has become a CLI.

$ node server.js
websvr~$ 

Open another terminal. Because Vantage is listening on port 80, you can remotely connect to it:

$ vantage 80
$ Connecting to 127.0.0.1:80 using http...
websvr~$ 

Try out your "foo" command.

websvr~$ foo
bar
websvr~$

Now type "help" to see Vantage's built in commands in addition to "foo":

websvr~$ help

  Commands

    help [command]    Provides help for a given command.
    exit [options]    Exits instance of Vantage.
    use <module>      Installs a vantage extension in realtime.
    vantage [server]  Connects to another application running vantage.
    foo               Outputs "bar".

websvr~$

That's the basic idea. Once you get the hang of it, read on to learn some of the fancier things Vantage can do.

API

Vantage is an extension of Vorpal, and so inherits all of its properties and methods. For all command creation and CLI syntax, refer to Vorpal's API.

.listen(app, [options or callback], [callback])

Starts Vantage as a server.

Vantage as a standalone web server

If you just want it to listen on a port independent of your web application, simply pass in the port and Vantage will spawn a new HTTP server. Every time a client connects to Vantage, the connection callback will be thrown and include the socket.io connection object.

var vantage = new Vantage();
vantage.listen(80, function(socket){
  this.log("Accepted a connection.")
});

Vantage with an existing web server

If you want Vantage to listen on the same port as your web application, you can use Vantage's listen function in place of your existing web server's listen function.

This is useful when running clustered instances of your server, such as behind a reverse proxy, where every instance has a separate port that can only be accessed internally. In this way, you can hop into any running instance without having to remember a separate set of ports.

With Koa.js
var koa = require('koa');
var Vantage = require('vantage');

var vantage = new Vantage();
var app = koa();

vantage.listen(app, 80);
With Express.js
var express = require('express');
var Vantage = require('vantage');

var vantage = new Vantage();
var app = express();

vantage.listen(app, 80);
With Hapi.js
var Hapi = require('hapi');
var Vantage = require('vantage');

var vantage = new Vantage();
var server = new Hapi.Server();

vantage.listen(server, 80);

server.start();
With SSL / advanced options

You can pass detailed options to your web server with the second argument in place of the port. These options are the same options you would pass into your web server, with a few exceptions:

  • options.port: Tells vantage what port to listen on.
  • options.ssl: A boolean that tells Vantage whether to spawn an HTTP or HTTPs server.
  • options.logActivity: When true, a TTY acting as a Vantage server that receives a connection will log when clients log in and out of the server. Defaults to false.

Default HTTPs server example:

var vantage = new Vantage();
vantage.listen(someMiddleware, {
  port: 443,
  ssl: true,
  key: fs.readFileSync('./../../server.key'),
  cert: fs.readFileSync('./../../server.crt'),
  ca: fs.readFileSync('./../../ca.crt'),
  requestCert: true,
  rejectUnauthorized: false,
});

.banner(string)

Sets a banner for display when logging into a given Vantage server.

var banner = 
"######################################################################" + 
"#                    Welcome to joescrabshack.com                    #" + 
"#                                                                    #" +
"#              All connections are monitored and recorded            #" + 
"#      Disconnect IMMEDIATELY if you are not an authorized user      #" + 
"######################################################################";
vantage
  .delimiter('appsvr:3000~$')
  .banner(banner)
  .listen(3000);
$ vantage 3000
$ Connecting to 127.0.0.1:3000...
$ Connected successfully.
######################################################################
#                    Welcome to joescrabshack.com                    # 
#                                                                    #
#              All connections are monitored and recorded            # 
#      Disconnect IMMEDIATELY if you are not an authorized user      # 
######################################################################
? user: 

Note: See authentication section for auth details.

Firewall

If your Vantage server is listening on a public-facing web port such as 80 or 443, your organization's firewall is not going to help you. This is a barebones IP firewall for limiting connections down to your internal subnets. For sensitive applications, this obviously does not replace authentication.

.firewall.policy(string)

Sets the default policy for the firewall to either ACCEPT or REJECT. Any request that does not match a rule will fall back to this policy. Returns vantage.firewall.

Defaults to ACCEPT.

// This will reject all remote connections.
vantage.firewall.policy("REJECT");

.firewall.accept(address, [subnet])

Allows a particular address / subnet to connect to Vantage. Returns vantage.firewall. If no arguments are passed, returns the currently-applied policy.

vantage.firewall
  .policy("REJECT")
  .accept("10.0.0.0/8")
  .accept("192.168.0.0", 24);

console.log(vantage.firewall.policy()) // -> REJECT  

.firewall.reject(address, [subnet])

Denies access to a particular address / subnet. Returns vantage.firewall.

vantage.firewall
  .policy("ACCEPT")
  .reject("64.0.0.0", 8)
  .reject("192.168.0.0/16");

.firewall.rules()

Returns an array of applied rules.

console.log(vantage.firewall.rules());
// -> [{ ip: "64.0.0.0", subnet: 8, rule: "REJECT" }]

.firewall.reset()

Reverts vantage.firewall to an ACCEPT policy and erases all rules.

Authentication

Vantage supports authentication strategies as middleware. It comes with a default Basic Authentication module.

vantage.auth(middleware, options)

Uses a given authentication strategy. Pass the required middleware into the first variable, and any options / configuration for that middleware as given in that module's documentation into the options parameter.

var pam = require("vantage-auth-pam");
vantage.auth(pam, options);

Vantage Basic Auth is built in, and so can be used with the "basic" string instead of requiring a module.

var users = [
    { user: "admin", pass: "4k#842jx!%s" },
    { user: "user", pass: "Unicorn11" }
];

var vantage = require("vantage")();

vantage.auth("basic", {
  "users": users,
  "retry": 3,
  "retryTime": 500,
  "deny": 1,
  "unlockTime": 3000
});
Security Note

If no vantage.auth function is declared, your app will not require authentication. As a security measure, if your NODE_ENV environment variable is not set to "development" and there is no authentication, Vantage will disallow remote connections. To permit remote connections without authentication, simply set your NODE_ENV to "development".

Building Authentication Strategies

You can publish your own custom authentication strategies for Vantage.js as its own Node module.

I am currently looking to team up with a rocket scientist like you to build a pam-based authentication strategy for Vantage. If you are interested, send me a note!

The format for publishing a strategy is simple:


module.exports = function(vantage, options) {

  // The Vantage instance is exposed through
  // the `vantage` parameter. `options` exposes
  // options passed in by the strategy's user, and
  // is defined by you.

  // This is where you can persist the log on state of 
  // the users attempting to log in, etc.

  // You return a function, which executes
  // in the same context as a vantage command.
  // Every time the user attempts to connect,
  // this function runs. In it you can prompt
  // the user, etc.
  return function(args, callback) {

    /** 
     * Args exposes several pieces of data
     * you can use:
     * {
     *   // If the user pre-passes auth data, it will be
     *   // available here. Otherwise, prompt him for it.
     *   user: "admin", 
     *   pass: "Unicorn11",
     *   // This is based on socket.io's connection handshake,
     *   // and has a lot more data than this.
     *   handshake: { 
     *     host: "192.168.0.1",
     *     port: "800"
     *   }
     * }
     */

    // Prompt user / look up credentials, etc.

    // Authentication is determined by your
    // callback: `callback(message, authenticated)`.

    // Example of rejected auth.
    callback("Invalid credentials.", false);

    // Example of accepted auth.
    // callback(void 0, true);
  }

}

Events

Vantage extends EventEmitter.prototype. Simply use vantage.on('event', fn) and vantage.emit('event', data). The following events are supported:

Socket.io client / server events

Vantage uses socket.io to handle all communication between instances. The following events map to the default socket.io events:

  • client_connect: Maps to connect for socket.io-client.

  • client_connect_error: Maps to connect_error for socket.io-client.

  • client_error: Maps to error for socket.io-client.

  • client_disconnect: Maps to disconnect for socket.io-client.

  • server_connection: Maps to connection for socket.io.

  • server_disconnect: Maps to `disconnect

Core symbols most depended-on inside this repo

stdout
called by 25
test/integration.js
exec
called by 14
test/integration.js
Vantage
called by 10
lib/index.js
on
called by 6
lib/server.js
viewed
called by 3
lib/logger.js
disconnect
called by 2
lib/client.js
isNumber
called by 2
bin/vantage.js
trimTo
called by 1
lib/logger.js

Shape

Function 33

Languages

TypeScript100%

Modules by API surface

test/integration.js6 symbols
bin/vantage.js5 symbols
lib/logger.js4 symbols
examples/hacker-news/hacker-news.js4 symbols
lib/server.js3 symbols
lib/firewall.js2 symbols
lib/client.js2 symbols
examples/server/server.js2 symbols
lib/intercept.js1 symbols
lib/index.js1 symbols
examples/tour/tour.js1 symbols
examples/tour/server.js1 symbols

Dependencies from manifests, versioned

chalk1.1.0 · 1×
commander2.8.1 · 1×
eslint1.2.1 · 1×
express4.12.4 · 1×
gulp3.9.0 · 1×
gulp-eslint1.0.0 · 1×
hapi8.8.1 · 1×
insubnet0.0.8 · 1×
koa0.21.0 · 1×
lodash3.10.0 · 1×
mocha2.2.5 · 1×
moment2.10.3 · 1×

For agents

$ claude mcp add vantage \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact