Lots of new stuff.
This commit is contained in:
parent
2c25af9efc
commit
b50d89d539
Binary file not shown.
Binary file not shown.
|
|
@ -16,8 +16,6 @@ class Kernel extends HttpKernel
|
|||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
|
|
@ -64,5 +62,6 @@ class Kernel extends HttpKernel
|
|||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'cors' => \App\Http\Middleware\Cors::class,
|
||||
'maintenance' => \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,144 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Foundation\Http\MaintenanceModeBypassCookie;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
class PreventRequestsDuringMaintenance
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
* The application implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* The URIs that should be accessible while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
protected $except = [];
|
||||
|
||||
/**
|
||||
* Create a new middleware instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->app->isDownForMaintenance()) {
|
||||
$data = json_decode(file_get_contents($this->app->storagePath().'/framework/down'), true);
|
||||
|
||||
if (isset($data['secret']) && $request->path() === $data['secret']) {
|
||||
return $this->bypassResponse($data['secret']);
|
||||
}
|
||||
|
||||
if ($this->hasValidBypassCookie($request, $data) ||
|
||||
$this->inExceptArray($request)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return response('{"errors":[{"code":503,"message":"ServiceUnavailable"}]}', 503)
|
||||
->header('Cache-Control', 'private')
|
||||
->header('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the incoming request has a maintenance mode bypass cookie.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasValidBypassCookie($request, array $data)
|
||||
{
|
||||
return isset($data['secret']) &&
|
||||
$request->cookie('laravel_maintenance') &&
|
||||
MaintenanceModeBypassCookie::isValid(
|
||||
$request->cookie('laravel_maintenance'),
|
||||
$data['secret']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the request has a URI that should be accessible in maintenance mode.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return bool
|
||||
*/
|
||||
protected function inExceptArray($request)
|
||||
{
|
||||
foreach ($this->except as $except) {
|
||||
if ($except !== '/') {
|
||||
$except = trim($except, '/');
|
||||
}
|
||||
|
||||
if ($request->fullUrlIs($except) || $request->is($except)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the user back to the root of the application with a maintenance mode bypass cookie.
|
||||
*
|
||||
* @param string $secret
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function bypassResponse(string $secret)
|
||||
{
|
||||
return redirect('/')->withCookie(
|
||||
MaintenanceModeBypassCookie::create($secret)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers that should be sent with the response.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function getHeaders($data)
|
||||
{
|
||||
$headers = isset($data['retry']) ? ['Retry-After' => $data['retry']] : [];
|
||||
|
||||
if (isset($data['refresh'])) {
|
||||
$headers['Refresh'] = $data['refresh'];
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URIs that should be accessible even when maintenance mode is enabled.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExcludedPaths()
|
||||
{
|
||||
return $this->except;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FFlag extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FastGroup extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"laravel/framework": "^8.54",
|
||||
"laravel/sail": "^1.12",
|
||||
"laravel/sanctum": "^2.11",
|
||||
"laravel/tinker": "^2.5",
|
||||
"laravel/ui": "^3.3",
|
||||
"predis/predis": "^1.1"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "eae1aa1a609fc45f372619bc8e23cafc",
|
||||
"content-hash": "c6a0e979567b55245388bdaffddfe2e4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
|
|
@ -1165,70 +1165,6 @@
|
|||
},
|
||||
"time": "2021-10-26T21:37:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/sanctum",
|
||||
"version": "v2.11.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/sanctum.git",
|
||||
"reference": "b21e65cbe13896946986cb0868180cd69e1bd5d3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/sanctum/zipball/b21e65cbe13896946986cb0868180cd69e1bd5d3",
|
||||
"reference": "b21e65cbe13896946986cb0868180cd69e1bd5d3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^6.9|^7.0|^8.0",
|
||||
"illuminate/database": "^6.9|^7.0|^8.0",
|
||||
"illuminate/support": "^6.9|^7.0|^8.0",
|
||||
"php": "^7.2|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"orchestra/testbench": "^4.0|^5.0|^6.0",
|
||||
"phpunit/phpunit": "^8.0|^9.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Sanctum\\SanctumServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Sanctum\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.",
|
||||
"keywords": [
|
||||
"auth",
|
||||
"laravel",
|
||||
"sanctum"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/sanctum/issues",
|
||||
"source": "https://github.com/laravel/sanctum"
|
||||
},
|
||||
"time": "2021-06-15T15:56:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/tinker",
|
||||
"version": "v2.6.1",
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Stateful Domains
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Requests from the following domains / hosts will receive stateful API
|
||||
| authentication cookies. Typically, these should include your local
|
||||
| and production domains which access your API via a frontend SPA.
|
||||
|
|
||||
*/
|
||||
|
||||
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
|
||||
'%s%s',
|
||||
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
|
||||
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
|
||||
))),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Expiration Minutes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value controls the number of minutes until an issued token will be
|
||||
| considered expired. If this value is null, personal access tokens do
|
||||
| not expire. This won't tweak the lifetime of first-party sessions.
|
||||
|
|
||||
*/
|
||||
|
||||
'expiration' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sanctum Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When authenticating your first-party SPA with Sanctum you may need to
|
||||
| customize some of the middleware Sanctum uses while processing the
|
||||
| request. You may change the middleware listed below as required.
|
||||
|
|
||||
*/
|
||||
|
||||
'middleware' => [
|
||||
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
|
||||
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
|
||||
],
|
||||
|
||||
];
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreatePersonalAccessTokensTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->morphs('tokenable');
|
||||
$table->string('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateFflagsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('fflags', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('value');
|
||||
$table->enum('dataType', ['Log', 'Int', 'String']);
|
||||
$table->enum('type', ['Raw', 'Fast', 'Dynamic', 'Shared']);
|
||||
$table->bigInteger('groupId');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('fflags');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateFastgroupsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('fastgroups', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->boolean('protected')->default(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('fastgroups');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
use App\Models\FFlag;
|
||||
use App\Models\FastGroup;
|
||||
|
||||
class FFlagSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$clientAppSettings = FastGroup::create([
|
||||
'name' => 'ClientAppSettings'
|
||||
]);
|
||||
|
||||
$cloudAppSettings = FastGroup::create([
|
||||
'name' => 'CloudCompute'
|
||||
]);
|
||||
|
||||
$clientSharedSettings = FastGroup::create([
|
||||
'name' => 'ClientSharedSettings'
|
||||
]);
|
||||
|
||||
$arbiterAppSettings = FastGroup::create([
|
||||
'name' => 'Arbiter'
|
||||
]);
|
||||
|
||||
$windowsBootstrapperSettings = FastGroup::create([
|
||||
'name' => 'WindowsBootstrapperSettings'
|
||||
]);
|
||||
|
||||
$windowsStudioBootstrapperSettings = FastGroup::create([
|
||||
'name' => 'WindowsStudioBootstrapperSettings'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1242,6 +1242,23 @@
|
|||
"@babel/runtime": "^7.6.2"
|
||||
}
|
||||
},
|
||||
"@react-three/fiber": {
|
||||
"version": "7.0.24",
|
||||
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-7.0.24.tgz",
|
||||
"integrity": "sha512-CJi1Mex7jqByTEVZoUzg0xZEw63CUjm4bUDx0XIhuAmNUsmFmht7cRt87zUQSSDQvmaDqvoDWW7dD+uFJW/kUQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"react-merge-refs": "^1.1.0",
|
||||
"react-reconciler": "^0.26.2",
|
||||
"react-three-fiber": "0.0.0-deprecated",
|
||||
"react-use-measure": "^2.1.1",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"scheduler": "^0.20.2",
|
||||
"use-asset": "^1.0.4",
|
||||
"utility-types": "^3.10.0",
|
||||
"zustand": "^3.5.1"
|
||||
}
|
||||
},
|
||||
"@restart/context": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz",
|
||||
|
|
@ -3146,6 +3163,11 @@
|
|||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz",
|
||||
"integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw=="
|
||||
},
|
||||
"debounce": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
||||
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
|
|
@ -6548,6 +6570,21 @@
|
|||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-merge-refs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz",
|
||||
"integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ=="
|
||||
},
|
||||
"react-reconciler": {
|
||||
"version": "0.26.2",
|
||||
"resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz",
|
||||
"integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"scheduler": "^0.20.2"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz",
|
||||
|
|
@ -6598,6 +6635,11 @@
|
|||
"tiny-warning": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"react-three-fiber": {
|
||||
"version": "0.0.0-deprecated",
|
||||
"resolved": "https://registry.npmjs.org/react-three-fiber/-/react-three-fiber-0.0.0-deprecated.tgz",
|
||||
"integrity": "sha512-EblIqTAsIpkYeM8bZtC4lcpTE0A2zCEGipFB52RgcQq/q+0oryrk7Sxt+sqhIjUu6xMNEVywV8dr74lz5yWO6A=="
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",
|
||||
|
|
@ -6609,6 +6651,14 @@
|
|||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"react-use-measure": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz",
|
||||
"integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==",
|
||||
"requires": {
|
||||
"debounce": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
|
|
@ -6759,6 +6809,11 @@
|
|||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
|
||||
"dev": true
|
||||
},
|
||||
"resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
||||
|
|
@ -6939,7 +6994,6 @@
|
|||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
|
||||
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
|
|
@ -7513,6 +7567,11 @@
|
|||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||
"dev": true
|
||||
},
|
||||
"three": {
|
||||
"version": "0.135.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.135.0.tgz",
|
||||
"integrity": "sha512-kuEpuuxRzLv0MDsXai9huCxOSQPZ4vje6y0gn80SRmQvgz6/+rI0NAvCRAw56zYaWKMGMfqKWsxF9Qa2Z9xymQ=="
|
||||
},
|
||||
"thunky": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
||||
|
|
@ -7694,6 +7753,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"use-asset": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/use-asset/-/use-asset-1.0.4.tgz",
|
||||
"integrity": "sha512-7/hqDrWa0iMnCoET9W1T07EmD4Eg/Wmoj/X8TGBc++ECRK4m5yTsjP4O6s0yagbxfqIOuUkIxe2/sA+VR2GxZA==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"util": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
|
||||
|
|
@ -7717,6 +7784,11 @@
|
|||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
},
|
||||
"utility-types": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
|
||||
"integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg=="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
|
|
@ -8150,6 +8222,11 @@
|
|||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"zustand": {
|
||||
"version": "3.6.7",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-3.6.7.tgz",
|
||||
"integrity": "sha512-bYWKXMfoJwZyliFgidcQ3tJC/F2f2hHq1+lhTk8dVPX2k28i4VnpnKjBGNxAd2QNliV0m455Vm+gDL8LShrV3g=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,13 @@
|
|||
"webpack-subresource-integrity": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^7.0.24",
|
||||
"@steveeeie/react-page-transition": "^1.2.1",
|
||||
"laravel-mix-react-css-modules": "^2.0.0",
|
||||
"mini-css-extract-plugin": "^2.4.3",
|
||||
"react-bootstrap": "^2.0.2",
|
||||
"react-google-recaptcha": "^2.1.0",
|
||||
"styled-components": "^5.3.1"
|
||||
"styled-components": "^5.3.1",
|
||||
"three": "^0.135.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import Navbar from '../components/Navbar.js';
|
|||
import Banner from '../components/Banner.js';
|
||||
import Footer from '../components/Footer.js';
|
||||
|
||||
import Loader from '../Components/Loader.js';
|
||||
|
||||
import { Home } from '../Pages/Home.js';
|
||||
|
||||
import { Auth } from '../Pages/Auth.js';
|
||||
|
|
@ -29,7 +31,7 @@ var protocol = Config.Protocol;
|
|||
class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {maintenance: false, theme: 0, banners: []};
|
||||
this.state = {maintenance: false, theme: 0, banners: [], offlineFetched: false};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
@ -37,22 +39,38 @@ class App extends React.Component {
|
|||
|
||||
function updateBanners()
|
||||
{
|
||||
axios.get(protocol + 'apis.' + url + '/banners/data').then((response) => {
|
||||
var result = [];
|
||||
response.data.map(function(banner){
|
||||
result.push(<Banner type={banner.type} description={banner.text} dismissible={banner.dismissable} />);
|
||||
axios.get(protocol + 'apis.' + url + '/banners/data')
|
||||
.then((response) => {
|
||||
var result = [];
|
||||
response.data.map(function(banner){
|
||||
result.push(<Banner type={banner.type} description={banner.text} dismissible={banner.dismissable} />);
|
||||
});
|
||||
app.setState({banners: result});
|
||||
});
|
||||
app.setState({banners: result});
|
||||
});
|
||||
}
|
||||
|
||||
if(this.state.maintenance === true)
|
||||
function updateOfflineStatus()
|
||||
{
|
||||
this.setState({theme: 1});
|
||||
axios.get(protocol + 'apis.' + url + '/')
|
||||
.then((response) => {
|
||||
app.setState({maintenance: false});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.response)
|
||||
{
|
||||
if(error.response.status == 503)
|
||||
app.setState({maintenance: true, theme: 1});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
app.setState({offlineFetched: true});
|
||||
});
|
||||
}
|
||||
|
||||
updateBanners();
|
||||
updateOfflineStatus();
|
||||
setInterval(updateBanners, 2*60*1000 /* 2 mins */);
|
||||
setInterval(updateOfflineStatus, 10*60*1000 /* 10 mins */);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
@ -60,8 +78,9 @@ class App extends React.Component {
|
|||
document.documentElement.classList.remove(!(this.state.theme === 0) ? 'gtoria-light' : 'gtoria-dark');
|
||||
|
||||
return (
|
||||
this.state.offlineFetched == true ?
|
||||
<Router>
|
||||
<Navbar maintenanceEnabled={false} />
|
||||
<Navbar maintenanceEnabled={this.state.maintenance} />
|
||||
{
|
||||
|
||||
this.state.banners.length !== 0 ?
|
||||
|
|
@ -134,6 +153,10 @@ class App extends React.Component {
|
|||
);
|
||||
}}/>
|
||||
</Router>
|
||||
:
|
||||
<div className="gtoria-loader-center">
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const LoginForm = (props) => {
|
|||
</div>
|
||||
<div className="col">
|
||||
<h5>New to Graphictoria?</h5>
|
||||
<p>Creating an account takes less than a minute, and you can join a community of 6k+ users for <b>completely free</b>.<br/><Link to="/register" className="text-decoration-none fw-normal">Sign Up</Link></p>
|
||||
<p>Creating an account takes less than a minute, and you can join a community of 7k+ users for <b>completely free</b>.<br/><Link to="/register" className="text-decoration-none fw-normal">Sign Up</Link></p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class Home extends React.Component {
|
|||
<div className="container graphictoria-center-vh my-auto text-center text-white">
|
||||
<div className="mb-4 graphictoria-home-shadow">
|
||||
<h1 className="graphictoria-homepage-header">Graphictoria</h1>
|
||||
<h5 className="mb-0">Graphictoria aims to revive the classic Roblox experience. Join <b>6k+</b> other users and relive your childhood!</h5>
|
||||
<h5 className="mb-0">Graphictoria aims to revive the classic Roblox experience. Join <b>7k+</b> other users and relive your childhood!</h5>
|
||||
<p className="graphictoria-homepage-fine-print fst-italic">* Graphictoria is not affiliated with, endorsed by, or sponsored by Roblox Corporation.</p>
|
||||
</div>
|
||||
<Link to="/register" className="btn btn-success">Create your account<i className="ps-2 graphictoria-small-aligned-text fas fa-chevron-right"></i></Link>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,47 @@
|
|||
// © XlXi 2021
|
||||
// Graphictoria 5
|
||||
|
||||
import React from "react";
|
||||
import React, { useRef } from 'react';
|
||||
|
||||
import { Canvas, useFrame } from '@react-three/fiber';
|
||||
|
||||
import SetTitle from "../Helpers/Title.js";
|
||||
|
||||
let Buttons = [];
|
||||
let ButtonsAlreadyTemplated = false;
|
||||
|
||||
function Box(props) {
|
||||
const ref = useRef();
|
||||
|
||||
const distanceFromCamera = Math.random() * 30
|
||||
|
||||
const rotX = (Math.random() * 200 - 100)/300
|
||||
const rotZ = (Math.random() * 200 - 100)/300
|
||||
|
||||
useFrame((state, delta) => {
|
||||
ref.current.position.y -= 0.6 * delta
|
||||
ref.current.rotation.x += rotX * delta
|
||||
ref.current.rotation.z += rotZ * delta
|
||||
|
||||
if(ref.current.position.y < -30)
|
||||
{
|
||||
ref.current.position.y = 30;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<mesh
|
||||
{...props}
|
||||
ref={ref}
|
||||
scale={1}
|
||||
position={[(Math.random() * 120) - 60, (Math.random() * 60) - 30, -distanceFromCamera]}
|
||||
rotation={[Math.random() * 360, Math.random() * 360, Math.random() * 360]}>
|
||||
<boxGeometry args={[1, 0.3, 0.5]} />
|
||||
<meshStandardMaterial color={'grey'} />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
function MakeButtons()
|
||||
{
|
||||
if(!ButtonsAlreadyTemplated)
|
||||
|
|
@ -37,20 +71,31 @@ class Maintenance extends React.Component {
|
|||
{
|
||||
MakeButtons();
|
||||
return (
|
||||
<div className="text-center mt-auto container">
|
||||
<h1>Graphictoria is currently under maintenance.</h1>
|
||||
<h4>Our advanced team of cyber monkes are working to make Graphictoria better. We'll be back soon!</h4>
|
||||
<div className="input-group mt-5">
|
||||
<input type="password" className="form-control" placeholder="Password" autoComplete="off"/>
|
||||
{
|
||||
Buttons.map(character => (
|
||||
<React.Fragment key={character.id}>
|
||||
<button className="btn btn-secondary" type="button" onClick={ () => DoButton(character.id) }>{character.value}</button>
|
||||
</React.Fragment>
|
||||
))
|
||||
}
|
||||
<>
|
||||
<div className="gtoria-maintenance-background">
|
||||
<Canvas>
|
||||
<ambientLight />
|
||||
<pointLight position={[10, 10, 10]} />
|
||||
{
|
||||
[...Array(100)].map((e, i) => (<Box key={i}/>))
|
||||
}
|
||||
</Canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-center mt-auto container">
|
||||
<h1>Graphictoria is currently under maintenance.</h1>
|
||||
<h4>Our advanced team of cyber monkes are working to make Graphictoria better. We'll be back soon!</h4>
|
||||
<div className="input-group mt-5">
|
||||
<input type="password" className="form-control" placeholder="Password" autoComplete="off"/>
|
||||
{
|
||||
Buttons.map(character => (
|
||||
<React.Fragment key={character.id}>
|
||||
<button className="btn btn-secondary" type="button" onClick={ () => DoButton(character.id) }>{character.value}</button>
|
||||
</React.Fragment>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,20 @@ $web-font-path: "https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,w
|
|||
border-width: 0 1px $width 1px;
|
||||
}
|
||||
|
||||
// Maintenance
|
||||
.gtoria-maintenance-background {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -9999;
|
||||
}
|
||||
|
||||
// Loader
|
||||
|
||||
.gtoria-loader-center {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.gtoria-loader {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,11 @@ use App\Http\Controllers\GamesController;
|
|||
|
|
||||
*/
|
||||
|
||||
Route::middleware(['cors'])->group(function() {
|
||||
|
||||
Route::middleware(['cors', 'maintenance'])->group(function() {
|
||||
Route::get('/', function () {
|
||||
return 'API OK';
|
||||
});
|
||||
|
||||
|
||||
Route::get('/banners/data', [BannerController::class, 'getBanners']);
|
||||
|
||||
Route::get('/games/metadata', [GamesController::class, 'isAvailable']);
|
||||
|
|
@ -31,5 +30,4 @@ Route::middleware(['cors'])->group(function() {
|
|||
->header('Cache-Control', 'private')
|
||||
->header('Content-Type', 'application/json; charset=utf-8');
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
Reference in New Issue