god i hate laravel sometimes^

This commit is contained in:
gtoriadotnet 2022-03-26 02:29:58 -04:00
parent a70bd470f5
commit 55acc9010e
36 changed files with 504 additions and 564 deletions

View File

@ -1,19 +1,24 @@
APP_NAME=Laravel
TRUSTED_HOSTS=localhost,gtoria.local
APP_NAME=Graphictoria
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_URL=http://gtoria.local
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_CONNECTION=mysql-primary
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_USERNAME=service-laravel
DB_PASSWORD=
DB_PRIMARY_DATABASE=gtoriadev_primary
DB_MEMBERSHIP_DATABASE=gtoriadev_membership
DB_FFLAG_DATABASE=gtoriadev_fflag
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
@ -21,7 +26,7 @@ QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
MEMCACHED_HOST=memcached
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
@ -48,4 +53,4 @@ PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

View File

@ -0,0 +1,65 @@
<?php
/*
Graphictoria 2022
Authentication helper
Written because FUCK WHOEVER IS BEHIND THE Illuminate\Foundation\Auth\User DEV TEAM AHHHHHH
my frustration is immeasureable ~ xlxi
*/
namespace App\Helpers;
use Illuminate\Http\Request;
use Carbon\Carbon;
use App\Models\User;
use App\Models\User\UserSession;
use App\Helpers\Random;
class AuthHelper
{
/**
* "Guards" a page in the sense where it kills the request if the user is logged in.
*
* @return boolean
*/
public static function Guard(Request $request) {
if(AuthHelper::GetCurrentUser($request))
return true;
}
/**
* Returns the current user.
*
* @return User?
*/
public static function GetCurrentUser(Request $request) {
if($request->session()->exists('authentication')) {
$session = UserSession::where('token', $request->session()->get('authentication'))->first();
if($session)
return User::where('id', $session->user)->first();
return;
}
return;
}
/**
* Grants a session.
*
* @return UserSession
*/
public static function GrantSession($request, $id) {
$session = new UserSession();
$session->user = $id;
// formerly cookies
$session->token = 'DO_NOT_SHARE_OR_YOUR_ITEMS_WILL_BE_STOLEN_|' . Random::Str(64);
$session->ip = $request->ip();
$session->last_seen = Carbon::now();
$session->save();
return $session;
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
Graphictoria 2022
Random generator
*/
namespace App\Helpers;
class Random
{
/**
* Creates a random string of the specified length.
*
* @return String
*/
public static function Str($length) {
// https://stackoverflow.com/questions/4356289/php-random-string-generator
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ConfirmsPasswords;
class ConfirmPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Confirm Password Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password confirmations and
| uses a simple trait to include the behavior. You're free to explore
| this trait and override any functions that require customization.
|
*/
use ConfirmsPasswords;
/**
* Where to redirect users when the intended url fails.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
}

View File

@ -1,40 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}

View File

@ -1,105 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Carbon;
use Request;
use Auth;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'username' => ['required', 'string', 'max:16', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\Models\User
*/
protected function create(Request $request)
{
$data = Request::all();
if (Request::input('password') != Request::input('confirmation')) {
return Response()->json(['message'=>"Those passwords don't match!", 'badInputs'=>['password','confirmation']]);
}
$valid = Validator::make($data, [
'username' => ['required', 'string', 'max:16', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8'],
]);
if ($valid->stopOnFirstFailure()->fails()) {
$error = $valid->errors()->first();
$messages = $valid->messages()->get('*');
return Response()->json(['message'=>$error, 'badInputs'=>[array_keys($messages)]]);
}
$prws = array_merge(range('a', 'z'), range('A', 'Z'), range(0, 8));
shuffle($prws);
$sc = substr(implode($prws), 0, 56);
$user = new User;
$user->username = $data['username'];
$user->email = $data['email'];
$user->password = Hash::make($data['password']);
$user->token = $sc;
$user->save();
Request::session()->regenerate();
Auth::login($user);
setcookie('gtok', $sc, time()+(345600*30), "/", $_POST['host']);
return Response()->json(['message'=>'Success!', 'badInputs'=>[]]);
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
}

View File

@ -1,42 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\VerifiesEmails;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use App\Helpers\AuthHelper;
use App\Models\User;
class AuthController extends Controller
{
/**
* Creates an account for the user.
*
* @return Response
*/
public function Register(Request $request) {
if(AuthHelper::Guard($request))
return Response(null, 400);
/* */
$data = $request->all();
if ($request->input('password') != $request->input('confirmation'))
return Response()->json(['message'=>'The passwords you supplied don\'t match!', 'badInputs'=>['password','confirmation']]);
$valid = Validator::make(
$data,
[
'username' => ['required', 'string', 'regex:/[a-zA-Z0-9._]+/', 'max:20'],
'email' => ['required', 'string', 'email', 'max:255'],
'password' => ['required', 'string', 'min:8'],
]
);
if ($valid->stopOnFirstFailure()->fails()) {
$error = $valid->errors()->first();
$messages = $valid->messages()->get('*');
return Response()->json(['message'=>$error, 'badInputs'=>[array_keys($messages)]]);
}
if(User::where('username', $data['username'])->first())
return Response()->json(['message'=>'This user already exists.', 'badInputs'=>['username']]);
if(User::where('email', $data['email'])->first())
return Response()->json(['message'=>'This email is already in use!', 'badInputs'=>['email']]);
$user = new User();
$user->username = $data['username'];
$user->email = $data['email'];
$user->password = Hash::make($data['password']);
$user->about = 'I\'m new to Graphictoria!';
$user->save();
$request->session()->regenerate();
$newSession = AuthHelper::GrantSession($request, $user->id);
$request->session()->put('authentication', $newSession->token);
return Response()->json(['message'=>'Success!', 'badInputs'=>[]]);
}
/**
* Logs the user in.
*
* @return Response
*/
public function Login(Request $request) {
if(AuthHelper::Guard($request))
return Response(null, 400);
/* */
$data = $request->all();
$valid = Validator::make(
$data,
[
'username' => ['required', 'string'],
'password' => ['required', 'string'],
]
);
if ($valid->stopOnFirstFailure()->fails()) {
$error = $valid->errors()->first();
$messages = $valid->messages()->get('*');
return Response()->json(['message'=>$error, 'badInputs'=>[array_keys($messages)]]);
}
/* */
$user = User::where('username', $request->input('username'))->first();
if (!$user)
return Response()->json(['message'=>'That user doesn\'t exist.', 'badInputs'=>['username']]);
if (!$user->password != Hash::make($data['password']))
return Response()->json(['message'=>'The password you tried is incorrect.', 'badInputs'=>['password']]);
$request->session()->regenerate();
$newSession = AuthHelper::GrantSession($request, $user->id);
$request->session()->put('authentication', $newSession);
return Response()->json(['message'=>'Success!', 'badInputs'=>[]]);
}
/**
* Logs the user out and kills the session.
*
* @return Response
*/
public function Logout(Request $request) {
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}

View File

@ -28,44 +28,6 @@ class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function fetchUser() {
$POST;
if (!isset($_POST['decision'])) {return Response()->json(false);}
$decision = $_POST['decision'];
switch($decision) {
case "metaUser":
if (!isset($_POST['token'])) {return Response()->json(false);}
$POST = $_POST['token'];
$user = User::where('token', $POST)->first();
if (!$user) {return Response()->json(false);}
$array = $user->toArray();
$staff = Staff::where('user_id', $user->id)->first();
if ($staff) {$array['power'] = $staff->power_level;}
$array['bank'] = $user->bank;
$array['email'] = $user->email;
return Response()->json(["data"=>$array]);
break;
case "fetchedUser":
if (!isset($_POST['userId'])) {return Response()->json(false);}
$POST = $_POST['userId'];
$user = User::where('id', $POST)->first();
if (!$user) {return Response()->json(false);}
$array = $user->toArray();
$staff = Staff::where('user_id', $user->id)->first();
if ($staff) {$array['power'] = $staff->power_level;}
return Response()->json(["data"=>$array]);
break;
default:
return Response()->json(false);
break;
}
return Response()->json(["data"=>$array]);
}
public function fetchCategoriesFP() {
if (!isset($_POST['token'])) {return Response()->json(["error"=>"No user."]);}
@ -153,66 +115,4 @@ class Controller extends BaseController
return Response()->json(["post"=>$postA,"replies"=>$replies]);
}
public function logout(Request $request) {
$POST;
if (!isset($_COOKIE['gtok'])) {return Redirect('/login');}
$POST = $_COOKIE['gtok'];
$user = User::where('token', $POST)->first();
if (!$user) {return Redirect('/login');}
setcookie('gtok', null, time()+(345600*30), "/", $_SERVER['HTTP_HOST']);
return Redirect('/');
}
public function login(Request $request) {
$data = Request::all();
$valid = Validator::make($data, [
'username' => ['required', 'string'],
'password' => ['required', 'string'],
]);
if ($valid->stopOnFirstFailure()->fails()) {
$error = $valid->errors()->first();
$messages = $valid->messages()->get('*');
return Response()->json(['message'=>$error, 'badInputs'=>[array_keys($messages)]]);
}
if (!User::where('username', Request::input('username'))->first()) {
return Response()->json(['message'=>"Sorry, that user wasn't found!", 'badInputs'=>['username']]);
}
$user = User::where('username', Request::input('username'))->first();
if (!Auth::attempt(Request::only('username', 'password'))) {
return Response()->json(['message'=>'Sorry, thats the wrong password!', 'badInputs'=>['password']]);
}
Request::session()->regenerate();
$prws = array_merge(range('a', 'z'), range('A', 'Z'), range(0, 8));
shuffle($prws);
$sc = substr(implode($prws), 0, 56);
$user->token = $sc;
$user->save();
setcookie('gtok', $user->token, time()+(345600*30), "/", $_POST['host']);
Auth::login($user);
return Response()->json(['message'=>'Success!', 'badInputs'=>[]]);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Helpers\AuthHelper;
class UserController extends Controller
{
/**
* Gets the current user's settings.
*
* @return Response
*/
public function GetSettings(Request $request) {
$currentUser = AuthHelper::GetCurrentUser($request);
if($currentUser) {
return Response()->json([
'data' => []
]);
} else {
return Response()->json([
'error' => 'Unauthorized',
'userFacingMessage' => 'You are not authorized to perform this request.'
]);
}
// Not sure how we'd get here, but just in case
return Response(null, 400);
}
}

View File

@ -5,7 +5,8 @@ namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Helpers\AuthHelper;
class RedirectIfAuthenticated
{
@ -22,7 +23,7 @@ class RedirectIfAuthenticated
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
if (AuthHelper::GetCurrentUser($request)) {
return redirect(RouteServiceProvider::HOME);
}
}

View File

@ -8,12 +8,12 @@ use Illuminate\Database\Eloquent\Model;
/* FFlag bucket */
class Fbucket extends Model
{
use HasFactory;
/**
* The database connection that should be used by the migration.
*
* @var string
*/
protected $connection = 'mysql-fflag';
use HasFactory;
}

View File

@ -2,58 +2,17 @@
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Models\Staff;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable
class User extends Model
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var string[]
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
'token',
'email',
'email_verified_at',
'bank'
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function Staff() {
$staff = Staff::where('user_id', $this->id)->first();
return $staff;
}
public function inventory() {
return $this->morphMany('App\Models\Inventory', 'owner');
}
use HasFactory;
/**
* The database connection that should be used by the migration.
*
* @var string
*/
protected $connection = 'mysql-membership';
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserSession extends Model
{
use HasFactory;
/**
* The database connection that should be used by the migration.
*
* @var string
*/
protected $connection = 'mysql-membership';
}

View File

@ -82,6 +82,26 @@ return [
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mysql-membership' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_MEMBERSHIP_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'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',

View File

@ -6,6 +6,13 @@ use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* The database connection that should be used by the migration.
*
* @var string
*/
protected $connection = 'mysql-membership';
/**
* Run the migrations.
*
@ -17,11 +24,10 @@ class CreateUsersTable extends Migration
$table->id();
$table->string('username');
$table->string('email');
$table->timestamp('email_verified_at')->default(null);
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('token');
$table->integer('bank')->default(150);
$table->string('about')->default(null);
$table->integer('bank')->default(15);
$table->string('about')->nullable();
$table->timestamps();
});
}

View File

@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserSessionsTable extends Migration
{
/**
* The database connection that should be used by the migration.
*
* @var string
*/
protected $connection = 'mysql-membership';
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_sessions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user');
$table->string('token');
$table->ipAddress('ip');
$table->timestamp('last_seen');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_sessions');
}
}

View File

@ -3,6 +3,7 @@
import React from 'react';
/* regular card */
export const Card = (props) => {
return (
<div className="container graphictoria-center-vh">
@ -23,3 +24,23 @@ export const CardTitle = (props) => {
</>
);
};
/* mini card */
export const MiniCardTitle = (props) => {
return (
<>
<h6 className='card-title'>{ props.children }</h6>
<hr className='mx-5 my-0 mb-2' />
</>
);
};
export const MiniCard = (props) => {
return (
<div className={`card${props.className ? ' ' + props.className : ''}`}>
<div className='card-body p-2 text-center'>
{ props.children }
</div>
</div>
);
};

View File

@ -9,7 +9,7 @@ const Navbar = (props) => {
return (
<>
<nav className="navbar graphictoria-navbar fixed-top navbar-expand-md shadow-sm">
<div className="container-sm">
<div className="container-md">
<NavLink className="navbar-brand" to={props.user? `/home` : `/`}>
<img src="/images/logo.png" alt="Graphictoria" width="43" height="43" draggable="false"/>
</NavLink>

View File

@ -18,7 +18,7 @@ export function CreateAccount(form)
var badInputs = [];
return new Promise(async (resolve, reject)=>{
await axios.post(`${protocol}apis.${url}/account/register`, body, {headers: {'X-CSRF-TOKEN': document.querySelector(`meta[name="csrf-token"]`).content, "X-Requested-With":"XMLHttpRequest", "accept":"application/json"}}).then(data=>{
await axios.post(`${protocol}apis.${url}/v1/user/register`, body, {headers: {'X-CSRF-TOKEN': document.querySelector(`meta[name="csrf-token"]`).content, "X-Requested-With":"XMLHttpRequest", "accept":"application/json"}}).then(data=>{
const res = data.data;
if (res.badInputs.length >= 1) {
badInputs=res.badInputs;
@ -39,7 +39,7 @@ export function LoginToAccount(form) {
var badInputs = [];
return new Promise(async (resolve, reject)=>{
await axios.post(`${protocol}apis.${url}/account/login`, body, {headers: {'X-CSRF-TOKEN': document.querySelector(`meta[name="csrf-token"]`).content, "X-Requested-With":"XMLHttpRequest"}}).then(data=>{
await axios.post(`${protocol}apis.${url}/v1/user/login`, body, {headers: {'X-CSRF-TOKEN': document.querySelector(`meta[name="csrf-token"]`).content, "X-Requested-With":"XMLHttpRequest"}}).then(data=>{
const res = data.data;
if (res.badInputs.length >= 1) {
badInputs=res.badInputs;
@ -61,25 +61,18 @@ export function CreateForum(form) {
return new Promise(async (resolve, reject)=>{
axios.post(`${protocol}apis.${url}/api/create/forum`, body, {headers: {'X-CSRF-TOKEN': document.querySelector(`meta[name="csrf-token"]`).content, "X-Requested-With":"XMLHttpRequest"}}).then(data=>{
const history = useHistory();
const res = data.data;
if (res.badInputs.length >= 1) {
badInputs=res.badInputs;
resolve({message: res.message, inputs: res.badInputs});
}
resolve("good");
}).catch(error=>{console.log(error);});
});
}
/*export function LogoutOfAccount() {
export function Logout() {
const body = form;
var badInputs = [];
axios.post(`${protocol}apis.${url}/account/logout`, body, {headers: {'X-CSRF-TOKEN': document.querySelector(`meta[name="csrf-token"]`).content, "X-Requested-With":"XMLHttpRequest"}}).then(data=>{
axios.post(`${protocol}apis.${url}/v1/user/logout`, body, {headers: {'X-CSRF-TOKEN': document.querySelector(`meta[name="csrf-token"]`).content, "X-Requested-With":"XMLHttpRequest"}}).then(data=>{
window.location.replace(`/`);
resolve("good");
}).catch(error=>{console.log(error);});
}*/
}

View File

@ -44,12 +44,10 @@ var protocol = Config.Protocol;
const App = () => {
const [state, setState] = useState({maintenance: false, theme: 0, banners: [], offlineFetch: false, loading: true});
const [user, setUser] = useState([]);
const [userLoad, setUserLoad] = useState(true);
const [state, setState] = useState({maintenance: false, theme: 0, banners: [], userFetched: false, offlineFetched: false, bannersFetched: false, loading: true});
const [user, setUser] = useState(false);
function updateBanners()
{
function updateBanners() {
axios.get(`${protocol}apis.${url}/banners/data`)
.then((response) => {
var result = [];
@ -57,25 +55,32 @@ const App = () => {
result.push(<Banner type={banner.type} description={banner.text} dismissible={banner.dismissable} />);
});
setState({banners: result});
})
.finally(() => {
setState({bannersFetched: true});
if(state.offlineFetched && state.userFetched) {
setState({loading: false});
}
});
}
function fetchUser() {
const body = new FormData();
body.append('token', encodeURIComponent(getCookie(`gtok`)));
body.append('decision', `metaUser`);
axios.post(`${protocol}apis.${url}/fetch/user`, body).then((res)=>{
if (res.data.data == `expired`) {setCookie(`gtok`, null, null);window.location.replace(`/login`);}
setUser(res.data.data);
setUserLoad(false);
});
return new Promise(async (resolve, reject)=>{
resolve("good");
});
axios.get(`${protocol}apis.${url}/v1/user/settings`)
.then((response) => {
if(!response.data.error)
setUser(response.data.data);
else
setUser(false);
})
.finally(() => {
setState({userFetched: true});
if(state.bannersFetched && state.offlineFetched) {
setState({loading: false});
}
});
}
function updateOfflineStatus()
{
function updateOfflineStatus() {
axios.get(`${protocol}apis.${url}/`)
.then((response) => {
if(state.maintenance == true)
@ -90,36 +95,40 @@ const App = () => {
})
.finally(() => {
setState({offlineFetched: true});
if(state.bannersFetched && state.userFetched) {
setState({loading: false});
}
});
}
const authMiddleware = (to, from, next) => {
console.log(user);
if (to.meta.auth) {
if (user) {next();}
if (user)
next();
next.redirect(`/login`);
}else if (to.meta.guest) {
if (!user) {next();}
} else if (to.meta.guest) {
if (!user)
next();
next.redirect(`/home`);
}else if (to.meta.staff) {
if (user && user.power) {next();}
next.redirect(`/`);
}
}
useEffect(async ()=>{
await fetchUser();
fetchUser();
updateBanners();
updateOfflineStatus();
setInterval(updateBanners, 2*60*1000 /* 2 mins */);
setInterval(updateOfflineStatus, 10*60*1000 /* 10 mins */);
setState({loading: true});
}, []);
document.documentElement.classList.add(state.theme == 0 ? 'gtoria-light' : 'gtoria-dark');
document.documentElement.classList.remove(!(state.theme == 0) ? 'gtoria-light' : 'gtoria-dark');
return (
!state.loading && !userLoad?
!state.loading ?
<Router>
<GuardProvider guards={[authMiddleware]}>
<Navbar maintenanceEnabled={state.maintenance} user={user} />

View File

@ -9,7 +9,7 @@ import ReCAPTCHA from 'react-google-recaptcha';
import SetTitle from '../Helpers/Title.js';
import { CreateAccount } from '../Helpers/Auth.js';
import { Card, CardTitle } from '../Layouts/Card.js';
import { Card, CardTitle } from '../Components/Card.js';
import LoginForm from './Auth/Login.js';
import ForgotPasswordForm from './Auth/ForgotPassword.js';
@ -47,10 +47,6 @@ class Auth extends React.Component {
pageLabel = (<><i className="fas fa-question-circle"></i> RESET PASSWORD</>);
pageContent = (<ForgotPasswordForm />);
break;
case `guest`:
pageLabel = (<><i className="fas fa-question-circle"></i> YOU NEED TO BE A GUEST!</>);
pageContent = (<div><div>Sorry, this page is for guests only!</div></div>);
break;
default:
pageLabel = (<><i className={`"fas fa-question-circle"`}></i> YOU'RE LOGGED IN!</>);
pageContent = (<div><div>Sorry, this page is for unauthenticated members only!</div></div>);

View File

@ -97,35 +97,4 @@ const RegisterForm = (props) => {
);
};
export default RegisterForm;
/*
const [values, setValues] = useState({
username: '',
email: '',
password: '',
confirmation: ''
});
const [validity, setValidity] = useState({
username: false,
email: false,
password: false,
confirmation: false
});
const [validityMessages, setValidityMessages] = useState({
username: 'test',
email: '',
password: '',
confirmation: ''
});
const handleChange = (e) => {
const {id, value} = e.target;
setValues(prevState => ({
...prevState,
[id] : value
}));
}
*/
export default RegisterForm;

View File

@ -12,7 +12,7 @@ import SetTitle from "../Helpers/Title.js";
import Loader from '../Components/Loader.js';
import { GenericErrorModal } from './Errors.js';
import { Card, CardTitle } from '../Layouts/Card.js';
import { Card, CardTitle } from '../Components/Card.js';
import { paginate } from '../helpers/utils.js';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@ -22,7 +22,7 @@ var protocol = Config.Protocol;
const Catalog = (props) => {
var id = useParams().id;
const [state, setState] = useState({offline: false, loading: true});
const [state, setState] = useState({loading: true});
const [categories, setCategoires] = useState([]);
const [category, setCategory] = useState([]);
const [items, setItems] = useState({items: [], currentPage: 1, meta: []});

View File

@ -11,7 +11,7 @@ import { getCookie } from '../helpers/utils';
import axios from "axios";
import Config from '../config.js';
import { Card, CardTitle } from '../Layouts/Card';
import { Card, CardTitle } from '../Components/Card';
axios.defaults.withCredentials = true

View File

@ -8,7 +8,7 @@ import ReCAPTCHA from 'react-google-recaptcha';
import { CreateAccount, LoginToAccount, CreateForum } from '../Helpers/Auth';
import Loader from '../Components/Loader';
import { getCookie } from '../helpers/utils';
import { Card, CardTitle } from '../Layouts/Card';
import { Card, CardTitle } from '../Components/Card';
import axios from "axios";
import Config from '../config.js';

View File

@ -12,19 +12,20 @@ import SetTitle from "../Helpers/Title.js";
import Loader from '../Components/Loader.js';
import { GenericErrorModal } from './Errors.js';
import { Card, CardTitle } from '../Layouts/Card.js';
import { MiniCard, MiniCardTitle } from '../Components/Card.js';
var url = Config.BaseUrl.replace('http://', '');
var protocol = Config.Protocol;
const Dashboard = (props) => {
const [state, setState] = useState({offline: false, loading: true});
const [state, setState] = useState({loading: true});
const [feedState, setFeedState] = useState({loading: true});
const user = props.user;
useEffect(()=>{
SetTitle(`Dashboard`);
setState({...state, loading: false});
setState({loading: false});
}, []);
return (
@ -32,39 +33,58 @@ const Dashboard = (props) => {
?
<Loader />
:
<div className='container'>
<h4>Hello, {user.username}!</h4>
<div className='container-lg'>
<div className='row'>
{/* User image, blog, friends */}
<div className='col-3'>
<div className='col-md-3'>
<h4>Hello, {user.username}!</h4>
<div className='card text-center'>
<p className='pt-3 px-3'>"{ user.about }"</p>
<img src='/images/testing/avatar.png' className='img-fluid' />
<img src='/images/testing/avatar.png' className='img-fluid gt-charimg' />
</div>
<div className='card mt-3'>
<div className='card-body p-2 text-center'>
<h6 className='card-title'>Blog</h6>
<hr className='mx-5 my-0 mb-2' />
<ul className="text-center list-unstyled mb-1">
<li className="pb-2"><a href="#" className="text-decoration-none fw-normal"><i className="fa-solid fa-circle-right"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</a></li>
<li className="pb-2"><a href="#" className="text-decoration-none fw-normal"><i className="fa-solid fa-circle-right"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</a></li>
<li className="pb-2"><a href="#" className="text-decoration-none fw-normal"><i className="fa-solid fa-circle-right"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</a></li>
</ul>
<div className="text-left px-2">
<a href="#" className="text-decoration-none fw-normal">More <i className="fa-solid fa-caret-right"></i></a>
</div>
<MiniCard className='mt-3'>
<MiniCardTitle>Blog</MiniCardTitle>
<ul className="text-center list-unstyled mb-1">
<li className="pb-2"><a href="#" className="text-decoration-none fw-normal"><i className="fa-solid fa-circle-right"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</a></li>
<li className="pb-2"><a href="#" className="text-decoration-none fw-normal"><i className="fa-solid fa-circle-right"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</a></li>
<li className="pb-2"><a href="#" className="text-decoration-none fw-normal"><i className="fa-solid fa-circle-right"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</a></li>
</ul>
<div className="text-left px-2">
<a href="#" className="text-decoration-none fw-normal">More <i className="fa-solid fa-caret-right"></i></a>
</div>
</div>
</MiniCard>
<MiniCard className='mt-3 d-none d-md-flex'>
<MiniCardTitle>Friends</MiniCardTitle>
</MiniCard>
</div>
{/* Feed */}
<div className='col-7'>
<div className='col-md-7 mt-3 mt-md-0'>
<h4>My Feed</h4>
<div className='card mb-2'>
<div className='input-group p-2'>
<input type='text' className='form-control' placeholder='What are you up to?' area-label='What are you up to?' />
<button className='btn btn-secondary' type='button'>Share</button>
</div>
</div>
{
feedState.loading
?
<div className='text-center'>
<Loader />
</div>
:
<div className='card'>
</div>
}
</div>
{/* Recently Played */}
<div className='col-2'>
<div className='col-md-2 d-none d-md-block'>
<h6>recently played</h6>
</div>
</div>
</div>

View File

@ -6,7 +6,7 @@ import { Link, useHistory } from "react-router-dom";
import SetTitle from "../Helpers/Title.js";
import { Card, CardTitle } from '../Layouts/Card.js';
import { Card, CardTitle } from '../Components/Card.js';
function GenericErrorModal(props)
{

View File

@ -12,7 +12,7 @@ import SetTitle from "../Helpers/Title.js";
import Loader from '../Components/Loader.js';
import { GenericErrorModal } from './Errors.js';
import { Card, CardTitle } from '../Layouts/Card.js';
import { Card, CardTitle } from '../Components/Card.js';
import { paginate } from '../helpers/utils.js';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

View File

@ -12,7 +12,7 @@ import SetTitle from "../Helpers/Title.js";
import Loader from '../Components/Loader.js';
import { GenericErrorModal } from './Errors.js';
import { Card, CardTitle } from '../Layouts/Card.js';
import { Card, CardTitle } from '../Components/Card.js';
import { paginate } from '../helpers/utils.js';
var url = Config.BaseUrl.replace('http://', '');

View File

@ -12,7 +12,7 @@ import SetTitle from "../Helpers/Title.js";
import Loader from '../Components/Loader.js';
import { GenericErrorModal } from './Errors.js';
import { Card, CardTitle } from '../Layouts/Card.js';
import { Card, CardTitle } from '../Components/Card.js';
import { getCookie, paginate } from '../helpers/utils.js';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

View File

@ -12,7 +12,7 @@ import SetTitle from "../Helpers/Title.js";
import Loader from '../Components/Loader.js';
import { GenericErrorModal } from './Errors.js';
import { Card, CardTitle } from '../Layouts/Card.js';
import { Card, CardTitle } from '../Components/Card.js';
var url = Config.BaseUrl.replace('http://', '');
var protocol = Config.Protocol;

View File

@ -193,6 +193,16 @@ html {
text-shadow: 0 0 4px $gray-700;
}
// Character
.gt-charimg {
max-height: 300px;
max-width: 300px;
@media (max-width: 768px) {
margin-left: auto;
margin-right: auto;
}
}
// Navbar
.navbar {

View File

@ -2,10 +2,12 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\BannerController;
use App\Http\Controllers\GamesController;
use App\Http\Controllers\Controller;
use App\Http\Controllers\UserController;
use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\Controller; // remove this and clean up the code lol
use App\Models\User;
/*
@ -23,6 +25,15 @@ Route::get('/', function(){
return 'API OK';
});
// Maintenance
Route::post('/v1/maintenance/bypass', 'MaintenanceController@bypass');
// User
Route::post('/v1/user/register', 'AuthController@Register');
Route::post('/v1/user/login', 'AuthController@Login');
Route::post('/v1/user/logout', 'AuthController@Logout');
Route::get('/v1/user/settings', 'UserController@GetSettings');
Route::get('/banners/data', 'BannerController@getBanners');
Route::get('/games/metadata', 'GamesController@isAvailable');
@ -41,14 +52,6 @@ Route::get('/fetch/posts/{id}', 'Controller@fetchPosts');
Route::get('/fetch/post/{id}', 'Controller@fetchPost');
Route::post('/fetch/user', 'Controller@fetchUser');
Route::post('/maintenance/bypass', 'MaintenanceController@bypass');
Route::post('/account/register', 'Auth\RegisterController@create');
Route::post('/account/login', 'Controller@login');
Route::post('/api/create/forum', 'HomeController@createPost');
Route::post('/api/create/reply/{id}', 'HomeController@createReply');