# Koa Integration

Follow this guide if you're integrating @211la/cs-sso-client into a Koa application.

# Prepare your app

To use this package, you'll need to install koa-session. That's because the SSO authentication uses sessions to identify users.

To install koa-session, run the following commands at the root of your Koa project.

npm i koa-session

# Optional (For Typescript)
npm i -D @types/koa-session

You'll need to register koa-session as a middleware. To do that, go where you're initializing your Koa app. In this tutorial, we'll assume it's in main.ts.

// main.ts
import Koa from 'koa';
import * as session from 'koa-session';
// ...

const app = new Koa();

app.use(
  session(
    {
      /* Session config goes here... */
    },
    app,
  ),
);

// .. The rest of the file

WARNING

🚨 This is not a production ready example. To properly configure koa-sesssion, please consult the official package docs.

Further reading:

# Register the Client

// main.ts
import Koa from 'koa';
import Router from 'koa-router';
import * as session from 'koa-session';
import { SsoClient } from ' @211la/cs-sso-client/koa';
// ..

const app = new Koa();
app.use(session(/* ... */));

// This is your app's router
const router = new Router();
// .. Register your routes

const sso = new SsoClient({
  // Be sure to provide the correct app definition id defined in 
  // 211CS Admin. You can omit this if you are using 211CS Resolution
  // Service.
  appDefinitionId: 'your app definition id goes here',
  /* The rest of the config  */
});

// Pass your app router to SsoClient, then pass that to app.use like this:
app.use(sso.routes(router));

// ⛔ DON'T pass app's router to app.use directly.
// app.use(router.routes());

// .. The rest of the file

The following routes will now be available on your Koa app:

  • /sso/login Redirects the user to CS SSO login flow.
  • /sso/logout Terminates the current SSO session.
  • /sso/callback Handles the callback from SSO service and starts a session in your app.

# Protect Endpoints (Guard)

When you want to prevent unathenticated requests to certain endpoints, simply use the requireAuth middleware to get the job done.

import { requireAuth } from '@211la/cs-sso-client/koa';

router.get('/protected', requireAuth(), async (ctx, next) => {
  // User is authenticated.
  next();
});

# Access Current User

Another common requirement is to access the currently authenticated user (Nexus profile). You can access that through ctx.state.sso.user.

import { requireAuth } from '@211la/cs-sso-client/koa';

router.get('/protected', requireAuth(), async (ctx, next) => {
  console.log(ctx.state.sso.user); // { profile...}
  next();
});

# Verify Session

Once the SSO handshake is complete, your app will have a local session.

If the user signs out of Caresuite from a different service or if the Nexus211 Access token expires, the local session will still be valid for your app until it expires. Therefore, you need to verify that the session is still active periodically.

Server-side rendered apps should run this check on every page load, and for Single page applications can run this check while fetching the current user.

router.get('/me', requireAuth(), async (ctx, next) => {
  const sessionAlive = await ctx.state.sso.user.verifySession();

  if (!sessionAlive) {
    ctx.status = 401;
    ctx.body = {'error': 'Unauthorized'};
    return next();
  }

  ctx.body = {
    id: user.id,
    name: user.name,
    email: user.email,
    organization: user.organization,
  };

  return next();
});