"devDependencies": {
"@tsed/cli-plugin-eslint": "2.7.5",
"@tsed/cli-plugin-mocha": "2.7.5",
"@tsed/cli-plugin-passport": "2.7.5",
"@types/chai": "4.2.14",
"@types/chai-as-promised": "7.1.3",
"@types/compression": "^1.7.0",
"@types/cookie-parser": "1.4.2",
"@types/cors": "^2.8.8",
"@types/express": "^4.17.9",
"@types/lodash": "^4.14.162",
"@types/method-override": "0.0.31",
"@types/mime-types": "^2.1.0",
"@types/mocha": "8.2.0",
"@types/morgan": "^1.9.1",
"@types/node": "14.14.11",
"@types/nodemailer": "^6.4.0",
"@types/passport": "1.0.4",
"@types/passport-jwt": "^3.0.3",
"@types/passport-local": "^1.0.33",
"@types/sinon": "9.0.9",
"@types/sinon-chai": "3.2.5",
"@types/supertest": "2.0.10",
"@typescript-eslint/eslint-plugin": "^4.9.1",
"@typescript-eslint/parser": "^4.9.1",
"chai": "4.2.0",
"chai-as-promised": "7.1.1",
"concurrently": "5.3.0",
"eslint": "^7.15.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.2.0",
"husky": "^4.3.5",
"lint-staged": "^10.5.3",
"mocha": "^8.2.1",
"nodemon": "2.0.6",
"nyc": "15.1.0",
"prettier": "^2.2.1",
"sinon": "^9.2.1",
"sinon-chai": "3.5.0",
"supertest": "^5.0.0",
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"tscpaths": "0.0.9",
"typescript": "4.1.2"
},
"dependencies": {
"@tsed/ajv": "6.14.3",
"@tsed/common": "6.14.3",
"@tsed/core": "6.14.3",
"@tsed/di": "6.14.3",
"@tsed/exceptions": "6.14.3",
"@tsed/json-mapper": "^6.14.3",
"@tsed/passport": "6.14.3",
"@tsed/platform-express": "6.14.3",
"@tsed/schema": "6.14.3",
"@tsed/swagger": "6.14.3",
"@types/bcrypt": "^3.0.0",
"@types/express-session": "^1.17.3",
"@types/express-useragent": "^1.0.0",
"@types/jsonwebtoken": "^8.3.8",
"@types/multer": "^1.4.5",
"@types/oracledb": "^5.0.0",
"@types/qs": "^6.9.5",
"@types/swagger-schema-official": "^2.0.21",
"ajv": "6.12.6",
"axios": "^0.21.0",
"bcrypt": "^5.0.0",
"body-parser": "^1.19.0",
"cerialize": "^0.1.18",
"compression": "^1.7.4",
"comtele-sdk": "^1.1.6",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.17.1",
"express-useragent": "^1.0.15",
"http-status-codes": "^2.1.4",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.20",
"memorystore": "^1.6.2",
"method-override": "^3.0.0",
"mime-types": "^2.1.26",
"moment": "^2.29.1",
"morgan": "^1.10.0",
"multer": "^1.4.2",
"nodemailer": "^6.4.16",
"oracledb": "^5.1.0",
"passport": "^0.4.1",
"passport-jwt": "4.0.0",
"passport-local": "1.0.0",
"qs": "^6.9.3",
"source-map-support": "^0.5.16",
"typescript-param-validator": "^1.1.0"
},
Hi,
first thanks for the amazing library.
I'm having some problems with @Catch()
Exceptions like Unauthorized, Forbidden, BadRequest among others, work perfectly
but when passport-jwt throws an exception, that exception does not pass through @Catch()
import {Catch, ExceptionFilterMethods, PlatformContext, ResponseErrorObject} from "@tsed/common";
import {Exception} from "@tsed/exceptions";
import {JsonWebTokenError, TokenExpiredError} from "jsonwebtoken";
import {ResultMessageModel} from "../core/response/result-message.model";
@Catch(Error, Exception, TokenExpiredError, JsonWebTokenError)
export class HttpExceptionFilter implements ExceptionFilterMethods {
catch(exception: Exception & Error, ctx: PlatformContext): void {
const {response, logger} = ctx;
const error = this.mapError(exception);
const headers = this.getHeaders(exception);
logger.error({
error,
});
response
.setHeaders(headers)
.status(error.httpStatus || 500)
.body(error);
}
mapError(error: Exception): ResultMessageModel {
return {
name: error.origin?.name || error.name,
message: error.message,
httpStatus: error.status || 500,
reasons: this.getErrors(error),
};
}
protected getErrors(error: Exception): string[] {
return [error, error.origin].filter(Boolean).reduce((errs, {errors}: ResponseErrorObject) => {
return [...errs, ...(errors || [])];
}, []);
}
protected getHeaders(error: Exception): {[key: string]: unknown} {
return [error, error.origin].filter(Boolean).reduce((obj, {headers}: ResponseErrorObject) => {
return {
...obj,
...(headers || {}),
};
}, {});
}
}
import {Inject, Req} from "@tsed/common";
import {Forbidden} from "@tsed/exceptions";
import {Arg, OnInstall, OnVerify, Protocol} from "@tsed/passport";
import {ExtractJwt, Strategy, StrategyOptions} from "passport-jwt";
import {UserModel} from "../models/user.model";
import {UserService} from "../services/user/user.service";
import {Randon} from "../utils/randon";
@Protocol<StrategyOptions>({
name: "jwt",
useStrategy: Strategy,
settings: {
jwtFromRequest: ExtractJwt.fromExtractors([
ExtractJwt.fromAuthHeaderAsBearerToken(),
ExtractJwt.fromHeader(process.env.JWT_ACCESS_TOKEN || ""),
ExtractJwt.fromUrlQueryParameter("auth_token"),
ExtractJwt.fromUrlQueryParameter(process.env.JWT_ACCESS_TOKEN || ""),
]),
secretOrKey: process.env.API_SECRET,
algorithms: ["HS256"],
issuer: "localhost",
audience: "localhost",
},
})
export class JwtProtocol implements OnVerify, OnInstall {
@Inject()
private userService: UserService;
async $onVerify(@Req() req: Req, @Arg(0) jwtPayload: UserModel): Promise<UserModel | boolean> {
if (jwtPayload.underAnalysis == true) {
throw new Forbidden("Account under analysis!");
}
const userType = Randon.decrypt(jwtPayload.type) as "ADMIN" | "CLIENT";
const user = await this.userService.findById(+Randon.decrypt(`${jwtPayload.id || ""}`));
if (!user || user.type !== userType) {
throw new Forbidden("Access not allowed! ");
}
req.user = user;
if (req.session) {
const session = req.session;
session.user = user;
}
return user ? user : false;
}
$onInstall(): void {
// intercept the strategy instance to adding extra configuration
}
}


Hello @teusemanuel :)
Unfortunately, I'm not sure if it's possible. Passport send the error directly to the client without forward error to the middlewares chain. It means, Ts.ED cannot intercept this error. I'll investigate to find a solution.
See you
Romain
Hello @teusemanuel
I found the reason. Passport doesn't use class inherited from Error.
The fix is ready. It should solve your issue!
:tada: This issue has been resolved in version 6.18.0 :tada:
The release is available on:
v6.18.0Your semantic-release bot :package::rocket:
Fixed
See: https://tsed.io/tutorials/passport.html#catch-passport-exception
Most helpful comment
Fixed
See: https://tsed.io/tutorials/passport.html#catch-passport-exception