Multiples corrections
This commit is contained in:
@@ -31,6 +31,14 @@ class AuthController extends Controller
|
||||
], 401);
|
||||
}
|
||||
|
||||
// Vérification si le compte est actif
|
||||
if (!$user->is_active) {
|
||||
return response([
|
||||
'status' => 'error',
|
||||
'message' => 'Votre compte a été désactivé par un administrateur.'
|
||||
], 403);
|
||||
}
|
||||
|
||||
// Log::info('Email reçu: ' . $request->email);
|
||||
// Log::info('Password saisi: ' . $request->password);
|
||||
// Log::info('Hachage en BDD: ' . $user->password);
|
||||
@@ -45,7 +53,7 @@ class AuthController extends Controller
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function register(Request $request)
|
||||
public function register(Request $request)
|
||||
{
|
||||
// 1. Validation des données (Standard Qualité)
|
||||
$validator = Validator::make($request->all(), [
|
||||
@@ -54,7 +62,7 @@ class AuthController extends Controller
|
||||
'password' => 'required|string|min:8|confirmed',
|
||||
]);
|
||||
|
||||
|
||||
|
||||
Log::info('Tentative de création', $request->all());
|
||||
|
||||
if ($validator->fails()) {
|
||||
@@ -90,8 +98,8 @@ class AuthController extends Controller
|
||||
$request->validate([
|
||||
'current_password' => 'required',
|
||||
'email' => [
|
||||
'sometimes',
|
||||
'email',
|
||||
'sometimes',
|
||||
'email',
|
||||
Rule::unique('users')->ignore($user->id) // Empêche les doublons en BDD
|
||||
],
|
||||
]);
|
||||
@@ -99,7 +107,7 @@ class AuthController extends Controller
|
||||
// 2. Vérification de sécurité (RGPD/Confidentialité)
|
||||
if (!Hash::check($request->current_password, $user->password)) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'status' => 'error',
|
||||
'message' => 'Le mot de passe actuel est incorrect'
|
||||
], 403);
|
||||
}
|
||||
@@ -114,4 +122,4 @@ class AuthController extends Controller
|
||||
'user' => $user
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,20 +30,16 @@ class DiagnosticController extends Controller
|
||||
return view('diagnostics.history', compact('history'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
public function store(Request $request, \App\Services\StressCalculator $calculator)
|
||||
{
|
||||
// Logique pour calculer le score Holmes-Rahe
|
||||
$totalPoints = 0;
|
||||
if ($request->has('events')) {
|
||||
$totalPoints = StressEvent::whereIn('id', $request->events)->sum('points');
|
||||
$points = StressEvent::whereIn('id', $request->events)->pluck('points')->toArray();
|
||||
$totalPoints = $calculator->calculateScore($points);
|
||||
}
|
||||
|
||||
$niveauStress = 'Faible';
|
||||
if ($totalPoints >= 300) {
|
||||
$niveauStress = 'Élevé';
|
||||
} elseif ($totalPoints >= 150) {
|
||||
$niveauStress = 'Modéré';
|
||||
}
|
||||
$niveauStress = $calculator->determineLevel($totalPoints);
|
||||
|
||||
// Enregistrement si l'utilisateur est connecté
|
||||
if (Auth::check()) {
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class StressEvent extends Model
|
||||
{
|
||||
//
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'event_name',
|
||||
'points',
|
||||
];
|
||||
}
|
||||
|
||||
+22
-23
@@ -2,61 +2,60 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Database\Factories\UserFactory;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Panel;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
class User extends Authenticatable implements FilamentUser
|
||||
{
|
||||
/** @use HasFactory<UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'id_role',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function emotionRecords()
|
||||
public function role(): BelongsTo
|
||||
{
|
||||
return $this->hasMany(EmotionRecord::class);
|
||||
return $this->belongsTo(Role::class, 'id_role');
|
||||
}
|
||||
|
||||
public function favoritedBy()
|
||||
public function emotionRecords(): HasMany
|
||||
{
|
||||
return $this->hasMany(EmotionRecord::class, 'user_id');
|
||||
}
|
||||
|
||||
public function favoritedActivities(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(RelaxationActivity::class, 'favorites', 'id_user', 'id_activite');
|
||||
}
|
||||
|
||||
public function canAccessPanel(Panel $panel): bool
|
||||
{
|
||||
// Autorise l'accès si l'utilisateur est actif et a le rôle 'Admin'
|
||||
return $this->is_active && $this->role && $this->role->libelle === 'Admin';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
if (config('app.env') === 'production' || config('app.env') === 'local') {
|
||||
\Illuminate\Support\Facades\URL::forceScheme('https');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Providers\AppServiceProvider;
|
||||
|
||||
return [
|
||||
AppServiceProvider::class,
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\Filament\AdminPanelProvider::class,
|
||||
];
|
||||
|
||||
+4
-1
@@ -8,6 +8,7 @@
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"blade-ui-kit/blade-heroicons": "^2.7",
|
||||
"filament/filament": "^3.2",
|
||||
"guzzlehttp/guzzle": "^7.10",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/sanctum": "^4.0",
|
||||
@@ -53,7 +54,8 @@
|
||||
],
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
"@php artisan package:discover --ansi",
|
||||
"@php artisan filament:upgrade"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||
@@ -79,6 +81,7 @@
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"platform-check": false,
|
||||
"allow-plugins": {
|
||||
"pestphp/pest-plugin": true,
|
||||
"php-http/discovery": true
|
||||
|
||||
Generated
+1692
-158
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@ class UserFactory extends Factory
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'remember_token' => Str::random(10),
|
||||
'id_role' => \App\Models\Role::first() ?? \App\Models\Role::create(['libelle' => 'Utilisateur']),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,13 @@ class DatabaseSeeder extends Seeder
|
||||
|
||||
$adminRole = Role::where('libelle', 'Admin')->first();
|
||||
|
||||
User::create([
|
||||
'name' => 'AdminCESI',
|
||||
'email' => 'admin@cesizen.fr',
|
||||
'password' => Hash::make('okokokok'), // Toujours hacher !
|
||||
'id_role' => $adminRole->id,
|
||||
]);
|
||||
User::firstOrCreate(
|
||||
['email' => 'admin@cesizen.fr'],
|
||||
[
|
||||
'name' => 'AdminCESI',
|
||||
'password' => Hash::make('okokokok'),
|
||||
'id_role' => $adminRole->id,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "WEB",
|
||||
"name": "www",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
@@ -14,20 +14,47 @@
|
||||
|
||||
<nav class="flex items-center gap-6" role="navigation" aria-label="Menu utilisateur">
|
||||
@auth
|
||||
<a href="{{ route('profile.index') }}" class="flex items-center gap-3 px-4 py-1.5 bg-slate-50 rounded-lg border border-slate-200 shadow-sm hover:border-[#000091] transition-all group">
|
||||
<div class="text-right">
|
||||
<p class="text-sm font-bold leading-none text-slate-900 group-hover:text-[#000091]">{{ Auth::user()->name }}</p>
|
||||
<p class="text-[10px] text-slate-500 font-bold uppercase tracking-tighter">Mon Profil</p>
|
||||
</div>
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode(Auth::user()->name) }}&background=000091&color=fff" class="w-9 h-9 rounded-lg border border-slate-200" alt="Avatar de {{ Auth::user()->name }}">
|
||||
</a>
|
||||
<form action="{{ route('logout') }}" method="POST" class="inline">
|
||||
@csrf
|
||||
<button type="submit" class="text-xs font-bold text-slate-500 hover:text-[#E1000F] uppercase tracking-tighter flex items-center gap-1">
|
||||
<x-heroicon-o-arrow-left-on-rectangle class="h-4 w-4" />
|
||||
Quitter
|
||||
<div class="relative" x-data="{ open: false }">
|
||||
<button @click="open = !open" @click.away="open = false" class="flex items-center gap-3 px-4 py-1.5 bg-slate-50 rounded-lg border border-slate-200 shadow-sm hover:border-[#000091] transition-all group">
|
||||
<div class="text-right">
|
||||
<p class="text-sm font-bold leading-none text-slate-900 group-hover:text-[#000091]">{{ Auth::user()->name }}</p>
|
||||
<p class="text-[10px] text-slate-500 font-bold uppercase tracking-tighter">Mon Profil</p>
|
||||
</div>
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode(Auth::user()->name) }}&background=000091&color=fff" class="w-9 h-9 rounded-lg border border-slate-200" alt="Avatar de {{ Auth::user()->name }}">
|
||||
<x-heroicon-o-chevron-down class="h-4 w-4 text-slate-400 group-hover:text-[#000091] transition-transform" ::class="open ? 'rotate-180' : ''" />
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Dropdown Menu -->
|
||||
<div x-show="open"
|
||||
x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="opacity-0 scale-95"
|
||||
x-transition:enter-end="opacity-100 scale-100"
|
||||
class="absolute right-0 mt-2 w-56 bg-white border border-slate-200 rounded-lg shadow-xl z-50 py-2 overflow-hidden">
|
||||
|
||||
<a href="{{ route('profile.index') }}" class="flex items-center gap-3 px-4 py-2.5 text-sm font-medium text-slate-700 hover:bg-slate-50 transition-colors">
|
||||
<x-heroicon-o-user class="h-4 w-4 text-slate-400" />
|
||||
Mon compte
|
||||
</a>
|
||||
|
||||
@if(Auth::user()->role && Auth::user()->role->libelle === 'Admin')
|
||||
<div class="border-t border-slate-100 my-1"></div>
|
||||
<a href="/admin" class="flex items-center gap-3 px-4 py-2.5 text-sm font-bold text-[--fr-blue] hover:bg-blue-50 transition-colors">
|
||||
<x-heroicon-o-shield-check class="h-4 w-4" />
|
||||
Administration
|
||||
</a>
|
||||
@endif
|
||||
|
||||
<div class="border-t border-slate-100 my-1"></div>
|
||||
|
||||
<form action="{{ route('logout') }}" method="POST" class="block w-full">
|
||||
@csrf
|
||||
<button type="submit" class="flex items-center gap-3 w-full px-4 py-2.5 text-sm font-medium text-red-600 hover:bg-red-50 transition-colors">
|
||||
<x-heroicon-o-arrow-left-on-rectangle class="h-4 w-4" />
|
||||
Déconnexion
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="/login" class="text-sm font-bold text-[#000091] hover:underline px-2 py-2">Se connecter</a>
|
||||
|
||||
@@ -40,6 +40,16 @@
|
||||
Exercices de Respiration
|
||||
</a>
|
||||
|
||||
<!-- Informations / Guides -->
|
||||
<a href="{{ route('informations.index') }}"
|
||||
class="flex items-center gap-4 px-4 py-3 rounded-sm transition-all group {{ request()->routeIs('informations.*') ? 'text-white bg-[#000091] font-bold shadow-md' : 'text-slate-700 hover:bg-slate-50 font-medium border-b border-slate-100/50' }}"
|
||||
{!! request()->routeIs('informations.*') ? 'aria-current="page"' : '' !!}>
|
||||
<div class="w-8 h-8 rounded-sm flex items-center justify-center transition-colors {{ request()->routeIs('informations.*') ? 'bg-white/20 text-white' : 'bg-blue-50 text-[--fr-blue]' }}" aria-hidden="true">
|
||||
<x-heroicon-o-document-text class="h-4 w-4" />
|
||||
</div>
|
||||
Guides & Informations
|
||||
</a>
|
||||
|
||||
<div class="pt-10 space-y-1">
|
||||
<p class="text-[10px] font-bold text-slate-500 uppercase tracking-[0.2em] mb-4 px-4">Services de l'État</p>
|
||||
<a href="#" class="flex items-center justify-between px-4 py-2 text-sm text-slate-600 hover:text-[--fr-blue] font-medium transition-colors">
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
Faire mon bilan de santé
|
||||
</a>
|
||||
<a href="{{ route('relaxation.index') }}" class="px-8 py-3.5 bg-white border-2 border-[#000091] text-[#000091] font-bold rounded-sm hover:bg-slate-50 transition-all">
|
||||
Voir mes favoris
|
||||
Travailler sa respiration
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,7 +77,7 @@
|
||||
</div>
|
||||
<h4 class="text-xl font-bold text-slate-900 mb-2">Guides Pratiques</h4>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-6">Consultez les fiches de prévention sur le sommeil et la nutrition.</p>
|
||||
<a href="#" class="inline-flex items-center gap-2 text-sm font-bold text-[--fr-blue] hover:underline underline-offset-4 decoration-2">
|
||||
<a href="{{ route('informations.index') }}" class="inline-flex items-center gap-2 text-sm font-bold text-[--fr-blue] hover:underline underline-offset-4 decoration-2">
|
||||
Lire les guides
|
||||
<x-heroicon-o-arrow-right class="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
@@ -105,7 +105,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Global Footer Gov -->
|
||||
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -25,4 +25,8 @@ Route::middleware('auth:sanctum')->group(function () {
|
||||
|
||||
Route::get('/emotions', [App\Http\Controllers\Api\EmotionController::class, 'index']);
|
||||
Route::post('/emotions', [App\Http\Controllers\Api\EmotionController::class, 'store']);
|
||||
|
||||
// Routes pour les informations (accessibles aux utilisateurs connectés)
|
||||
Route::get('/informations', [App\Http\Controllers\Api\InformationController::class, 'index']);
|
||||
Route::get('/informations/{id}', [App\Http\Controllers\Api\InformationController::class, 'show']);
|
||||
});
|
||||
|
||||
@@ -9,10 +9,14 @@ use App\Http\Controllers\Web\RelaxationController;
|
||||
use App\Http\Controllers\Web\AuthController;
|
||||
use App\Http\Controllers\Web\ProfileController;
|
||||
|
||||
use App\Http\Controllers\Web\InformationController;
|
||||
|
||||
// Public Routes
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('home');
|
||||
Route::get('/diagnostics', [DiagnosticController::class, 'index'])->name('diagnostics.index');
|
||||
Route::get('/relaxation', [RelaxationController::class, 'index'])->name('relaxation.index');
|
||||
Route::get('/informations', [InformationController::class, 'index'])->name('informations.index');
|
||||
Route::get('/informations/{id}', [InformationController::class, 'show'])->name('informations.show');
|
||||
|
||||
// Authentification
|
||||
Route::get('/login', [AuthController::class, 'showLogin'])->name('login');
|
||||
|
||||
Reference in New Issue
Block a user