Typescript Example
Let's walk through an example of how to leverage Satosa libraries with typescript. In this example, we will create a fastify application in node with some middleware to check if a user has acknowledged the latest terms of service.
Install the typescript client
Install the Satosa typescript client npm package.
npm install @satosa/client
Create a basic web app
Let's start by installing fastify and creating an entrypoint for our application.
npm install fastify
// index.ts
import Fastify from 'fastify';
const fastify = Fastify({
logger: true
});
fastify.get('/', function (request, reply) {
reply.send({ hello: 'world' });
});
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
Adding middleware
In this example, we will create middleware for our application that interacts with Satosa's API. To do so, we will need to add the following to use middleware with fastify:
npm install @fastify/express
// index.ts
import Fastify from 'fastify';
import express from '@fastify/express';
const fastify = Fastify({
logger: true
});
fastify.register(express).then(() => {
fastify.get('/', function (request, reply) {
reply.send({ hello: 'world' });
});
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
});
Environment Variables
We'll need to expose three parameters before we can start using the Satosa client:
Organization and document ID
Navigate to the Terms of Service in your Satosa dashboard and copy the link from the Preview button. You should have a URL that looks like this:
https://dashboard.satosa.com/organizations/01H5Z9ADASV2Q94V0TX5437X92/documents/01H5Z9QE7YZYQ7YMEJMYPXBE5M?revisionId=2&returnUrl=https%3A%2F%2Fdashboard.satosa.com%2Fdocuments%2F01H5Z9QE7YZYQ7YMEJMYPXBE5M%2Frevisions%2F2
Export the following variables from the link you copied:
export SATOSA_ORGANIZATION_ID=01H5Z9ADASV2Q94V0TX5437X92
export SATOSA_DOCUMENT_ID=01H5Z9QE7YZYQ7YMEJMYPXBE5M
API Access
To gain access to the Satosa API, you will need an API key. Begin by navigating to the developers dashboard in Satosa and clicking Create API Key. We'll name it something like "WebApp" so we know what it's being used for. Copy and export the variable.
export SATOSA_API_KEY=48E35905ACC91366A23FB3633DA9BFF92E1B7E6C5B1ADEEAD5DD20DA170FE200
Create the middleware
Let's create the middleware to check if the logged in user has acknowledged the terms of service, and if not, redirect to the hosted document page. To do so, we need to write some logic that follows these steps:
- Get the published revision number for our terms of service document.
- Check if the user has interacted with that revision.
- Note: We'll just use a query parameter to simulate the logged in user.
- If not, create a session with that user's properties.
- Redirect the request to the hosted document page for the client to redirect to.
import Fastify from 'fastify';
import express from '@fastify/express';
import { InteractionsApi, SessionsApi, DocumentsApi, Configuration } from '@satosa/client';
const fastify = Fastify({
logger: true
});
fastify.register(express).then(() => {
fastify.use(async (req, res, next) => {
const satosaConfig = new Configuration({
apiKey: process.env.SATOSA_API_KEY,
});
const documentService = new DocumentsApi(satosaConfig);
const interactionService = new InteractionsApi(satosaConfig);
const sessionService = new SessionsApi(satosaConfig);
const satosaDocument = await documentService.getDocument({ documentId: process.env.SATOSA_DOCUMENT_ID });
const userInteraction = await interactionService.listInteractions({
userKey: req.query.userKey, // simulated user
documentId: satosaDocument.id,
revisionId: satosaDocument.publishedRevision,
});
if (userInteraction.items.length > 0) return next(); // user has already acknowledged
const session = await sessionService.createSession({
createSessionRequest: { userKey: req.query.userKey },
});
const callbackUrl = new URL(`https://dashboard.satosa.com/organizations/${process.env.SATOSA_ORGANIZATION_ID}/documents/${process.env.SATOSA_DOCUMENT_ID}`);
callbackUrl.searchParams.set('callbackUrl', req.protocol + '://' + req.get('host') + req.originalUrl);
callbackUrl.searchParams.set('sessionId', session.id);
res.redirect(callbackUrl.toString());
});
fastify.get('/', function (request, reply) {
reply.send({ hello: 'world' });
});
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
});
Calling the endpoint
To run our example web app, run the following script to complie the typescript and start the server.
npx tsc --skipLibCheck index.ts && node index
Now when we ping our service, the middlware should check if the user has acknowledged the terms of service, and if not, redirect them to the hosted document page.
$ curl 'http://localhost:3000?userKey=someuserkey'
Found. Redirecting to https://dashboard.satosa.com/organizations/01H5Z9ADASV2Q94V0TX5437X92/documents/01H5Z9QE7YZYQ7YMEJMYPXBE5M?callbackUrl=http%3A%2F%2Flocalhost%3A3001%2F%3FuserKey%3Dsomeuserkey&sessionId=01H5ZV8P3E1NWHFMCW6J5DNQE6