blob: 7bbd20c28209627153b5d4472cfa014cec1b773c [file] [log] [blame]
Misha Krieger-Raynauld242560f2022-10-16 19:59:58 -04001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
18import { NextFunction, Request, Response } from 'express';
Misha Krieger-Raynauld2f5d1ce2022-10-23 21:13:33 -040019import { HttpStatusCode } from 'jami-web-common';
Misha Krieger-Raynauld242560f2022-10-16 19:59:58 -040020
Misha Krieger-Raynauldb933fbb2022-11-15 15:11:09 -050021import { verifyJwt } from '../utils/jwt.js';
Misha Krieger-Raynauld242560f2022-10-16 19:59:58 -040022
Misha Krieger-Raynauld6f9c7ae2022-10-28 11:41:45 -040023function createAuthenticationMiddleware(isAuthenticationRequired: boolean) {
24 return async (req: Request, res: Response, next: NextFunction) => {
Misha Krieger-Raynauld6f9c7ae2022-10-28 11:41:45 -040025 const authorizationHeader = req.headers.authorization;
26 if (!authorizationHeader) {
27 if (isAuthenticationRequired) {
28 res.status(HttpStatusCode.Unauthorized).send('Missing Authorization header');
29 } else {
30 // Skip authentication if it is optional, in which case the Authorization header should not have been set
31 res.locals.accountId = undefined;
32 next();
33 }
34 return;
35 }
Misha Krieger-Raynauld242560f2022-10-16 19:59:58 -040036
Misha Krieger-Raynauld6f9c7ae2022-10-28 11:41:45 -040037 const token = authorizationHeader.split(' ')[1];
38 if (token === undefined) {
39 res.status(HttpStatusCode.BadRequest).send('Missing JSON web token');
40 return;
41 }
Misha Krieger-Raynauld242560f2022-10-16 19:59:58 -040042
Misha Krieger-Raynauld6f9c7ae2022-10-28 11:41:45 -040043 try {
Misha Krieger-Raynauldb933fbb2022-11-15 15:11:09 -050044 const { payload } = await verifyJwt(token);
45 res.locals.accountId = payload.accountId;
Misha Krieger-Raynauld6f9c7ae2022-10-28 11:41:45 -040046 next();
Misha Krieger-Raynauld8a381da2022-11-03 17:37:51 -040047 } catch (e) {
Misha Krieger-Raynauldcb11bba2022-11-11 18:08:33 -050048 res.status(HttpStatusCode.Unauthorized).send('Invalid access token');
Misha Krieger-Raynauld6f9c7ae2022-10-28 11:41:45 -040049 }
50 };
Misha Krieger-Raynauld242560f2022-10-16 19:59:58 -040051}
Misha Krieger-Raynauld6f9c7ae2022-10-28 11:41:45 -040052
53export const authenticateToken = createAuthenticationMiddleware(true);
54
55export const authenticateOptionalToken = createAuthenticationMiddleware(false);