Skip to content

Commit

Permalink
#4 - users and authentication (#32)
Browse files Browse the repository at this point in the history
* #4 - wip, basic login

* #4 - wip

* #4 - wip

* #4 - wip

* #4 - wip

* #4 - fixed bugs with logout, changes in routing

* #4 - fixed students tests
  • Loading branch information
KarolZygadlo authored Sep 25, 2023
1 parent ddbb902 commit 75393f2
Show file tree
Hide file tree
Showing 18 changed files with 508 additions and 77 deletions.
24 changes: 24 additions & 0 deletions app/Http/Controllers/Dashboard/LogoutController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Dashboard;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LogoutController extends Controller
{
public function __invoke(Request $request): RedirectResponse
{
Auth::logout();

$request->session()->invalidate();

$request->session()->regenerateToken();

return redirect()->route("main");
}
}
35 changes: 35 additions & 0 deletions app/Http/Controllers/Dashboard/PasswordUpdateController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Dashboard;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
use Inertia\Response;

class PasswordUpdateController extends Controller
{
public function edit(): Response
{
return inertia("Dashboard/PasswordUpdate");
}

public function update(Request $request): RedirectResponse
{
$validated = $request->validate([
"current_password" => ["required", "current_password"],
"password" => ["required", Password::defaults(), "confirmed"],
]);

$request->user()->update([
"password" => Hash::make($validated["password"]),
]);

return redirect()->back()
->with("success", "Zaktualizowano hasło");
}
}
36 changes: 36 additions & 0 deletions app/Http/Controllers/Public/LoginController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Public;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Response;

class LoginController extends Controller
{
public function create(): Response
{
return inertia("Public/Login", [
"universityLogo" => "https://irg2023.collegiumwitelona.pl/assets/logos/cwup.png",
]);
}

public function store(Request $request): RedirectResponse
{
$credentials = $request->only("email", "password");

if (Auth::attempt($credentials)) {
$request->session()->regenerate();

return redirect()->route("dashboard");
}

return back()->withErrors([
"email" => "Niepoprawne dane logowania",
]);
}
}
15 changes: 8 additions & 7 deletions app/Http/Middleware/HandleInertiaRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@

class HandleInertiaRequests extends Middleware
{
protected $rootView = "app";

public function version(Request $request): ?string
{
return parent::version($request);
}

public function share(Request $request): array
{
return array_merge(parent::share($request), [
"auth" => $this->getAuthData($request),
"flash" => $this->getFlashedData($request),
]);
}

protected function getAuthData(Request $request): array
{
return [
"user" => $request->user() ? $request->user()->only("id", "name", "email") : null,
];
}

protected function getFlashedData(Request $request): Closure
{
return fn(): array => [
Expand Down
3 changes: 1 addition & 2 deletions app/Http/Middleware/RedirectIfAuthenticated.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace App\Http\Middleware;

use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
Expand All @@ -18,7 +17,7 @@ public function handle(Request $request, Closure $next, string ...$guards): Resp

foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
return redirect()->route("dashboard");
}
}

Expand Down
21 changes: 12 additions & 9 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,31 @@

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

/**
* @property string $id
* @property string $name
* @property string $email
* @property string $password
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class User extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use Notifiable;
use HasUlids;

protected $fillable = [
"name",
"email",
"password",
];
protected $guarded = [];
protected $hidden = [
"password",
"remember_token",
];
protected $casts = [
"email_verified_at" => "datetime",
"password" => "hashed",
];
}
21 changes: 5 additions & 16 deletions database/factories/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

namespace Database\Factories;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;

/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
* @extends Factory<User>
*/
class UserFactory extends Factory
{
Expand All @@ -21,20 +22,8 @@ public function definition(): array
{
return [
"name" => fake()->name(),
"email" => fake()->unique()->safeEmail(),
"email_verified_at" => now(),
"password" => "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi",
"remember_token" => Str::random(10),
"email" => fake()->email(),
"password" => Hash::make("password"),
];
}

/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): static
{
return $this->state(fn(array $attributes) => [
"email_verified_at" => null,
]);
}
}
4 changes: 1 addition & 3 deletions database/migrations/2014_10_12_000000_create_users_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@
public function up(): void
{
Schema::create("users", function (Blueprint $table): void {
$table->id();
$table->ulid("id")->primary();
$table->string("name");
$table->string("email")->unique();
$table->timestamp("email_verified_at")->nullable();
$table->string("password");
$table->rememberToken();
$table->timestamps();
});
}
Expand Down
5 changes: 2 additions & 3 deletions database/seeders/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
User::factory(1)->create();
}
}
8 changes: 5 additions & 3 deletions resources/js/Layouts/DashboardLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ClipboardIcon,
CodeBracketSquareIcon,
Cog6ToothIcon,
LockOpenIcon,
} from '@heroicons/vue/24/outline'
import { watch } from 'vue'
import { useToast } from 'vue-toastification'
Expand All @@ -37,6 +38,7 @@ const navigation = [
elements: [
{ name: 'Dashboard', href: '/dashboard', icon: HomeIcon, current: true },
{ name: 'Ustawienia', href: '#', icon: Cog6ToothIcon, current: false },
{ name: 'Aktualizacja hasła', href: '/dashboard/password', icon: LockOpenIcon, current: false },
{ name: 'Aktualności', href: '#', icon: NewspaperIcon, current: false },
{ name: 'FAQ', href: '#', icon: QuestionMarkCircleIcon, current: false },
{ name: 'Formy kontaktu', href: '#', icon: AtSymbolIcon, current: false },
Expand Down Expand Up @@ -150,7 +152,7 @@ watch(() => props.flash, (flash) => {
<HomeIcon class="h-6 w-6 text-gray-700" title="Strona główna" />
<span aria-hidden="true">Strona główna</span>
</InertiaLink>
<InertiaLink href="#" class="flex items-center gap-x-4 px-6 py-3 text-sm font-semibold leading-6 text-gray-900 hover:bg-gray-50">
<InertiaLink href="/dashboard/logout" method="post" as="button" class="flex items-center gap-x-4 px-6 py-3 text-sm font-semibold leading-6 text-gray-900 hover:bg-gray-50">
<PowerIcon class="h-6 w-6 text-gray-700" title="Wyloguj się" />
<span aria-hidden="true">Wyloguj się</span>
</InertiaLink>
Expand All @@ -172,10 +174,10 @@ watch(() => props.flash, (flash) => {
<span class="sr-only">Strona główna</span>
<HomeIcon class="h-6 w-6 text-gray-700" title="Strona główna" />
</InertiaLink>
<a href="#">
<InertiaLink href="/dashboard/logout" method="post" as="button">
<span class="sr-only">Wyloguj się</span>
<PowerIcon class="h-6 w-6 text-gray-700" title="Wyloguj się" />
</a>
</InertiaLink>
</div>

<main class="py-10 lg:pl-72">
Expand Down
19 changes: 13 additions & 6 deletions resources/js/Layouts/PublicLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ const mobileMenuOpen = ref(false)
</Link>
</div>
<div class="hidden lg:flex lg:flex-1 lg:justify-end">
<Link href="#" class="text-sm font-semibold leading-6 text-gray-900">
Logowanie <span
aria-hidden="true"
>&rarr;</span>
<Link v-if="$page.props.auth.user" href="/dashboard" class="text-sm font-semibold leading-6 text-gray-900">
Dashboard <span aria-hidden="true">&rarr;</span>
</Link>
<Link v-else href="/login" class="text-sm font-semibold leading-6 text-gray-900">
Logowanie <span aria-hidden="true">&rarr;</span>
</Link>
</div>
</nav>
Expand All @@ -64,7 +65,12 @@ const mobileMenuOpen = ref(false)
</Link>
</div>
<div class="py-6">
<Link href="#"
<Link v-if="$page.props.auth.user" href="/dashboard"
class="-mx-3 block rounded-lg px-3 py-2.5 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50"
>
Dashboard
</Link>
<Link v-else href="/login"
class="-mx-3 block rounded-lg px-3 py-2.5 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50"
>
Logowanie
Expand All @@ -86,7 +92,8 @@ const mobileMenuOpen = ref(false)
<p class="text-center text-xs leading-5 text-gray-500">
2023
<EllipsisHorizontalIcon class="mx-2 inline-block w-6" />
<a class="font-semibold" href="https://github.com/blumilksoftware/keating" target="_blank">keating management system</a>
<a class="font-semibold" href="https://github.com/blumilksoftware/keating" target="_blank">keating
management system</a>
developed at
<a class="font-semibold" href="https://blumilk.pl/" target="_blank">Blumilk</a>
</p>
Expand Down
Loading

0 comments on commit 75393f2

Please sign in to comment.