This commit is contained in:
Your Name committed 2026-06-28 21:34:58 -04:00
1 parent 3965f4f4da
commit 70877882b0
82 files changed
+4353 -186

No files matched your search

+208
View File
@@ -0,0 +1,208 @@
import { createHmac } from "crypto";
function base64url(buf: Buffer): string {
return buf.toString("base64")
.replace(/=/g, "")
.replace(/\+/g, "-")
.replace(/\//g, "_");
}
function signJWT(payload: object, secret: string): string {
const header = { alg: "HS256", typ: "JWT" };
const headerStr = base64url(Buffer.from(JSON.stringify(header)));
const payloadStr = base64url(Buffer.from(JSON.stringify(payload)));
const signature = createHmac("sha256", secret)
.update(`${headerStr}.${payloadStr}`)
.digest();
return `${headerStr}.${payloadStr}.${base64url(signature)}`;
}
const API_BASE = "http://localhost:3051/api";
async function run() {
console.log("=== STEP 1: Login via Auth Route ===");
const loginRes = await fetch(`${API_BASE}/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "admin", password: "homaroma123" })
});
const loginData = await loginRes.json() as any;
console.log("Login status:", loginRes.status);
console.log("Login response:", loginData);
if (!loginData.success) {
console.error("Login failed!");
return;
}
const loginToken = loginData.token;
console.log("\n=== STEP 2: Test POST /menus with login token ===");
const testMenuPayload = {
name: "challenger-test-menu",
rootImage: "https://example.com/root.jpg",
items: [
{
label: "Item 1",
url: "/item1",
order: 1,
columnImage: "https://example.com/column1.jpg",
hoverImage: "https://example.com/hover1.jpg"
}
]
};
const postRes = await fetch(`${API_BASE}/menus`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${loginToken}`
},
body: JSON.stringify(testMenuPayload)
});
console.log("POST /menus with login token status:", postRes.status);
const postData = await postRes.json();
console.log("POST /menus response:", postData);
// If unauthorized, let's sign tokens with different secret fallbacks to see which works!
let workingToken = loginToken;
if (postRes.status === 401) {
console.log("\n⚠️ Detected JWT Secret Mismatch! Trying manually signed tokens...");
const payload = {
id: 1,
username: "admin",
role: "ADMIN"
};
const secrets = [
"homaroma_secret_2026_scent",
"homaroma_secret_2026_brand",
"fallback-secret"
];
for (const secret of secrets) {
const token = signJWT(payload, secret);
const testRes = await fetch(`${API_BASE}/menus`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify(testMenuPayload)
});
console.log(`Testing secret '${secret}': status = ${testRes.status}`);
if (testRes.status !== 401) {
console.log(`✅ Success with secret '${secret}'!`);
workingToken = token;
break;
}
}
}
console.log("\n=== STEP 3: Perform correct Menu creation & retrieval ===");
// Ensure the menu doesn't exist already by trying to query / delete it first
// Let's create it clean
const menuName = "challenger-test-" + Date.now();
const menuPayload = {
name: menuName,
rootImage: "https://example.com/challenger-root.png",
items: [
{
label: "Challenger Link",
url: "/challenger-link",
order: 2,
columnImage: "https://example.com/challenger-column.png",
hoverImage: "https://example.com/challenger-hover.png"
}
]
};
const createRes = await fetch(`${API_BASE}/menus`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${workingToken}`
},
body: JSON.stringify(menuPayload)
});
console.log("Creation status:", createRes.status);
const createdMenu = await createRes.json() as any;
console.log("Created menu:", JSON.stringify(createdMenu, null, 2));
// Verify DB retrieval via GET /api/menus/:name
const getRes = await fetch(`${API_BASE}/menus/${menuName}`);
console.log("GET /menus/:name status:", getRes.status);
const retrievedMenu = await getRes.json() as any;
console.log("Retrieved menu:", JSON.stringify(retrievedMenu, null, 2));
// Verify that rootImage, columnImage, and hoverImage are correctly stored and retrieved
const rootImageOk = retrievedMenu.rootImage === menuPayload.rootImage;
const item = retrievedMenu.items?.[0];
const columnImageOk = item?.columnImage === menuPayload.items[0].columnImage;
const hoverImageOk = item?.hoverImage === menuPayload.items[0].hoverImage;
console.log(`\nVerification Results:`);
console.log(`- rootImage correct: ${rootImageOk} (Expected: ${menuPayload.rootImage}, Got: ${retrievedMenu.rootImage})`);
console.log(`- columnImage correct: ${columnImageOk} (Expected: ${menuPayload.items[0].columnImage}, Got: ${item?.columnImage})`);
console.log(`- hoverImage correct: ${hoverImageOk} (Expected: ${menuPayload.items[0].hoverImage}, Got: ${item?.hoverImage})`);
console.log("\n=== STEP 4: Perform PUT update menu ===");
const updatePayload = {
rootImage: "https://example.com/challenger-root-updated.png",
items: [
{
id: item?.id,
label: "Challenger Link Updated",
url: "/challenger-link-updated",
order: 5,
columnImage: "https://example.com/challenger-column-updated.png",
hoverImage: "https://example.com/challenger-hover-updated.png"
}
]
};
const updateRes = await fetch(`${API_BASE}/menus/${menuName}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${workingToken}`
},
body: JSON.stringify(updatePayload)
});
console.log("PUT status:", updateRes.status);
const updatedMenu = await updateRes.json() as any;
console.log("Updated menu retrieved:", JSON.stringify(updatedMenu, null, 2));
console.log("\n=== STEP 5: Verify Validation Errors for Incorrect Types ===");
const invalidPayload = {
name: "challenger-invalid-menu",
rootImage: 12345, // Should fail: expected string
items: [
{
label: "Invalid Link",
url: "/invalid",
order: "not-a-number", // Should fail: expected number
columnImage: true // Should fail: expected string
}
]
};
const invalidRes = await fetch(`${API_BASE}/menus`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${workingToken}`
},
body: JSON.stringify(invalidPayload)
});
console.log("POST invalid payload status:", invalidRes.status);
const invalidData = await invalidRes.json();
console.log("POST invalid payload response (expected validation error):", JSON.stringify(invalidData, null, 2));
}
run().catch(console.error);