"Invotastic for Business" is a multi-tenant demo app that serves other companies as its customers. This repo utilizes a "Backend Server" OAuth2 client type. The backend server technology here is NodeJS along with the ExpressJS web application framework. NodeJS hosts and serves up a React single-page application to the browser upon request.
Disclaimer: Invotastic for Business is not a real-world application and cannot be used to send invoices to real people.
Below is a quick overview of how Invotastic for Business looks behind the scenes and how it interacts with Wristband.
The entity model starts at the top with an application that encapsulates everything related to Invotastic for Business. The application has the Wristband identity provider enabled by default so that all users can login with an email and a password. The application has one OAuth2 client through which users will be authenticated. In this case, the client is a NodeJS server with Express.
Companies that signup with Invotastic for Business will be provisioned a tenant under the application (1 company = 1 tenant). When a new user signs up their company, they are assigned the "Owner" role by default and have full access to their company resources. Owners of a company can also invite new users into their company. Invited users can be assigned either the "Owner" role or the "Viewer" role. A user that is assigned the "Viewer" role can't perform the following operations:
- Create new invoices
- Cancel invoices
- Update company information
- Invite admins
The Invotastic for Business application in this repository utilizes the Backend for Frontend (BFF) pattern. The NodeJS server with Express is the backend for the React single-page app frontend. The server is responsible for:
- Storing the client ID and secret.
- Handling the OAuth2 authorization code flow redirections to and from Wristband during user login.
- Creating the application session cookie to be sent back to the browser upon successful login. The application session cookie contains the access and refresh tokens as well as some basic user info.
- Refreshing the access token if the access token is expired.
- Orchestrating all API calls from the React frontend to both Wristband and the Invotastic backend data store.
- Destroying the application session cookie and revoking the refresh token when a user logs out.
API calls made from React to NodeJS pass along the application session cookie and a CSRF token with every request. The server has three middlewares for all protected routes responsbile for:
- Validating and refreshing the access token (if necessary)
- "Touching" the application session cookie
- Validating the CSRF token
For any Invotastic-specific APIs (i.e. invoice APIs), the server will perform an authorization check before processing the API request by checking against the permissions assigned to the session user's role.
It is also important to note that Wristband hosts all onboarding workflow pages (signup, login, etc), and the NodeJS server will redirect to Wristband in order to show users those pages.
Within the demo app code base, you can search in your IDE of choice for the text WRISTBAND_TOUCHPOINT
. This will show the various places in both the React frontend code and NodeJS backend code where Wristband is involved. You will find the search results return one of a few possible comments using that search text:
/* WRISTBAND_TOUCHPOINT - AUTHENTICATION */
- Code that deals with an authenticated user's application session. This includes managing their application session cookie and JWTs, OAuth2-related endpoints for login/callback/logout, NodeJS middleware for validating/refreshing tokens, and React context used to check if the user is authenticated./* WRISTBAND_TOUCHPOINT - AUTHORIZATION */
- Code that checks whether a user has the required permissions to interact with Invotastic-specific resource APIs or can access certain application functionality in the UI./* WRISTBAND_TOUCHPOINT - RESOURCE API */
- Code that interacts with any Wristband-specific resource APIs or workflow APIs that are not related to authentication or authorization directly. For example, it could be an API call to update the user's profile or change their password.
There are also some visual cues in the Invotastic for Business UI that indicate if certain forms or buttons will trigger the execution of code that runs through any of the touchpoint categories above. For example, if we look at the Invite Admins UI:
Submitting the form to invite another admin into your company will ultimately trigger an API call to Wristband to peform the Invite New User workflow, and thus would execute code in the category of WRISTBAND_TOUCHPOINT - RESOURCE API
.
You can start up the Invotastic for Business demo application in a few simple steps.
First thing is first: make sure you sign up for an Wristband account at https://wristband.dev.
After your Wristband account is set up, log in to the Wristband dashboard. Once you land on the home page of the dashboard, click the button labelled "Add Demo App". Make sure you choose the following options:
- Step 1: App Type - B2B
- Step 2: Client Framework - Express
- Step 3: Domain Format - Choosing
Localhost
is fastest to setup. You can alternatively chooseVanity Domain
if you want a production-like experience on your local machine for tenant-specific vanity domains, but this method will require additional setup.
Upon completing the demo application setup, you will be prompted with values that you should copy into the environment variable configuration for this demo repository, which is located in server/.env
. Replace the following values:
APPLICATION_DOMAIN
DOMAIN_FORMAT
CLIENT_ID
CLIENT_SECRET
Make sure you are in the root directory of this repository.
Now install all dependencies for both the React client application and the NodeJS server:
npm run install-all
Next, build the React asset bundle that will be served up by NodeJS (asset bundle target location is server/dist/
):
npm run build
Start up the NodeJS server in "production" mode. This lets NodeJS serve the React bundle as static content from the NodeJS server. The NodeJS server runs on port 6001
.
npm start
Now that Invotastic for Business is up and running, you can sign up your first customer on the Invotastic for Business Signup Page at the following location:
http://{application_vanity_domain}/signup
, where{application_vanity_domain}
should be replaced with the value of the "Application Vanity Domain" value of the Invotastic for Business application (can be found in the Wristband Dashboard by clicking the Application Details side menu of this app).
This signup page is hosted by Wristband. Completing the signup form will provision both a new tenant with the specified tenant domain name and a new user that is assigned to that tenant.
For reference, the home page of this Inovtastic for Business app can be accessed at the following locations:
- Localhost domain format: http://localhost:6001/home
- Vanity domain format: http://{tenant_domain}.business.invotastic.com:6001/home, where
{tenant_domain}
should be replaced with the value of the desired tenant's domain name.
Users of Invotastic for Business can access the Invotastic for Business Application-level Login Page at the following location:
http://{application_vanity_domain}/login
, where{application_vanity_domain}
should be replaced with the value of the "Application Vanity Domain" value of the Invotastic for Business application (can be found in the Wristband Dashboard by clicking the Application Details side menu of this app).
This login page is hosted by Wristband. Here, the user will be prompted to enter their tenant's domain name for which they want to log in to. Successfully entering the tenant domain name will redirect the user to the tenant-level login page for their specific tenant.
Users also have the option here to execute the Forgot Tenant workflow and entering their email address in order to receive a list of all tenants that they belong to.
If users wish to directly access the Invotastic Tenant-level Login Page without having to go through the application-level login, they can do so at the following locations:
- Localhost domain format: http://localhost:6001/api/auth/login?tenant_domain={tenant_domain}, where
{tenant_domain}
should be replaced with the value of the desired tenant's domain name. - Vanity domain format: http://{tenant_domain}.business.invotastic.com:6001/api/auth/login, where
{tenant_domain}
should be replaced with the value of the desired tenant's domain name.
This login page is hosted by Wristband. Here, the user will be prompted to enter their credentials in order to login to the application.
You can run this demo application in "dev" mode in order to actively debug or experiment with any of the code. This will require starting up the React client application in a separate CLI from the NodeJS server. All API calls made from React to NodeJS are configured to be proxied in order to avoid CORS issues.
In one CLI, change to the client
directory and run the following to start Create React App's Webpack dev server (runs on port 6001
):
npm start
In a second separate CLI, change to the server
directory and run the following to start the NodeJS server in "dev" mode (runs on port 3001
):
npm run dev
All Invotastic URL locations should remain the same as when using the app in "production" mode.
If you choose to use vanity domains as the domain format for the demo application, you will need to install a local DNS server to provide custom configurations. This configuration forces any requests made to domains ending with .business.invotastic.com
to get routed to your localhost. This configuration is necessary since all vanity domains that get generated when running the demo application locally will have a domain suffix of *.business.invotastic.com
. Therefore, the above setting will force those domains to resolve back to your local machine instead of attempting to route them out to the web.
The goal is the following mapping:
business.invotastic.com
=> 127.0.0.1
.
Here are some options which you can use, depending on your operating system:
More to setup-specific instructions to come...