feat: implement OpenID Connect authentication with Infomaniak
This commit is contained in:
136
index.html
136
index.html
@@ -13,7 +13,20 @@
|
||||
<div class="container mt-4">
|
||||
<h1 class="mb-4 text-center">MyIce - Games</h1>
|
||||
|
||||
<div id="apikeyContainer" class="mb-3"></div>
|
||||
<div id="loginContainer" class="mb-3">
|
||||
<div id="oidcLoginSection">
|
||||
<button id="oidcLoginBtn" class="btn btn-primary">Se connecter avec Infomaniak</button>
|
||||
</div>
|
||||
<div id="apikeySection" style="display: none;">
|
||||
<label for="apikey" class="form-label">API Key</label>
|
||||
<input type="text" id="apikey" class="form-control" placeholder="Entrez votre API Key">
|
||||
<button id="validateApiKey" class="btn btn-success mt-2">Valider</button>
|
||||
</div>
|
||||
<div id="connectedUser" style="display: none;">
|
||||
<p>Connecté en tant que: <span id="userName"></span></p>
|
||||
<button id="disconnect" class="btn btn-danger">Déconnecter</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="eventFilters" style="display: none;">
|
||||
<div class="mb-3">
|
||||
@@ -50,7 +63,10 @@
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const apikeyContainer = document.getElementById("apikeyContainer");
|
||||
const loginContainer = document.getElementById("loginContainer");
|
||||
const oidcLoginSection = document.getElementById("oidcLoginSection");
|
||||
const apikeySection = document.getElementById("apikeySection");
|
||||
const connectedUser = document.getElementById("connectedUser");
|
||||
const eventFilters = document.getElementById("eventFilters");
|
||||
const accountSelect = document.getElementById("account");
|
||||
const agegroupSelect = document.getElementById("agegroup");
|
||||
@@ -62,33 +78,86 @@
|
||||
let storedApiKey = localStorage.getItem("apikey");
|
||||
let lastFetchedEvents = [];
|
||||
let storedAccount = localStorage.getItem("account") || "default";
|
||||
let userInfo = JSON.parse(localStorage.getItem("userInfo") || "null");
|
||||
|
||||
// Handle OIDC callback
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const code = urlParams.get('code');
|
||||
if (code) {
|
||||
// We're coming back from OIDC login
|
||||
exchangeCodeForToken(code);
|
||||
// Remove code from URL
|
||||
window.history.replaceState({}, document.title, "/");
|
||||
}
|
||||
|
||||
function renderLoginSection() {
|
||||
if (storedApiKey || userInfo) {
|
||||
// User is logged in
|
||||
connectedUser.style.display = "block";
|
||||
oidcLoginSection.style.display = "none";
|
||||
apikeySection.style.display = "none";
|
||||
|
||||
const userNameElement = document.getElementById("userName");
|
||||
if (userInfo && userInfo.email) {
|
||||
userNameElement.textContent = userInfo.email;
|
||||
} else {
|
||||
userNameElement.textContent = "Utilisateur";
|
||||
}
|
||||
|
||||
function renderApiKeyInput() {
|
||||
if (storedApiKey) {
|
||||
apikeyContainer.innerHTML = `<button id="disconnect" class="btn btn-danger">Déconnecter</button>`;
|
||||
document.getElementById("disconnect").addEventListener("click", () => {
|
||||
localStorage.removeItem("apikey");
|
||||
localStorage.removeItem("account");
|
||||
location.reload();
|
||||
});
|
||||
eventFilters.style.display = "block";
|
||||
// Load available accounts from server or use predefined ones
|
||||
updateAccountOptions();
|
||||
fetchEvents(storedApiKey, storedAccount);
|
||||
if (storedApiKey) {
|
||||
fetchEvents(storedApiKey, storedAccount);
|
||||
}
|
||||
} else {
|
||||
apikeyContainer.innerHTML = `
|
||||
<label for="apikey" class="form-label">API Key</label>
|
||||
<input type="text" id="apikey" class="form-control" placeholder="Entrez votre API Key">
|
||||
<button id="validateApiKey" class="btn btn-success mt-2">Valider</button>
|
||||
`;
|
||||
// User is not logged in
|
||||
connectedUser.style.display = "none";
|
||||
oidcLoginSection.style.display = "block";
|
||||
apikeySection.style.display = "none";
|
||||
eventFilters.style.display = "none";
|
||||
document.getElementById("validateApiKey").addEventListener("click", saveApiKey);
|
||||
document.getElementById("apikey").addEventListener("keypress", function (event) {
|
||||
if (event.key === "Enter") {
|
||||
saveApiKey();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("oidcLoginBtn").addEventListener("click", initiateOIDCLogin);
|
||||
}
|
||||
|
||||
// Add disconnect handler
|
||||
const disconnectBtn = document.getElementById("disconnect");
|
||||
if (disconnectBtn) {
|
||||
disconnectBtn.addEventListener("click", logout);
|
||||
}
|
||||
}
|
||||
|
||||
function initiateOIDCLogin() {
|
||||
// Redirect to backend login endpoint
|
||||
window.location.href = `${apiBaseUrl}/login`;
|
||||
}
|
||||
|
||||
function exchangeCodeForToken(code) {
|
||||
fetch(`${apiBaseUrl}/callback?code=${code}&state=ignored`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.access_token) {
|
||||
localStorage.setItem("apikey", data.access_token);
|
||||
localStorage.setItem("userInfo", JSON.stringify(data.user));
|
||||
storedApiKey = data.access_token;
|
||||
userInfo = data.user;
|
||||
renderLoginSection();
|
||||
} else {
|
||||
alert("Échec de la connexion OIDC");
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Erreur lors de l'échange du code:", error);
|
||||
alert("Échec de la connexion OIDC");
|
||||
});
|
||||
}
|
||||
|
||||
function logout() {
|
||||
localStorage.removeItem("apikey");
|
||||
localStorage.removeItem("account");
|
||||
localStorage.removeItem("userInfo");
|
||||
storedApiKey = null;
|
||||
userInfo = null;
|
||||
location.reload();
|
||||
}
|
||||
|
||||
function saveApiKey() {
|
||||
@@ -128,7 +197,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
renderApiKeyInput();
|
||||
renderLoginSection();
|
||||
|
||||
accountSelect.addEventListener("change", () => {
|
||||
const selectedAccount = accountSelect.value;
|
||||
@@ -140,7 +209,7 @@
|
||||
|
||||
fetchButton.addEventListener("click", () => {
|
||||
if (!storedApiKey) {
|
||||
alert("Veuillez entrer une clé API");
|
||||
alert("Veuillez vous connecter");
|
||||
return;
|
||||
}
|
||||
const selectedAccount = accountSelect.value;
|
||||
@@ -155,11 +224,20 @@
|
||||
fetch(`${apiBaseUrl}/schedule?account=${account}`, {
|
||||
headers: { "Authorization": `Bearer ${apiKey}` }
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.status === 401) {
|
||||
// Token expired or invalid
|
||||
logout();
|
||||
return;
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
lastFetchedEvents = data.filter(event => event.event === "Jeu");
|
||||
updateAgeGroupOptions(lastFetchedEvents);
|
||||
displayEvents(lastFetchedEvents);
|
||||
if (data) {
|
||||
lastFetchedEvents = data.filter(event => event.event === "Jeu");
|
||||
updateAgeGroupOptions(lastFetchedEvents);
|
||||
displayEvents(lastFetchedEvents);
|
||||
}
|
||||
})
|
||||
.catch(error => console.error("Erreur lors du chargement des événements:", error));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user