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

antisocial-auth

v1.0.3

Published

Social authentication for websites that don't provide any.

Downloads

8

Readme

antisocial-auth npm version

Social authentication for websites that don't provide any.

Overview

This project will both describe:

  1. a protocol to authenticate users from any website on your software, regardless they provide social authentication feature,
  2. a Node.js library to ease the implementation.

Protocol

An user wants to authenticate on your website with his example.com username.

  1. They fill a form with the username they want to authenticate with.

  2. You generates a nonce, and store it in some kind of session (like signed cookies) for this user, together with the username they want to authenticate.

  3. The user is then told to paste this "verification code" (the nonce) somewhere on example.com where they can easily be identified, that may be in a private message to a "bot" user you own, in teir profile description, or whatever is possible on the website.

  4. When the use is done, they confirm it to your website (optionally providing some data so you can easily find the key if it's not ovbious), which will search the expected location for the nonce.

  5. If the nonce is found, and it was effectively posted by the user in question, the user is a authenticated, and you can be sure they own the example.com account they claimed.

Also, note you could add some time limit to complete the authentication, for exmaple by storing the current time in session when the authentication request is made (when the nonce is generated), and checking it before verifying the nonce.

Library

Example with an Express web app.

// Default settings.
const auth = require('antisocial-auth')

// Extend settings.
const auth = require('antisocial-auth').extend({
  nonceSize: 256, // Change nonce size (default is 128).
  expirationTime: 1000 * 60 * 10, // Expire after 10 minutes (default is 2).
})

// example.com imaginary API/crawler.
const example = require('example')

const app = require('express')()
const then = require('express-then')

app.use(require('cookie-parser')('secret'))
app.set('views', __dirname + '/views')
app.set('view engine', 'whatever')

// Request user authentication.
app.get('/auth/:user', then(async (req, res) => {
  const user = req.param.user
  const nonce = await auth.generateNonce() // Generate nonce buffer.
  const nonce64 = nonce.toString('base64') // Can't set a buffer as JSON cookie.
  const beginTime = Date.now() // Store the time for later verification.

  res.cookie('auth', { user, nonce64, beginTime }, { httpOnly: true, signed: true })
  res.render('auth', { user, nonce: auth.beautify(nonce) })

  // `auth.beautify` will return something like this:
  //
  //     -----BEGIN AUTH-----
  //     1RZqcR7W+Z5itOuGVyEmIquYWpdMW92u
  //     rq4zbiUb4VhZIymJg4pQC4uLRHqcCqKk
  //     /06zQIt7Hf/j5ssElL+ZChkVlV6qoZxt
  //     M9dhXjoeYDkpG9BWXOnb7EsNWQiWsoYY
  //     GM9ApEoVFX34DZ8eSVa9TWLOZ0yKK/xf
  //     aEHXsz8qJHk=
  //     -----END AUTH-----
  //
  // The user is supposed to paste it somewhere on his example.com
  // account, like in a private message to a bot you own, or his profile
  // description.
}))

// Verify authentication.
app.get('/auth/:user/confirm', then(async (req, res) => {
  const { user, nonce64, beginTime } = req.signedCookies.auth
  const nonce = new Buffer(nonce64, 'base64')

  // Bad request.
  if (user !== req.params.user) {
    return res.status(400).end()
  }

  // Authentication timeout expired.
  if (!auth.checkTime(beginTime)) {
    return res.status(401).end()
  }

  // Get (for example) user profile description.
  const { desc } = await example.getProfile(user)

  // Search for authentication tags and parse wrapped content.
  const buffer = auth.uglify(desc)

  // Failed authentication.
  if (!nonce.equals(buffer)) {
    return res.status(401).end()
  }

  // The user is authenticated!
  res.cookie('user', user, { httpOnly: true, signed: true })
  res.clearCookie('auth')
  res.redirect('/')
}))

// Regular page.
app.get('/', (req, res) => {
  if (req.signedCookies.user) {
    // The user is authenticated.
  }

  // ...
})

Example

See jvc-auth for a practical usage example.