Skip to content

Commit

Permalink
2087 Fix error handling between blockchain and email service (#2090)
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelPull authored Nov 11, 2024
1 parent 789517c commit b1859c1
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 16 deletions.
2 changes: 1 addition & 1 deletion blockchain/src/envVarsSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const envVarsSchema = Joi.object({
JWT_SECRET: Joi.string()
.when("EMAIL_SERVICE_ENABLED", {
is: true,
then: Joi.required(),
then: Joi.required().when("JWT_ALGORITHM", { is: "RS256", then: Joi.string().base64().min(2240) }),
otherwise: Joi.optional().allow("", null),
})
.note(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
let jwt = require("jsonwebtoken");
const jwt = require("jsonwebtoken");

function createJWT(secret, id, algorithm = "HS256") {
if (!secret || typeof secret !== "string") {
throw new Error("Invalid or missing secret key.");
}

const supportedAlgorithms = ["HS256", "RS256"];
if (!supportedAlgorithms.includes(algorithm)) {
throw new Error(`Unsupported algorithm: ${algorithm}`);
}

const secretOrPrivateKey = algorithm === "RS256" ? Buffer.from(secret, "base64") : secret;
return jwt.sign(
{
id,
},
secretOrPrivateKey,
{ expiresIn: "8h", algorithm },
);

try {
return jwt.sign({ id }, secretOrPrivateKey, { expiresIn: "8h", algorithm });
} catch (error) {
throw new Error(`JWT creation failed: ${error.message}`);
}
}

module.exports = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ function ExpiredTokenException(message) {
this.name = "ExpiredTokenException";
}

function InvalidAlgorithmException(message) {
this.message = message;
this.name = "InvalidAlgorithmException";
}

function InvalidTokenException(message) {
this.message = message;
this.name = "InvalidTokenException";
}

function ConnectionRefusedException(message) {
this.message = message;
this.name = "ECONNREFUSED";
Expand Down Expand Up @@ -79,10 +89,15 @@ const sendNotifications = async (path, emailServiceSocketAddress, token, ssl = f
}
}
switch (error.response.status) {
case 400:
// If Bearer token has expired
throw new ExpiredTokenException("JWT-Token expired");

case 400: {
if (error.response.data.message === "invalid algorithm") {
throw new InvalidAlgorithmException("invalid algorithm");
}
if (error.response.data.message === "jwt expired") {
throw new ExpiredTokenException("JWT-Token expired");
}
throw new InvalidTokenException("invalid token");
}
case 404:
// If no email address is found in the database delete the notification file
if (error.response.data.notification.emailAddress === "Not Found") {
Expand Down Expand Up @@ -143,7 +158,13 @@ const [path, emailServiceSocketAddress, secret, maxPersistenceHours, loopInterva
const absolutePath = process.cwd() + "/" + path;

(async () => {
let token = createJWT(secret, "notification-watcher", algorithm);
let token;
try {
token = createJWT(secret, "notification-watcher", algorithm);
} catch (error) {
log.error(error, "Error creating JWT. Notification Watcher exiting.");
process.exit(1);
}

while (true) {
log.trace("Checking for new notifications");
Expand All @@ -154,8 +175,10 @@ const absolutePath = process.cwd() + "/" + path;
if (error.name === "ExpiredTokenException") {
token = createJWT(secret, "notification-watcher", algorithm);
log.info("New JWT token created due to expiration.");
} else if (error.name === "InvalidAlgorithmException") {
log.error(error, `Notification e-mail request signed with invalid algorithm: ${algorithm}`);
} else {
log.error("Error during notification processing:", error);
log.error(error, "Error during notification processing");
}
}
await sleep(loopIntervalSeconds);
Expand Down
8 changes: 7 additions & 1 deletion email-notification-service/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ export const verifyNotificationJWT = (req: Request, res, next): void => {
})
.catch((err) => {
logger.error({ err, token }, "Notification-JWT invalid");
const body: InvalidJWTResponseBody = { message: "Invalid JWT token provided." };
let message = "Invalid JWT token provided.";
if (err.message === "invalid algorithm") {
message = err.message;
} else if (err.message === "jwt expired") {
message = err.message;
}
const body: InvalidJWTResponseBody = { message };
res.status(400).json(body);
});
};
Expand Down

0 comments on commit b1859c1

Please sign in to comment.