1. Integrate your backend
  2. Node Backend Integration

For the full Node Library Reference, click here. This library is useful if you are in a pure node environment, like AWS Lambda. If you are using a framework like Express, you should prefer to use our Express library.

Quick example

The following example validates an Authorization HTTP header was sent from a logged-in user.

const propelAuth = require("@propelauth/node");
const { validateAccessTokenAndGetUser } = propelAuth.initBaseAuth({
  // You can find your Auth URL and API key under the Backend Integration
  //   section for your project at https://app.propelauth.com.
  authUrl: "YOUR_AUTH_URL",
  apiKey: "YOUR_API_KEY",
});

const authorizationHeader = // Get the Authorization header from an HTTP request
validateAccessTokenAndGetUser(authorizationHeader).then(
  (user) => {
    console.log(`Got request from user ${user.userId}`);
  },
  (err) => {
    // You can return a 401, or continue the request knowing it wasn't sent from a logged-in user
    console.log(`Unauthorized request ${err}`);
  }
);

How it works

For a detailed description of what’s going on under the hood, see here.

Installation

In your Node app, install the @propelauth/node library.

$ npm install --save @propelauth/node

Initialize

In a new file, add the following:

// propelauth.js
const propelAuth = require("@propelauth/node");
module.exports = propelAuth.initBaseAuth({
  authUrl: "https://auth.yourdomain.com",
  apiKey: "YOUR_API_KEY",
});

initBaseAuth performs a one-time initialization of the library. It will verify your apiKey is correct and fetch the metadata needed to verify access tokens in validateAccessTokenAndGetUser and validateAccessTokenAndGetUserWithOrgInfo.

Protect API routes

validateAccessTokenAndGetUser

This function takes in the Authorization HTTP header and verifies the request was made by a valid user. It expects the header to be in the format Bearer ACCESS_TOKEN. If the Authorization HTTP header is malformed or doesn’t contain a valid access token, an UnauthorizedException is thrown.

const authorizationHeader = // Get the Authorization header from an HTTP request
try {
    const user = await validateAccessTokenAndGetUser(authorizationHeader)
    console.log(`Got request from user ${user.userId}`);
} catch (err) {
    // You can return a 401, or continue the request knowing it wasn't sent from a logged-in user
    console.log(`Unauthorized request ${err}`);
}

The user object looks like:

PropertyDescription
userIdThe id of the user
orgIdToOrgMemberInfoA dictionary of org ids to metadata about the org. Includes all orgs that the user is in
legacyUserIdThe original ID of the user, if the user was migrated from an external source

The values of orgIdToOrgMemberInfo are OrgMemberInfo’s, with the following fields/functions:

FieldDescription
orgIdThe id of the org
orgNameThe name of the org
urlSafeOrgNameA URL-safe version of the name of the org
assignedRole(): stringThe user’s role within the organization. See Roles and Permissions for more details.
permissions(): string[]The user’s permissions within the organization. See Roles and Permissions
isRole(role: string): booleanReturns True if the user’s role within the organization matches the role passed in
isAtLeastRole(role: string): booleanReturns True if the user’s role within the organization is at least the role passed in. If the hierarchy of roles is Owner => Admin => Member, specifying “Admin” will return True for Admins and Owners, but False for Members.
hasPermission(permission: string): booleanReturns True if the user has a specific permission. The users’ permissions are derived from their role within this organization.
hasAllPermissions(permissions: string[]): booleanReturns True if the user has all the specified permissions. The users’ permissions are derived from their role within this organization.

validateAccessTokenAndGetUserWithOrgInfo

This function will verify that a request was made by a valid user AND that user is in an organization.

ArgumentDescription
Authorization HTTP HeaderIt expects the header to be in the format Bearer ACCESS_TOKEN. If the Authorization HTTP header is malformed or doesn’t contain a valid access token, an UnauthorizedException is thrown.
Required Org InfoAn object with optional fields orgId and orgName. This function will make sure the user who made the request is a member of an organization with the specified orgId and orgName. If the user is NOT a member of the specified organization, a ForbiddenException is thrown.

It returns an object with two fields:

{
    user: //...
    orgMemberInfo: //...
}

You can see the structure of the user and orgMemberInfo objects above: validateAccessTokenAndGetUser.

Roles and Permissions

A user has a Role within an organization. By default, the available roles are Owner, Admin, or Member, but these can be configured. These roles are also hierarchical, so Owner > Admin > Member.

Roles allow you to control what different users can do within your product. If you want to check a user’s role, you can use validateAccessTokenAndGetUserWithOrgInfoWithExactRole or validateAccessTokenAndGetUserWithOrgInfoWithMinimumRole.

Permissions are arbitrary strings associated with a role. For example, can_view_billing, ProductA::CanCreate, and ReadOnly are all valid permissions. The PropelAuth dashboard allows you to set up these permissions.

You can use validateAccessTokenAndGetUserWithOrgInfoWithPermission or validateAccessTokenAndGetUserWithOrgInfoWithAllPermissions to check for a given permission.

All of these functions, just like validateAccessTokenAndGetUserWithOrgInfo, will take in an authorization header and an organization ID. The last parameter is either a role, permission, or list of permissions depending on the function.

API calls

In addition to protecting API routes, you can make requests to PropelAuth to fetch more information about your users or organizations. You can also create new users, update user metadata, and more.

// Example
const usersResponse = await fetchUsersByQuery({
  emailOrUsername: "@example.com",
  orderBy: "LAST_ACTIVE_AT_DESC",
});
for (const user of userResponse.users) {
  console.log("Found user " + user);
}

See Node Library Reference for more information on available functionality.

Next Steps

Done with your backend? Next you can deploy to production.