ajout de l'authentification SSO/A5L
This commit is contained in:
8
.theia/launch.json
Normal file
8
.theia/launch.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
44
public/auth.js
Normal file
44
public/auth.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// auth.js - Gestion de la connexion SSO
|
||||||
|
const authConfig = {
|
||||||
|
authority: "https://idp.a5l.fr/realms/A5L",
|
||||||
|
client_id: "soundboard_a5l", // À enregistrer sur votre IdP
|
||||||
|
redirect_uri: window.location.origin + "/callback.html",
|
||||||
|
response_type: "code",
|
||||||
|
scope: "openid profile email"
|
||||||
|
};
|
||||||
|
|
||||||
|
function login() {
|
||||||
|
// Construction de l'URL exacte attendue par Keycloak
|
||||||
|
const authUrl = `${authConfig.authority}/protocol/openid-connect/auth?` +
|
||||||
|
`client_id=${authConfig.client_id}&` +
|
||||||
|
`redirect_uri=${encodeURIComponent(authConfig.redirect_uri)}&` +
|
||||||
|
`response_type=${authConfig.response_type}&` +
|
||||||
|
`scope=${authConfig.scope}&` +
|
||||||
|
`state=${generateState()}`; // Sécurité recommandée
|
||||||
|
|
||||||
|
window.location.href = authUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction utilitaire pour le paramètre 'state' (protection CSRF)
|
||||||
|
function generateState() {
|
||||||
|
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||||
|
let result = '';
|
||||||
|
for (let i = 0; i < 16; i++) {
|
||||||
|
result += charset.charAt(Math.floor(Math.random() * charset.length));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
localStorage.removeItem('auth_token');
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkAuth() {
|
||||||
|
const token = localStorage.getItem('auth_token');
|
||||||
|
if (!token) {
|
||||||
|
document.body.classList.add('not-logged-in');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
20
public/callback.html
Normal file
20
public/callback.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
// Récupération du code dans l'URL
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const code = urlParams.get('code');
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
// Ici, normalement, on échange le code contre un token via un fetch vers l'IdP
|
||||||
|
// Pour l'exemple, on simule la réussite :
|
||||||
|
localStorage.setItem('auth_token', 'session_active_' + btoa(code));
|
||||||
|
window.location.href = 'index.html';
|
||||||
|
} else {
|
||||||
|
document.body.innerHTML = "Erreur d'authentification. Redirection...";
|
||||||
|
setTimeout(() => window.location.href = 'index.html', 2000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Soundboard A5L</title>
|
<title>Soundboard A5L</title>
|
||||||
|
<script src="auth.js"></script>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<meta name="theme-color" content="#00f2ff">
|
<meta name="theme-color" content="#00f2ff">
|
||||||
@@ -16,9 +17,18 @@
|
|||||||
<header>
|
<header>
|
||||||
<div style="display: flex; gap: 10px; align-items: center;">
|
<div style="display: flex; gap: 10px; align-items: center;">
|
||||||
<button class="stop-all" onclick="stopAll()">🛑 STOP ALL</button>
|
<button class="stop-all" onclick="stopAll()">🛑 STOP ALL</button>
|
||||||
<span id="app-version" style="color: #555; font-size: 0.8rem; margin-left: 10px;">v1.213</span>
|
<span id="app-version" style="color: #555; font-size: 0.8rem; margin-left: 10px;"><a href="readme.md">1.214</a></span>
|
||||||
|
|
||||||
<button id="installBtn" style="display:none; ...">📥 INSTALLER</button>
|
<button id="installBtn" style="display:none; ...">📥 INSTALLER</button>
|
||||||
|
|
||||||
|
<div id="auth-zone">
|
||||||
|
<button id="loginBtn" onclick="login()" style="background:var(--accent); color:black;">SE CONNECTER</button>
|
||||||
|
<div id="userProfile" style="display:none;">
|
||||||
|
<span id="userName"></span>
|
||||||
|
<button onclick="logout()" style="background:none; color:var(--danger); border:1px solid">DÉCONNEXION</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button onclick="toggleEditMode()" id="toggleBtn">MODE ÉDITION</button>
|
<button onclick="toggleEditMode()" id="toggleBtn">MODE ÉDITION</button>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -10,9 +10,11 @@
|
|||||||
* Arrêt de toutes les pistes avec un bouton STOP ALL
|
* Arrêt de toutes les pistes avec un bouton STOP ALL
|
||||||
* Progressif Web App : fonctionnement offline
|
* Progressif Web App : fonctionnement offline
|
||||||
* Utilisation d'IndexedDB pour stocker les son
|
* Utilisation d'IndexedDB pour stocker les son
|
||||||
|
* Empecher le device de se mettre en veille
|
||||||
|
|
||||||
## Fonctionnalités à venir
|
## Fonctionnalités à venir
|
||||||
|
|
||||||
|
* Suppression d'une association
|
||||||
* Authentification pour stocker les sons sur le serveur
|
* Authentification pour stocker les sons sur le serveur
|
||||||
* Authentification pour récuperer les sons depuis le serveur
|
* Authentification pour récuperer les sons depuis le serveur
|
||||||
* Partager des sons pour que d'autres puissent les déployer dans leur soundboard
|
* Partager des sons pour que d'autres puissent les déployer dans leur soundboard
|
||||||
|
|||||||
@@ -43,6 +43,16 @@ async function getSound(id) {
|
|||||||
// Lancement automatique au démarrage
|
// Lancement automatique au démarrage
|
||||||
// On attend que la page soit prête
|
// On attend que la page soit prête
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
|
if (checkAuth()) {
|
||||||
|
document.getElementById('loginBtn').style.display = 'none';
|
||||||
|
document.getElementById('userProfile').style.display = 'flex';
|
||||||
|
// Charger les données utilisateur depuis le serveur ici si besoin
|
||||||
|
init();
|
||||||
|
} else {
|
||||||
|
// Optionnel : afficher une grille vide ou un message
|
||||||
|
console.log("Utilisateur non connecté.");
|
||||||
|
}
|
||||||
|
|
||||||
migrateToIndexedDB();
|
migrateToIndexedDB();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user