generated from thegrind/laravel-dockerized
Bunch of progress
This commit is contained in:
parent
9746756a44
commit
38c0c70ded
3
.gitignore
vendored
3
.gitignore
vendored
@ -21,4 +21,5 @@ yarn-error.log
|
|||||||
/.nova
|
/.nova
|
||||||
/.vscode
|
/.vscode
|
||||||
/.zed
|
/.zed
|
||||||
/storage/oauth/*
|
/storage/oauth/*
|
||||||
|
/storage/avatars/*
|
@ -172,7 +172,8 @@ class OIDCController extends Controller
|
|||||||
'sub' => (string) $user->id,
|
'sub' => (string) $user->id,
|
||||||
'email' => $user->email,
|
'email' => $user->email,
|
||||||
'name' => $user->name,
|
'name' => $user->name,
|
||||||
'preferred_username' => str($user->name)->slug()->toString(),
|
'preferred_username' => $user->preferred_username,
|
||||||
|
'picture' => $user->avatar ? $user->avatarUrl() : null
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +207,14 @@ class OIDCController extends Controller
|
|||||||
'scopes_supported' => ["openid", "profile", "email"],
|
'scopes_supported' => ["openid", "profile", "email"],
|
||||||
'response_types_supported' => ["code"],
|
'response_types_supported' => ["code"],
|
||||||
"jwks_uri" => route('auth.keys'),
|
"jwks_uri" => route('auth.keys'),
|
||||||
"id_token_signing_alg_values_supported" => ["RS256"]
|
"id_token_signing_alg_values_supported" => ["RS256"],
|
||||||
|
'claims_supported' => [
|
||||||
|
'sub',
|
||||||
|
'email',
|
||||||
|
'name',
|
||||||
|
'preferred_username',
|
||||||
|
'picture'
|
||||||
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
93
app/Livewire/Forms/UserProfile.php
Normal file
93
app/Livewire/Forms/UserProfile.php
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Forms;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Session;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Livewire\Attributes\Validate;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithFileUploads;
|
||||||
|
|
||||||
|
class UserProfile extends Component
|
||||||
|
{
|
||||||
|
use WithFileUploads;
|
||||||
|
// Profile info
|
||||||
|
public string $name = '';
|
||||||
|
public string $email = '';
|
||||||
|
public ?string $preferred_username = null;
|
||||||
|
public string $avatar = '';
|
||||||
|
#[Validate('image|max:10000')]
|
||||||
|
public $avatarUpload;
|
||||||
|
// Password
|
||||||
|
public string $current_password = '';
|
||||||
|
public string $password = '';
|
||||||
|
public string $password_confirmation = '';
|
||||||
|
|
||||||
|
public function mount(): void
|
||||||
|
{
|
||||||
|
$this->name = Auth::user()->name;
|
||||||
|
$this->email = Auth::user()->email;
|
||||||
|
$this->preferred_username = Auth::user()->preferred_username;
|
||||||
|
$this->avatar = Auth::user()->avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the profile information for the currently authenticated user.
|
||||||
|
*/
|
||||||
|
public function updateProfileInformation(): void
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
$validated = $this->validate([
|
||||||
|
'name' => 'required|string|max:255',
|
||||||
|
'email' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'lowercase',
|
||||||
|
'email',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique(User::class)->ignore($user->id),
|
||||||
|
],
|
||||||
|
'preferred_username' => 'string|max:255'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user->fill($validated);
|
||||||
|
|
||||||
|
if (!empty($this->avatarUpload)) {
|
||||||
|
if (!empty($user->avatar)) {
|
||||||
|
Storage::disk('avatars')->delete($user->avatar);
|
||||||
|
}
|
||||||
|
$user->avatar = $this->avatarUpload->store(options: 'avatars');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
$this->dispatch('profile-updated', name: $user->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an email verification notification to the current user.
|
||||||
|
*/
|
||||||
|
public function resendVerificationNotification(): void
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if ($user->hasVerifiedEmail()) {
|
||||||
|
$this->redirectIntended(default: route('dashboard', absolute: false));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->sendEmailVerificationNotification();
|
||||||
|
|
||||||
|
Session::flash('status', 'verification-link-sent');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.forms.user-profile');
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,6 @@ use Livewire\Component;
|
|||||||
class Profile extends Component
|
class Profile extends Component
|
||||||
{
|
{
|
||||||
public string $name = '';
|
public string $name = '';
|
||||||
|
|
||||||
public string $email = '';
|
public string $email = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,6 +23,8 @@ class User extends Authenticatable
|
|||||||
'name',
|
'name',
|
||||||
'email',
|
'email',
|
||||||
'password',
|
'password',
|
||||||
|
'avatar',
|
||||||
|
'preferred_username'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,4 +66,9 @@ class User extends Authenticatable
|
|||||||
{
|
{
|
||||||
return $this->hasMany(AuthenticationToken::class);
|
return $this->hasMany(AuthenticationToken::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function avatarUrl()
|
||||||
|
{
|
||||||
|
return route('user.avatar', ['path' => $this->avatar]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,21 @@ return [
|
|||||||
'public' => [
|
'public' => [
|
||||||
'driver' => 'local',
|
'driver' => 'local',
|
||||||
'root' => storage_path('app/public'),
|
'root' => storage_path('app/public'),
|
||||||
'url' => env('APP_URL').'/storage',
|
'url' => env('APP_URL') . '/storage',
|
||||||
'visibility' => 'public',
|
'visibility' => 'public',
|
||||||
'throw' => false,
|
'throw' => false,
|
||||||
'report' => false,
|
'report' => false,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'avatars' => [
|
||||||
|
'driver' => 'local',
|
||||||
|
'root' => storage_path('avatars'),
|
||||||
|
'url' => env('APP_URL') . '/storage',
|
||||||
|
'visibility' => 'public',
|
||||||
|
'throw' => true,
|
||||||
|
'report' => true,
|
||||||
|
],
|
||||||
|
|
||||||
's3' => [
|
's3' => [
|
||||||
'driver' => 's3',
|
'driver' => 's3',
|
||||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('avatar')->nullable()->after('email');
|
||||||
|
$table->string('preferred_username')->nullable()->after('avatar');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('avatar');
|
||||||
|
$table->dropColumn('preferred_username');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -57,8 +57,10 @@
|
|||||||
<flux:menu.separator />
|
<flux:menu.separator />
|
||||||
|
|
||||||
<flux:menu.radio.group>
|
<flux:menu.radio.group>
|
||||||
<flux:menu.item :href="route('settings.profile')" icon="cog" wire:navigate>{{ __('Settings') }}
|
<flux:modal.trigger name="user-profile">
|
||||||
</flux:menu.item>
|
<flux:menu.item>{{ __('Edit your profile') }}
|
||||||
|
</flux:menu.item>
|
||||||
|
</flux:modal.trigger>
|
||||||
</flux:menu.radio.group>
|
</flux:menu.radio.group>
|
||||||
|
|
||||||
<flux:menu.separator />
|
<flux:menu.separator />
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<x-layouts.auth.simple :title="$title ?? null">
|
<x-layouts.auth.split :title="$title ?? null">
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
</x-layouts.auth.simple>
|
</x-layouts.auth.split>
|
@ -1,43 +1,53 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
|
||||||
<head>
|
|
||||||
@include('partials.head')
|
|
||||||
</head>
|
|
||||||
<body class="min-h-screen bg-white antialiased dark:bg-linear-to-b dark:from-neutral-950 dark:to-neutral-900">
|
|
||||||
<div class="relative grid h-dvh flex-col items-center justify-center px-8 sm:px-0 lg:max-w-none lg:grid-cols-2 lg:px-0">
|
|
||||||
<div class="bg-muted relative hidden h-full flex-col p-10 text-white lg:flex dark:border-e dark:border-neutral-800">
|
|
||||||
<div class="absolute inset-0 bg-neutral-900"></div>
|
|
||||||
<a href="{{ route('home') }}" class="relative z-20 flex items-center text-lg font-medium" wire:navigate>
|
|
||||||
<span class="flex h-10 w-10 items-center justify-center rounded-md">
|
|
||||||
<x-app-logo-icon class="me-2 h-7 fill-current text-white" />
|
|
||||||
</span>
|
|
||||||
{{ config('app.name', 'Laravel') }}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
@php
|
<head>
|
||||||
[$message, $author] = str(Illuminate\Foundation\Inspiring::quotes()->random())->explode('-');
|
@include('partials.head')
|
||||||
@endphp
|
</head>
|
||||||
|
|
||||||
<div class="relative z-20 mt-auto">
|
<body class="min-h-screen bg-white antialiased dark:bg-linear-to-b dark:from-neutral-950 dark:to-neutral-900">
|
||||||
<blockquote class="space-y-2">
|
<div
|
||||||
<flux:heading size="lg">“{{ trim($message) }}”</flux:heading>
|
class="relative grid h-dvh flex-col items-center justify-center px-8 sm:px-0 lg:max-w-none lg:grid-cols-2 lg:px-0">
|
||||||
<footer><flux:heading>{{ trim($author) }}</flux:heading></footer>
|
<div
|
||||||
</blockquote>
|
class="bg-muted relative hidden h-full flex-col p-10 text-white lg:flex dark:border-e dark:border-neutral-800">
|
||||||
</div>
|
<div style="background: url('/img/background.jpg') no-repeat center center; background-size: cover;"
|
||||||
</div>
|
class="absolute inset-0 bg-neutral-900"></div>
|
||||||
<div class="w-full lg:p-8">
|
<a href="{{ route('home') }}" class="relative z-20 flex items-center text-lg font-medium" wire:navigate>
|
||||||
<div class="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]">
|
<span class="flex h-10 w-10 items-center justify-center rounded-md">
|
||||||
<a href="{{ route('home') }}" class="z-20 flex flex-col items-center gap-2 font-medium lg:hidden" wire:navigate>
|
<x-app-logo-icon class="me-2 h-7 fill-current text-white" />
|
||||||
<span class="flex h-9 w-9 items-center justify-center rounded-md">
|
</span>
|
||||||
<x-app-logo-icon class="size-9 fill-current text-black dark:text-white" />
|
{{ config('app.name', 'Laravel') }}
|
||||||
</span>
|
</a>
|
||||||
|
|
||||||
<span class="sr-only">{{ config('app.name', 'Laravel') }}</span>
|
@php
|
||||||
</a>
|
[$message, $author] = str(Illuminate\Foundation\Inspiring::quotes()->random())->explode('-');
|
||||||
{{ $slot }}
|
@endphp
|
||||||
</div>
|
|
||||||
|
<div class="relative z-20 mt-auto">
|
||||||
|
<blockquote class="space-y-2">
|
||||||
|
<flux:heading size="lg">“{{ trim($message) }}”</flux:heading>
|
||||||
|
<footer>
|
||||||
|
<flux:heading>{{ trim($author) }}</flux:heading>
|
||||||
|
</footer>
|
||||||
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@fluxScripts
|
<div class="w-full lg:p-8">
|
||||||
</body>
|
|
||||||
</html>
|
<div class="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]">
|
||||||
|
<a href="{{ route('home') }}" class="z-20 flex flex-col items-center gap-2 font-medium lg:hidden"
|
||||||
|
wire:navigate>
|
||||||
|
<span class="flex h-9 w-9 items-center justify-center rounded-md">
|
||||||
|
<x-app-logo-icon class="size-9 fill-current text-black dark:text-white" />
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="sr-only">{{ config('app.name', 'Laravel') }}</span>
|
||||||
|
</a>
|
||||||
|
{{ $slot }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@fluxScripts
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -1,5 +1,8 @@
|
|||||||
<x-layouts.app :title="__('Dashboard')">
|
<x-layouts.app :title="__('Dashboard')">
|
||||||
<div class="max-w-4xl mx-auto py-12">
|
<div class="max-w-4xl mx-auto py-12">
|
||||||
<livewire:app-container />
|
<livewire:app-container />
|
||||||
|
<div class="mt-4">
|
||||||
|
<livewire:forms.user-profile />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</x-layouts.app>
|
</x-layouts.app>
|
90
resources/views/livewire/forms/user-profile.blade.php
Normal file
90
resources/views/livewire/forms/user-profile.blade.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<div>
|
||||||
|
<div x-data="{edit: false}" class="border rounded-sm dark:border-zinc-600 border-stone-300 p-4">
|
||||||
|
<div x-show="!edit" class="flex gap-4">
|
||||||
|
<div>
|
||||||
|
@if (!empty($avatarUpload))
|
||||||
|
<img src="{{$avatarUpload->temporaryUrl()}}" alt="" class="size-20">
|
||||||
|
@elseif(!empty($avatar))
|
||||||
|
<img src="{{auth()->user()->avatarUrl()}}" alt="" class="size-20">
|
||||||
|
@else
|
||||||
|
<div
|
||||||
|
class="size-20 flex items-center justify-center mx-auto rounded-sm dark:bg-zinc-600 bg-stone-300 dark:text-white text-black">
|
||||||
|
<div class="text-4xl font-bold">{{auth()->user()->initials()}}</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 flex flex-col justify-between">
|
||||||
|
<flux:text>{{auth()->user()->name}}</flux:text>
|
||||||
|
<flux:text>{{auth()->user()->preferred_username}} <span class="italic">(preferred username)</span>
|
||||||
|
</flux:text>
|
||||||
|
<flux:text>{{auth()->user()->email}}</flux:text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form x-show="edit" wire:submit="updateProfileInformation" x-on:submit="edit = false"
|
||||||
|
class="my-6 w-full space-y-6">
|
||||||
|
<div class="flex items-center gap-8">
|
||||||
|
<div class="relative">
|
||||||
|
<label for="avatar-upload"
|
||||||
|
class="flex items-center justify-center absolute bg-black opacity-0 cursor-pointer hover:opacity-80 top-0 bottom-0 left-0 right-0">
|
||||||
|
<flux:icon.pencil class="size-12" />
|
||||||
|
</label>
|
||||||
|
@if (!empty($avatarUpload))
|
||||||
|
<img src="{{$avatarUpload->temporaryUrl()}}" alt="" class="size-32">
|
||||||
|
@elseif(!empty($avatar))
|
||||||
|
<img src="{{auth()->user()->avatarUrl()}}" alt="" class="size-32">
|
||||||
|
@else
|
||||||
|
<div
|
||||||
|
class="size-32 flex items-center justify-center mx-auto rounded-sm dark:bg-zinc-600 bg-stone-300 dark:text-white text-black">
|
||||||
|
<div class="text-4xl font-bold">{{auth()->user()->initials()}}</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
<flux:input type="file" id="avatar-upload" wire:model="avatarUpload" class="hidden" />
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 flex flex-col gap-4">
|
||||||
|
<flux:input wire:model="name" :label="__('Name')" type="text" required autofocus
|
||||||
|
autocomplete="name" />
|
||||||
|
<flux:input wire:model="preferred_username" :label="__('Preferred Username')" type="text" required
|
||||||
|
autofocus autocomplete="username" />
|
||||||
|
<flux:input wire:model="email" :label="__('Email')" type="email" required autocomplete="email" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<div class="flex items-center justify-end">
|
||||||
|
<flux:button variant="primary" type="submit" class="w-full">{{ __('Save') }}</flux:button>
|
||||||
|
<flux:button variant="subtle" x-on:click="edit = false">Cancel</flux:button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<x-action-message class="me-3" on="profile-updated">
|
||||||
|
{{ __('Saved.') }}
|
||||||
|
</x-action-message>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="mt-4">
|
||||||
|
<flux:button variant="subtle" icon="pencil" x-on:click="edit = true" inset>Edit Profile information
|
||||||
|
</flux:button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div x-data="{edit: false}" class="mt-4">
|
||||||
|
<flux:button variant="primary" x-show="!edit" x-on:click="edit = true">Change Password</flux:button>
|
||||||
|
<form wire:submit="updatePassword" class="mt-6 space-y-6" x-show="edit">
|
||||||
|
<flux:input wire:model="current_password" :label="__('Current password')" type="password" required
|
||||||
|
autocomplete="current-password" />
|
||||||
|
<flux:input wire:model="password" :label="__('New password')" type="password" required
|
||||||
|
autocomplete="new-password" />
|
||||||
|
<flux:input wire:model="password_confirmation" :label="__('Confirm Password')" type="password" required
|
||||||
|
autocomplete="new-password" />
|
||||||
|
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<div class="flex items-center justify-end">
|
||||||
|
<flux:button variant="primary" type="submit" class="w-full">{{ __('Save') }}</flux:button>
|
||||||
|
<flux:button variant="subtle" x-on:click="edit = false">Cancel</flux:button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<x-action-message class="me-3" on="password-updated">
|
||||||
|
{{ __('Saved.') }}
|
||||||
|
</x-action-message>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -5,8 +5,10 @@ use App\Livewire\ConsentScreen;
|
|||||||
use App\Livewire\Settings\Appearance;
|
use App\Livewire\Settings\Appearance;
|
||||||
use App\Livewire\Settings\Password;
|
use App\Livewire\Settings\Password;
|
||||||
use App\Livewire\Settings\Profile;
|
use App\Livewire\Settings\Profile;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
return view('welcome');
|
return view('welcome');
|
||||||
@ -24,6 +26,12 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
Route::get('settings/appearance', Appearance::class)->name('settings.appearance');
|
Route::get('settings/appearance', Appearance::class)->name('settings.appearance');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::get('avatars/{path}', function (string $path) {
|
||||||
|
$path = Storage::disk('avatars')->path($path);
|
||||||
|
|
||||||
|
return response()->file($path);
|
||||||
|
})->name('user.avatar');
|
||||||
|
|
||||||
// OIDC Endpoints
|
// OIDC Endpoints
|
||||||
Route::prefix('application/o')->group(function () {
|
Route::prefix('application/o')->group(function () {
|
||||||
Route::get('authorize', [OIDCController::class, 'authorize'])->middleware('auth')->name('auth.authorize');
|
Route::get('authorize', [OIDCController::class, 'authorize'])->middleware('auth')->name('auth.authorize');
|
||||||
|
@ -3,6 +3,8 @@ import {
|
|||||||
} from 'vite';
|
} from 'vite';
|
||||||
import laravel from 'laravel-vite-plugin';
|
import laravel from 'laravel-vite-plugin';
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -14,6 +16,14 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
server: {
|
server: {
|
||||||
cors: true,
|
cors: true,
|
||||||
host: "homelab-sso.test"
|
host: "homelab-sso.test",
|
||||||
|
// https: {
|
||||||
|
// key: fs.readFileSync(path.resolve(
|
||||||
|
// process.env.HOME, '.valet/Certificates/homelab-sso.test.key'
|
||||||
|
// )),
|
||||||
|
// cert: fs.readFileSync(path.resolve(
|
||||||
|
// process.env.HOME, '.valet/Certificates/homelab-sso.test.crt'
|
||||||
|
// )),
|
||||||
|
// },
|
||||||
},
|
},
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user