update: link to authentik to change password if needed

This commit is contained in:
Nathan FONTEYNE 2026-07-08 17:00:47 +02:00
parent 7e4b067e54
commit 09b7b0bc10
6 changed files with 35 additions and 2 deletions

View file

@ -28,6 +28,12 @@ OIDC_CLIENT_SECRET=
OIDC_REDIRECT_URI=https://octane.dandrove.com/auth/callback
ADMIN_GROUP_NAME=octane-admins
# Optional — public URL of Authentik (the one users' browsers can actually
# reach, unlike AUTHENTIK_ISSUER_URL above which may be an internal Docker
# address). Shows a "Mon compte" link in the nav and on the profile page so
# users can change their own password. Hidden entirely if left blank.
AUTHENTIK_PUBLIC_URL=https://auth.dandrove.com
# Docker networking: external network shared with Traefik and Authentik
TRAEFIK_NETWORK_NAME=traefik-proxy

View file

@ -340,6 +340,7 @@ Le [Démarrage rapide](#démarrage-rapide-serveur-avec-traefik) ci-dessus couvre
| `OIDC_CLIENT_ID` / `OIDC_CLIENT_SECRET` | Identifiants du provider Authentik |
| `OIDC_REDIRECT_URI` | URL publique de callback, doit correspondre à celle configurée dans Authentik (ex: `https://octane.dandrove.com/auth/callback`) |
| `ADMIN_GROUP_NAME` | Nom du groupe Authentik dont les membres deviennent admins |
| `AUTHENTIK_PUBLIC_URL` | Optionnel — URL publique d'Authentik, pour afficher un lien "Mon compte" (nav + page profil) permettant à chacun de changer son mot de passe. Masqué si absent |
| `TRAEFIK_NETWORK_NAME` | Nom du réseau Docker externe partagé avec Traefik et Authentik (défaut `traefik-proxy`) |
| `APP_DOMAIN` | Nom de domaine public utilisé par Traefik pour router vers l'app (ex: `octane.dandrove.com`) |
| `APP_PORT` | Port hôte utilisé uniquement par `docker-compose.dev.yml` (test local sans Traefik) |

View file

@ -34,6 +34,7 @@ async function initNav(activePage) {
</div>
<div class="nav-user">
<button type="button" class="icon-btn secondary" id="theme-toggle" title="Changer de thème" aria-label="Changer de thème"></button>
${me.authentikAccountUrl ? `<a href="${escapeHtml(me.authentikAccountUrl)}" target="_blank" rel="noopener" title="Gérer mon compte Authentik (mot de passe, etc.)">Mon compte</a>` : ''}
<a class="nav-profile-link" href="/profile.html">
${avatarHtml(me, 'avatar-sm')}
<span>${escapeHtml(me.name)}${me.isAdmin ? ' <span class="badge">admin</span>' : ''}</span>

View file

@ -46,7 +46,12 @@ function statTile(value, label) {
</div>
<div class="panel">
<p class="empty">Identité gérée par Authentik pour changer votre nom, email ou mot de passe, rendez-vous sur votre compte Authentik.</p>
<p class="empty">
Identité gérée par Authentik pour changer votre nom, email ou mot de passe,
${profile.authentikAccountUrl
? `rendez-vous sur <a href="${escapeHtml(profile.authentikAccountUrl)}" target="_blank" rel="noopener">votre compte Authentik</a>.`
: 'rendez-vous sur votre compte Authentik.'}
</p>
<a href="/auth/logout"><button type="button" class="danger">Se déconnecter</button></a>
</div>
`;

View file

@ -42,6 +42,11 @@ module.exports = {
process.env.POST_LOGOUT_REDIRECT_URI ||
(process.env.OIDC_REDIRECT_URI ? new URL('/', process.env.OIDC_REDIRECT_URI).href : undefined),
adminGroupName: process.env.ADMIN_GROUP_NAME || 'octane-admins',
// Optional: public URL of the Authentik instance (e.g. https://auth.dandrove.com),
// used only to show users a link to manage their own account/password.
// Distinct from AUTHENTIK_ISSUER_URL, which is often an internal/Docker
// address not reachable from a user's browser. Hidden from the UI if unset.
authentikPublicUrl: process.env.AUTHENTIK_PUBLIC_URL || null,
// All optional: the "add a song" autocomplete works with none of these set
// (title/artist suggestions come from Apple's free, key-less iTunes Search
// API). Without Spotify/YouTube credentials, the matching links are just

View file

@ -1,14 +1,28 @@
const express = require('express');
const usersRepo = require('../repositories/usersRepo');
const config = require('../config');
const asyncHandler = require('../lib/asyncHandler');
const router = express.Router();
function authentikAccountUrl() {
if (!config.authentikPublicUrl) return null;
return new URL('/if/user/', config.authentikPublicUrl).href;
}
router.get(
'/me',
asyncHandler(async (req, res) => {
const { id, name, username, email, avatar_url, is_admin } = req.user;
res.json({ id, name, username, email, avatarUrl: avatar_url, isAdmin: is_admin });
res.json({
id,
name,
username,
email,
avatarUrl: avatar_url,
isAdmin: is_admin,
authentikAccountUrl: authentikAccountUrl(),
});
})
);
@ -27,6 +41,7 @@ router.get(
isAdmin: is_admin,
createdAt: created_at,
stats,
authentikAccountUrl: authentikAccountUrl(),
});
})
);