diff --git a/src/front/Components/Debug/JwtDebugger.tsx b/src/front/Components/Debug/JwtDebugger.tsx new file mode 100644 index 00000000..e4cd5cee --- /dev/null +++ b/src/front/Components/Debug/JwtDebugger.tsx @@ -0,0 +1,123 @@ +import React, { useEffect, useState } from "react"; +import JwtService from "@Front/Services/JwtService/JwtService"; +import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule"; + +interface JwtDebuggerProps { + expectedRules?: string[]; + showAlways?: boolean; +} + +export default function JwtDebugger({ expectedRules = [], showAlways = false }: JwtDebuggerProps) { + const [isVisible, setIsVisible] = useState(showAlways); + const [debugInfo, setDebugInfo] = useState(null); + + useEffect(() => { + // Only show in development + if (process.env.NODE_ENV !== "development" && !showAlways) { + return; + } + + const jwt = JwtService.getInstance().debugJwtToken(); + if (jwt) { + setDebugInfo(jwt); + } + }, [showAlways]); + + // Keyboard shortcut to toggle debugger (Ctrl+Shift+D) + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.ctrlKey && e.shiftKey && e.key === "D") { + e.preventDefault(); + setIsVisible(!isVisible); + } + }; + + document.addEventListener("keydown", handleKeyDown); + return () => document.removeEventListener("keydown", handleKeyDown); + }, [isVisible]); + + if (!isVisible) return null; + + return ( +
+
+ JWT Debugger + +
+ + {debugInfo && ( +
+
User ID: {debugInfo.userId}
+
Email: {debugInfo.email}
+
Role: {debugInfo.role}
+
Office ID: {debugInfo.office_Id}
+
Rules Count: {debugInfo.rules?.length || 0}
+
Rules:
+
    + {debugInfo.rules?.map((rule: string, index: number) => ( +
  • {rule}
  • + ))} +
+
Expires: {new Date(debugInfo.exp * 1000).toLocaleString()}
+ + {expectedRules.length > 0 && ( +
+
Expected Rules:
+
    + {expectedRules.map((rule, index) => ( +
  • + {rule} {debugInfo.rules?.includes(rule) ? "✓" : "✗"} +
  • + ))} +
+
+ )} + +
+ Quick Tests: +
+ + +
+
+
+ )} + +
+ Press Ctrl+Shift+D to toggle +
+
+ ); +} \ No newline at end of file diff --git a/src/front/Services/JwtService/JwtService.ts b/src/front/Services/JwtService/JwtService.ts index e53789ad..ad2e37bf 100644 --- a/src/front/Services/JwtService/JwtService.ts +++ b/src/front/Services/JwtService/JwtService.ts @@ -165,4 +165,75 @@ export default class JwtService { if (!token) return false; return token?.rules?.some((rule: string) => rule === `${action} ${name}`); } + + /** + * Debug method to log JWT token details including rules + */ + public debugJwtToken() { + const token = this.decodeJwt(); + if (!token) { + console.warn("No JWT token found"); + return null; + } + + console.log("=== JWT Token Debug Info ==="); + console.log("User ID:", token.userId); + console.log("Email:", token.email); + console.log("Role:", token.role); + console.log("Office ID:", token.office_Id); + console.log("Rules count:", token.rules?.length || 0); + console.log("Rules:", token.rules); + console.log("Expiration:", new Date(token.exp * 1000).toISOString()); + console.log("============================="); + + return token; + } + + /** + * Check if a specific rule exists in the JWT token + */ + public checkSpecificRule(name: string, action: string) { + const token = this.decodeJwt(); + if (!token) { + console.warn("No JWT token found"); + return false; + } + + const expectedRule = `${action} ${name}`; + const hasRule = token?.rules?.some((rule: string) => rule === expectedRule); + + console.log(`=== Rule Check: ${expectedRule} ===`); + console.log("Expected rule:", expectedRule); + console.log("Available rules:", token.rules); + console.log("Rule found:", hasRule); + console.log("============================="); + + return hasRule; + } + + /** + * Compare JWT rules with expected rules from database + */ + public compareRulesWithDatabase(expectedRules: string[]) { + const token = this.decodeJwt(); + if (!token) { + console.warn("No JWT token found"); + return { missing: expectedRules, extra: [], matches: [] }; + } + + const jwtRules = token.rules || []; + const missing = expectedRules.filter(rule => !jwtRules.includes(rule)); + const extra = jwtRules.filter(rule => !expectedRules.includes(rule)); + const matches = jwtRules.filter(rule => expectedRules.includes(rule)); + + console.log("=== Rules Comparison ==="); + console.log("Expected rules (from DB):", expectedRules); + console.log("JWT rules:", jwtRules); + console.log("Missing rules:", missing); + console.log("Extra rules:", extra); + console.log("Matching rules:", matches); + console.log("========================="); + + return { missing, extra, matches }; + } }