server/middleware/oktaServerSideAuthMiddleware.ts (66 lines of code) (raw):

import type { NextFunction, Request, Response } from 'express'; import { clearIdentityLocalState, getIdentityLocalState, setIdentityLocalState, } from '@/server/identityLocalState'; import { OAuthAccessTokenCookieName } from '@/server/oauthConfig'; import { validateWithOkta } from '@/server/okta'; import { getConfig as getOktaConfig } from '@/server/oktaConfig'; import { requiresSignin } from '@/shared/requiresSignin'; import { log } from '../log'; declare const CYPRESS: string; export interface OktaValidationResponse { ok: boolean; valid: boolean; userId?: string; displayName?: string; email?: string; } export const withOktaServerSideValidation = async ( req: Request, res: Response, next: NextFunction, ) => { if (CYPRESS === 'SKIP_IDAPI') { return next(); } const oktaConfig = await getOktaConfig(); if (!oktaConfig.useOkta) { /** * OKTA NOT ENABLED * * If Okta is disabled, we will still run this middleware, but * it won't be able to do anything so we just pass through. */ return next(); } const signinRequired = requiresSignin(req.originalUrl); const locallyValidatedIdentityData = getIdentityLocalState(res); const accessToken = req.signedCookies[OAuthAccessTokenCookieName]; if (!accessToken || !locallyValidatedIdentityData?.userId) { if (signinRequired) { /** * NO TOKEN OR USER - SIGN IN REQUIRED * * This is unexpected and should be impossible because the withIdentity * middleware should have run first and not allowed the request to get * here. Return a 500. */ log.error( `OAuth / Serverside Validation Middleware / Error: no access token or user in request for a sign-in required endpoint! This should have failed local validation.`, ); return res.sendStatus(500); } else { /** * NO TOKEN OR USER - SIGN IN NOT REQUIRED * * This is expected - continue. */ return next(); } } const oktaValidationResponse = await validateWithOkta({ oktaConfig, accessToken, }); if (!oktaValidationResponse.ok) { /** * UNEXPECTED ERROR */ return res.sendStatus(500); } if (!oktaValidationResponse.valid) { /** * INVALID TOKEN * * Clear the local state. If the endpoint requires sign-in, * return a 401 which can be handled down the line. Otherwise * continue (the user will see the page as if they are not * signed in). */ clearIdentityLocalState(res); if (signinRequired) { return res.sendStatus(401); } return next(); } /** * VALID TOKEN * * Update the local state with the latest user info from Okta. */ setIdentityLocalState(res, { // This is always 'signedInRecently' because we've just checked // the token is valid with Okta, and it's only valid for 30 minutes. signInStatus: 'signedInRecently', userId: oktaValidationResponse.userId, displayName: oktaValidationResponse.displayName, email: oktaValidationResponse.email, }); return next(); };