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

device-auth

v1.2.3

Published

A simple library for authenticating with just one click, and it's more secure than a password!

Downloads

31

Readme

device-auth

Device-Auth is a simple library that allows you to authenticate users on both the browser and server side.

Demo

https://github.com/zlenner/device-auth/assets/119705166/b8bba30f-ee0e-4a87-b2c7-81f255142b34

Here!

This demo uses an in-browser mock server to complete the sign-in, and stores the returned access token in your localStorage.

Installation

To install the library, run the following command:

npm install device-auth

Quickstart

(1) Issue a challenge in the server.

BROWSER:

const challenge = await fetchJsonFromServer.get("/issue_challenge")

SERVER: Create one instance of DeviceAuth per server, and a route to issue a challenge.

import { server } from "device-auth"

device_auth = new server.DeviceAuth()

// Whatever your app is, express fastify etc.
app.get("/issue_challenge", async () => {
  return device_auth.issue_challenge()
})

(2) Use the authenticate_or_register function, which takes a challenge as an argument and registers a user. If already registered, the function will authenticate the user instead.

BROWSER:

import { browser } from "device-auth"

const payload = await browser.authenticate_or_register(challenge)

NOTE: On incognito, or if the user has cleared their localStorage, this will register a new user, but the previous user will still be available for sign-in after a new user has been registered.

(3) Send the payload to the server to complete the sign-in and get a token back.

BROWSER:

const token = await fetchJsonFromServer.post("/verify", payload)

SERVER:

If the payload.type == authenticate, we'll fetch the credential from our database and use the verify_authentication method.

If the payload.type == register, we'll use the verify_registration method.

Either way, the server should respond with a token if the authentication/registration was successful.

const access_tokens: string[] = []

app.post("/verify", async (request) => {
  const payload = request.body
  if (payload.type == "authenticate") {
    const credential = await database.get(payload.credential_id)
    await device_auth.verify_authentication(payload, credential)
  
  } else if (payload.type == "register") {
    await device_auth.verify_registration(payload)
    await database.store(payload.credential_id, payload.credential)
  }
  // If the code didn't throw an error by now, sign-in succeeded!

  // Generate a token and return it to the client.
  // Use something more secure than this on your app!
  const token = Math.random().toString(36)
  access_tokens.push(token)

  return token
})

(4) You're a member of the app (club)! You now have access to all the secrets of the club :D

BROWSER:

const secret_thing = await fetchJsonFromServer.post("/get-secret-thing", { token })

SERVER:

app.post("/get-secret-thing", async (request) => {
  if (!access_tokens.includes(request.body.token)) {
    throw new Error("You don't have access!!!")
  }
  // Woosh, this request was made by a member of the club.

  return "Psst, the secret is ____________"
})

Full documentation

The Quickstart is what most people will need. There are more functions available which you can check out through the typescript auto-complete.

Known issues

  1. An attacker can issue infinite challenges until the memory overflows and the app crashes. Can be somewhat mitigated with IP rate-limiting.