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

@donation-alerts/auth

v3.0.1

Published

Authentication provider for Donation Alerts API with ability to automatically refresh user tokens.

Downloads

34

Readme

Donation Alerts - Authentication

Authentication provider with ability to automatically refresh user tokens.

Installation

Using npm:

npm i @donation-alerts/auth

Using yarn:

yarn add @donation-alerts/auth

Usage

Authentication provider

Authentication provider is a class that implements the AuthProvider interface. In general, it allows users to register and manage authenticated users and their authentication data (access tokens, refresh tokens, etc.).

There are two built-in authentication providers you can use: StaticAuthProvider and RefreshingAuthProvider.

If these implementations do not meet your needs, and, for example, you need to share authentication data across multiple processes, you can create your own provider (e.g., based on Redis) that implements the AuthProvider interface.

First of all, you must register your application in Donation Alerts and obtain a client ID and a client secret key. Read more here in the Authorization section.

Static authentication provider

The StaticAuthProvider allows to register users with their credentials in the internal registry and allows to get the access tokens of the registered users. However, this provider is not able to refresh user tokens on expiration.

To instantiate the StaticAuthProvider you must specify the application client ID.

import { StaticAuthProvider } from '@donation-alerts/auth';

const authProvider = new StaticAuthProvider('<CLIENT_ID>');

Optionally, you can provide an array of scopes that all registering tokens must be valid for.

const authProvider = new StaticAuthUser('<CLIENT_ID>', ['oauth-user-show', 'oauth-donation-index']);

If the registering token misses any scope from this list, MissingScopeError exception will be thrown.

If scopes were not specified for the registering token, scope validation will be skipped.

It's also recommended to set scopes for each added token. In this case, the library will compare the requested scopes against the token scopes.

Managing users in static authentication provider

To manage users in the StaticAuthProvider, you can use hasUser, addUser, and removeUser methods.

hasUser

Checks whether a user is added to the provider.

const hasUser = authProvider.hasUser(123456789);

Returns boolean.

addUser

Adds a user to the provider. The first argument is the ID of the user, the second is authentication data that includes accessToken and optional scopes.

authProvider.addUser(123456789, {
	accessToken: '<ACCESS_TOKEN>',
	scopes: ['oauth-user-show', 'oauth-donation-index', 'oauth-custom_alert-store']
});

removeUser

Removes a user from the provider.

authProvider.removeUser(123456789);

Getting tokens from the static authentication provider

After user registration, you can use the getAccessTokenForUser method to get the access token for the specified user.

const token = await authProvider.getAccessTokenForUser(123456789);

This method also optionally takes requested scopes as the second scopes?: string[] argument. If scopes are provided, the library checks whether the access token is valid for the requested scopes. If the check fails, the MissingScopeError will be thrown.

// Add token with 'oauth-user-show' and 'oauth-donation-index' scopes
authProvider.addUser(123456789, {
	accessToken: '<ACCESS_TOKEN>',
	scopes: ['oauth-user-show', 'oauth-donation-index']
});

// Throws 'MissingScopeError' because the token
// is not valid for 'oauth-custom_alert-store' scope
const token = await authProvider.getAccessTokenForUser(123456789, ['oauth-custom_alert-store']);

Returns AccessTokenWithUserId object.

Refreshing authentication provider

Unlike StaticAuthProvider, RefreshingAuthProvider has an ability to automatically refresh user tokens whether necessary.

To instantiate a RefreshingAuthProvider you must set up RefreshingAuthProviderConfig.

  • clientId - Donation Alerts application's client ID
  • clientSecret - Donation Alerts application's client secret
  • redirectUri (optional) - Donation Alerts application's redirect URI. Only used in addAuthForCode method to exchange an authorization code for an access token.
  • scopes (optional) - an array of scopes that all registering tokens must be valid for.
import { RefreshingAuthProvider } from '@donation-alerts/auth';

const authProvider = new RefreshingAuthProvider({
	clientId: '<CLIENT_ID>',
	clientSecret: '<CLIENT_SECRET>',
	redirectUri: '<REDIRECT_URI>',
	scopes: ['oauth-user-show', 'oauth-donation-index', 'oauth-custom_alert-store']
});

Managing users in refreshing authentication provider

hasUser

Checks whether a user was added to the provider.

const hasUser = authProvider.hasUser(123456789);

Returns boolean.

addUser

Adds a user to the provider:

const userId = 123456789;
authProvider.addUser(userId, {
	accessToken: '<ACCESS_TOKEN>',
	refreshToken: '<REFRESH_TOKEN>',
	expiresIn: 0,
	obtainmentTimestamp: 0,
	scopes: ['oauth-user-show', 'oauth-donation-index', 'oauth-custom_alert-store']
});

[!NOTE] Both aceessToken and refreshToken must be non-empty strings. Otherwise, InvalidTokenError will be thrown.

If expiresIn and obtainmentTimestamp are unknown, you can set them both to 0 to force refresh the token on the first access.

Also keep in mind that there is actually no way to dynamically figure out scopes the token is valid for, so if you need scope validation, you have to set valid scopes for the token when you are adding it to the provider. The right approach would be to persist the token with its valid scopes and obtainment timestamp in the database (or any other persistent storage) after the authentication flow.

addUserForToken

You can also add a user to the auth provider with only token data:

const tokenWithUserId = await authProvider.addUserForToken({
	accessToken: '<ACCESS_TOKEN>',
	refreshToken: '<REFRESH_TOKEN>',
	expiresIn: 0,
	obtainmentTimestamp: 0,
	scopes: ['oauth-user-show', 'oauth-donation-index', 'oauth-custom_alert-store']
});

The ID of the user will be fetched internally followed by adding it to the provider with the given token data.

Returns AccessTokenWithUserId object.

[!WARNING] The token must be valid for oauth-user-show scope to fetch the user data. Otherwise, the MissingScopeError exception will be thrown.

addUserForCode

Another option to add a user to the provider is using an authorization code received during the OAuth2 authorization flow.

const tokenWithUserId = await authProvider.addUserForCode('<AUTH_CODE>', [
	'oauth-user-show',
	'oauth-donation-index',
	'oauth-custom_alert-store'
]);

addUserForCode method accepts token scopes as the second argument. They will be compared against the provider's scopes (if any) as described above.

This method exchanges the code for the access token, followed by getting the user associated with the token and adding it to the auth provider.

[!WARNING] The token must be valid for oauth-user-show scope to fetch the user data. Otherwise, the MissingScopeError exception will be thrown.

Returns AccessTokenWithUserId object.

removeUser

Removes the specified user ID from the auth provider.

authProvider.removeUser(123456789);

Managing tokens in refreshing authentication provider

Now let's move on to what we started all this for.

getAccessTokenForUser

You can get the user's access token by calling the getAccessTokenForUser method. If the token has expired, it will be refreshed internally by the provider, and a new one will be returned.

const token = await authProvider.getAccessTokenForUser(12345678);

Returns AccessTokenWithUserId object.

refreshAccessTokenForUser

If for some reason you need to force refresh the access token, you can call refreshAccessTokenForUsermethod:

const token = await authProvider.refreshAccessTokenForUser(12345678);

Returns AccessTokenWithUserId object.

Events

When an access token is refreshed, whether internally or externally, onRefresh event occurs. You can listen to it, for example, to save the token to a persistence storage.

import { AccessToken } from '@donation-alerts/auth';

authProvider.onRefresh((userId: number, token: AccessToken) => {
	console.log(`The access token was refreshed for user ${userId}`);
});

Check the StaticAuthProvider and RefreshingAuthProvider documentation pages to see the full list of available properties and methods.


For more information check the documentation.