given files

This commit is contained in:
Gu://em_ 2026-05-15 11:08:23 +02:00
parent 9bf88844e9
commit a2c31f873d
48 changed files with 10458 additions and 0 deletions

View file

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Debug Page</title>
</head>
<body>
<div class="AlertContainer" id="alert-container"></div>
<div class="container">
<h1>Debug Dashboard</h1>
<section class="card">
<h2>Local Storage Tokens</h2>
<div class="token-section">
<h3>Access Token</h3>
<p id="token" class="token-text">{{ token }}</p>
<h3>Refresh Token</h3>
<p id="refresh_token" class="token-text">{{ refresh_token }}</p>
</div>
<div class="token-actions button-group">
<button id="deleteTokenBtn">Delete Access Token</button>
<button id="deleteRefreshTokenBtn">Delete Refresh Token</button>
<button id="clearTokens">Clear All Tokens</button>
</div>
</section>
<section class="card">
<h2>User Profile</h2>
<div class="StudentProfile">
<img src="" class="Avatar" id="profile-info-avatar" alt="User Avatar" />
<div class="TextContainer">
<span class="Login" id="profile-info-login">no login</span>
<span class="Quote" id="profile-info-quote"></span>
</div>
</div>
<div class="profile-actions button-group">
<button id="launchOIDC">Launch OIDC</button>
<button id="displayProfile">Display Profile Info</button>
<button id="hideProfile">Clear Profile Info</button>
</div>
</section>
<section class="card">
<h2>Error Simulation</h2>
<div class="error-actions button-group">
<button id="errorBtn">Generate Error Response</button>
<button id="invalidToken">Generate Invalid Token</button>
<button id="expiredTokenBtn">Generate Expired Token</button>
</div>
</section>
</div>
</body>
</html>

122
src/pages/debug/debug.js Normal file
View file

@ -0,0 +1,122 @@
import $ from "jquery";
import debugHtml from "./debug.html";
import { displayStudentProfile, expired } from "./utils";
import { createAlert } from "../../utils/notify";
const { authedAPIRequest, authenticate } = await import("../../utils/auth.js");
const authed = authedAPIRequest ?? (() => {});
function clearLocalStorage() {
localStorage.removeItem("token");
localStorage.removeItem("refresh_token");
}
function clearUserProfile(log = true) {
$("#profile-info-login").text("No login");
$("#profile-info-quote").text("No quote");
log && createAlert("Debug", "Clear user profile info", "success");
}
function refreshLocalStorage() {
$("#token").text(localStorage.getItem("token") ?? "N/A");
$("#refresh_token").text(localStorage.getItem("refresh_token") ?? "N/A");
}
async function refreshProfile() {
await displayStudentProfile()
.then(() => {
createAlert("Debug", "Display profile succeed", "success");
})
.catch((_error) => {
createAlert("Debug", "Cannot display profile", "error");
clearUserProfile(false);
});
}
async function refresh() {
refreshLocalStorage();
await refreshProfile();
}
(() => {
if (import.meta.env.MODE !== "debug") {
return;
}
$.get(debugHtml, function (response) {
$("body").html(response);
refreshLocalStorage();
}).fail(function (_xhr, _status, error) {
console.error("Error fetching debug HTML:", error);
});
$(document).on("click", "#launchOIDC", async function () {
clearLocalStorage();
if (await authenticate()) {
createAlert("Debug", "OIDC succeed", "error");
} else {
createAlert("Debug", "OIDC failed", "error");
}
await refresh();
});
$(document).on("click", "#displayProfile", refreshProfile);
$(document).on("click", "#hideProfile", clearUserProfile);
$(document).on("click", "#errorBtn", async function () {
await authed("/tests/error", { method: "GET" });
createAlert("Debug", "Error response generated", "success");
await refresh();
});
$(document).on("click", "#invalidToken", async function () {
await authedAPIRequest("/tests/invalid-token", { method: "POST" });
createAlert("Debug", "Invalid token response generated", "success");
await refresh();
});
$(document).on("click", "#expiredTokenBtn", async function () {
expired();
let res = await authedAPIRequest("/tests/valid", { method: "GET" });
res = await res.json();
if (res.response === "A valid response") {
createAlert(
"Debug",
"Token has been refreshed and the request has been re-send",
"success",
);
} else {
createAlert("Debug", "An error occured", "error");
}
await refresh();
});
$(document).on("click", "#deleteTokenBtn", async function () {
localStorage.removeItem("token");
createAlert("Debug", "Token removed from local storage", "success");
await refresh();
});
$(document).on("click", "#deleteRefreshTokenBtn", async function () {
localStorage.removeItem("refresh_token");
createAlert(
"Debug",
"Refresh token removed from local storage",
"success",
);
await refresh();
});
$(document).on("click", "#clearTokens", async function () {
createAlert(
"Debug",
"Token and refresh token removed from local storage",
"success",
);
clearLocalStorage();
await refresh();
});
refresh();
})();

128
src/pages/debug/index.css Normal file
View file

@ -0,0 +1,128 @@
:root {
--bg-page: #f0f2f5;
--bg-card: #5A6991;
--bg-token: #e8eaed;
--bg-profile: #e8eaed;
--border-card: #d1d5db;
--text-heading: #111827;
--text-label: #6b7280;
--text-body: #1f2937;
--text-quote: #6b7280;
--shadow-card: 0 2px 8px rgba(0, 0, 0, 0.08);
--btn-bg: #455069;
--btn-bg-hover: #111827;
--btn-text: #ffffff;
}
@media (prefers-color-scheme: dark) {
:root {
--bg-page: #0f1117;
--bg-card: #1a1d27;
--bg-token: #2a2d3a;
--bg-profile: #2a2d3a;
--border-card: #2e3348;
--text-heading: #f0f2f5;
--text-label: #8b92a5;
--text-body: #e2e5ed;
--text-quote: #8b92a5;
--shadow-card: 0 2px 8px rgba(0, 0, 0, 0.4);
--btn-bg: #3B4257;
--btn-bg-hover: #51596E;
--btn-text: #e2e5ed;
}
}
body {
background-color: var(--bg-page);
color: var(--text-body);
transition: background-color 0.2s, color 0.2s;
}
.container {
width: 800px;
}
.card {
background-color: var(--bg-card);
border: 1px solid var(--border-card);
border-radius: 10px;
padding: 20px;
margin: 20px;
box-shadow: var(--shadow-card);
}
.card h2 {
margin-top: 0;
margin-bottom: 15px;
font-size: 1.5em;
color: var(--text-heading);
}
.token-section h3 {
margin-bottom: 5px;
font-size: 1.1em;
color: var(--text-body);
}
.token-text {
background-color: var(--bg-token);
padding: 10px;
border-radius: 5px;
word-break: break-all;
color: var(--text-body);
}
.StudentProfile {
display: flex;
align-items: center;
gap: 15px;
width: 30%;
margin: 10px 0 30px;
border-radius: 5px;
padding: 7px 10px;
background-color: var(--bg-profile);
}
.Avatar {
width: 60px;
height: 60px;
border-radius: 50%;
object-fit: cover;
border: 1px solid var(--border-card);
}
.TextContainer {
display: flex;
flex-direction: column;
}
.Login {
font-weight: bold;
font-size: 1.1em;
color: var(--text-body);
}
.Quote {
font-style: italic;
color: var(--text-quote);
}
.button-group {
display: flex;
justify-content: space-around;
}
button {
background-color: var(--btn-bg);
color: var(--btn-text);
border: none;
border-radius: 6px;
padding: 8px 16px;
font-size: 0.9em;
cursor: pointer;
}
button:hover {
background-color: var(--btn-bg-hover);
}

57
src/pages/debug/utils.js Normal file
View file

@ -0,0 +1,57 @@
// FIXME: File that provide utils function for the debug page
import $ from "jquery";
import jwt_decode from "jwt-decode";
import { createAlert } from "../../utils/notify";
export async function displayStudentProfile() {
const token = localStorage.getItem("token");
const decoded = jwt_decode(token);
const _uid = decoded.uid;
// You have to write a request to fetch your informations
const request_result = null;
if (request_result === null) {
createAlert(
"debug",
"Fetch not implemented in the pages/debug/utils.js file",
"error",
);
}
const student_resources = await request_result?.json();
$("#profile-info-avatar").attr(
"src",
student_resources.avatarURL ?? "/default-avatar.png",
);
$("#profile-info-login").text(student_resources.login);
$("#profile-info-quote").text(student_resources.quote);
}
export function expired() {
const token = localStorage.getItem("token");
const splited_token = token.split(".");
let base64 = splited_token[1].replace(/-/g, "+").replace(/_/g, "/");
while (base64.length % 4 !== 0) {
base64 += "=";
}
const parts = JSON.parse(atob(base64));
parts["exp"] = 0;
const recodedValue = btoa(JSON.stringify(parts))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "");
splited_token[1] = recodedValue;
const expiredToken = splited_token.join(".");
localStorage.setItem("token", expiredToken);
}