Add Passkey Support & Pint
This commit is contained in:
@@ -4,14 +4,16 @@ namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Alert;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class AlertController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display alert index page
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.alert.index');
|
||||
}
|
||||
@@ -19,7 +21,7 @@ class AlertController extends Controller
|
||||
/**
|
||||
* Create Alert.
|
||||
*/
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'message' => 'required|string|max:255',
|
||||
@@ -39,7 +41,7 @@ class AlertController extends Controller
|
||||
/**
|
||||
* Delete Alert.
|
||||
*/
|
||||
public function delete(int $alert_id): \Illuminate\Http\RedirectResponse
|
||||
public function delete(int $alert_id): RedirectResponse
|
||||
{
|
||||
Alert::where('id', $alert_id)->delete();
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class CommentsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Comments Page.
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.comments.index');
|
||||
}
|
||||
|
||||
@@ -4,13 +4,15 @@ namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Contact;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Contact Page.
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
$contacts = Contact::orderBy('created_at', 'DESC')->get();
|
||||
|
||||
@@ -22,7 +24,7 @@ class ContactController extends Controller
|
||||
/**
|
||||
* Delete Contact.
|
||||
*/
|
||||
public function delete(int $contact_id): \Illuminate\Http\RedirectResponse
|
||||
public function delete(int $contact_id): RedirectResponse
|
||||
{
|
||||
Contact::where('id', $contact_id)->delete();
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Models\Episode;
|
||||
use App\Services\DownloadService;
|
||||
use App\Services\EpisodeService;
|
||||
use App\Services\GalleryService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EpisodeController extends Controller
|
||||
@@ -31,7 +32,7 @@ class EpisodeController extends Controller
|
||||
/**
|
||||
* Add Episode to existing series
|
||||
*/
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$referenceEpisode = Episode::with('hentai')->where('id', $request->input('episode_id'))->firstOrFail();
|
||||
$episodeNumber = $referenceEpisode->hentai->episodes()->count() + 1;
|
||||
@@ -59,7 +60,7 @@ class EpisodeController extends Controller
|
||||
/**
|
||||
* Edit Episode
|
||||
*/
|
||||
public function update(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
$episode = Episode::with('hentai')->where('id', $request->input('episode_id'))->firstOrFail();
|
||||
$studio = $this->episodeService->getOrCreateStudio(json_decode($request->input('studio'))[0]->value);
|
||||
|
||||
@@ -8,7 +8,9 @@ use App\Models\Hentai;
|
||||
use App\Services\DownloadService;
|
||||
use App\Services\EpisodeService;
|
||||
use App\Services\GalleryService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ReleaseController extends Controller
|
||||
{
|
||||
@@ -31,7 +33,7 @@ class ReleaseController extends Controller
|
||||
/**
|
||||
* Display release page
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.release.create');
|
||||
}
|
||||
@@ -39,7 +41,7 @@ class ReleaseController extends Controller
|
||||
/**
|
||||
* Upload New Hentai with One or Multipe Episodes
|
||||
*/
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
// Create new Hentai or find existing one
|
||||
$slug = $this->episodeService->generateSlug($request->input('title'));
|
||||
|
||||
@@ -4,10 +4,12 @@ namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\SiteBackground;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
use Intervention\Image\Encoders\WebpEncoder;
|
||||
use Intervention\Image\Laravel\Facades\Image;
|
||||
|
||||
@@ -16,7 +18,7 @@ class SiteBackgroundController extends Controller
|
||||
/**
|
||||
* Display admin index page
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.background.index', [
|
||||
'images' => SiteBackground::all(),
|
||||
@@ -26,7 +28,7 @@ class SiteBackgroundController extends Controller
|
||||
/**
|
||||
* Create new site backgrounds
|
||||
*/
|
||||
public function create(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function create(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'images' => 'required',
|
||||
@@ -73,7 +75,7 @@ class SiteBackgroundController extends Controller
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function update(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'id' => 'required|exists:site_backgrounds,id',
|
||||
@@ -96,7 +98,7 @@ class SiteBackgroundController extends Controller
|
||||
/**
|
||||
* Delete backround
|
||||
*/
|
||||
public function delete(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function delete(Request $request): RedirectResponse
|
||||
{
|
||||
$id = $request->input('id');
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Models\Episode;
|
||||
use App\Models\EpisodeSubtitle;
|
||||
use App\Models\Subtitle;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SubtitleController extends Controller
|
||||
@@ -13,7 +14,7 @@ class SubtitleController extends Controller
|
||||
/**
|
||||
* Add new Subtitle.
|
||||
*/
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$subtitle = Subtitle::create([
|
||||
'name' => $request->name,
|
||||
@@ -32,7 +33,7 @@ class SubtitleController extends Controller
|
||||
/**
|
||||
* Update Episode Subtitles.
|
||||
*/
|
||||
public function update(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
$episode = Episode::where('id', $request->input('episode_id'))->firstOrFail();
|
||||
|
||||
|
||||
@@ -6,13 +6,14 @@ use App\Enums\UserRole;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Users Page.
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.users.index');
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class NewPasswordController extends Controller
|
||||
@@ -26,7 +27,7 @@ class NewPasswordController extends Controller
|
||||
/**
|
||||
* Handle an incoming new password request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class PasswordResetLinkController extends Controller
|
||||
@@ -21,7 +22,7 @@ class PasswordResetLinkController extends Controller
|
||||
/**
|
||||
* Handle an incoming password reset link request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
|
||||
@@ -11,13 +11,14 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\Rules;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class RegisteredUserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle an incoming registration request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
|
||||
@@ -4,14 +4,16 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Rules\ValidCaptcha;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Contact Page.
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
return view('contact.form');
|
||||
}
|
||||
@@ -19,7 +21,7 @@ class ContactController extends Controller
|
||||
/**
|
||||
* Store Contact Submission.
|
||||
*/
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|max:30',
|
||||
|
||||
@@ -4,15 +4,17 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\CacheHelper;
|
||||
use App\Models\Episode;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Home Page.
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
$guest = Auth::guest();
|
||||
|
||||
@@ -45,7 +47,7 @@ class HomeController extends Controller
|
||||
/**
|
||||
* Display Banned Page.
|
||||
*/
|
||||
public function banned(): \Illuminate\View\View
|
||||
public function banned(): View
|
||||
{
|
||||
return view('auth.banned');
|
||||
}
|
||||
@@ -54,7 +56,7 @@ class HomeController extends Controller
|
||||
* Redirects to a random Hentai episode
|
||||
* Done due to performance reasons
|
||||
*/
|
||||
public function random(): \Illuminate\Http\RedirectResponse
|
||||
public function random(): RedirectResponse
|
||||
{
|
||||
$random = Episode::inRandomOrder()
|
||||
->limit(1)
|
||||
@@ -69,7 +71,7 @@ class HomeController extends Controller
|
||||
/**
|
||||
* Display Search Page.
|
||||
*/
|
||||
public function search(): \Illuminate\View\View
|
||||
public function search(): View
|
||||
{
|
||||
return view('search.index');
|
||||
}
|
||||
@@ -77,7 +79,7 @@ class HomeController extends Controller
|
||||
/**
|
||||
* Display Download Search Page.
|
||||
*/
|
||||
public function downloadSearch(): \Illuminate\View\View
|
||||
public function downloadSearch(): View
|
||||
{
|
||||
return view('search.download');
|
||||
}
|
||||
@@ -85,7 +87,7 @@ class HomeController extends Controller
|
||||
/**
|
||||
* Redirect POST Data to GET with Query String.
|
||||
*/
|
||||
public function searchRedirect(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function searchRedirect(Request $request): RedirectResponse
|
||||
{
|
||||
return redirect()->route('hentai.search', [
|
||||
'search' => $request->input('live-search'),
|
||||
@@ -95,7 +97,7 @@ class HomeController extends Controller
|
||||
/**
|
||||
* Display Stats Page.
|
||||
*/
|
||||
public function stats(): \Illuminate\View\View
|
||||
public function stats(): View
|
||||
{
|
||||
return view('home.stats', [
|
||||
'viewCount' => CacheHelper::getTotalViewCount(),
|
||||
@@ -107,7 +109,7 @@ class HomeController extends Controller
|
||||
/**
|
||||
* Manually set website language
|
||||
*/
|
||||
public function updateLanguage(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function updateLanguage(Request $request): RedirectResponse
|
||||
{
|
||||
abort_unless(in_array($request->language, config('app.supported_locales'), true), 404);
|
||||
|
||||
|
||||
@@ -5,13 +5,14 @@ namespace App\Http\Controllers;
|
||||
use App\Http\Requests\MatrixRegisterRequest;
|
||||
use App\Services\MatrixRegistrationService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class MatrixController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the user page.
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$rooms = [
|
||||
['name' => '🏠 General', 'description' => 'Our main chat.', 'alias' => 'https://matrix.to/#/#general:hstream.moe'],
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class NotificationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the user's notification page.
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
return view('profile.notifications', [
|
||||
'user' => $request->user(),
|
||||
@@ -20,7 +22,7 @@ class NotificationController extends Controller
|
||||
/**
|
||||
* Delete Notifcation
|
||||
*/
|
||||
public function delete(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function delete(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'id' => 'required|exists:notifications,id',
|
||||
|
||||
@@ -6,7 +6,10 @@ use App\Models\Episode;
|
||||
use App\Models\Playlist;
|
||||
use App\Models\PlaylistEpisode;
|
||||
use App\Services\PlaylistService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class PlaylistController extends Controller
|
||||
{
|
||||
@@ -20,7 +23,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Display the public playlists page.
|
||||
*/
|
||||
public function index(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
return view('playlist.index');
|
||||
}
|
||||
@@ -28,7 +31,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Display public playlist.
|
||||
*/
|
||||
public function show($playlist_id): \Illuminate\View\View
|
||||
public function show($playlist_id): View
|
||||
{
|
||||
if (! is_numeric($playlist_id)) {
|
||||
abort(404);
|
||||
@@ -44,7 +47,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Display the user's playlists page.
|
||||
*/
|
||||
public function playlists(Request $request): \Illuminate\View\View
|
||||
public function playlists(Request $request): View
|
||||
{
|
||||
$title = 'Delete Playlist!';
|
||||
$text = 'Are you sure you want to delete?';
|
||||
@@ -59,7 +62,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Display user's playlist.
|
||||
*/
|
||||
public function showPlaylist(Request $request, $playlist_id): \Illuminate\View\View
|
||||
public function showPlaylist(Request $request, $playlist_id): View
|
||||
{
|
||||
if (! is_numeric($playlist_id)) {
|
||||
abort(404);
|
||||
@@ -77,7 +80,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Create user playlist (Form).
|
||||
*/
|
||||
public function createPlaylist(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function createPlaylist(Request $request): RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|max:30',
|
||||
@@ -95,7 +98,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Delete user playlist.
|
||||
*/
|
||||
public function deletePlaylist(Request $request, $playlist_id): \Illuminate\Http\RedirectResponse
|
||||
public function deletePlaylist(Request $request, $playlist_id): RedirectResponse
|
||||
{
|
||||
if (! is_numeric($playlist_id)) {
|
||||
abort(404);
|
||||
@@ -115,7 +118,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Delete episode from playlist.
|
||||
*/
|
||||
public function deleteEpisodeFromPlaylist(Request $request): \Illuminate\Http\JsonResponse
|
||||
public function deleteEpisodeFromPlaylist(Request $request): JsonResponse
|
||||
{
|
||||
if (! is_numeric($request->input('playlist')) || ! is_numeric($request->input('episode'))) {
|
||||
return response()->json([
|
||||
@@ -143,7 +146,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Add to user playlist (API).
|
||||
*/
|
||||
public function addPlaylistApi(Request $request): \Illuminate\Http\JsonResponse
|
||||
public function addPlaylistApi(Request $request): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
@@ -180,7 +183,7 @@ class PlaylistController extends Controller
|
||||
/**
|
||||
* Create user playlist (API).
|
||||
*/
|
||||
public function createPlaylistApi(Request $request): \Illuminate\Http\JsonResponse
|
||||
public function createPlaylistApi(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|max:30',
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Models\User;
|
||||
use Conner\Tagging\Model\Tag;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
@@ -138,7 +139,7 @@ class ProfileController extends Controller
|
||||
/**
|
||||
* Delete the user's account.
|
||||
*/
|
||||
public function destroy(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(Request $request): RedirectResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
@@ -173,7 +174,7 @@ class ProfileController extends Controller
|
||||
/**
|
||||
* Store custom user avatar.
|
||||
*/
|
||||
protected function storeAvatar(\Illuminate\Http\UploadedFile $file, User $user): void
|
||||
protected function storeAvatar(UploadedFile $file, User $user): void
|
||||
{
|
||||
// Create Folder for Image Upload
|
||||
if (! Storage::disk('public')->exists('/images/avatars')) {
|
||||
|
||||
@@ -13,13 +13,14 @@ use hisorange\BrowserDetect\Facade as Browser;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class StreamController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display Stream Page.
|
||||
*/
|
||||
public function index(Request $request, string $title): \Illuminate\View\View
|
||||
public function index(Request $request, string $title): View
|
||||
{
|
||||
$titleParts = explode('-', $title);
|
||||
if (! is_numeric($titleParts[array_key_last($titleParts)])) {
|
||||
|
||||
@@ -2,7 +2,34 @@
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\Authenticate;
|
||||
use App\Http\Middleware\EncryptCookies;
|
||||
use App\Http\Middleware\IsAdmin;
|
||||
use App\Http\Middleware\IsBanned;
|
||||
use App\Http\Middleware\IsModerator;
|
||||
use App\Http\Middleware\PreventRequestsDuringMaintenance;
|
||||
use App\Http\Middleware\RedirectIfAuthenticated;
|
||||
use App\Http\Middleware\SetLocale;
|
||||
use App\Http\Middleware\TrimStrings;
|
||||
use App\Http\Middleware\TrustProxies;
|
||||
use App\Http\Middleware\ValidateSignature;
|
||||
use App\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
||||
use Illuminate\Auth\Middleware\Authorize;
|
||||
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
|
||||
use Illuminate\Auth\Middleware\RequirePassword;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
|
||||
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;
|
||||
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
||||
use Illuminate\Http\Middleware\HandleCors;
|
||||
use Illuminate\Http\Middleware\SetCacheHeaders;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
@@ -15,12 +42,12 @@ class Kernel extends HttpKernel
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
TrustProxies::class,
|
||||
HandleCors::class,
|
||||
PreventRequestsDuringMaintenance::class,
|
||||
ValidatePostSize::class,
|
||||
TrimStrings::class,
|
||||
ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -30,20 +57,20 @@ class Kernel extends HttpKernel
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\IsBanned::class,
|
||||
\App\Http\Middleware\SetLocale::class,
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
SubstituteBindings::class,
|
||||
IsBanned::class,
|
||||
SetLocale::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
ThrottleRequests::class.':api',
|
||||
SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -55,18 +82,18 @@ class Kernel extends HttpKernel
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'auth.admin' => \App\Http\Middleware\IsAdmin::class,
|
||||
'auth.moderator' => \App\Http\Middleware\IsModerator::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'auth' => Authenticate::class,
|
||||
'auth.basic' => AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => AuthenticateSession::class,
|
||||
'auth.admin' => IsAdmin::class,
|
||||
'auth.moderator' => IsModerator::class,
|
||||
'cache.headers' => SetCacheHeaders::class,
|
||||
'can' => Authorize::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'password.confirm' => RequirePassword::class,
|
||||
'precognitive' => HandlePrecognitiveRequests::class,
|
||||
'signed' => ValidateSignature::class,
|
||||
'throttle' => ThrottleRequests::class,
|
||||
'verified' => EnsureEmailIsVerified::class,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class IsModerator
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @param Closure(Request): (Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ class RedirectIfAuthenticated
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @param Closure(Request): (Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, string ...$guards): Response
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ class SetLocale
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @param Closure(Request): (Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Requests\Auth;
|
||||
|
||||
use App\Rules\ValidCaptcha;
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
@@ -23,7 +24,7 @@ class LoginRequest extends FormRequest
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
@@ -37,7 +38,7 @@ class LoginRequest extends FormRequest
|
||||
/**
|
||||
* Attempt to authenticate the request's credentials.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function authenticate(): void
|
||||
{
|
||||
@@ -57,7 +58,7 @@ class LoginRequest extends FormRequest
|
||||
/**
|
||||
* Ensure the login request is not rate limited.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function ensureIsNotRateLimited(): void
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class MatrixRegisterRequest extends FormRequest
|
||||
@@ -20,7 +21,7 @@ class MatrixRegisterRequest extends FormRequest
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
@@ -11,7 +12,7 @@ class ProfileUpdateRequest extends FormRequest
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Enums\UserRole;
|
||||
use App\Models\Downloads;
|
||||
use Livewire\Attributes\Url;
|
||||
use Livewire\Component;
|
||||
@@ -74,9 +75,9 @@ class DownloadsSearch extends Component
|
||||
$types[] = 'FHD';
|
||||
} elseif ($label === 'FHD 48fps') {
|
||||
$types[] = 'FHDi';
|
||||
} elseif ($label === 'UHD' && auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
||||
} elseif ($label === 'UHD' && auth()->user()->hasRole(UserRole::SUPPORTER)) {
|
||||
$types[] = 'UHD';
|
||||
} elseif ($label === 'UHD 48fps' && auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
||||
} elseif ($label === 'UHD 48fps' && auth()->user()->hasRole(UserRole::SUPPORTER)) {
|
||||
$types[] = 'UHDi';
|
||||
}
|
||||
}
|
||||
@@ -99,7 +100,7 @@ class DownloadsSearch extends Component
|
||||
|
||||
public function mount()
|
||||
{
|
||||
if (! auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
||||
if (! auth()->user()->hasRole(UserRole::SUPPORTER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class SiteBackground extends Model
|
||||
{
|
||||
@@ -21,7 +22,7 @@ class SiteBackground extends Model
|
||||
/**
|
||||
* Returns the current IDs of active wallpaper
|
||||
*/
|
||||
public function getImages(): ?\Illuminate\Support\Collection
|
||||
public function getImages(): ?Collection
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
|
||||
@@ -11,10 +11,12 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Spatie\LaravelPasskeys\Models\Concerns\HasPasskeys;
|
||||
use Spatie\LaravelPasskeys\Models\Concerns\InteractsWithPasskeys;
|
||||
|
||||
class User extends Authenticatable
|
||||
class User extends Authenticatable implements HasPasskeys
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
use HasFactory, InteractsWithPasskeys, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use SocialiteProviders\Discord\Provider;
|
||||
use SocialiteProviders\Manager\SocialiteWasCalled;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -20,8 +22,8 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
|
||||
$event->extendSocialite('discord', \SocialiteProviders\Discord\Provider::class);
|
||||
Event::listen(function (SocialiteWasCalled $event) {
|
||||
$event->extendSocialite('discord', Provider::class);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use AltchaOrg\Altcha\Solution;
|
||||
use AltchaOrg\Altcha\VerifySolutionOptions;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Translation\PotentiallyTranslatedString;
|
||||
|
||||
/**
|
||||
* Validation rule to verify captcha solution.
|
||||
@@ -97,7 +98,7 @@ class ValidCaptcha implements ValidationRule
|
||||
/**
|
||||
* Run the validation rule.
|
||||
*
|
||||
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
* @param Closure(string, ?string=): PotentiallyTranslatedString $fail
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
use App\Exceptions\Handler;
|
||||
use App\Http\Kernel;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Create The Application
|
||||
@@ -11,7 +16,7 @@
|
||||
|
|
||||
*/
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
$app = new Application(
|
||||
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
|
||||
);
|
||||
|
||||
@@ -28,7 +33,7 @@ $app = new Illuminate\Foundation\Application(
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Http\Kernel::class,
|
||||
App\Http\Kernel::class
|
||||
Kernel::class
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
@@ -37,8 +42,8 @@ $app->singleton(
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Debug\ExceptionHandler::class,
|
||||
App\Exceptions\Handler::class
|
||||
ExceptionHandler::class,
|
||||
Handler::class
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"rtconner/laravel-tagging": "^5.0",
|
||||
"socialiteproviders/discord": "^4.2",
|
||||
"spatie/laravel-discord-alerts": "^1.8",
|
||||
"spatie/laravel-passkeys": "^1.7",
|
||||
"spatie/laravel-sitemap": "^7.3"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
2325
composer.lock
generated
2325
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,12 @@
|
||||
<?php
|
||||
|
||||
use App\Providers\AppServiceProvider;
|
||||
use App\Providers\AuthServiceProvider;
|
||||
use App\Providers\EventServiceProvider;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Mews\Captcha\Facades\Captcha;
|
||||
|
||||
return [
|
||||
|
||||
@@ -175,11 +180,11 @@ return [
|
||||
/*
|
||||
* Application Service Providers...
|
||||
*/
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
AppServiceProvider::class,
|
||||
AuthServiceProvider::class,
|
||||
// App\Providers\BroadcastServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
EventServiceProvider::class,
|
||||
RouteServiceProvider::class,
|
||||
])->toArray(),
|
||||
|
||||
/*
|
||||
@@ -195,7 +200,7 @@ return [
|
||||
|
||||
'aliases' => Facade::defaultAliases()->merge([
|
||||
// 'Example' => App\Facades\Example::class,
|
||||
'Captcha' => Mews\Captcha\Facades\Captcha::class,
|
||||
'Captcha' => Captcha::class,
|
||||
])->toArray(),
|
||||
|
||||
];
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
@@ -62,7 +64,7 @@ return [
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => App\Models\User::class,
|
||||
'model' => User::class,
|
||||
],
|
||||
|
||||
// 'users' => [
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Spatie\DiscordAlerts\Jobs\SendToDiscordChannelJob;
|
||||
|
||||
return [
|
||||
/*
|
||||
* The webhook URLs that we'll use to send a message to Discord.
|
||||
@@ -14,5 +16,5 @@ return [
|
||||
* This job will send the message to Discord. You can extend this
|
||||
* job to set timeouts, retries, etc...
|
||||
*/
|
||||
'job' => Spatie\DiscordAlerts\Jobs\SendToDiscordChannelJob::class,
|
||||
'job' => SendToDiscordChannelJob::class,
|
||||
];
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Intervention\Image\Drivers\Gd\Driver;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
@@ -16,7 +18,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => \Intervention\Image\Drivers\Gd\Driver::class,
|
||||
'driver' => Driver::class,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
49
config/passkeys.php
Normal file
49
config/passkeys.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use Spatie\LaravelPasskeys\Actions\ConfigureCeremonyStepManagerFactoryAction;
|
||||
use Spatie\LaravelPasskeys\Actions\FindPasskeyToAuthenticateAction;
|
||||
use Spatie\LaravelPasskeys\Actions\GeneratePasskeyAuthenticationOptionsAction;
|
||||
use Spatie\LaravelPasskeys\Actions\GeneratePasskeyRegisterOptionsAction;
|
||||
use Spatie\LaravelPasskeys\Actions\StorePasskeyAction;
|
||||
use Spatie\LaravelPasskeys\Models\Passkey;
|
||||
|
||||
return [
|
||||
/*
|
||||
* After a successful authentication attempt using a passkey
|
||||
* we'll redirect to this URL.
|
||||
*/
|
||||
'redirect_to_after_login' => '/',
|
||||
|
||||
/*
|
||||
* These class are responsible for performing core tasks regarding passkeys.
|
||||
* You can customize them by creating a class that extends the default, and
|
||||
* by specifying your custom class name here.
|
||||
*/
|
||||
'actions' => [
|
||||
'generate_passkey_register_options' => GeneratePasskeyRegisterOptionsAction::class,
|
||||
'store_passkey' => StorePasskeyAction::class,
|
||||
'generate_passkey_authentication_options' => GeneratePasskeyAuthenticationOptionsAction::class,
|
||||
'find_passkey' => FindPasskeyToAuthenticateAction::class,
|
||||
'configure_ceremony_step_manager_factory' => ConfigureCeremonyStepManagerFactoryAction::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* These properties will be used to generate the passkey.
|
||||
*/
|
||||
'relying_party' => [
|
||||
'name' => config('app.name'),
|
||||
'id' => parse_url(config('app.url'), PHP_URL_HOST),
|
||||
'icon' => null,
|
||||
],
|
||||
|
||||
/*
|
||||
* The models used by the package.
|
||||
*
|
||||
* You can override this by specifying your own models
|
||||
*/
|
||||
'models' => [
|
||||
'passkey' => Passkey::class,
|
||||
'authenticatable' => env('AUTH_MODEL', User::class),
|
||||
],
|
||||
];
|
||||
@@ -1,5 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken;
|
||||
use Laravel\Sanctum\Http\Middleware\AuthenticateSession;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
return [
|
||||
@@ -60,9 +63,9 @@ return [
|
||||
*/
|
||||
|
||||
'middleware' => [
|
||||
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
|
||||
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
|
||||
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
|
||||
'authenticate_session' => AuthenticateSession::class,
|
||||
'encrypt_cookies' => EncryptCookies::class,
|
||||
'validate_csrf_token' => ValidateCsrfToken::class,
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Episode;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Episode>
|
||||
* @extends Factory<Episode>
|
||||
*/
|
||||
class EpisodeFactory extends Factory
|
||||
{
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Hentai;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Hentai>
|
||||
* @extends Factory<Hentai>
|
||||
*/
|
||||
class HentaiFactory extends Factory
|
||||
{
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Studios;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Studios>
|
||||
* @extends Factory<Studios>
|
||||
*/
|
||||
class StudiosFactory extends Factory
|
||||
{
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
|
||||
* @extends Factory<User>
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ return new class extends Migration
|
||||
|
||||
$alreadyexists = Episode::where('slug', $episode->slug)->first();
|
||||
if ($alreadyexists) {
|
||||
throw new \RuntimeException('Migration stopped! Slug already exists: '.$episode->slug);
|
||||
throw new RuntimeException('Migration stopped! Slug already exists: '.$episode->slug);
|
||||
}
|
||||
|
||||
$episode->save();
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Spatie\LaravelPasskeys\Support\Config;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$authenticatableClass = Config::getAuthenticatableModel();
|
||||
|
||||
$authenticatableTableName = (new $authenticatableClass)->getTable();
|
||||
|
||||
Schema::create('passkeys', function (Blueprint $table) use ($authenticatableTableName, $authenticatableClass) {
|
||||
$table->id();
|
||||
|
||||
$table
|
||||
->foreignIdFor($authenticatableClass, 'authenticatable_id')
|
||||
->constrained(table: $authenticatableTableName, indexName: 'passkeys_authenticatable_fk')
|
||||
->cascadeOnDelete();
|
||||
|
||||
$table->text('name');
|
||||
$table->text('credential_id');
|
||||
$table->json('data');
|
||||
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
};
|
||||
7
package-lock.json
generated
7
package-lock.json
generated
@@ -7,6 +7,7 @@
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@jellyfin/libass-wasm": "^4.1.1",
|
||||
"@simplewebauthn/browser": "^13.3.0",
|
||||
"@yaireo/tagify": "^4.21.2",
|
||||
"altcha": "^3.0.0",
|
||||
"chart.js": "^4.5.0",
|
||||
@@ -998,6 +999,12 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@simplewebauthn/browser": {
|
||||
"version": "13.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.3.0.tgz",
|
||||
"integrity": "sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@svta/cml-608": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@svta/cml-608/-/cml-608-1.0.1.tgz",
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@jellyfin/libass-wasm": "^4.1.1",
|
||||
"@simplewebauthn/browser": "^13.3.0",
|
||||
"@yaireo/tagify": "^4.21.2",
|
||||
"altcha": "^3.0.0",
|
||||
"chart.js": "^4.5.0",
|
||||
|
||||
@@ -23,3 +23,16 @@ import "altcha/themes/cupcake.css";
|
||||
// Alpine.start();
|
||||
|
||||
initTE({ Collapse, Carousel, Clipboard, Modal, Tab, Lightbox, Tooltip, Ripple });
|
||||
|
||||
/**
|
||||
* Passkey Support
|
||||
*/
|
||||
import {
|
||||
browserSupportsWebAuthn,
|
||||
startAuthentication,
|
||||
startRegistration,
|
||||
} from '@simplewebauthn/browser'
|
||||
|
||||
window.browserSupportsWebAuthn = browserSupportsWebAuthn;
|
||||
window.startAuthentication = startAuthentication;
|
||||
window.startRegistration = startRegistration;
|
||||
@@ -31,7 +31,18 @@
|
||||
<!-- Or -->
|
||||
<div class="grid grid-cols-3">
|
||||
<hr class="self-center border-neutral-600">
|
||||
<p>OR</p>
|
||||
<p class="text-neutral-800 dark:text-neutral-400">OR</p>
|
||||
<hr class="self-center border-neutral-600">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Passkey Login -->
|
||||
<div class="w-full text-center text-white mb-3">
|
||||
<x-authenticate-passkey />
|
||||
|
||||
<div class="grid grid-cols-3 pt-3">
|
||||
<hr class="self-center border-neutral-600">
|
||||
<p class="text-neutral-800 dark:text-neutral-400">OR</p>
|
||||
<hr class="self-center border-neutral-600">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
<div class="p-4 sm:p-8 bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow sm:rounded-lg">
|
||||
@include('profile.partials.update-profile-information-form')
|
||||
</div>
|
||||
<div class="p-4 sm:p-8 bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow sm:rounded-lg">
|
||||
<livewire:passkeys />
|
||||
</div>
|
||||
<div class="p-4 sm:p-8 bg-white/40 dark:bg-neutral-950/40 backdrop-blur shadow sm:rounded-lg">
|
||||
@include('profile.partials.update-password-form')
|
||||
</div>
|
||||
|
||||
23
resources/views/vendor/passkeys/components/authenticate.blade.php
vendored
Normal file
23
resources/views/vendor/passkeys/components/authenticate.blade.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<div>
|
||||
@include('passkeys::components.partials.authenticateScript')
|
||||
|
||||
<form id="passkey-login-form" method="POST" action="{{ route('passkeys.login') }}">
|
||||
@csrf
|
||||
</form>
|
||||
|
||||
@if($message = session()->get('authenticatePasskey::message'))
|
||||
<div class="bg-red-100 text-red-700 p-4 border border-red-400 rounded">
|
||||
{{ $message }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div onclick="authenticateWithPasskey()">
|
||||
@if ($slot->isEmpty())
|
||||
<div class="bg-zinc-700 hover:bg-zinc-600 text-white font-bold px-4 h-10 rounded text-center p-[10px] cursor-pointer">
|
||||
<i class="fa-solid fa-key"></i> {{ __('passkeys::passkeys.authenticate_using_passkey') }}
|
||||
</div>
|
||||
@else
|
||||
{{ $slot }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
18
resources/views/vendor/passkeys/components/partials/authenticateScript.blade.php
vendored
Normal file
18
resources/views/vendor/passkeys/components/partials/authenticateScript.blade.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<script>
|
||||
async function authenticateWithPasskey(remember = false) {
|
||||
const response = await fetch('{{ route('passkeys.authentication_options') }}')
|
||||
|
||||
const options = await response.json();
|
||||
|
||||
const startAuthenticationResponse = await startAuthentication({ optionsJSON: options, });
|
||||
|
||||
const form = document.getElementById('passkey-login-form');
|
||||
|
||||
form.addEventListener('formdata', ({formData}) => {
|
||||
formData.set('remember', remember);
|
||||
formData.set('start_authentication_response', JSON.stringify(startAuthenticationResponse));
|
||||
});
|
||||
|
||||
form.submit();
|
||||
}
|
||||
</script>
|
||||
11
resources/views/vendor/passkeys/livewire/partials/createScript.blade.php
vendored
Normal file
11
resources/views/vendor/passkeys/livewire/partials/createScript.blade.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
@script
|
||||
<script>
|
||||
Livewire.on('passkeyPropertiesValidated', async function (eventData) {
|
||||
const passkeyOptions = eventData[0].passkeyOptions;
|
||||
|
||||
const passkey = await startRegistration({ optionsJSON: passkeyOptions });
|
||||
|
||||
@this.call('storePasskey', JSON.stringify(passkey));
|
||||
});
|
||||
</script>
|
||||
@endscript
|
||||
44
resources/views/vendor/passkeys/livewire/passkeys.blade.php
vendored
Normal file
44
resources/views/vendor/passkeys/livewire/passkeys.blade.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<section>
|
||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ __('passkeys::passkeys.passkeys') }}
|
||||
</h2>
|
||||
<div class="mt-2">
|
||||
<label for="name" class="block mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ __('passkeys::passkeys.name') }}
|
||||
</label>
|
||||
<form id="passkeyForm" wire:submit="validatePasskeyProperties" class="flex items-center space-x-2 mt-2">
|
||||
<div>
|
||||
<input autocomplete="off" type="text" wire:model="name" class="border-gray-300 dark:border-gray-700 dark:bg-neutral-900 dark:text-gray-300 focus:border-rose-500 dark:focus:border-rose-600 focus:ring-rose-500 dark:focus:ring-rose-600 rounded-md shadow-sm">
|
||||
@error('name')
|
||||
<span class="text-red-500 text-sm">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<button type="submit" class="inline-flex items-center px-4 py-2 bg-rose-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-rose-700 active:bg-rose-900 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150">
|
||||
{{ __('passkeys::passkeys.create') }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<ul class="space-y-4">
|
||||
@foreach($passkeys as $passkey)
|
||||
<li class="flex justify-between items-center p-4 bg-white border-neutral-200 dark:bg-neutral-900 dark:border-neutral-700 border rounded-lg shadow-sm">
|
||||
<div class="text-gray-900 dark:text-gray-100">
|
||||
{{ $passkey->name }}
|
||||
</div>
|
||||
<div class="ml-2 text-gray-900 dark:text-gray-100">
|
||||
{{ __('passkeys::passkeys.last_used') }}: {{ $passkey->last_used_at?->diffForHumans() ?? __('passkeys::passkeys.not_used_yet') }}
|
||||
</div>
|
||||
<div>
|
||||
<button wire:click="deletePasskey({{ $passkey->id }})" class="inline-flex items-center px-4 py-2 bg-rose-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-rose-700 active:bg-rose-900 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150">
|
||||
{{ __('passkeys::passkeys.delete') }}
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@include('passkeys::livewire.partials.createScript')
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
use App\Http\Controllers\Api\UserApiController;
|
||||
use App\Http\Controllers\HomeController;
|
||||
use App\Http\Controllers\MatrixController;
|
||||
use App\Http\Controllers\NotificationController;
|
||||
use App\Http\Controllers\PlaylistController;
|
||||
use App\Http\Controllers\ProfileController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
@@ -13,11 +15,11 @@ use Illuminate\Support\Facades\Route;
|
||||
*/
|
||||
|
||||
// Matrix
|
||||
Route::get('/join-matrix', [App\Http\Controllers\MatrixController::class, 'index'])->name('join.matrix');
|
||||
Route::get('/join-matrix', [MatrixController::class, 'index'])->name('join.matrix');
|
||||
|
||||
Route::middleware('auth')->group(function () {
|
||||
// Matrix
|
||||
Route::post('/join-matrix', [App\Http\Controllers\MatrixController::class, 'store'])->name('join.matrix.create');
|
||||
Route::post('/join-matrix', [MatrixController::class, 'store'])->name('join.matrix.create');
|
||||
|
||||
Route::get('/user/profile', [ProfileController::class, 'index'])->name('profile.show');
|
||||
Route::get('/user/comments', [ProfileController::class, 'comments'])->name('profile.comments');
|
||||
@@ -25,8 +27,8 @@ Route::middleware('auth')->group(function () {
|
||||
Route::get('/user/watched', [ProfileController::class, 'watched'])->name('user.watched');
|
||||
|
||||
// Notifications
|
||||
Route::get('/user/notifications', [App\Http\Controllers\NotificationController::class, 'index'])->name('profile.notifications');
|
||||
Route::delete('/user/notifications', [App\Http\Controllers\NotificationController::class, 'delete'])->name('profile.notifications.delete');
|
||||
Route::get('/user/notifications', [NotificationController::class, 'index'])->name('profile.notifications');
|
||||
Route::delete('/user/notifications', [NotificationController::class, 'delete'])->name('profile.notifications.delete');
|
||||
|
||||
// User Profile Actions
|
||||
Route::get('/user/settings', [ProfileController::class, 'settings'])->name('profile.settings');
|
||||
|
||||
@@ -45,6 +45,11 @@ Route::post('/get-download', [DownloadApiController::class, 'getDownload']);
|
||||
|
||||
Route::post('/update-language', [HomeController::class, 'updateLanguage'])->name('update.language');
|
||||
|
||||
/**
|
||||
* Passkey Routes
|
||||
*/
|
||||
Route::passkeys();
|
||||
|
||||
require __DIR__.'/user.php';
|
||||
require __DIR__.'/admin.php';
|
||||
require __DIR__.'/auth.php';
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Models\Hentai;
|
||||
use App\Models\Studios;
|
||||
use App\Services\GalleryService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Tests\TestCase;
|
||||
@@ -38,7 +39,7 @@ class GalleryServiceTest extends TestCase
|
||||
$file = UploadedFile::fake()->image('test_image.jpg');
|
||||
|
||||
// Create a request with the fake file
|
||||
$request = new \Illuminate\Http\Request;
|
||||
$request = new Request;
|
||||
$request->files->add(['episodegallery1' => [$file]]);
|
||||
|
||||
// Call the method to test
|
||||
|
||||
Reference in New Issue
Block a user