diff --git a/web/app/Http/Controllers/ContentController.php b/web/app/Http/Controllers/ContentController.php
new file mode 100644
index 0000000..7d83d5d
--- /dev/null
+++ b/web/app/Http/Controllers/ContentController.php
@@ -0,0 +1,16 @@
+input('id'));
+ }
+}
diff --git a/web/app/Http/Controllers/MaintenanceController.php b/web/app/Http/Controllers/MaintenanceController.php
index fd2929e..fceb5bf 100644
--- a/web/app/Http/Controllers/MaintenanceController.php
+++ b/web/app/Http/Controllers/MaintenanceController.php
@@ -10,6 +10,10 @@ use App\Models\WebsiteConfiguration;
class MaintenanceController extends Controller
{
+ public function showPage() {
+ return view('maintenance');
+ }
+
/**
* Handles the maintenance bypass request.
*
@@ -20,50 +24,49 @@ class MaintenanceController extends Controller
$password = $request->input('password');
$buttons = $request->input('buttons');
- if($password && $buttons)
- {
- $mtconf = json_decode(WebsiteConfiguration::whereName('MaintenancePassword')->first()->value);
-
- if($password == $mtconf->password)
- {
- $btns = array_slice($buttons, -count($mtconf->combination));
- $data = json_decode(file_get_contents(storage_path('framework/down')), true);
-
- if(isset($data['secret']) && $btns === $mtconf->combination)
- {
- $trustedHosts = explode(',', env('TRUSTED_HOSTS'));
- $origin = parse_url($request->headers->get('origin'), PHP_URL_HOST);
- $passCheck = false;
-
- foreach($trustedHosts as &$host)
- {
- if(str_ends_with($origin, $host))
- $passCheck = true;
- }
-
- $expiresAt = Carbon::now()->addHours(24);
- $bypassCookie = new Cookie('gt_constraint', base64_encode(json_encode([
- 'expires_at' => $expiresAt->getTimestamp(),
- 'mac' => hash_hmac('SHA256', $expiresAt->getTimestamp(), $data['secret']),
- ])), $expiresAt);
-
- if($passCheck)
- $bypassCookie = $bypassCookie->withDomain('.' . $origin);
-
- return response('')
- ->withCookie($bypassCookie);
- }
- }
-
- return response('')
- ->setStatusCode(403);
- }
- else
- {
+ if(!$password || !$buttons) {
return response('{"errors":[{"code":400,"message":"BadRequest"}]}')
->setStatusCode(400)
->header('Cache-Control', 'private')
->header('Content-Type', 'application/json; charset=utf-8');
}
+
+ /* */
+
+ $mtconf = json_decode(WebsiteConfiguration::whereName('MaintenancePassword')->first()->value);
+
+ if(file_exists(storage_path('framework/down')) && $password == $mtconf->password)
+ {
+ $btns = array_slice($buttons, -count($mtconf->combination));
+ $data = json_decode(file_get_contents(storage_path('framework/down')), true);
+
+ if(isset($data['secret']) && $btns === $mtconf->combination)
+ {
+ $trustedHosts = explode(',', env('TRUSTED_HOSTS'));
+ $origin = parse_url($request->headers->get('origin'), PHP_URL_HOST);
+ $passCheck = false;
+
+ foreach($trustedHosts as &$host)
+ {
+ if(str_ends_with($origin, $host))
+ $passCheck = true;
+ }
+
+ $expiresAt = Carbon::now()->addHours(24);
+ $bypassCookie = new Cookie('gt_constraint', base64_encode(json_encode([
+ 'expires_at' => $expiresAt->getTimestamp(),
+ 'mac' => hash_hmac('SHA256', $expiresAt->getTimestamp(), $data['secret']),
+ ])), $expiresAt);
+
+ if($passCheck)
+ $bypassCookie = $bypassCookie->withDomain('.' . $origin);
+
+ return response('')
+ ->withCookie($bypassCookie);
+ }
+ }
+
+ return response('')
+ ->setStatusCode(403);
}
}
diff --git a/web/app/Http/Kernel.php b/web/app/Http/Kernel.php
index b26462e..3c37488 100644
--- a/web/app/Http/Kernel.php
+++ b/web/app/Http/Kernel.php
@@ -37,6 +37,7 @@ class Kernel extends HttpKernel
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
+ \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
],
'admin' => [
diff --git a/web/app/Http/Middleware/PreventRequestsDuringMaintenance.php b/web/app/Http/Middleware/PreventRequestsDuringMaintenance.php
index 444821c..1b7d639 100644
--- a/web/app/Http/Middleware/PreventRequestsDuringMaintenance.php
+++ b/web/app/Http/Middleware/PreventRequestsDuringMaintenance.php
@@ -21,7 +21,7 @@ class PreventRequestsDuringMaintenance
*
* @var array
*/
- protected $except = ['banners/data', 'maintenance/bypass'];
+ protected $except = ['maintenance', 'maintenance/bypass'];
/**
* Create a new middleware instance.
diff --git a/web/app/Models/AssetGenre.php b/web/app/Models/AssetGenre.php
new file mode 100644
index 0000000..7910df3
--- /dev/null
+++ b/web/app/Models/AssetGenre.php
@@ -0,0 +1,11 @@
+ env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
+
+ 'mysql-asset' => [
+ 'driver' => 'mysql',
+ 'url' => env('DATABASE_URL'),
+ 'host' => env('DB_HOST', '127.0.0.1'),
+ 'port' => env('DB_PORT', '3306'),
+ 'database' => env('DB_ASSET_DATABASE', 'gtoriadev_primary'),
+ 'username' => env('DB_USERNAME', 'gtoriadev_primary'),
+ 'password' => env('DB_PASSWORD', ''),
+ 'unix_socket' => env('DB_SOCKET', ''),
+ 'charset' => 'utf8mb4',
+ 'collation' => 'utf8mb4_unicode_ci',
+ 'prefix' => '',
+ 'prefix_indexes' => true,
+ 'strict' => true,
+ 'engine' => null,
+ 'options' => extension_loaded('pdo_mysql') ? array_filter([
+ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
+ ]) : [],
+ ],
'pgsql' => [
'driver' => 'pgsql',
diff --git a/web/database/migrations/2022_04_15_000406_create_asset_types_table.php b/web/database/migrations/2022_04_15_000406_create_asset_types_table.php
index 466f7eb..188c56c 100644
--- a/web/database/migrations/2022_04_15_000406_create_asset_types_table.php
+++ b/web/database/migrations/2022_04_15_000406_create_asset_types_table.php
@@ -6,6 +6,13 @@ use Illuminate\Support\Facades\Schema;
class CreateAssetTypesTable extends Migration
{
+ /**
+ * The database connection that should be used by the migration.
+ *
+ * @var string
+ */
+ protected $connection = 'mysql-asset';
+
/**
* Run the migrations.
*
@@ -15,6 +22,8 @@ class CreateAssetTypesTable extends Migration
{
Schema::create('asset_types', function (Blueprint $table) {
$table->id();
+ $table->longText('name');
+ $table->boolean('binaryFormat')->default(false);
$table->timestamps();
});
}
diff --git a/web/database/migrations/2022_04_15_000413_create_assets_table.php b/web/database/migrations/2022_04_15_000413_create_assets_table.php
index ab361cb..ba87aa3 100644
--- a/web/database/migrations/2022_04_15_000413_create_assets_table.php
+++ b/web/database/migrations/2022_04_15_000413_create_assets_table.php
@@ -6,6 +6,13 @@ use Illuminate\Support\Facades\Schema;
class CreateAssetsTable extends Migration
{
+ /**
+ * The database connection that should be used by the migration.
+ *
+ * @var string
+ */
+ protected $connection = 'mysql-asset';
+
/**
* Run the migrations.
*
@@ -13,8 +20,19 @@ class CreateAssetsTable extends Migration
*/
public function up()
{
+ // TODO: relational genres?
+ // god i fucking hate foreign keys
Schema::create('assets', function (Blueprint $table) {
$table->id();
+ $table->unsignedBigInteger('creatorId');
+ $table->longText('title');
+ $table->longText('description');
+ $table->json('settings');
+ $table->boolean('commentsEnabled')->default(true);
+ $table->boolean('purchasable')->default(false);
+ $table->unsignedBigInteger('assetVersionId');
+ $table->unsignedBigInteger('assetTypeId');
+ $table->unsignedBigInteger('assetGenreId');
$table->timestamps();
});
}
diff --git a/web/database/migrations/2022_04_15_000429_create_asset_versions_table.php b/web/database/migrations/2022_04_15_000429_create_asset_versions_table.php
index 1b53497..1f1b8f1 100644
--- a/web/database/migrations/2022_04_15_000429_create_asset_versions_table.php
+++ b/web/database/migrations/2022_04_15_000429_create_asset_versions_table.php
@@ -6,6 +6,13 @@ use Illuminate\Support\Facades\Schema;
class CreateAssetVersionsTable extends Migration
{
+ /**
+ * The database connection that should be used by the migration.
+ *
+ * @var string
+ */
+ protected $connection = 'mysql-asset';
+
/**
* Run the migrations.
*
@@ -15,6 +22,8 @@ class CreateAssetVersionsTable extends Migration
{
Schema::create('asset_versions', function (Blueprint $table) {
$table->id();
+ $table->unsignedBigInteger('assetId');
+ $table->longText('cdnHash');
$table->timestamps();
});
}
diff --git a/web/database/migrations/2022_04_17_030538_create_asset_genres_table.php b/web/database/migrations/2022_04_17_030538_create_asset_genres_table.php
new file mode 100644
index 0000000..6d8b672
--- /dev/null
+++ b/web/database/migrations/2022_04_17_030538_create_asset_genres_table.php
@@ -0,0 +1,33 @@
+id();
+ $table->longText('name');
+ $table->longText('iconUrl');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('asset_genres');
+ }
+}
diff --git a/web/public/mix-manifest.json b/web/public/mix-manifest.json
index 9525ade..e716ec6 100644
--- a/web/public/mix-manifest.json
+++ b/web/public/mix-manifest.json
@@ -1,4 +1,5 @@
{
"/js/app.js": "/js/app.js",
+ "/js/pages/maintenance.js": "/js/pages/maintenance.js",
"/css/graphictoria.css": "/css/graphictoria.css"
}
diff --git a/web/resources/js/pages/Maintenance.js b/web/resources/js/pages/Maintenance.js
new file mode 100644
index 0000000..09f505d
--- /dev/null
+++ b/web/resources/js/pages/Maintenance.js
@@ -0,0 +1,95 @@
+// © XlXi 2021
+// Graphictoria 5
+
+import axios from 'axios';
+
+import $ from 'jquery';
+
+import * as ReactDOM from 'react-dom';
+import React, { useRef, Suspense } from 'react';
+
+import { buildGenericApiUrl } from '../util/HTTP.js';
+
+import { Canvas, useFrame } from '@react-three/fiber';
+import { Instances, Instance, PerspectiveCamera, useGLTF } from '@react-three/drei';
+
+const randomVector = (r) => [r / 2 - Math.random() * r, r / 2 - Math.random() * r, r / 2 - Math.random() * r];
+const randomEuler = () => [Math.random() * Math.PI, Math.random() * Math.PI, Math.random() * Math.PI];
+const randomData = Array.from({ length: 2000 }, (r = 200) => ({ random: Math.random(), position: randomVector(r), rotation: randomEuler() }));
+
+function Scene() {
+ const { nodes, materials } = useGLTF('/models/graphictoriapart.glb');
+
+ return (
+ <>
+