import { Express, Response } from 'express'; import { Config } from './app-config'; import { Unauthorized } from './errors'; import { validate } from './cognito'; export const getAuthUserEmail = (res: Response): string => { const user = res.locals.user as unknown; if (user === undefined || typeof user !== 'string') { throw new Error(`Can't get current user`); } return user; }; export const configureAuth = (config: Config, app: Express): Express => { return app.use(async (req, res, next) => { try { if (config.authConfig.type === 'test') { const response = config.authConfig.validate(req); const userEmail = response?.email; if (typeof userEmail !== 'string') { throw new Unauthorized('Email property missing on auth validate response'); } res.locals.user = config.caseSensitiveEmail === true ? userEmail : userEmail.toLocaleLowerCase(); next(); } else { //I'm passing in the access token in header under key accessToken const authHeader = req.headers.authorization; //Fail if token not present in header. if (typeof authHeader !== 'string') throw new Unauthorized('Header not set'); const bearerRegex = /^Bearer ([a-zA-Z0-9_\-\.]*)$/g; const parsed = bearerRegex.exec(authHeader); const token = parsed?.[1]; if (typeof token !== 'string') throw new Unauthorized('Could not parse Bearer token'); const authResult = await validate( { region: config.authConfig.region, userPoolId: config.authConfig.cognitoUserPoolId, tokenUse: 'id', }, token ); if (authResult.valid) { const userEmail = authResult.token.email as string; res.locals.user = config.caseSensitiveEmail === true ? userEmail : userEmail.toLocaleLowerCase(); next(); } else { throw new Unauthorized('Bearer token not valid'); } } } catch (e) { next(e); } return undefined; }); };