Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions platforms/registry/motd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"status": "up",
"message": "Registry service is running"
}
22 changes: 21 additions & 1 deletion platforms/registry/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import fastify from "fastify";
import { generateEntropy, generatePlatformToken, getJWK } from "./jwt";
import dotenv from "dotenv";
import path from "path";
import path from "node:path";
import { AppDataSource } from "./config/database";
import { VaultService } from "./services/VaultService";
import { UriResolutionService } from "./services/UriResolutionService";
import { KubernetesService } from "./services/KubernetesService";
import cors from "@fastify/cors";

import fs from "node:fs";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Synchronous I/O blocks the event loop and lacks error handling.

The implementation has several serious issues:

  1. Blocking I/O: fs.readFileSync blocks the event loop during startup and file reloads, degrading server responsiveness.
  2. No error handling: Missing try-catch will crash the server if the file is missing or contains invalid JSON.
  3. Path resolution risk: __dirname may not resolve correctly after TypeScript compilation, depending on build configuration.

Apply this diff to use async I/O with proper error handling:

-import fs from "node:fs";
+import fs from "node:fs/promises";

-function loadMotdJSON() {
-    const motdJSON = fs.readFileSync(path.resolve(__dirname, "../motd.json"), "utf8");
-    return JSON.parse(motdJSON) as {
+async function loadMotdJSON() {
+    try {
+        const motdPath = path.resolve(__dirname, "../motd.json");
+        const motdJSON = await fs.readFile(motdPath, "utf8");
+        return JSON.parse(motdJSON) as {
+            status: "up" | "maintenance"
+            message: string
+        };
+    } catch (error) {
+        server.log.error({ message: "Failed to load MOTD", error });
+        return {
+            status: "up" as const,
+            message: "Registry service is running"
+        };
+    }
+}
+
+let motd = {
-        status: "up" | "maintenance"
-        message: string
-    };
+    status: "up" as const,
+    message: "Registry service is running"
-}
+};

-let motd = loadMotdJSON();
+(async () => {
+    motd = await loadMotdJSON();
+})();

Note: You'll also need to update the file watcher (see next comment).

Also applies to: 13-19, 21-21


function loadMotdJSON() {
const motdJSON = fs.readFileSync(path.resolve(__dirname, "../motd.json"), "utf8");
return JSON.parse(motdJSON) as {
status: "up" | "maintenance"
message: string
};
}

let motd = loadMotdJSON();

fs.watchFile(path.resolve(__dirname, "../motd.json"), (_curr, _prev) => {
motd = loadMotdJSON();
});
Comment on lines +23 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Major: Use fs.watch instead of fs.watchFile and add cleanup.

fs.watchFile uses inefficient stat polling and creates a resource leak without cleanup.

Apply this diff to use event-based watching with proper cleanup:

-fs.watchFile(path.resolve(__dirname, "../motd.json"), (_curr, _prev) => {
-    motd = loadMotdJSON();
-});
+const motdWatcher = fs.watch(
+    path.resolve(__dirname, "../motd.json"),
+    async (eventType) => {
+        if (eventType === "change") {
+            motd = await loadMotdJSON();
+            server.log.info("MOTD reloaded");
+        }
+    }
+);
+
+// Cleanup on server close
+server.addHook("onClose", async () => {
+    motdWatcher.close();
+});

Note: This assumes you've converted loadMotdJSON() to async as suggested in the previous comment.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fs.watchFile(path.resolve(__dirname, "../motd.json"), (_curr, _prev) => {
motd = loadMotdJSON();
});
const motdWatcher = fs.watch(
path.resolve(__dirname, "../motd.json"),
async (eventType) => {
if (eventType === "change") {
motd = await loadMotdJSON();
server.log.info("MOTD reloaded");
}
}
);
// Cleanup on server close
server.addHook("onClose", async () => {
motdWatcher.close();
});


dotenv.config({ path: path.resolve(__dirname, "../../../.env") });

const server = fastify({ logger: true });
Expand Down Expand Up @@ -55,6 +71,10 @@ const checkSharedSecret = async (request: any, reply: any) => {
}
};

server.get("/motd", async (request, reply) => {
return motd;
});

// Create a new vault entry
server.post(
"/register",
Expand Down
Loading