npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gandalf

v2.0.2

Published

node.js oauth login wizard with leveldb session storage

Downloads

42

Readme

gandalf

node.js oauth login wizard with leveldb session storage

Travis

gandalf gif

install

$ npm install gandalf

usage

var http = require('http')
var Router = require('routes-router')
var mount = require('routes-router-mount')
var level    = require('level-test')()
var Gandalf = require('gandalf')
var ecstatic = require('ecstatic')
var db = level('gandalf-examples--simple', {encoding: 'json'})

var gandalf = Gandalf(db, {
  providers:{
    facebook:{
      id:process.env.FACEBOOK_ID,
      secret:process.env.FACEBOOK_SECRET
    },
    twitter:{
      id:process.env.TWITTER_ID,
      secret:process.env.TWITTER_SECRET
    }
  }
})

var router = mount(Router())

// mount the OAuth login handlers
router.mount('/auth', gandalf.handler())

// get the current session data
router.addRoute('/status', {
	// add session handler to this method
	'GET':gandalf.session(function(req, res){
		req.session.get('userid', function(err, id){

			// load the user from the userid in the session
			gandalf.loadUser(id, function(err, user){
				res.end(JSON.stringify(user))	
			})
		})
	})
})

// only logged in people can see this route
router.addRoute('/private', gandalf.protect())

// these are served without hitting the session
router.addRoute('/*', ecstatic(__dirname + '/www'))

var server = http.createServer(router)

server.listen(80, function(){
  console.log('server listening');
})

api

var gandalf = Gandalf(db, options)

create a new authentication handler by passing in an existing leveldb - this can also be a sub-level

Pass a providers config to activate external OAUTH providers:

var gandalf = Gandalf(db, {
  providers:{
    facebook:{
      id:process.env.FACEBOOK_ID,
      secret:process.env.FACEBOOK_SECRET
    },
    twitter:{
      id:process.env.TWITTER_ID,
      secret:process.env.TWITTER_SECRET
    }
  }
})

The supported types are:

  • google
  • facebook
  • github
  • dropbox
  • twitter

Password mode (/register and /login) are activated automatically.

One user can connect multiple external providers and link them to the same user id.

gandalf.session()

Return a function that will create a session property of the request:

var session = gandalf.session()

router.addRoute('/api', function(req, res){
	session(req, res, function(){

		// we now have a session for the request
		req.session.get('userid', function(err, userid){

		})
	})
})

You can also pass a function to gandalf.session and it will be wrapped:

router.addRoute('/api', gandalf.session(function(req, res){
	//req.session is populated
}))

gandalf.handler()

Mount the authentication handler onto an endpoint of your application (for example on /auth).

You can then link to /auth/github to perform a github login or POST to /auth/register to register new accounts.

router.addRoute('/api', gandalf.handler())

The following are the routes that are mounted:

GET /PROVIDER

e.g. /google - this triggers the OAuth login loop for a provider

POST /register

post username and password and other fields to register a new user

{
	"username":"bob",
	"password":"123",
	"email":"[email protected]",
	"likes":"porridge"
}
POST /login

post username and password fields to login using the password method

{
	"username":"bob",
	"password":"123"
}
POST /claim

post a username to use for a connected user - use this when a user connects using an external service but you still need a username (as opposed to just an id)

{
	"username":"bob"
}
GET /logout

clear the session and redirect to '/'

GET /check?username=

check if the given username exists

GET /status

return a JSON representation of the current session - this includes OAuth tokens

gandalf.protect(function(req, appid, userid, done){})

Return a 403 error if the user is not logged in:

router.addRoute('/private', gandalf.protect(function(req, res){
	// the user is logged in
	// we also have req.session and req.userid
}))

If you do not pass a function then there just needs to be a user for access to be granted.

gandalf.delete(id, function(){})

Delete a user and all their details

gandalf.disconnect(id, provider, function(){})

Remove the connection details for 'provider' in the given user

events

gandalf.on('storage:put', function(key, value){})

When a value has been put to the database

gandalf.on('storage:batch', function(key, value){})

When a batch has been sent to the database

gandalf.on('request', function(req){})

A HTTP request has hit the handler

gandalf.on('provider', function(name, req){})

A HTTP request has hit a provider handler

gandalf.on('protect', function(req){})

A resource has been denied in a protect handler

gandalf.on('login', function(username){})

A login request

gandalf.on('register', function(username, body){})

A register request

gandalf.on('connect', function(provider, profile){})

A connect request

gandalf.on('save', function(id, provider, profile){})

A user profile has been created by provider

gandalf.on('claim', function(username){})

A claim request

gandalf.on('logout', function(req){})

A logout request

gandalf.on('log', function(type, message){})

gandalf.on('log:error', function(type, message){})

license

MIT