3.0.1 • Published 7 months ago

@donation-alerts/auth v3.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

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.

3.0.1

7 months ago

3.0.0

7 months ago

2.0.1

12 months ago

2.0.0

1 year ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

1.0.0-pre.9

2 years ago

1.0.0-pre.8

2 years ago

1.0.0-pre.7

2 years ago

1.0.0-pre.6

2 years ago

1.0.0-pre.5

2 years ago

1.0.0-pre.4

2 years ago

1.0.0-pre.3

2 years ago

1.0.0-pre.2

2 years ago

1.0.0-pre.1

2 years ago

1.0.0-pre.0

2 years ago