CI / test (push) Successful in 1m53s
- Comptes en base (PBKDF2), rôles, désactivation qui tue la session, audit ; secours environnement pour l'opérateur ; liaison draco par utilisateur ; page /profile. - Espaces de travail : connexions, membres, sélection de projets ; board/notes/épingles/journal scopés par espace ; sélecteur d'espace, badge connexion. - Panneaux /admin (utilisateurs, connexions, espaces, paramètres — l'environnement amorce, le panneau gouverne). - /archives : archive locale réversible, archivage forge confirmé, purge de l'état local, export Markdown, file « à archiver ? » avec archivage en lot. - Correctif session : les comptes membres résolus par la base (la session n'est plus limitée à l'opérateur d'environnement). - 231 tests verts (12 nouveaux au palier 19).
96 lines
5.3 KiB
HTML
96 lines
5.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr" data-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="csrf-token" content="{{ csrf_token }}">
|
|
<title>Mon profil — Kanbante</title>
|
|
<link rel="stylesheet" href="/static/css/style.css?v={{ version }}">
|
|
</head>
|
|
<body>
|
|
{% include "_header.html" %}
|
|
|
|
<main class="focus-main">
|
|
<div class="page-head">
|
|
<h1>👤 Mon profil</h1>
|
|
<p class="page-sub">{{ profile_user.username }} · rôle : {{ profile_user.role }}</p>
|
|
</div>
|
|
{% if msg %}<p class="chip-ok">✅ {{ msg }}</p>{% endif %}
|
|
{% if err %}<p class="chip-warn">⚠️ {{ err }}</p>{% endif %}
|
|
{% if profile_user.must_change_password %}<p class="chip-warn">⚠️ Ton mot de passe est temporaire : change-le ci-dessous.</p>{% endif %}
|
|
|
|
<section class="briefing-card">
|
|
<h2>Informations</h2>
|
|
<form method="post" action="/profile" class="admin-form">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<label>Nom d'affichage <input type="text" name="display_name" value="{{ profile_user.display_name or '' }}"></label>
|
|
<button type="submit" class="btn-save btn-inline">Enregistrer</button>
|
|
</form>
|
|
<p class="muted">Mes espaces :
|
|
{% for m in memberships %}<span class="ws-dot" style="background: {{ m.color }}"></span> {{ m.name }} ({{ m.member_role }}){% if not loop.last %} · {% endif %}
|
|
{% else %}aucun{% endfor %}
|
|
</p>
|
|
</section>
|
|
|
|
<section class="briefing-card">
|
|
<h2>🔑 Mot de passe</h2>
|
|
{% if profile_user.id %}
|
|
<form method="post" action="/profile/password" class="admin-form">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<label>Mot de passe actuel <input type="password" name="current_password" required autocomplete="current-password"></label>
|
|
<label>Nouveau mot de passe <input type="password" name="new_password" required autocomplete="new-password"></label>
|
|
<button type="submit" class="btn-save btn-inline">Changer</button>
|
|
</form>
|
|
{% else %}
|
|
<p class="muted">Compte défini par l'environnement (KANBANTE_AUTH_*) : le mot de passe se change dans la configuration du déploiement.</p>
|
|
{% endif %}
|
|
</section>
|
|
|
|
<section class="briefing-card">
|
|
<h2>✦ Liaison draco (SSO)</h2>
|
|
{% if profile_user.draco_sub %}
|
|
<p>Compte lié à l'identité draco <code>{{ profile_user.draco_sub }}</code> — la connexion via ObsiGate ouvre directement cette session.</p>
|
|
<form method="post" action="/profile/draco/unlink" class="inline-form">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<button type="submit" class="btn-mini">Délier</button>
|
|
</form>
|
|
{% else %}
|
|
<p class="muted">Pas de liaison. Elle se crée automatiquement à la première visite où ta session Kanbante et ton cookie draco coexistent (par exemple en arrivant depuis ObsiGate).</p>
|
|
{% endif %}
|
|
</section>
|
|
|
|
<section class="briefing-card">
|
|
<h2>🔌 Mes connexions personnelles</h2>
|
|
<p class="muted">Visibles de toi seul. Pour les utiliser, ajoute-les à un de tes espaces (ou demande à un admin d'espace).</p>
|
|
{% for c in my_connections %}
|
|
<p>
|
|
{% if c.kind == 'github' %}🐙{% else %}🍵{% endif %} <strong>{{ c.name }}</strong>
|
|
<span class="muted">({{ c.slug }}) · {{ c.base_url }} · compte : {{ c.account_login or 'à tester' }} · jeton : {{ c.token_mask }}</span>
|
|
<form method="post" action="/profile/connections/{{ c.id }}/test" class="inline-form">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<button type="submit" class="btn-mini">🧪 Tester</button>
|
|
</form>
|
|
<form method="post" action="/profile/connections/{{ c.id }}/delete" class="inline-form" onsubmit="return confirm('Supprimer cette connexion personnelle ?');">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<button type="submit" class="btn-mini btn-danger">Supprimer</button>
|
|
</form>
|
|
</p>
|
|
{% endfor %}
|
|
<form method="post" action="/profile/connections" class="admin-form">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<label>Type
|
|
<select name="kind">
|
|
<option value="gitea">Gitea</option>
|
|
<option value="github">GitHub</option>
|
|
</select>
|
|
</label>
|
|
<label>Nom <input type="text" name="name" required></label>
|
|
<label>URL de base <input type="text" name="base_url" required placeholder="https://api.github.com"></label>
|
|
<label>Jeton d'accès <input type="password" name="token" autocomplete="off"></label>
|
|
<button type="submit" class="btn-save btn-inline">Ajouter</button>
|
|
</form>
|
|
</section>
|
|
</main>
|
|
</body>
|
|
</html>
|