Giter VIP home page Giter VIP logo

node-openvpn's Introduction

node-openvpn

NPM version Dependency Status npm

Communicate with an OpenVPN client instance via telnet using node.

Installation

$ npm install node-openvpn --save

Usage

const openvpnmanager = require('node-openvpn');

const opts = {
  host: '127.0.0.1', // normally '127.0.0.1', will default to if undefined
  port: 1337, //port openvpn management console
  timeout: 1500, //timeout for connection - optional, will default to 1500ms if undefined
  logpath: 'log.txt' //optional write openvpn console output to file, can be relative path or absolute
};
const auth = {
  user: 'vpnUserName',
  pass: 'vpnPassword',
};
const openvpn = openvpnmanager.connect(opts)

// will be emited on successful interfacing with openvpn instance
openvpn.on('connected', () => {
  openvpnmanager.authorize(auth);
});

// emits console output of openvpn instance as a string
openvpn.on('console-output', output => {
  console.log(output)
});

// emits console output of openvpn state as a array
openvpn.on('state-change', state => {
  console.log(state)
});

// emits console output of openvpn state as a string
openvpn.on('error', error => {
  console.log(error)
});

// get all console logs up to this point
openvpnmanager.getLog(console.log)

// and finally when/if you want to
openvpnmanager.disconnect();

// emits on disconnect
openvpn.on('disconnected', () => {
  // finally destroy the disconnected manager 
  openvpnmanager.destroy()
});

node-openvpn's People

Contributors

amilajack avatar luigiplr avatar mkozjak avatar shumkov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-openvpn's Issues

How to use .ovpn file in windows using node-openvpn

var openvpnmanager = require('node-openvpn')
var openvpnBin = require('openvpn-bin')
var path = require('path')

openvpnBin.initialize('C:/Program Files/OpenVPN/bin/openvpn.exe', {
host: '127.0.0.1',
port: 1337,
config: path.normalize('C:/Users/toshiba/Desktop/client.ovpn')
}).then(function() {
var managerInstance = openvpnmanager.connect({ host: '127.0.0.1', port: 1337 })

managerInstance.on('connected', function() {
managerInstance.authorize({
user: '',
pass: ''
})
})

managerInstance.on('console-output', function(output) {
console.log(output)
})
})

How to use it with .ovpn file?

I want to start use OpenVPN connection in it. To do that I found 2 modules on npm (openvpn-client and openvpn-bin) - but any of them has no good docs and examples, but I try as I can to use them and it was unsuccessful.

I have Ipvanish account (login/password) with 540 .opvn files, which I can use. I try this:

var openvpnmanager = require('node-openvpn');
 var openvpnBin = require('openvpn-bin');
 var path = require('path');

 var filePath = path.normalize('../geo/ipvanish/ipvanish-AU-Sydney-syd-a16.ovpn');

    var opts = {
        host: 'syd-a16.ipvanish.com', // normally '127.0.0.1', will default to if undefined
        port: 443, //port openvpn management console
        timeout: 60000, //timeout for connection - optional, will default to 1500ms if undefined
        config: filePath
    };
    var auth = {
        user: '[email protected]',
        pass: 'password'
    };

    var openvpn = openvpnmanager.connect(opts)

    openvpn.on('connected', function() { 
        // will be emited on successful interfacing with openvpn instance
        console.log('connected')
        openvpnmanager.authorize(auth).then(function(res){

        });
    });

Error while connecting

When I'm using this code

var openvpnmanager = require('node-openvpn')
var openvpnBin = require('openvpn-bin')
var path = require('path')

openvpnBin.initialize('openvpn', {
  host: '(VPNServerIP)',
  port: 1194,
  config: path.normalize('config.ovpn')
}).then(function() {
  var managerInstance = openvpnmanager.connect({ host: '(VPNServerIP)', port: 1194 })

  managerInstance.on('connected', function() {
    managerInstance.authorize({
      user: 'username',
      pass: 'password'
    })
  })

  managerInstance.on('console-output', function(output) {
    console.log(output)
  })
})

I am getting these errors

Uncaught Error: Uncaught, unspecified "error" event. (Cannot connect)
    at Telnet.emit (events.js:163)
    at Socket.<anonymous> (/Users/MyName/Desktop/VPN/node_modules/telnet-client/lib/telnet-client.js:52)
    at Object.onceWrapper (events.js:290)
    at emitNone (events.js:86)
    at Socket.emit (events.js:185)
    at Socket._onTimeout (net.js:342)
    at ontimeout (timers.js:365)
    at tryOnTimeout (timers.js:237)
    at Timer.listOnTimeout (timers.js:207)
Uncaught Error: connect ECONNREFUSED (VPNServerIP):1194
    at Object.exports._errnoException (util.js:1022)
    at exports._exceptionWithHostPort (util.js:1045)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090)

Also in terminal after I enter my password on the popup while trying to connect to the server I am getting these errors.

Unhandled rejection TypeError: managerInstance.authorize is not a function
    at EventEmitter.<anonymous> (file:///Users/myname/Desktop/VPN/openVPN.js:15:21)
    at emitNone (events.js:86:13)
    at EventEmitter.emit (events.js:185:7)
    at /Users/myname/Desktop/VPN/node_modules/node-openvpn/lib/openvpn.js:26:28
    at tryCatcher (/Users/myname/Desktop/VPN/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/Users/myname/Desktop/VPN/node_modules/bluebird/js/main/promise.js:510:31)
    at Promise._settlePromiseAt (/Users/myname/Desktop/VPN/node_modules/bluebird/js/main/promise.js:584:18)
    at Promise._settlePromises (/Users/myname/Desktop/VPN/node_modules/bluebird/js/main/promise.js:700:14)
    at Async._drainQueue (/Users/myname/Desktop/VPN/node_modules/bluebird/js/main/async.js:123:16)
    at Async._drainQueues (/Users/myname/Desktop/VPN/node_modules/bluebird/js/main/async.js:133:10)
    at MutationObserver.Async.drainQueues (/Users/myname/Desktop/VPN/node_modules/bluebird/js/main/async.js:15:14)

Any ideas on how I would go about fixing these issues? Thanks!

Currently I'm just using a button that calls a function that includes the code above. I'm new to node.js and electron.js so if it is something stupid I'm sorry. I think the problem is with the line that has managerInstance.authorize, maybe I messed up installing the packages?

openvpn is not defined

I am trying to use this library, I have the following

  openvpnBin
    .initialize(path.normalize('c:/Program Files/OpenVPN/bin/openvpn.exe'), {
      host: '176.126.237.217',
      port: 443,
      config: path.normalize('./ovpn/vpnbook-euro1-tcp443.ovpn')
    })
    .then(function() {
      console.log('openvpn running');

      const managerInstance = openvpnmanager.connect({
        host: '176.126.237.217',
        port: 443
      });

      managerInstance.on('connected', function() {
        managerInstance.authorize({
          user: 'vpnbook',
          pass: 'xf5s3d9'
        });
      });

      managerInstance.on('console-output', function(output) {
        console.log(output);
      });
    });

console log

openvpn running
Unhandled rejection ReferenceError: openvpn is not defined

Any ideas?

Install fails: error: no matching function for call to 'v8::String::Utf8Value::Utf8Value(v8::Local<v8::Value>)'

I am getting an error trying to install:

# npm install node-openvpn
npm ERR! code 1
npm ERR! path /code/node_modules/runas
npm ERR! command failed
npm ERR! command sh -c -- node-gyp rebuild
npm ERR! make: Entering directory '/code/node_modules/runas/build'
npm ERR!   CXX(target) Release/obj.target/runas/src/main.o
npm ERR! make: Leaving directory '/code/node_modules/runas/build'
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using [email protected]
npm ERR! gyp info using [email protected] | linux | x64
npm ERR! gyp info find Python using Python version 3.9.2 found at "/usr/bin/python3"
npm ERR! gyp info spawn /usr/bin/python3
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args   '/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py',
npm ERR! gyp info spawn args   'binding.gyp',
npm ERR! gyp info spawn args   '-f',
npm ERR! gyp info spawn args   'make',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/code/node_modules/runas/build/config.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi',
npm ERR! gyp info spawn args   '-I',
npm ERR! gyp info spawn args   '/root/.cache/node-gyp/18.12.0/include/node/common.gypi',
npm ERR! gyp info spawn args   '-Dlibrary=shared_library',
npm ERR! gyp info spawn args   '-Dvisibility=default',
npm ERR! gyp info spawn args   '-Dnode_root_dir=/root/.cache/node-gyp/18.12.0',
npm ERR! gyp info spawn args   '-Dnode_gyp_dir=/usr/local/lib/node_modules/npm/node_modules/node-gyp',
npm ERR! gyp info spawn args   '-Dnode_lib_file=/root/.cache/node-gyp/18.12.0/<(target_arch)/node.lib',
npm ERR! gyp info spawn args   '-Dmodule_root_dir=/code/node_modules/runas',
npm ERR! gyp info spawn args   '-Dnode_engine=v8',
npm ERR! gyp info spawn args   '--depth=.',
npm ERR! gyp info spawn args   '--no-parallel',
npm ERR! gyp info spawn args   '--generator-output',
npm ERR! gyp info spawn args   'build',
npm ERR! gyp info spawn args   '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! gyp info spawn make
npm ERR! gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
npm ERR! ../src/main.cc: In function 'void {anonymous}::Runas(const Nan::FunctionCallbackInfo<v8::Value>&)':
npm ERR! ../src/main.cc:19:49: error: no matching function for call to 'v8::String::Utf8Value::Utf8Value(v8::Local<v8::Value>)'
npm ERR!    19 |   std::string command(*String::Utf8Value(info[0]));
npm ERR!       |                                                 ^
npm ERR! In file included from /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-array-buffer.h:13,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8.h:24,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/node.h:73,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:510:5: note: candidate: 'v8::String::Utf8Value::Utf8Value(v8::Isolate*, v8::Local<v8::Value>)'
npm ERR!   510 |     Utf8Value(Isolate* isolate, Local<v8::Value> obj);
npm ERR!       |     ^~~~~~~~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:510:5: note:   candidate expects 2 arguments, 1 provided
npm ERR! ../src/main.cc:27:53: error: no matching function for call to 'v8::Array::Get(uint32_t&)'
npm ERR!    27 |     std::string arg(*String::Utf8Value(v_args->Get(i)));
npm ERR!       |                                                     ^
npm ERR! In file included from /root/.cache/node-gyp/18.12.0/include/node/v8-array-buffer.h:13,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8.h:24,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/node.h:73,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:290:43: note: candidate: 'v8::MaybeLocal<v8::Value> v8::Object::Get(v8::Local<v8::Context>, v8::Local<v8::Value>)'
npm ERR!   290 |   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,
npm ERR!       |                                           ^~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:290:43: note:   candidate expects 2 arguments, 1 provided
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:293:43: note: candidate: 'v8::MaybeLocal<v8::Value> v8::Object::Get(v8::Local<v8::Context>, uint32_t)'
npm ERR!   293 |   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Get(Local<Context> context,
npm ERR!       |                                           ^~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:293:43: note:   candidate expects 2 arguments, 1 provided
npm ERR! ../src/main.cc:32:47: error: no matching function for call to 'v8::Value::ToObject()'
npm ERR!    32 |   Local<Object> v_options = info[2]->ToObject();
npm ERR!       |                                               ^
npm ERR! In file included from /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-array-buffer.h:13,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8.h:24,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/node.h:73,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:372:44: note: candidate: 'v8::MaybeLocal<v8::Object> v8::Value::ToObject(v8::Local<v8::Context>) const'
npm ERR!   372 |   V8_WARN_UNUSED_RESULT MaybeLocal<Object> ToObject(
npm ERR!       |                                            ^~~~~~~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:372:44: note:   candidate expects 1 argument, 0 provided
npm ERR! ../src/main.cc:34:73: error: no matching function for call to 'v8::Value::BooleanValue()'
npm ERR!    34 |   if (GetProperty(v_options, "hide", &v_value) && v_value->BooleanValue())
npm ERR!       |                                                                         ^
npm ERR! In file included from /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-array-buffer.h:13,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8.h:24,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/node.h:73,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:408:8: note: candidate: 'bool v8::Value::BooleanValue(v8::Isolate*) const'
npm ERR!   408 |   bool BooleanValue(Isolate* isolate) const;
npm ERR!       |        ^~~~~~~~~~~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:408:8: note:   candidate expects 1 argument, 0 provided
npm ERR! ../src/main.cc:36:74: error: no matching function for call to 'v8::Value::BooleanValue()'
npm ERR!    36 |   if (GetProperty(v_options, "admin", &v_value) && v_value->BooleanValue())
npm ERR!       |                                                                          ^
npm ERR! In file included from /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-array-buffer.h:13,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8.h:24,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/node.h:73,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:408:8: note: candidate: 'bool v8::Value::BooleanValue(v8::Isolate*) const'
npm ERR!   408 |   bool BooleanValue(Isolate* isolate) const;
npm ERR!       |        ^~~~~~~~~~~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:408:8: note:   candidate expects 1 argument, 0 provided
npm ERR! ../src/main.cc:41:43: error: no matching function for call to 'v8::String::Utf8Value::Utf8Value(v8::Local<v8::Value>&)'
npm ERR!    41 |     std_input = *String::Utf8Value(v_value);
npm ERR!       |                                           ^
npm ERR! In file included from /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-array-buffer.h:13,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8.h:24,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/node.h:73,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:510:5: note: candidate: 'v8::String::Utf8Value::Utf8Value(v8::Isolate*, v8::Local<v8::Value>)'
npm ERR!   510 |     Utf8Value(Isolate* isolate, Local<v8::Value> obj);
npm ERR!       |     ^~~~~~~~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:510:5: note:   candidate expects 2 arguments, 1 provided
npm ERR! ../src/main.cc:45:45: error: no matching function for call to 'v8::Value::BooleanValue()'
npm ERR!    45 |                       v_value->BooleanValue();
npm ERR!       |                                             ^
npm ERR! In file included from /root/.cache/node-gyp/18.12.0/include/node/v8-primitive.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-object.h:11,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8-array-buffer.h:13,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/v8.h:24,
npm ERR!                  from /root/.cache/node-gyp/18.12.0/include/node/node.h:73,
npm ERR!                  from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:408:8: note: candidate: 'bool v8::Value::BooleanValue(v8::Isolate*) const'
npm ERR!   408 |   bool BooleanValue(Isolate* isolate) const;
npm ERR!       |        ^~~~~~~~~~~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/v8-value.h:408:8: note:   candidate expects 1 argument, 0 provided
npm ERR! ../src/main.cc: At global scope:
npm ERR! ../src/main.cc:70:6: error: variable or field 'Init' declared void
npm ERR!    70 | void Init(Handle<Object> exports) {
npm ERR!       |      ^~~~
npm ERR! ../src/main.cc:70:11: error: 'Handle' was not declared in this scope
npm ERR!    70 | void Init(Handle<Object> exports) {
npm ERR!       |           ^~~~~~
npm ERR! ../src/main.cc:70:24: error: expected primary-expression before '>' token
npm ERR!    70 | void Init(Handle<Object> exports) {
npm ERR!       |                        ^
npm ERR! ../src/main.cc:70:26: error: 'exports' was not declared in this scope
npm ERR!    70 | void Init(Handle<Object> exports) {
npm ERR!       |                          ^~~~~~~
npm ERR! In file included from ../../nan/nan.h:60,
npm ERR!                  from ../src/main.cc:1:
npm ERR! ../src/main.cc:76:20: error: 'Init' was not declared in this scope
npm ERR!    76 | NODE_MODULE(runas, Init)
npm ERR!       |                    ^~~~
npm ERR! /root/.cache/node-gyp/18.12.0/include/node/node.h:976:36: note: in definition of macro 'NODE_MODULE_X'
npm ERR!   976 |       (node::addon_register_func) (regfunc),                          \
npm ERR!       |                                    ^~~~~~~
npm ERR! ../src/main.cc:76:1: note: in expansion of macro 'NODE_MODULE'
npm ERR!    76 | NODE_MODULE(runas, Init)
npm ERR!       | ^~~~~~~~~~~
npm ERR! ../src/main.cc:13:6: warning: 'void {anonymous}::Runas(const Nan::FunctionCallbackInfo<v8::Value>&)' defined but not used [-Wunused-function]
npm ERR!    13 | void Runas(const Nan::FunctionCallbackInfo<Value>& info) {
npm ERR!       |      ^~~~~
npm ERR! make: *** [runas.target.mk:115: Release/obj.target/runas/src/main.o] Error 1
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:201:23)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:513:28)
npm ERR! gyp ERR! stack     at ChildProcess._handle.onexit (node:internal/child_process:291:12)
npm ERR! gyp ERR! System Linux 5.10.0-19-amd64
npm ERR! gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
npm ERR! gyp ERR! cwd /code/node_modules/runas
npm ERR! gyp ERR! node -v v18.12.0
npm ERR! gyp ERR! node-gyp -v v9.1.0
npm ERR! gyp ERR! not ok

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.