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

@usher.so/auth

v0.0.6

Published

Usher Auth is a package that contains all of the authentication processes required to interface with Ceramic and with Usher's APIs.

Downloads

6

Readme

@usher.so/auth

Usher Auth is a package that contains all of the authentication processes required to interface with Ceramic and with Usher's APIs.

Features

Wallet Abstraction

The Usher Auth module abstracts authentication with different wallets and authentication methods.
During authentication, a unique DID is produced deterministically dependent on the authentication method.
Authentication methods supported:

  • Metamask
  • Coinbase Wallet
  • Wallet Connect
  • Magic SDK
  • Arweave (JWK) compatibile wallets

Authentication

import { Connections } from "@usher.so/shared";

const authInstance = new Authenticate(arweave, ethProvider);

await authInstance.withEthereum(
	wallet.accounts[0].address,
	Connections.METAMASK
);
const ethAuth = authInstance.getAuth(wallet.accounts[0].address);

// Print DID for this Auth
console.log(ethAuth.did.id);

Auth Tokens for API usage

By generating a unique DID for each specific authentication, there is now a collection of authentications that represent the same user.
Each DID exposes the same interface for using cryptography to identify the underlying authentication/user.
A token can be generated using this collection of authentications to uniquely indetify the user inside of a backend stateless environment. ie. a centralised serverless API handler.
An API can then intelligently store each unqiue DID in relation to each other, ideally in a graph, to produce a profile of a user based on their authentication methods.

Generating an Auth Token

import { Connections } from "@usher.so/shared";

const authInstance = new Authenticate(arweave, ethProvider);

await authInstance.withEthereum(
	wallet.accounts[0].address,
	Connections.METAMASK
);
await authInstance.withArweave(
	arweaveWalletAddress,
	Connections.ARCONNECT,
	arConnect // window.arweaveWallet
);

// Print DID for this Auth
const token = await authInstance.getAuthToken();
console.log(token);

Validating an Auth Token

The following example illustrates Auth Token validation inside of an Express.js Middleware/Handler.

import { Base64 } from "js-base64";
import { DagJWS, DID } from "dids";
import { getResolver as getKeyResolver } from "key-did-resolver";

const verify = async (did: string, sig: DagJWS): Promise<boolean> => {
	const instance = new DID({
		resolver: {
			...getKeyResolver(),
		},
	});
	const result = await instance.verifyJWS(sig, { issuer: did });
	if (result.kid) {
		return true;
	}

	return false;
};

// --- Inside of Express.js handler
let payload;
try {
	payload = JSON.parse(Base64.decode(req.token));
} catch (e) {
	req.log.debug("Failed to parse token");
	return res.status(403).json({
		success: false,
	});
}

// Payload is an array of dids and their respective signature
try {
	const user = (
		await Promise.all(
			payload.map(
				async ([did, sig, wallet]: [string, DagJWS, string[] | undefined]) => {
					try {
						const instance = new DID({
							resolver: {
								...getKeyResolver(),
							},
						});
						const result = await instance.verifyJWS(sig, { issuer: did });
						const verified = !!result.kid;
						if (verified) {
							return {
								did,
								wallet: wallet
									? {
											chain: wallet[0],
											address: wallet[1],
									  }
									: null,
							};
						}
					} catch (e) {
						//* This will fail if the Signature Payload includes sepcial characters
						req.log.debug(
							{ error: e, did, sig, wallet },
							"Cannot verify JWS for DID"
						);
					}
					return null;
				}
			)
		)
	).filter((did) => typeof did !== null && !isEmpty(did));

	if (user.length === 0) {
		req.log.debug("No user loaded");
		return res.status(403).json({
			success: false,
		});
	}

	req.user = user;

	// Perform some logic on the user

	return next();
} catch (e) {
	req.log.error(e);
	return res.status(403).json({
		success: false,
	});
}

📕 Documentation

Troubleshooting