You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

63 lines
1.7 KiB

import { FastifyReply, FastifyRequest } from "fastify";
import Application from "@server/Application";
import jwt from "jsonwebtoken";
import { IteratorNext, MiddlewareRequest } from ".";
import { ITokenSchema } from "@common/api_schema";
import { User } from "@server/database/entities";
/**
* Attempt to authenticate a client's JWT token
*/
async function authenticateJwtToken(request: FastifyRequest, reply: FastifyReply): Promise<User|undefined> {
// Verify headers
if (!request.headers["authorization"]) {
reply.status(401);
reply.send({ status: "Unauthorized" });
return;
}
if (!request.headers["authorization"].startsWith("Bearer ")) {
reply.status(400);
reply.send({ status: "Bad request" });
return;
}
// Construct the token string
let token = request.headers["authorization"].slice(7).trim();
if ((token.match(/\./g)||[]).length < 2) {
token += '.' + (request.cookies.jwt_signature ?? "").trim();
}
// Decode the token
let user: User;
try {
let decoded = <ITokenSchema>jwt.verify(token, Application.instance().APP_KEY);
user = await User.findOneOrFail(decoded.id);
} catch(e) {
reply.status(401);
reply.send({ status: "Unauthorized" });
return;
}
return user;
}
/**
* The parameter types for the auth middleware
*/
export interface IAuthMiddlewareParams {
auth: {
user: User
}
}
/**
* Ensure that a valid authentication token is provided
*/
export async function auth<T extends IAuthMiddlewareParams>(request: MiddlewareRequest<T>, reply: FastifyReply, next: IteratorNext) {
let user = await authenticateJwtToken(request, reply);
if (user === undefined) {
// The authenticateJwtToken function sends out the response
return;
}
request.middlewareParams = <any><IAuthMiddlewareParams>{
auth: { user }
};
next();
}