retour sur v5rc9

Locked by Fred · 15 Jan 2026 12:33 • Solved by arpinux · 14 Jan 2026 15:04
Avatar
Posts 224 1010

salut :)

mise à jour effectuée sur v5rc8 sans soucis.

bugs :

  • impossible de marquer comme résolu
  • impossible d'épingler

logs en pj

Attachments
logs.zip
30.27 KB Please log in to download files.
  • french solved
Avatar
Posts 460 2057

Ah, tu vois, je te l’avais bien dit ! 😉
Mais cette fois, je reproduis facilement l’erreur de mon côté, je vais corriger ça tout de suite. Merci pour ton retour !

Avatar
Posts 224 1010

bug groupes modifiés :
contexte : une fois l'installation rc9 faite, j'ai modifié le groupe "Membre" en "membre". une fois la modification appliquée, plusieurs utilisateurs sont venus s'inscrire, ce qui a créé automatiquement un nouveau groupe "Membre", rendant ainsi ma modification "membre" inutile.

Avatar
Posts 460 2057

Bien vu !
J'ai corrigé les options de modération (épingles/fermetures/résolutions) dans l'archive en téléchargement via le lien officiel.
J'ai également résolu le problème lié au groupe.

Si tu ne souhaites pas mettre à jour toute l'archive, voici le fichier concerné :

  • app/Controllers/Auth/RegisterController.php
<?php
/*
 * Project name: Flatboard 5
 * Project URL: https://flatboard.org
 * Author: Frédéric Kaplon and contributors
 * All Flatboard code is released under the GPL3 license.
 *
 * Flatboard 5 - Contrôleur Register
 */

namespace App\Controllers\Auth;

use App\Core\Controller;
use App\Core\Session;
use App\Core\Validator;
use App\Core\RateLimiter;
use App\Core\Config;
use App\Models\User;
use App\Services\EmailService;

class RegisterController extends Controller
{
    public function show()
    {
        if (Session::get('user_id')) {
            $this->redirect(\App\Helpers\UrlHelper::to('/'));
            return;
        }

        $config = Config::getInstance();
        if (!$config->get('registration_enabled', true)) {
            Session::flash('error', \App\Helpers\Translator::trans('auth.registrationDisabled', [], 'errors'));
            $this->redirect(\App\Helpers\UrlHelper::to('/'));
            return;
        }

        $config = Config::getInstance();
        $forumTitle = $config->get('forum.title');
        $forumDescription = $config->get('forum.description');
        // Normaliser les chaînes vides en null
        if ($forumTitle === '') {
            $forumTitle = null;
        }
        if ($forumDescription === '') {
            $forumDescription = null;
        }
        $siteDescription = $config->get('site_description', $forumDescription);
        $pageTitle = \App\Helpers\Translator::trans('register.title', [], 'auth') ?: 'Register';

        $this->view('auth/register', [
            'bannerType' => 'index',
            'forumTitle' => $forumTitle,
            'forumDescription' => $forumDescription,
            'pageTitle' => $pageTitle,
            'pageIcon' => 'fas fa-user-plus',
            // SEO
            'title' => $pageTitle,
            'description' => $siteDescription,
            'canonical' => '/register',
        ], 'frontend');
    }

    public function register()
    {
        $limiter = new RateLimiter();
        $ip = $this->request->getIp();

        // Vérifier si l'IP est bannie
        if (\App\Models\Ban::isIpBanned($ip)) {
            $ban = \App\Models\Ban::getActiveByIp($ip);
            \App\Core\Logger::security('Registration attempt from banned IP', [
                'ip' => $ip,
                'email' => $this->request->get('email'),
                'ban_id' => $ban['id'] ?? null
            ]);
            Session::flash('error', \App\Helpers\Translator::trans('auth.account.banned', [], 'errors') ?: 'Votre adresse IP a été bannie.');
            $this->redirect(\App\Helpers\UrlHelper::to('/register'));
            return;
        }

        if (!$limiter->check('register', $ip)) {
            \App\Core\Logger::security('Rate limit exceeded for registration attempt', [
                'ip' => $ip,
                'email' => $this->request->get('email')
            ]);
            Session::flash('error', \App\Helpers\Translator::trans('auth.tooManyRegisterAttempts', [], 'errors'));
            $this->redirect(\App\Helpers\UrlHelper::to('/register'));
            return;
        }

        $config = Config::getInstance();
        if (!$config->get('registration_enabled', true)) {
            Session::flash('error', \App\Helpers\Translator::trans('auth.registrationDisabled', [], 'errors'));
            $this->redirect(\App\Helpers\UrlHelper::to('/'));
            return;
        }

        $validator = new Validator($this->request->all());
        $validator->required('username')
            ->min('username', 3)
            ->max('username', 30)
            ->regex('username', '/^[a-zA-Z0-9_-]+$/', \App\Helpers\Translator::trans('validation.username.invalidFormat', [], 'errors') ?: 'Le nom d\'utilisateur ne peut contenir que des lettres, chiffres, tirets et underscores');
        $validator->required('email')->email('email');
        $validator->required('password')->min('password', 8)->confirmed('password');

        if (!$validator->isValid()) {
            Session::flash('errors', $validator->getErrors());
            $this->redirect(\App\Helpers\UrlHelper::to('/register'));
            return;
        }

        $username = $this->request->get('username');
        $email = $this->request->get('email');
        $password = $this->request->get('password');

        // Vérifier si l'utilisateur existe déjà
        if (User::findByEmail($email)) {
            \App\Core\Logger::warning('Registration attempt with existing email', [
                'ip' => $ip,
                'email' => $email,
                'username' => $username
            ]);
            Session::flash('error', \App\Helpers\Translator::trans('validation.email.alreadyUsed', [], 'errors'));
            $this->redirect(\App\Helpers\UrlHelper::to('/register'));
            return;
        }

        if (User::findByUsername($username)) {
            \App\Core\Logger::warning('Registration attempt with existing username', [
                'ip' => $ip,
                'email' => $email,
                'username' => $username
            ]);
            Session::flash('error', \App\Helpers\Translator::trans('validation.username.alreadyUsed', [], 'errors'));
            $this->redirect(\App\Helpers\UrlHelper::to('/register'));
            return;
        }

        $emailVerificationEnabled = $config->get('email_verification', false);

        // Initialiser les groupes et permissions par défaut si nécessaire
        \App\Models\Group::initDefaults();
        \App\Helpers\PermissionHelper::initDefaults();

        // Récupérer le groupe membre via GroupHelper (utilise le champ 'type', pas le nom)
        // Permet le renommage libre du groupe sans casser la fonctionnalité
        $memberGroupId = \App\Helpers\GroupHelper::getMemberGroupId();

        if (!$memberGroupId) {
            // Si aucun groupe membre n'existe après l'initialisation, c'est une erreur critique
            \App\Core\Logger::error('Member group not found after initialization', [
                'ip' => $ip
            ]);
            Session::flash('error', \App\Helpers\Translator::trans('auth.system.error', [], 'errors') ?: 'Erreur système : groupe membre introuvable');
            $this->redirect(\App\Helpers\UrlHelper::to('/register'));
            return;
        }

        // Créer l'utilisateur avec le groupe membre par défaut
        try {
            $userId = User::create([
                'username' => $username,
                'email' => $email,
                'password' => $password,
                'email_verified' => !$emailVerificationEnabled,
                'group_id' => $memberGroupId
            ]);
        } catch (\Exception $e) {
            // Gérer les violations de contrainte UNIQUE (race condition)
            if ($e->getCode() == 409 || strpos($e->getMessage(), 'already exists') !== false) {
                if (strpos($e->getMessage(), 'Email') !== false) {
                    \App\Core\Logger::warning('Registration failed: Email already exists (race condition)', [
                        'ip' => $ip,
                        'email' => $email,
                        'username' => $username
                    ]);
                    Session::flash('error', \App\Helpers\Translator::trans('validation.email.alreadyUsed', [], 'errors'));
                } elseif (strpos($e->getMessage(), 'Username') !== false) {
                    \App\Core\Logger::warning('Registration failed: Username already exists (race condition)', [
                        'ip' => $ip,
                        'email' => $email,
                        'username' => $username
                    ]);
                    Session::flash('error', \App\Helpers\Translator::trans('validation.username.alreadyUsed', [], 'errors'));
                } else {
                    Session::flash('error', \App\Helpers\Translator::trans('general.errorOccurred', [], 'errors') ?: 'Erreur lors de l\'inscription');
                }
                $this->redirect(\App\Helpers\UrlHelper::to('/register'));
                return;
            }
            // Relancer l'exception si ce n'est pas une contrainte UNIQUE
            throw $e;
        }

        \App\Core\Logger::info('New user registered', [
            'user_id' => $userId,
            'username' => $username,
            'email' => $email,
            'ip' => $ip,
            'email_verified' => !$emailVerificationEnabled,
            'group_id' => $memberGroupId
        ]);

        // Déclencher l'événement user.registered via les plugins
        if (class_exists('\App\Core\Plugin')) {
            $createdUser = User::find($userId);
            if ($createdUser) {
                \App\Core\Plugin::trigger('user.registered', $createdUser);
            }
        }

        // Envoyer l'email de vérification si nécessaire
        if ($emailVerificationEnabled) {
            $token = bin2hex(random_bytes(32));
            $expiresAt = time() + (3600 * 24 * 7); // 7 jours

            // Stocker le token
            $storage = \App\Storage\StorageFactory::create();
            $storage->createEmailVerificationToken($userId, $token, $expiresAt);

            // Envoyer l'email
            $emailService = new EmailService();
            $siteUrl = rtrim($config->get('site_url', ''), '/');
            $verificationUrl = $siteUrl . '/verify-email?token=' . $token;
            $emailService->sendVerification($email, $token, $verificationUrl);

            Session::flash('success', \App\Helpers\Translator::trans('register.successVerifyEmail', [], 'auth'));
            $this->redirect(\App\Helpers\UrlHelper::to('/login'));
        } else {
            // Connecter automatiquement si la vérification email n'est pas activée
            Session::set('user_id', $userId);
            Session::set('username', $username);
            // Déterminer is_admin depuis le groupe
            $isAdmin = \App\Helpers\GroupHelper::isAdmin($userId);
            Session::set('is_admin', $isAdmin);
            Session::flash('success', \App\Helpers\Translator::trans('register.success', [], 'auth'));
            $this->redirect(\App\Helpers\UrlHelper::to('/'));
        }
    }
}
Avatar
Posts 224 1010

re :)

j'ai remplacé le fichier correspondant mais je ne peux toujours pas épingler/résolu.

pour le groupe "Membre/membre", j'ai basculé les utilisateurs sur "membre" mais maintenant, comment je fais pour supprimer le groupe "Membre" ?

edit : j'ai tenté de téléchargé l'archive complète mais le lien "Téléchargement" est inactif.

Edited on  Jan 11, 2026  By  arpinux .

Avatar
Posts 224 1010

re :)

pour le debug : la fonction debug est activé par défaut (normal) mais est grisée et je ne peux la désactiver. lorsque je me connecte à l'interface d'administration, j'ai un pop-up " Mode debug verrouillé temporairement pour maintenance " alors que je ne suis pas en mode maintenance.

Avatar
Posts 224 1010

re :)

lien de téléchargement fonctionnel, du coup, mise à jour depuis l'archive.

bug épingler/résolu fonctionnel :)

en revanche, mode debug toujours vérrouillé par défaut et non désactivable depuis l'interface d'admin.

Avatar
Posts 224 1010

re :)

pour le groupe "Member", je l'ai tout simplement effacé de /stockage/json/groups.json ;)

Avatar
Posts 224 1010

re :)

un certaine latence est remarquée sur le forum. il faut recharger plusieurs fois la page d'accueil pour voir appara

Avatar
Posts 460 2057

Hello Arpinux, je vois que tu te fais toi-même les questions et réponses ! 😄

1. Mode débogage actif

Concernant le mode débogage restant activé, c'est une décision de ma part. La minification des assets est assez complexe et peut parfois causer des problèmes d'affichage 🖥️. Je travaille dessus pour la prochaine version 🚀.

2. Problème de groupe

Le problème de groupe est maintenant résolu et corrigé dans la version disponible en téléchargement 📥. J’ai également découvert une anomalie qui invalidait les groupes, réinitialisant fréquemment les permissions 🔒, ce qui n'était pas idéal. Cela a également été corrigé ✅.

3. Latence globale du forum

Pour la latence globale du forum sur l'index, je vais affiner la gestion du cache, qui est peut-être un peu trop agressive pour le moment 🕐. Une fois la minification en place et la gestion du cache optimisée, Flatboard sera beaucoup plus réactif ⚡.

4. Conclusion

La base est maintenant solide, il ne reste plus que quelques ajustements à faire en fonction des retours 🛠️.

Donc, pas de panique 😌 !

Avatar
Posts 224 1010

pas de panique de mon côté :)

oki pour le debug par défaut.

je passe en pro quand tu passes en stable :) merci encore pour ton travail et ta réactivité :)

  • Like(1)
    FredFred
Avatar
Posts 224 1010

re :)

un petit bug : dans les paramêtres du profil, section "notifications", si je déselectionne les notifications web, elles reviennent par défaut.

Edited on  Jan 11, 2026  By  arpinux .

Avatar
Posts 460 2057

arpinux

Archive à jour !
PS: les signature sont aussi disponible au survol des avatars ;)

Edited on  Jan 12, 2026  By  Fred .

Avatar
Posts 224 1010

cool pour les signatures :) mais il faudrait modifier la description dans les paramêtres du profil car "Votre signature apparaîtra sous vos messages. Markdown supporté. " est spécifié ;)

je chope l'archive dès que le bouton "download" fonctionne ;)

Edited on  Jan 12, 2026  By  arpinux .

Avatar
Posts 224 1010

archive téléchargée, mise à jour effectuée et oops ... 404 sur la page d'accueil /forum/ :D

bref, j'ai recollé ma sauvegarde. je retente plus tard pour récolter les logs mais là, j'ai pas le temps.

Avatar
Posts 224 1010

re :)

ah bah si, j'ai un peu de temps :)

donc : mise à jour effectuée par écrasement simple, bug : page principale en 404, logs en pj

puis j'ai re-re-collé mon backup pour garder mon forum accessible.

Attachments
logs.zip
13 KB Please log in to download files.
Avatar
Posts 460 2057

Salut, mise à jour RC10 dispo qui re-corrige cette erreur de route....Et plein d'autres bugs.

Avatar
Posts 224 1010

cool :) je télécharge dès que le bouton est actif ;)

Avatar
Posts 460 2057

Je pige pas ce problème, je viens de faire le test de télécharger l'archive avant de publier justement avant de poster cette mise à jour, tu as quoi une 404 ?

Avatar
Posts 460 2057

Avant que tu me le dise, j'ai corrigé le problème de l'affichage de :root{}, il faut re téléchargé l'archive

This discussion is locked

Log in to reply
Navigation
22 Posts
post #1
10 Jan 2026
By Utilisateur
Statistics
177
Discussions
965
Replies
21
Flatboarders
6
Contributors
New member : sietsietnoa
Online
35 Guests online