refactor: code style changes

Signed-off-by: miguel456 <me@nogueira.codes>
This commit is contained in:
Miguel Nogueira 2023-01-15 00:04:00 +00:00
parent 25155bff2e
commit 3727c84f3e
No known key found for this signature in database
GPG Key ID: 3C6A7E29AF26D370
146 changed files with 1013 additions and 1341 deletions

View File

@ -20,7 +20,7 @@ class Absence extends Model
'reason', 'reason',
'status', 'status',
'reviewer', 'reviewer',
'reviewed_date' 'reviewed_date',
]; ];
public function requester(): BelongsTo public function requester(): BelongsTo
@ -28,7 +28,6 @@ class Absence extends Model
return $this->belongsTo('App\User', 'requesterID', 'id'); return $this->belongsTo('App\User', 'requesterID', 'id');
} }
/** /**
* Determines whether this model can be setApproved(), setDeclined() or setCancelled() * Determines whether this model can be setApproved(), setDeclined() or setCancelled()
* *
@ -37,63 +36,61 @@ class Absence extends Model
*/ */
public function isActionable(bool $toCancel = false): bool public function isActionable(bool $toCancel = false): bool
{ {
if ($toCancel) if ($toCancel) {
{
return in_array($this->getRawOriginal('status'), ['PENDING', 'APPROVED']); return in_array($this->getRawOriginal('status'), ['PENDING', 'APPROVED']);
} }
return $this->getRawOriginal('status') == 'PENDING'; return $this->getRawOriginal('status') == 'PENDING';
} }
/** /**
* Sets the Absence's status as approved * Sets the Absence's status as approved
* *
* @return Absence * @return Absence
*
* @throws AbsenceNotActionableException * @throws AbsenceNotActionableException
*/ */
public function setApproved(): Absence public function setApproved(): Absence
{ {
if ($this->isActionable()) if ($this->isActionable()) {
{
return tap($this)->update([ return tap($this)->update([
'status' => 'APPROVED' 'status' => 'APPROVED',
]); ]);
} }
throw new AbsenceNotActionableException('This absence is not actionable!'); throw new AbsenceNotActionableException('This absence is not actionable!');
} }
/** /**
* Sets the absence's status as declined * Sets the absence's status as declined
* *
* @return Absence * @return Absence
*
* @throws AbsenceNotActionableException * @throws AbsenceNotActionableException
*/ */
public function setDeclined(): Absence public function setDeclined(): Absence
{ {
if ($this->isActionable()) { if ($this->isActionable()) {
return tap($this)->update([ return tap($this)->update([
'status' => 'DECLINED' 'status' => 'DECLINED',
]); ]);
} }
throw new AbsenceNotActionableException('This absence is not actionable!'); throw new AbsenceNotActionableException('This absence is not actionable!');
} }
/** /**
* Sets the absence's status as cancelled * Sets the absence's status as cancelled
* *
* @return Absence * @return Absence
*
* @throws AbsenceNotActionableException Thrown when the switch to this status would be invalid * @throws AbsenceNotActionableException Thrown when the switch to this status would be invalid
*/ */
public function setCancelled(): Absence public function setCancelled(): Absence
{ {
if ($this->isActionable(true)) { if ($this->isActionable(true)) {
return tap($this)->update([ return tap($this)->update([
'status' => 'CANCELLED' 'status' => 'CANCELLED',
]); ]);
} }
@ -108,18 +105,16 @@ class Absence extends Model
public function setEnded(): Absence public function setEnded(): Absence
{ {
return tap($this)->update([ return tap($this)->update([
'status' => 'ENDED' 'status' => 'ENDED',
]); ]);
} }
// Look out when retrieving this value; // Look out when retrieving this value;
//If you need the unaltered version of it, either adapt to its formatting or call getRawOriginal() //If you need the unaltered version of it, either adapt to its formatting or call getRawOriginal()
protected function status(): Attribute { protected function status(): Attribute
{
return Attribute::make( return Attribute::make(
get: fn ($value) => ucfirst(strtolower($value)) get: fn ($value) => ucfirst(strtolower($value))
); );
} }
} }

View File

@ -64,5 +64,4 @@ class Application extends Model
'applicationStatus' => $status, 'applicationStatus' => $status,
]); ]);
} }
} }

View File

@ -39,14 +39,11 @@ class Install extends Command
public function handle() public function handle()
{ {
$basePath = base_path(); $basePath = base_path();
if (Storage::disk('local')->missing('INSTALLED')) if (Storage::disk('local')->missing('INSTALLED')) {
{
$this->info('[!! Welcome to Rasberry Teams !!]'); $this->info('[!! Welcome to Rasberry Teams !!]');
$this->info('>> Installing...'); $this->info('>> Installing...');
$this->call('down', [ $this->call('down', [
'--message' => 'Down for maintenance. We\'ll be right back!' '--message' => 'Down for maintenance. We\'ll be right back!',
]); ]);
copy($basePath.'/.env.example', $basePath.'/.env'); copy($basePath.'/.env.example', $basePath.'/.env');
@ -63,22 +60,17 @@ class Install extends Command
exec('cd '.$basePath.' && npm install --silent', $npmBuildOut, $npmOut); exec('cd '.$basePath.' && npm install --silent', $npmBuildOut, $npmOut);
exec('cd '.$basePath.'&& npm run dev --silent', $npmBuildMessages, $npmBuildOut); exec('cd '.$basePath.'&& npm run dev --silent', $npmBuildMessages, $npmBuildOut);
if ($npmOut !== 0 && $npmBuildOut !== 0) {
if($npmOut !== 0 && $npmBuildOut !== 0)
{
$this->error('[!] One or more errors have ocurred whilst attempting to install dependencies.'); $this->error('[!] One or more errors have ocurred whilst attempting to install dependencies.');
$this->error('[!] It is recommended to run this command again, and report a bug if it keeps happening.'); $this->error('[!] It is recommended to run this command again, and report a bug if it keeps happening.');
return false; return false;
} }
$settings = []; $settings = [];
$this->info('>> Configuring application - We\'re going to ask a few questions here!'); $this->info('>> Configuring application - We\'re going to ask a few questions here!');
do do {
{
$this->info('== Database Settings (1/6) =='); $this->info('== Database Settings (1/6) ==');
$settings['DB_USERNAME'] = $this->ask('Database username'); $settings['DB_USERNAME'] = $this->ask('Database username');
@ -108,15 +100,12 @@ class Install extends Command
$settings['APP_URL'] = $this->ask('Application\'s URL (ex. https://where.you.installed.theapp.com): '); $settings['APP_URL'] = $this->ask('Application\'s URL (ex. https://where.you.installed.theapp.com): ');
$settings['APP_LOGO'] = $this->ask('App logo (Link to an image): '); $settings['APP_LOGO'] = $this->ask('App logo (Link to an image): ');
$settings['APP_SITEHOMEPAGE'] = $this->ask('Site homepage (appears in the main header): '); $settings['APP_SITEHOMEPAGE'] = $this->ask('Site homepage (appears in the main header): ');
} while (! $this->confirm('Are you sure you want to save these settings? You can always go back and try again.')); } while (! $this->confirm('Are you sure you want to save these settings? You can always go back and try again.'));
foreach($settings as $keyname => $value) foreach ($settings as $keyname => $value) {
{
$this->call('environment:modify', [ $this->call('environment:modify', [
'key' => $keyname, 'key' => $keyname,
'value' => $value 'value' => $value,
]); ]);
} }
@ -131,10 +120,7 @@ class Install extends Command
$this->call('up'); $this->call('up');
$this->info('>> All done! Visit '.$basePath.' to start using your brand new installation of Raspberry Teams!'); $this->info('>> All done! Visit '.$basePath.' to start using your brand new installation of Raspberry Teams!');
} else {
}
else
{
$this->error('[!] The application is already installed!'); $this->error('[!] The application is already installed!');
} }
} }

View File

@ -52,6 +52,7 @@ class SetEnv extends Command
/** /**
* Execute the console command. * Execute the console command.
*
* @return mixed * @return mixed
*/ */
public function handle() public function handle()

View File

@ -23,7 +23,6 @@ namespace App\CustomFacades;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class IP class IP
{ {
@ -31,14 +30,14 @@ class IP
// For views, this is in a service provider, and is shared with all of them // For views, this is in a service provider, and is shared with all of them
/** /**
* Determines whether you should collect/display IP addresses in the app. * Determines whether you should collect/display IP addresses in the app.
*
* @return bool Whether you should collect/display IPs, in the context in which this is called * @return bool Whether you should collect/display IPs, in the context in which this is called
*/ */
public function shouldCollect(): bool public function shouldCollect(): bool
{ {
// should collect or display IPs? // should collect or display IPs?
if (config('demo.is_enabled') || config('app.hide_ips')) if (config('demo.is_enabled') || config('app.hide_ips')) {
{
return false; // do not collect! return false; // do not collect!
} }
@ -47,6 +46,7 @@ class IP
/** /**
* Looks up information on a specified IP address. Caches results automatically. * Looks up information on a specified IP address. Caches results automatically.
*
* @param string $IP IP address to lookup * @param string $IP IP address to lookup
* @return object * @return object
*/ */
@ -58,19 +58,17 @@ class IP
]; ];
if ($this->shouldCollect()) { if ($this->shouldCollect()) {
return json_decode(Cache::remember($IP, 3600, function () use ($IP) { return json_decode(Cache::remember($IP, 3600, function () use ($IP) {
return Http::get(config('general.urls.ipapi.ipcheck'), [ return Http::get(config('general.urls.ipapi.ipcheck'), [
'apiKey' => config('general.keys.ipapi.apikey'), 'apiKey' => config('general.keys.ipapi.apikey'),
'ip' => $IP, 'ip' => $IP,
])->body(); ])->body();
})); }));
} }
return new class { return new class
public $message = "This feature is disabled."; {
public $message = 'This feature is disabled.';
}; };
} }
} }

View File

@ -2,7 +2,6 @@
namespace App\Exceptions; namespace App\Exceptions;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
class ApplicationNotFoundException extends ModelNotFoundException class ApplicationNotFoundException extends ModelNotFoundException

View File

@ -2,7 +2,6 @@
namespace App\Exceptions; namespace App\Exceptions;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
class VacancyNotFoundException extends ModelNotFoundException class VacancyNotFoundException extends ModelNotFoundException

View File

@ -1,17 +1,13 @@
<?php <?php
namespace App\Facades; namespace App\Facades;
use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\Facade;
class DigitalStorageHelper extends Facade class DigitalStorageHelper extends Facade
{ {
protected static function getFacadeAccessor() protected static function getFacadeAccessor()
{ {
return 'digitalStorageHelperFacadeRoot'; return 'digitalStorageHelperFacadeRoot';
} }
} }

View File

@ -1,17 +1,13 @@
<?php <?php
namespace App\Facades; namespace App\Facades;
use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\Facade;
class JSON extends Facade class JSON extends Facade
{ {
protected static function getFacadeAccessor() protected static function getFacadeAccessor()
{ {
return 'json'; return 'json';
} }
} }

View File

@ -28,6 +28,7 @@ class ContextAwareValidator
{ {
/** /**
* The excludedNames array will make the validator ignore any of these names when including names into the rules. * The excludedNames array will make the validator ignore any of these names when including names into the rules.
*
* @var array * @var array
*/ */
private $excludedNames = [ private $excludedNames = [

View File

@ -1,5 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace App\Helpers; namespace App\Helpers;
@ -10,18 +11,16 @@ namespace App\Helpers;
* It should be used whenever you need to display a file's size in a human readable way. * It should be used whenever you need to display a file's size in a human readable way.
* *
* It's framework agnostic, meaning you can take it out of context and it'll still work; However, you'll have to instantiate it first. * It's framework agnostic, meaning you can take it out of context and it'll still work; However, you'll have to instantiate it first.
* @package App\Helpers
*/ */
class DigitalStorageHelper class DigitalStorageHelper
{ {
/** /**
* The digital storage value to be manipulated. * The digital storage value to be manipulated.
* @var $value *
* @var
*/ */
protected $value; protected $value;
/** /**
* Sets the digital storage value for manipulation. * Sets the digital storage value for manipulation.
* *
@ -31,10 +30,10 @@ class DigitalStorageHelper
public function setValue(int $value): DigitalStorageHelper public function setValue(int $value): DigitalStorageHelper
{ {
$this->value = $value; $this->value = $value;
return $this; return $this;
} }
/** /**
* Converts the digital storage value to kilobytes. * Converts the digital storage value to kilobytes.
* *
@ -45,7 +44,6 @@ class DigitalStorageHelper
return $this->value / 1000; return $this->value / 1000;
} }
/** /**
* Converts the digital storage value to megabytes. * Converts the digital storage value to megabytes.
* *
@ -56,7 +54,6 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 6)); // 1 times 10 to the power of 6 return $this->value / (1 * pow(10, 6)); // 1 times 10 to the power of 6
} }
/** /**
* Convert the digital storage value to gigabytes. Might be an approximation * Convert the digital storage value to gigabytes. Might be an approximation
* *
@ -67,7 +64,6 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 9)); return $this->value / (1 * pow(10, 9));
} }
/** /**
* Convert the digital storage value to terabytes. * Convert the digital storage value to terabytes.
* *
@ -78,7 +74,6 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 12)); return $this->value / (1 * pow(10, 12));
} }
/** /**
* Format the digital storage value to one of the units: b, kb, mb, gb and tb. * Format the digital storage value to one of the units: b, kb, mb, gb and tb.
* The method has been adapted to use both MiB and MB values. * The method has been adapted to use both MiB and MB values.
@ -86,14 +81,16 @@ class DigitalStorageHelper
* @param int $precision The rounding precision * @param int $precision The rounding precision
* @param bool $si Use international system units. Defaults to false * @param bool $si Use international system units. Defaults to false
* @return string The human readable digital storage value, in either, for instance, MB or MiB * @return string The human readable digital storage value, in either, for instance, MB or MiB
*
* @see https://stackoverflow.com/a/2510459/11540218 StackOverflow question regarding unit conversion * @see https://stackoverflow.com/a/2510459/11540218 StackOverflow question regarding unit conversion
* @since 7.3.23 * @since 7.3.23
*/ */
public function formatBytes($precision = 2, $si = false): string public function formatBytes($precision = 2, $si = false): string
{ {
$units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']; $units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
if ($si) if ($si) {
$units = ['B', 'KB', 'MB', 'GB', 'TB']; $units = ['B', 'KB', 'MB', 'GB', 'TB'];
}
$bytes = max($this->value, 0); $bytes = max($this->value, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(($si) ? 1000 : 1024)); $pow = floor(($bytes ? log($bytes) : 0) / log(($si) ? 1000 : 1024));
@ -103,5 +100,4 @@ class DigitalStorageHelper
return round($bytes, $precision).' '.$units[$pow]; return round($bytes, $precision).' '.$units[$pow];
} }
} }

View File

@ -19,30 +19,25 @@
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>. * along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
*/ */
namespace App\Helpers; namespace App\Helpers;
use App\Exceptions\AccountNotLinkedException; use App\Exceptions\AccountNotLinkedException;
use App\User; use App\User;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Http\Client\RequestException; use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
// Small wrapper for the necessary sections of the Discord API; A library is overkill here // Small wrapper for the necessary sections of the Discord API; A library is overkill here
class Discord class Discord
{ {
/** /**
* The current working guild. Default is Home guild from app config * The current working guild. Default is Home guild from app config
*
* @var string * @var string
*/ */
protected string $workingGuild; protected string $workingGuild;
/** /**
* Current user. * Current user.
* *
@ -50,15 +45,13 @@ class Discord
*/ */
protected User $user; protected User $user;
public function __construct()
{
public function __construct() {
if (isset($this->workingGuild)) { if (isset($this->workingGuild)) {
$this->setWorkingGuild(config('services.discord.home_guild')); $this->setWorkingGuild(config('services.discord.home_guild'));
} }
} }
/** /**
* Sets the working guild * Sets the working guild
* *
@ -68,6 +61,7 @@ class Discord
public function setWorkingGuild(string $workingGuild): Discord public function setWorkingGuild(string $workingGuild): Discord
{ {
$this->workingGuild = $workingGuild; $this->workingGuild = $workingGuild;
return $this; return $this;
} }
@ -76,12 +70,14 @@ class Discord
* *
* @param User $user * @param User $user
* @return Discord * @return Discord
*
* @throws AccountNotLinkedException * @throws AccountNotLinkedException
*/ */
public function setUser(User $user): Discord public function setUser(User $user): Discord
{ {
if ($user->hasDiscordConnection()) { if ($user->hasDiscordConnection()) {
$this->user = $user; $this->user = $user;
return $this; return $this;
} }
@ -93,14 +89,14 @@ class Discord
* preventing unnecessary API requests. * preventing unnecessary API requests.
* *
* @return object Current user's authentication info (has no sensitive fields) * @return object Current user's authentication info (has no sensitive fields)
*
* @throws RequestException * @throws RequestException
*/ */
public function getAuthorizationInfo(): object { public function getAuthorizationInfo(): object
{
if (Cache::has($this->user->discord_user_id)) { if (Cache::has($this->user->discord_user_id)) {
return unserialize(Cache::get($this->user->discord_user_id)); return unserialize(Cache::get($this->user->discord_user_id));
} } else {
else {
$authInfo = (object) Http::withToken($this->user->discord_token) $authInfo = (object) Http::withToken($this->user->discord_token)
->get(config('services.discord.base_url').'/oauth2/@me') ->get(config('services.discord.base_url').'/oauth2/@me')
->throw() ->throw()
@ -112,42 +108,41 @@ class Discord
} }
} }
/** /**
* Checks if the user's token is close to expiring. * Checks if the user's token is close to expiring.
* Tokens should be refreshed the day before they expire. * Tokens should be refreshed the day before they expire.
* *
* @return bool Whether the user's token needs to be refreshed * @return bool Whether the user's token needs to be refreshed
*
* @throws RequestException * @throws RequestException
*/ */
public function needsRefresh(): bool { public function needsRefresh(): bool
{
return Carbon::parse($this->getAuthorizationInfo()->expires)->diffInDays() == 1; return Carbon::parse($this->getAuthorizationInfo()->expires)->diffInDays() == 1;
} }
public function exchangeRefreshToken()
{
public function exchangeRefreshToken() {
} }
/** /**
* Adds current working user to current working guild. Bot must be member of target guild, and account must be linked * Adds current working user to current working guild. Bot must be member of target guild, and account must be linked
* *
* @return object|bool A GuildMember object; false if member is already in guild * @return object|bool A GuildMember object; false if member is already in guild
*
* @throws RequestException Any client and server errors * @throws RequestException Any client and server errors
*
* @see https://discord.com/developers/docs/resources/guild#guild-member-object * @see https://discord.com/developers/docs/resources/guild#guild-member-object
*/ */
public function addGuildMember(): object|bool public function addGuildMember(): object|bool
{ {
$params = [ $params = [
'access_token' => $this->user->discord_token 'access_token' => $this->user->discord_token,
]; ];
$member = Http::withBody(json_encode($params), 'application/json') $member = Http::withBody(json_encode($params), 'application/json')
->withHeaders([ ->withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token') 'Authorization' => 'Bot '.config('services.discord.token'),
])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/members/{$this->user->discord_user_id}") ])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/members/{$this->user->discord_user_id}")
->throw(); ->throw();
@ -158,20 +153,21 @@ class Discord
} }
} }
/** /**
* Bans a specified user from the guild. * Bans a specified user from the guild.
* May be called from the suspension service optionally by the banning user * May be called from the suspension service optionally by the banning user
* *
* @param string $reason The reason to supply Discord with * @param string $reason The reason to supply Discord with
* @return void Nothing on success * @return void Nothing on success
*
* @throws RequestException * @throws RequestException
* @throws AccountNotLinkedException * @throws AccountNotLinkedException
*/ */
public function addGuildBan(string $reason): void { public function addGuildBan(string $reason): void
{
Http::withHeaders([ Http::withHeaders([
'Authorization' => 'Bot '.config('services.discord.token'), 'Authorization' => 'Bot '.config('services.discord.token'),
'X-Audit-Log-Reason' => $reason 'X-Audit-Log-Reason' => $reason,
])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}") ])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
->throw(); ->throw();
@ -181,19 +177,21 @@ class Discord
/** /**
* @param string $reason The removal reason to provide Discord with (e.g. ban expired) * @param string $reason The removal reason to provide Discord with (e.g. ban expired)
* @return null|bool Null on unnan, false if user is not banned * @return null|bool Null on unnan, false if user is not banned
*
* @throws RequestException * @throws RequestException
*/ */
public function removeGuildBan(string $reason): null|bool { public function removeGuildBan(string $reason): null|bool
{
if ($this->getGuildBan($this->user)) { if ($this->getGuildBan($this->user)) {
Http::withHeaders([ Http::withHeaders([
'Authorization' => 'Bot '.config('services.discord.token'), 'Authorization' => 'Bot '.config('services.discord.token'),
'X-Audit-Log-Reason' => $reason 'X-Audit-Log-Reason' => $reason,
])->delete(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}") ])->delete(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
->throw(); ->throw();
return null; return null;
} }
return false; return false;
} }
@ -201,13 +199,15 @@ class Discord
* Gets (possible) ban for current user. * Gets (possible) ban for current user.
* *
* @return object|bool Ban object if user is banned. Null * @return object|bool Ban object if user is banned. Null
*
* @throws RequestException * @throws RequestException
*
* @see https://discord.com/developers/docs/resources/guild#ban-object * @see https://discord.com/developers/docs/resources/guild#ban-object
*/ */
public function getGuildBan(): object|bool public function getGuildBan(): object|bool
{ {
$ban = Http::withHeaders([ $ban = Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token') 'Authorization' => 'Bot '.config('services.discord.token'),
])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}"); ])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}");
if ($ban->status() == 404) { if ($ban->status() == 404) {
@ -217,20 +217,21 @@ class Discord
return ($ban->successful()) ? (object) $ban->json() : $ban->throwIf($ban->status() !== 404); return ($ban->successful()) ? (object) $ban->json() : $ban->throwIf($ban->status() !== 404);
} }
/** /**
* Retrieves list of Role objects * Retrieves list of Role objects
*
* @see https://discord.com/developers/docs/topics/permissions#role-object * @see https://discord.com/developers/docs/topics/permissions#role-object
*
* @return array List of role objects * @return array List of role objects
* *
* @throws RequestException * @throws RequestException
*/ */
public function getGuildRoles(): array { public function getGuildRoles(): array
{
return Http::withHeaders([ return Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token') 'Authorization' => 'Bot '.config('services.discord.token'),
])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/roles") ])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/roles")
->throw() ->throw()
->json(); ->json();
} }
} }

View File

@ -1,16 +1,23 @@
<?php <?php
namespace App\Helpers; namespace App\Helpers;
/** /**
* Class JSON - Used for JSON responses. * Class JSON - Used for JSON responses.
* @package App\Helpers
*/ */
class JSON class JSON
{ {
protected $type;
protected $type, $status, $message, $code, $data, $additional; protected $status;
protected $message;
protected $code;
protected $data;
protected $additional;
/** /**
* @param mixed $type * @param mixed $type
@ -18,6 +25,7 @@ class JSON
public function setResponseType($type): JSON public function setResponseType($type): JSON
{ {
$this->type = $type; $this->type = $type;
return $this; return $this;
} }
@ -27,6 +35,7 @@ class JSON
public function setAdditional($additional) public function setAdditional($additional)
{ {
$this->additional = $additional; $this->additional = $additional;
return $this; return $this;
} }
@ -61,6 +70,7 @@ class JSON
public function setStatus($status) public function setStatus($status)
{ {
$this->status = $status; $this->status = $status;
return $this; return $this;
} }
@ -79,6 +89,7 @@ class JSON
public function setMessage($message) public function setMessage($message)
{ {
$this->message = $message; $this->message = $message;
return $this; return $this;
} }
@ -97,6 +108,7 @@ class JSON
public function setCode($code) public function setCode($code)
{ {
$this->code = $code; $this->code = $code;
return $this; return $this;
} }
@ -115,6 +127,7 @@ class JSON
public function setData($data) public function setData($data)
{ {
$this->data = $data; $this->data = $data;
return $this; return $this;
} }
@ -126,17 +139,15 @@ class JSON
'meta' => [ 'meta' => [
'status' => $this->getStatus(), 'status' => $this->getStatus(),
'message' => $this->getMessage(), 'message' => $this->getMessage(),
] ],
]; ];
if (!empty($this->additional)) if (! empty($this->additional)) {
{ foreach ($this->additional as $additionalKeyName => $key) {
foreach($this->additional as $additionalKeyName => $key)
{
$response[$additionalKeyName] = $key; $response[$additionalKeyName] = $key;
} }
} }
return response($response, $this->getCode(), $headers); return response($response, $this->getCode(), $headers);
} }
} }

View File

@ -33,30 +33,28 @@ use Illuminate\Support\Facades\Log;
*/ */
class Options class Options
{ {
/** /**
* Returns an assortment of settings found in the mentioned category * Returns an assortment of settings found in the mentioned category
* *
* @param string $category The category * @param string $category The category
* @return Collection The settings in this category * @return Collection The settings in this category
*
* @throws EmptyOptionsException * @throws EmptyOptionsException
*/ */
public function getCategory(string $category): Collection public function getCategory(string $category): Collection
{ {
$options = Option::where('option_category', $category)->get(); $options = Option::where('option_category', $category)->get();
if ($options->isEmpty()) if ($options->isEmpty()) {
{
throw new EmptyOptionsException('There are no options in category '.$category); throw new EmptyOptionsException('There are no options in category '.$category);
} }
return $options; return $options;
} }
public function getOption(string $option): string public function getOption(string $option): string
{ {
$value = Cache::get($option); $value = Cache::get($option);
if (is_null($value)) { if (is_null($value)) {
Log::debug('Option '.$option.'not found in cache, refreshing from database'); Log::debug('Option '.$option.'not found in cache, refreshing from database');
$value = Option::where('option_name', $option)->first(); $value = Option::where('option_name', $option)->first();
@ -79,7 +77,7 @@ class Options
'option_name' => $option, 'option_name' => $option,
'option_value' => $value, 'option_value' => $value,
'friendly_name' => $description, 'friendly_name' => $description,
'option_category' => $category 'option_category' => $category,
]); ]);
Cache::put($option, $value, now()->addDay()); Cache::put($option, $value, now()->addDay());

View File

@ -5,24 +5,20 @@ namespace App\Http\Controllers;
use App\Absence; use App\Absence;
use App\Exceptions\AbsenceNotActionableException; use App\Exceptions\AbsenceNotActionableException;
use App\Http\Requests\StoreAbsenceRequest; use App\Http\Requests\StoreAbsenceRequest;
use App\Http\Requests\UpdateAbsenceRequest;
use App\Services\AbsenceService; use App\Services\AbsenceService;
use App\User; use App\User;
use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
class AbsenceController extends Controller class AbsenceController extends Controller
{ {
private AbsenceService $absenceService; private AbsenceService $absenceService;
public function __construct (AbsenceService $absenceService) { public function __construct(AbsenceService $absenceService)
{
$this->absenceService = $absenceService; $this->absenceService = $absenceService;
} }
/** /**
@ -38,11 +34,11 @@ class AbsenceController extends Controller
->with('absences', Absence::paginate(6)); ->with('absences', Absence::paginate(6));
} }
/** /**
* Display a listing of absences belonging to the current user. * Display a listing of absences belonging to the current user.
* *
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws AuthorizationException * @throws AuthorizationException
*/ */
public function showUserAbsences() public function showUserAbsences()
@ -54,11 +50,8 @@ class AbsenceController extends Controller
return view('dashboard.absences.own') return view('dashboard.absences.own')
->with('absences', $absences); ->with('absences', $absences);
} }
/** /**
* Show the form for creating a new absence request. * Show the form for creating a new absence request.
* *
@ -99,6 +92,7 @@ class AbsenceController extends Controller
* Display the specified absence request. * Display the specified absence request.
* *
* @param \App\Absence $absence * @param \App\Absence $absence
*
* @throws AuthorizationException * @throws AuthorizationException
*/ */
public function show(Absence $absence) public function show(Absence $absence)
@ -108,7 +102,7 @@ class AbsenceController extends Controller
return view('dashboard.absences.view') return view('dashboard.absences.view')
->with([ ->with([
'absence' => $absence, 'absence' => $absence,
'totalDays' => Carbon::parse($absence->start)->diffInDays($absence->predicted_end) 'totalDays' => Carbon::parse($absence->start)->diffInDays($absence->predicted_end),
]); ]);
} }
@ -117,18 +111,16 @@ class AbsenceController extends Controller
* *
* @param Absence $absence * @param Absence $absence
* @return RedirectResponse * @return RedirectResponse
*
* @throws AuthorizationException * @throws AuthorizationException
*/ */
public function approveAbsence(Absence $absence): RedirectResponse public function approveAbsence(Absence $absence): RedirectResponse
{ {
$this->authorize('approve', $absence); $this->authorize('approve', $absence);
try try {
{
$this->absenceService->approveAbsence($absence); $this->absenceService->approveAbsence($absence);
} } catch (AbsenceNotActionableException $notActionableException) {
catch (AbsenceNotActionableException $notActionableException)
{
return redirect() return redirect()
->back() ->back()
->with('error', $notActionableException->getMessage()); ->with('error', $notActionableException->getMessage());
@ -139,23 +131,21 @@ class AbsenceController extends Controller
->with('success', __('Absence request successfully approved. It will automatically transition to "Ended" on its predicted end date.')); ->with('success', __('Absence request successfully approved. It will automatically transition to "Ended" on its predicted end date.'));
} }
/** /**
* Decline the specified absence. * Decline the specified absence.
* *
* @param Absence $absence * @param Absence $absence
* @return RedirectResponse * @return RedirectResponse
*
* @throws AuthorizationException * @throws AuthorizationException
*/ */
public function declineAbsence(Absence $absence): RedirectResponse public function declineAbsence(Absence $absence): RedirectResponse
{ {
$this->authorize('decline', $absence); $this->authorize('decline', $absence);
try try {
{
$this->absenceService->declineAbsence($absence); $this->absenceService->declineAbsence($absence);
} catch (AbsenceNotActionableException $notActionableException) } catch (AbsenceNotActionableException $notActionableException) {
{
return redirect() return redirect()
->back() ->back()
->with('error', $notActionableException->getMessage()); ->with('error', $notActionableException->getMessage());
@ -166,24 +156,21 @@ class AbsenceController extends Controller
->with('success', __('Absence request successfully declined.')); ->with('success', __('Absence request successfully declined.'));
} }
/** /**
* Cancel the specified absence. * Cancel the specified absence.
* *
* @param Absence $absence * @param Absence $absence
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws AuthorizationException * @throws AuthorizationException
*/ */
public function cancelAbsence(Absence $absence): \Illuminate\Http\RedirectResponse public function cancelAbsence(Absence $absence): RedirectResponse
{ {
$this->authorize('cancel', $absence); $this->authorize('cancel', $absence);
try try {
{
$this->absenceService->cancelAbsence($absence); $this->absenceService->cancelAbsence($absence);
} } catch (AbsenceNotActionableException $notActionableException) {
catch (AbsenceNotActionableException $notActionableException)
{
return redirect() return redirect()
->back() ->back()
->with('error', $notActionableException->getMessage()); ->with('error', $notActionableException->getMessage());

View File

@ -29,23 +29,19 @@ use App\Exceptions\IncompleteApplicationException;
use App\Exceptions\InvalidAgeException; use App\Exceptions\InvalidAgeException;
use App\Exceptions\UnavailableApplicationException; use App\Exceptions\UnavailableApplicationException;
use App\Exceptions\VacancyNotFoundException; use App\Exceptions\VacancyNotFoundException;
use App\Facades\IP;
use App\Services\ApplicationService; use App\Services\ApplicationService;
use App\Vacancy;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
class ApplicationController extends Controller class ApplicationController extends Controller
{ {
private $applicationService; private $applicationService;
public function __construct(ApplicationService $applicationService) { public function __construct(ApplicationService $applicationService)
{
$this->applicationService = $applicationService; $this->applicationService = $applicationService;
} }
public function showUserApps() public function showUserApps()
{ {
return view('dashboard.user.applications') return view('dashboard.user.applications')
@ -67,7 +63,6 @@ class ApplicationController extends Controller
'canVote' => $this->applicationService->canVote($application->votes), 'canVote' => $this->applicationService->canVote($application->votes),
] ]
); );
} }
public function showAllApps(Request $request) public function showAllApps(Request $request)
@ -76,42 +71,36 @@ class ApplicationController extends Controller
return view('dashboard.appmanagement.all') return view('dashboard.appmanagement.all')
->with('applications', Application::orderBy('applicationStatus', 'ASC')->paginate(6)); ->with('applications', Application::orderBy('applicationStatus', 'ASC')->paginate(6));
} }
public function discordApply(Request $request, $vacancySlug)
public function discordApply(Request $request, $vacancySlug) { {
$request->session()->put('discordApplicationRedirectedSlug', $vacancySlug); $request->session()->put('discordApplicationRedirectedSlug', $vacancySlug);
return redirect(route('discordRedirect'));
return redirect(route('discordRedirect'));
} }
public function renderApplicationForm($vacancySlug) public function renderApplicationForm($vacancySlug)
{ {
try { try {
return $this->applicationService->renderForm($vacancySlug); return $this->applicationService->renderForm($vacancySlug);
} } catch (ApplicationNotFoundException $ex) {
catch (ApplicationNotFoundException $ex) {
return redirect() return redirect()
->back() ->back()
->with('error', $ex->getMessage()); ->with('error', $ex->getMessage());
} catch (DiscordAccountRequiredException $e) { } catch (DiscordAccountRequiredException $e) {
\Log::info('Redirecting user: '.$e->getMessage(), [ \Log::info('Redirecting user: '.$e->getMessage(), [
'user' => Auth::user()->email 'user' => Auth::user()->email,
]); ]);
request()->session()->put('discordApplicationRedirectedSlug', $vacancySlug); request()->session()->put('discordApplicationRedirectedSlug', $vacancySlug);
return redirect(route('discordRedirect')); return redirect(route('discordRedirect'));
} catch (IncompatibleAgeException $e) { } catch (IncompatibleAgeException $e) {
return redirect() return redirect()
->to(route('dashboard')) ->to(route('dashboard'))
->with('error', $e->getMessage()); ->with('error', $e->getMessage());
} catch (InvalidAgeException $e) { } catch (InvalidAgeException $e) {
return view('dashboard.application-rendering.add-age'); return view('dashboard.application-rendering.add-age');
} }
} }
@ -121,9 +110,7 @@ class ApplicationController extends Controller
if (Auth::user()->isEligible()) { if (Auth::user()->isEligible()) {
try { try {
$this->applicationService->fillForm(Auth::user(), $request->all(), $vacancySlug); $this->applicationService->fillForm(Auth::user(), $request->all(), $vacancySlug);
} catch (VacancyNotFoundException|IncompleteApplicationException|UnavailableApplicationException $e) { } catch (VacancyNotFoundException|IncompleteApplicationException|UnavailableApplicationException $e) {
return redirect() return redirect()
->back() ->back()
->with('error', $e->getMessage()); ->with('error', $e->getMessage());
@ -146,8 +133,7 @@ class ApplicationController extends Controller
try { try {
$status = $this->applicationService->updateStatus($application, $newStatus); $status = $this->applicationService->updateStatus($application, $newStatus);
} catch (\LogicException $ex) } catch (\LogicException $ex) {
{
return redirect() return redirect()
->back() ->back()
->with('error', $ex->getMessage()); ->with('error', $ex->getMessage());
@ -170,6 +156,5 @@ class ApplicationController extends Controller
return redirect() return redirect()
->back() ->back()
->with('success', __('Application deleted. Comments, appointments and responses have also been deleted.')); ->with('success', __('Application deleted. Comments, appointments and responses have also been deleted.'));
} }
} }

View File

@ -36,13 +36,12 @@ use Illuminate\Http\Request;
class AppointmentController extends Controller class AppointmentController extends Controller
{ {
private $appointmentService; private $appointmentService;
private $meetingNoteService; private $meetingNoteService;
public function __construct(AppointmentService $appointmentService, MeetingNoteService $meetingNoteService)
public function __construct(AppointmentService $appointmentService, MeetingNoteService $meetingNoteService) { {
$this->appointmentService = $appointmentService; $this->appointmentService = $appointmentService;
$this->meetingNoteService = $meetingNoteService; $this->meetingNoteService = $meetingNoteService;
} }
@ -71,10 +70,8 @@ class AppointmentController extends Controller
return redirect() return redirect()
->back() ->back()
->with('success', __("Interview finished! Staff members can now vote on it.")); ->with('success', __('Interview finished! Staff members can now vote on it.'));
} catch (InvalidAppointmentStatusException $ex) {
}
catch (InvalidAppointmentStatusException $ex) {
return redirect() return redirect()
->back() ->back()
->with('error', $ex->getMessage()); ->with('error', $ex->getMessage());
@ -86,35 +83,26 @@ class AppointmentController extends Controller
$this->authorize('update', $application->appointment); $this->authorize('update', $application->appointment);
try { try {
$this->appointmentService->deleteAppointment($application, $request->reason); $this->appointmentService->deleteAppointment($application, $request->reason);
return redirect() return redirect()
->back() ->back()
->with('success', __('Appointment cancelled.')); ->with('success', __('Appointment cancelled.'));
} catch (\Exception $ex) {
}
catch (\Exception $ex) {
return redirect() return redirect()
->back() ->back()
->with('error', $ex->getMessage()); ->with('error', $ex->getMessage());
} }
} }
public function saveNotes(SaveNotesRequest $request, Application $application) public function saveNotes(SaveNotesRequest $request, Application $application)
{ {
try { try {
$this->meetingNoteService->addToApplication($application, $request->noteText); $this->meetingNoteService->addToApplication($application, $request->noteText);
return redirect() return redirect()
->back() ->back()
->with('success', __('Saved notes.')); ->with('success', __('Saved notes.'));
} catch (InvalidAppointmentException $ex) { } catch (InvalidAppointmentException $ex) {
return redirect() return redirect()
->back() ->back()

View File

@ -21,46 +21,39 @@
namespace App\Http\Controllers\Auth; namespace App\Http\Controllers\Auth;
use App\Facades\Discord;
use App\Facades\Options;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\User; use App\User;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite; use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Two\InvalidStateException; use Laravel\Socialite\Two\InvalidStateException;
class DiscordController extends Controller class DiscordController extends Controller
{ {
public function discordRedirect()
{
public function discordRedirect() {
return Socialite::driver('discord') return Socialite::driver('discord')
->scopes(['email', 'guilds.join', 'guilds.members.read', 'guilds']) ->scopes(['email', 'guilds.join', 'guilds.members.read', 'guilds'])
->redirect(); ->redirect();
} }
public function discordCallback() { public function discordCallback()
{
try { try {
$discordUser = Socialite::driver('discord')->user(); $discordUser = Socialite::driver('discord')->user();
} catch (InvalidStateException $stateException) { } catch (InvalidStateException $stateException) {
Log::warning('Invalid state for social authentication: ', [ Log::warning('Invalid state for social authentication: ', [
'message' => $stateException->getMessage(), 'message' => $stateException->getMessage(),
'ua' => request()->userAgent(), 'ua' => request()->userAgent(),
'ip' => request()->ip() 'ip' => request()->ip(),
]); ]);
return redirect(route('discordRedirect')); return redirect(route('discordRedirect'));
} }
$appUser = User::where('email', $discordUser->getEmail())->first(); $appUser = User::where('email', $discordUser->getEmail())->first();
if ($appUser) { if ($appUser) {
$appUser->discord_token = $discordUser->token; $appUser->discord_token = $discordUser->token;
$appUser->discord_refresh_token = $discordUser->refreshToken; $appUser->discord_refresh_token = $discordUser->refreshToken;
$appUser->discord_user_id = $discordUser->getId(); $appUser->discord_user_id = $discordUser->getId();
@ -68,9 +61,7 @@ class DiscordController extends Controller
$appUser->save(); $appUser->save();
Auth::login($appUser, true); Auth::login($appUser, true);
} else { } else {
$oAuthUser = User::create([ $oAuthUser = User::create([
'uuid' => null, 'uuid' => null,
'name' => $discordUser->getName(), 'name' => $discordUser->getName(),
@ -82,7 +73,7 @@ class DiscordController extends Controller
'discord_user_id' => $discordUser->getId(), 'discord_user_id' => $discordUser->getId(),
'discord_pfp' => $discordUser->getAvatar(), 'discord_pfp' => $discordUser->getAvatar(),
'discord_token' => $discordUser->token, 'discord_token' => $discordUser->token,
'discord_refresh_token' => $discordUser->refreshToken 'discord_refresh_token' => $discordUser->refreshToken,
]); ]);
$oAuthUser->assignRole('user'); $oAuthUser->assignRole('user');
@ -97,5 +88,4 @@ class DiscordController extends Controller
return redirect() return redirect()
->route('dashboard'); ->route('dashboard');
} }
} }

View File

@ -21,17 +21,13 @@
namespace App\Http\Controllers\Auth; namespace App\Http\Controllers\Auth;
use App\Facades\IP;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Services\AccountSuspensionService; use App\Services\AccountSuspensionService;
use App\User; use App\User;
use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use App\Facades\IP;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;
class LoginController extends Controller class LoginController extends Controller
{ {
@ -79,12 +75,11 @@ class LoginController extends Controller
$isLocked = $service->isLocked($user); $isLocked = $service->isLocked($user);
if ($isBanned || $isLocked) { if ($isBanned || $isLocked) {
Log::alert('Restricted user attempting to login.', [ Log::alert('Restricted user attempting to login.', [
'ip' => $request->ip(), 'ip' => $request->ip(),
'email' => $user->email, 'email' => $user->email,
'isBanned' => $isBanned, 'isBanned' => $isBanned,
'isLocked' => $isLocked 'isLocked' => $isLocked,
]); ]);
return false; return false;
@ -99,17 +94,14 @@ class LoginController extends Controller
public function authenticated(Request $request, User $user) public function authenticated(Request $request, User $user)
{ {
if (IP::shouldCollect()) { if (IP::shouldCollect()) {
if ($user->originalIP !== $request->ip()) if ($user->originalIP !== $request->ip()) {
{
Log::alert('User IP address changed from last login. Updating.', [ Log::alert('User IP address changed from last login. Updating.', [
'prev' => $user->originalIP, 'prev' => $user->originalIP,
'new' => $request->ip() 'new' => $request->ip(),
]); ]);
$user->currentIp = $request->ip(); $user->currentIp = $request->ip();
$user->save(); $user->save();
} }
} }
} }
} }

View File

@ -21,15 +21,12 @@
namespace App\Http\Controllers\Auth; namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Profile;
use App\Services\AccountSuspensionService;
use App\User;
use App\Facades\Options;
use App\Facades\IP; use App\Facades\IP;
use App\Facades\Options;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller class RegisterController extends Controller
@ -74,8 +71,7 @@ class RegisterController extends Controller
{ {
$password = ['required', 'string', 'confirmed']; $password = ['required', 'string', 'confirmed'];
switch (Options::getOption('pw_security_policy')) switch (Options::getOption('pw_security_policy')) { // this could be better structured, switch doesn't feel right
{ // this could be better structured, switch doesn't feel right
case 'off': case 'off':
$password = ['required', 'string', 'confirmed']; $password = ['required', 'string', 'confirmed'];
break; break;
@ -102,7 +98,7 @@ class RegisterController extends Controller
'dob.before' => __('You must be 13 years of age or older in order to sign up for an account.'), 'dob.before' => __('You must be 13 years of age or older in order to sign up for an account.'),
'dob.required' => __('Please enter your date of birth.'), 'dob.required' => __('Please enter your date of birth.'),
'uuid.required' => __('Please enter a valid (and Premium) Minecraft username! We do not support cracked users.'), 'uuid.required' => __('Please enter a valid (and Premium) Minecraft username! We do not support cracked users.'),
'acceptTerms.required' => __('Please accept the Community Guidelines, Terms of Service and Privacy Policy to continue.') 'acceptTerms.required' => __('Please accept the Community Guidelines, Terms of Service and Privacy Policy to continue.'),
]); ]);
} }
@ -117,13 +113,13 @@ class RegisterController extends Controller
$ip = IP::shouldCollect() ? request()->ip() : '0.0.0.0'; $ip = IP::shouldCollect() ? request()->ip() : '0.0.0.0';
$user = User::create([ $user = User::create([
'uuid' => $data['uuid'] ?? "disabled", 'uuid' => $data['uuid'] ?? 'disabled',
'name' => $data['name'], 'name' => $data['name'],
'email' => $data['email'], 'email' => $data['email'],
'password' => Hash::make($data['password']), 'password' => Hash::make($data['password']),
'registrationIp' => $ip, 'registrationIp' => $ip,
'currentIp' => $ip, 'currentIp' => $ip,
'dob' => $data['dob'] 'dob' => $data['dob'],
]); ]);
$user->assignRole('user'); $user->assignRole('user');

View File

@ -26,13 +26,13 @@ use App\Comment;
use App\Http\Requests\NewCommentRequest; use App\Http\Requests\NewCommentRequest;
use App\Services\CommentService; use App\Services\CommentService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class CommentController extends Controller class CommentController extends Controller
{ {
private $commentService; private $commentService;
public function __construct(CommentService $commentService) { public function __construct(CommentService $commentService)
{
$this->commentService = $commentService; $this->commentService = $commentService;
} }

View File

@ -39,12 +39,12 @@ class DashboardController extends Controller
$totalDeniedSingle = Application::where([ $totalDeniedSingle = Application::where([
['applicationStatus', '=', 'DENIED'], ['applicationStatus', '=', 'DENIED'],
['applicantUserID', '=', Auth::user()->id] ['applicantUserID', '=', Auth::user()->id],
])->get(); ])->get();
$totalNewSingle = Application::where([ $totalNewSingle = Application::where([
['applicationStatus', '=', 'STAGE_SUBMITTED'], ['applicationStatus', '=', 'STAGE_SUBMITTED'],
['applicantUserID', '=', Auth::user()->id] ['applicantUserID', '=', Auth::user()->id],
])->get(); ])->get();
return view('dashboard.dashboard') return view('dashboard.dashboard')
@ -55,7 +55,7 @@ class DashboardController extends Controller
'totalPeerReview' => $totalPeerReview, 'totalPeerReview' => $totalPeerReview,
'totalNewApplications' => $totalNewApplications, 'totalNewApplications' => $totalNewApplications,
'totalNewSingle' => $totalNewSingle->count(), 'totalNewSingle' => $totalNewSingle->count(),
'totalDeniedSingle' => $totalDeniedSingle->count() 'totalDeniedSingle' => $totalDeniedSingle->count(),
]); ]);
} }
} }

View File

@ -33,17 +33,20 @@ use Illuminate\Support\Facades\Log;
class DevToolsController extends Controller class DevToolsController extends Controller
{ {
public function __construct() { public function __construct()
{
// //
} }
private function singleAuthorise() { private function singleAuthorise()
{
if (! Auth::user()->can('admin.developertools.use')) { if (! Auth::user()->can('admin.developertools.use')) {
abort(403, __('You\'re not authorized to access this page.')); abort(403, __('You\'re not authorized to access this page.'));
} }
} }
public function index() { public function index()
{
$this->singleAuthorise(); $this->singleAuthorise();
return view('dashboard.administration.devtools') return view('dashboard.administration.devtools')
@ -54,7 +57,8 @@ class DevToolsController extends Controller
/** /**
* Force an application to be approved. * Force an application to be approved.
*/ */
public function forceApprovalEvent(Request $request) { public function forceApprovalEvent(Request $request)
{
$this->singleAuthorise(); $this->singleAuthorise();
$application = Application::find($request->application); $application = Application::find($request->application);
@ -80,20 +84,19 @@ class DevToolsController extends Controller
->with('success', __('Event dispatched; Candidate rejection sequence initiated.')); ->with('success', __('Event dispatched; Candidate rejection sequence initiated.'));
} }
public function evaluateVotes() { public function evaluateVotes()
{
$this->singleAuthorise(); $this->singleAuthorise();
$code = Artisan::call("votes:evaluate"); $code = Artisan::call('votes:evaluate');
return redirect() return redirect()
->back() ->back()
->with('success', __('Ran vote evaluation logic, with exit code :exitCode ', ['exitCode' => $code])); ->with('success', __('Ran vote evaluation logic, with exit code :exitCode ', ['exitCode' => $code]));
} }
public function purgeSuspensions(AccountSuspensionService $service) { public function purgeSuspensions(AccountSuspensionService $service)
{
$this->singleAuthorise(); $this->singleAuthorise();
if ($service->purgeExpired()) { if ($service->purgeExpired()) {
@ -105,7 +108,6 @@ class DevToolsController extends Controller
return redirect() return redirect()
->back() ->back()
->with('error', __('There were no expired suspensions (or no suspensions at all) to purge.')); ->with('error', __('There were no expired suspensions (or no suspensions at all) to purge.'));
} }
public function endAbsencesNow(AbsenceService $service) public function endAbsencesNow(AbsenceService $service)

View File

@ -25,14 +25,14 @@ use App\Exceptions\EmptyFormException;
use App\Exceptions\FormHasConstraintsException; use App\Exceptions\FormHasConstraintsException;
use App\Form; use App\Form;
use App\Services\FormManagementService; use App\Services\FormManagementService;
use ContextAwareValidator;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class FormController extends Controller class FormController extends Controller
{ {
private $formService; private $formService;
public function __construct(FormManagementService $formService) { public function __construct(FormManagementService $formService)
{
$this->formService = $formService; $this->formService = $formService;
} }
@ -56,17 +56,14 @@ class FormController extends Controller
{ {
try { try {
$form = $this->formService->addForm($request->all()); $form = $this->formService->addForm($request->all());
} } catch (EmptyFormException $ex) {
catch (EmptyFormException $ex)
{
return redirect() return redirect()
->back() ->back()
->with('exception', $ex->getMessage()); ->with('exception', $ex->getMessage());
} }
// Form is boolean or array // Form is boolean or array
if ($form) if ($form) {
{
return redirect() return redirect()
->back() ->back()
->with('success', __('Form created!')); ->with('success', __('Form created!'));
@ -81,18 +78,15 @@ class FormController extends Controller
{ {
$this->authorize('delete', $form); $this->authorize('delete', $form);
try { try {
$this->formService->deleteForm($form); $this->formService->deleteForm($form);
return redirect() return redirect()
->back() ->back()
->with('success', __('Form deleted successfuly')); ->with('success', __('Form deleted successfuly'));
} catch (FormHasConstraintsException $ex) { } catch (FormHasConstraintsException $ex) {
return redirect() return redirect()
->back() ->back()
->with('error', $ex->getMessage()); ->with('error', $ex->getMessage());
} }
} }

View File

@ -24,20 +24,17 @@ namespace App\Http\Controllers;
use App\Exceptions\InvalidGamePreferenceException; use App\Exceptions\InvalidGamePreferenceException;
use App\Exceptions\OptionNotFoundException; use App\Exceptions\OptionNotFoundException;
use App\Facades\Options; use App\Facades\Options;
use App\Options as Option;
use App\Services\ConfigurationService; use App\Services\ConfigurationService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class OptionsController extends Controller class OptionsController extends Controller
{ {
private $configurationService; private $configurationService;
public function __construct(ConfigurationService $configurationService) { public function __construct(ConfigurationService $configurationService)
{
$this->configurationService = $configurationService; $this->configurationService = $configurationService;
} }
/** /**
@ -56,16 +53,15 @@ class OptionsController extends Controller
'graceperiod' => Options::getOption('graceperiod'), 'graceperiod' => Options::getOption('graceperiod'),
'pwExpiry' => Options::getOption('password_expiry'), 'pwExpiry' => Options::getOption('password_expiry'),
'requiresPMC' => Options::getOption('requireGameLicense'), 'requiresPMC' => Options::getOption('requireGameLicense'),
'enforce2fa' => Options::getOption('force2fa') 'enforce2fa' => Options::getOption('force2fa'),
], ],
'currentGame' => Options::getOption('currentGame') 'currentGame' => Options::getOption('currentGame'),
]); ]);
} }
public function saveSettings(Request $request): \Illuminate\Http\RedirectResponse public function saveSettings(Request $request): \Illuminate\Http\RedirectResponse
{ {
try { try {
if (Auth::user()->can('admin.settings.edit')) { if (Auth::user()->can('admin.settings.edit')) {
$this->configurationService->saveConfiguration($request->all()); $this->configurationService->saveConfiguration($request->all());
@ -73,13 +69,10 @@ class OptionsController extends Controller
->back() ->back()
->with('success', __('Options updated successfully!')); ->with('success', __('Options updated successfully!'));
} }
} catch (OptionNotFoundException|\Exception $ex) { } catch (OptionNotFoundException|\Exception $ex) {
return redirect() return redirect()
->back() ->back()
->with('error', $ex->getMessage()); ->with('error', $ex->getMessage());
} }
return redirect() return redirect()
@ -90,12 +83,11 @@ class OptionsController extends Controller
public function saveGameIntegration(Request $request) public function saveGameIntegration(Request $request)
{ {
try { try {
$this->configurationService->saveGameIntegration($request->gamePref); $this->configurationService->saveGameIntegration($request->gamePref);
return redirect() return redirect()
->back() ->back()
->with('success', __('Game preference updated.')); ->with('success', __('Game preference updated.'));
} catch (InvalidGamePreferenceException $ex) { } catch (InvalidGamePreferenceException $ex) {
return redirect() return redirect()
->back() ->back()

View File

@ -21,8 +21,6 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Exceptions\ProfileAlreadyExistsException;
use App\Exceptions\ProfileCreationFailedException;
use App\Exceptions\ProfileNotFoundException; use App\Exceptions\ProfileNotFoundException;
use App\Facades\IP; use App\Facades\IP;
use App\Http\Requests\ProfileSave; use App\Http\Requests\ProfileSave;
@ -32,13 +30,13 @@ use App\User;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Spatie\Permission\Models\Role;
class ProfileController extends Controller class ProfileController extends Controller
{ {
private ProfileService $profileService; private ProfileService $profileService;
public function __construct(ProfileService $profileService) { public function __construct(ProfileService $profileService)
{
$this->profileService = $profileService; $this->profileService = $profileService;
} }
@ -60,27 +58,22 @@ class ProfileController extends Controller
public function showSingleProfile(AccountSuspensionService $accountSuspensionService, User $user) public function showSingleProfile(AccountSuspensionService $accountSuspensionService, User $user)
{ {
if (is_null($user->profile)) { if (is_null($user->profile)) {
return redirect() return redirect()
->back() ->back()
->with('error', "This user doesn't have a profile."); ->with('error', "This user doesn't have a profile.");
} }
$socialMediaProfiles = json_decode($user->profile->socialLinks, true); $socialMediaProfiles = json_decode($user->profile->socialLinks, true);
$createdDate = Carbon::parse($user->created_at); $createdDate = Carbon::parse($user->created_at);
$suspensionInfo = null; $suspensionInfo = null;
if ($accountSuspensionService->isSuspended($user)) if ($accountSuspensionService->isSuspended($user)) {
{
$suspensionInfo = [ $suspensionInfo = [
'isPermanent' => $user->bans->isPermanent, 'isPermanent' => $user->bans->isPermanent,
'reason' => $user->bans->reason, 'reason' => $user->bans->reason,
'bannedUntil' => $user->bans->bannedUntil 'bannedUntil' => $user->bans->bannedUntil,
]; ];
} }
@ -94,7 +87,7 @@ class ProfileController extends Controller
'discord' => $socialMediaProfiles['links']['discord'] ?? 'UpdateMe#12345', 'discord' => $socialMediaProfiles['links']['discord'] ?? 'UpdateMe#12345',
'since' => $createdDate->englishMonth.' '.$createdDate->year, 'since' => $createdDate->englishMonth.' '.$createdDate->year,
'ipInfo' => IP::lookup($user->currentIp), 'ipInfo' => IP::lookup($user->currentIp),
'suspensionInfo' => $suspensionInfo 'suspensionInfo' => $suspensionInfo,
]); ]);
} else { } else {
abort(403, __('You cannot view someone else\'s profile.')); abort(403, __('You cannot view someone else\'s profile.'));
@ -104,23 +97,20 @@ class ProfileController extends Controller
public function saveProfile(ProfileSave $request) public function saveProfile(ProfileSave $request)
{ {
$this->profileService->updateProfile(Auth::user()->id, $request); $this->profileService->updateProfile(Auth::user()->id, $request);
return redirect() return redirect()
->back() ->back()
->with('success', __('Profile updated.')); ->with('success', __('Profile updated.'));
} }
public function createProfile(Request $request) public function createProfile(Request $request)
{ {
try { try {
$this->profileService->createProfile($request->user()); $this->profileService->createProfile($request->user());
} catch (\Exception $e) { } catch (\Exception $e) {
return redirect() return redirect()
->back() ->back()
->with('error', $e->getMessage()); ->with('error', $e->getMessage());
} }
return redirect() return redirect()
@ -128,24 +118,18 @@ class ProfileController extends Controller
->with('success', __('Your profile has been created.')); ->with('success', __('Your profile has been created.'));
} }
public function deleteProfile(Request $request) public function deleteProfile(Request $request)
{ {
try { try {
$this->profileService->deleteProfile($request->user()); $this->profileService->deleteProfile($request->user());
} catch (ProfileNotFoundException $e) { } catch (ProfileNotFoundException $e) {
return redirect() return redirect()
->back() ->back()
->with('error', $e->getMessage()); ->with('error', $e->getMessage());
} }
return redirect() return redirect()
->back() ->back()
->with('success', __('Profile deleted successfully.')); ->with('success', __('Profile deleted successfully.'));
} }
} }

View File

@ -2,19 +2,15 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Facades\Options;
use App\Http\Requests\SaveSecuritySettings; use App\Http\Requests\SaveSecuritySettings;
use App\Services\SecuritySettingsService; use App\Services\SecuritySettingsService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use function PHPSTORM_META\map;
class SecuritySettingsController extends Controller class SecuritySettingsController extends Controller
{ {
private $securityService; private $securityService;
public function __construct(SecuritySettingsService $securityService) { public function __construct(SecuritySettingsService $securityService)
{
$this->securityService = $securityService; $this->securityService = $securityService;
} }
@ -24,12 +20,11 @@ class SecuritySettingsController extends Controller
'graceperiod' => $request->graceperiod, 'graceperiod' => $request->graceperiod,
'pwExpiry' => $request->pwExpiry, 'pwExpiry' => $request->pwExpiry,
'enforce2fa' => $request->enforce2fa, 'enforce2fa' => $request->enforce2fa,
'requirePMC' => $request->requirePMC 'requirePMC' => $request->requirePMC,
]); ]);
return redirect() return redirect()
->back() ->back()
->with('success', __('Settings saved.')); ->with('success', __('Settings saved.'));
} }
} }

View File

@ -27,7 +27,6 @@ use App\Exceptions\UserAlreadyInvitedException;
use App\Http\Requests\EditTeamRequest; use App\Http\Requests\EditTeamRequest;
use App\Http\Requests\NewTeamRequest; use App\Http\Requests\NewTeamRequest;
use App\Http\Requests\SendInviteRequest; use App\Http\Requests\SendInviteRequest;
use App\Mail\InviteToTeam;
use App\Services\TeamService; use App\Services\TeamService;
use App\Team; use App\Team;
use App\User; use App\User;
@ -35,22 +34,19 @@ use App\Vacancy;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Mpociot\Teamwork\Exceptions\UserNotInTeamException; use Mpociot\Teamwork\Exceptions\UserNotInTeamException;
use Mpociot\Teamwork\Facades\Teamwork;
use Mpociot\Teamwork\TeamInvite;
class TeamController extends Controller class TeamController extends Controller
{ {
private $teamService; private $teamService;
public function __construct(TeamService $teamService) { public function __construct(TeamService $teamService)
{
$this->teamService = $teamService; $this->teamService = $teamService;
} }
/** /**
* Display a listing of the resource. * Display a listing of the resource.
*
*/ */
public function index() public function index()
{ {
@ -67,6 +63,7 @@ class TeamController extends Controller
* *
* @param NewTeamRequest $request * @param NewTeamRequest $request
* @return RedirectResponse * @return RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function store(NewTeamRequest $request) public function store(NewTeamRequest $request)
@ -84,16 +81,18 @@ class TeamController extends Controller
* *
* @param Team $team * @param Team $team
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\Response * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function edit(Team $team) public function edit(Team $team)
{ {
$this->authorize('update', $team); $this->authorize('update', $team);
return view('dashboard.teams.edit-team') return view('dashboard.teams.edit-team')
->with([ ->with([
'team' => $team, 'team' => $team,
'users' => User::all(), 'users' => User::all(),
'vacancies' => Vacancy::with('teams')->get()->all() 'vacancies' => Vacancy::with('teams')->get()->all(),
]); ]);
} }
@ -103,6 +102,7 @@ class TeamController extends Controller
* @param EditTeamRequest $request * @param EditTeamRequest $request
* @param Team $team * @param Team $team
* @return RedirectResponse * @return RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function update(EditTeamRequest $request, Team $team): RedirectResponse public function update(EditTeamRequest $request, Team $team): RedirectResponse
@ -110,7 +110,6 @@ class TeamController extends Controller
$this->authorize('update', $team); $this->authorize('update', $team);
$team = $this->teamService->updateTeam($team, $request->teamDescription, $request->joinType); $team = $this->teamService->updateTeam($team, $request->teamDescription, $request->joinType);
if ($team) { if ($team) {
return redirect() return redirect()
->to(route('teams.index')) ->to(route('teams.index'))
@ -138,13 +137,11 @@ class TeamController extends Controller
$this->authorize('invite', $team); $this->authorize('invite', $team);
try { try {
$this->teamService->inviteUser($team, $request->user); $this->teamService->inviteUser($team, $request->user);
return redirect() return redirect()
->back() ->back()
->with('success', __('User invited successfully!')); ->with('success', __('User invited successfully!'));
} catch (UserAlreadyInvitedException|PublicTeamInviteException $ex) { } catch (UserAlreadyInvitedException|PublicTeamInviteException $ex) {
return redirect() return redirect()
->back() ->back()
@ -155,19 +152,15 @@ class TeamController extends Controller
public function processInviteAction(Request $request, $action, $token): RedirectResponse public function processInviteAction(Request $request, $action, $token): RedirectResponse
{ {
try { try {
$this->teamService->processInvite(Auth::user(), $action, $token); $this->teamService->processInvite(Auth::user(), $action, $token);
return redirect() return redirect()
->to(route('teams.index')) ->to(route('teams.index'))
->with('success', __('Invite processed successfully!')); ->with('success', __('Invite processed successfully!'));
} catch (InvalidInviteException $e) { } catch (InvalidInviteException $e) {
return redirect() return redirect()
->back() ->back()
->with('error', $e->getMessage()); ->with('error', $e->getMessage());
} }
} }

View File

@ -4,31 +4,23 @@ namespace App\Http\Controllers;
// Most of these namespaces have no effect on the code, however, they're used by IDEs so they can resolve return types and for PHPDocumentor as well // Most of these namespaces have no effect on the code, however, they're used by IDEs so they can resolve return types and for PHPDocumentor as well
use App\Exceptions\FileUploadException; use App\Exceptions\FileUploadException;
use App\Http\Requests\UploadFileRequest;
use App\Services\TeamFileService; use App\Services\TeamFileService;
use App\TeamFile; use App\TeamFile;
use App\Http\Requests\UploadFileRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FileNotFoundException;
// Documentation-purpose namespaces
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; use Illuminate\Support\Facades\Auth;
// Documentation-purpose namespaces
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FileNotFoundException;
class TeamFileController extends Controller class TeamFileController extends Controller
{ {
private $fileService; private $fileService;
public function __construct(TeamFileService $fileService) { public function __construct(TeamFileService $fileService)
{
$this->fileService = $fileService; $this->fileService = $fileService;
} }
@ -41,9 +33,9 @@ class TeamFileController extends Controller
{ {
$this->authorize('index', TeamFile::class); $this->authorize('index', TeamFile::class);
if (is_null(Auth::user()->currentTeam)) if (is_null(Auth::user()->currentTeam)) {
{
$request->session()->flash('error', __('Please choose a team before viewing it\'s files.')); $request->session()->flash('error', __('Please choose a team before viewing it\'s files.'));
return redirect()->to(route('teams.index')); return redirect()->to(route('teams.index'));
} }
@ -51,7 +43,6 @@ class TeamFileController extends Controller
->with('files', TeamFile::with('team', 'uploader')->paginate(6)); ->with('files', TeamFile::with('team', 'uploader')->paginate(6));
} }
/** /**
* Store a newly created resource in storage. * Store a newly created resource in storage.
* *
@ -62,8 +53,7 @@ class TeamFileController extends Controller
{ {
$this->authorize('store', TeamFile::class); $this->authorize('store', TeamFile::class);
if (config('demo.is_enabled')) if (config('demo.is_enabled')) {
{
return redirect() return redirect()
->back() ->back()
->with('error', __('This feature is disabled')); ->with('error', __('This feature is disabled'));
@ -78,31 +68,23 @@ class TeamFileController extends Controller
return redirect() return redirect()
->back() ->back()
->with('success', __('File uploaded successfully.')); ->with('success', __('File uploaded successfully.'));
} catch (FileUploadException $uploadException) { } catch (FileUploadException $uploadException) {
return redirect() return redirect()
->back() ->back()
->with('error', $uploadException->getMessage()); ->with('error', $uploadException->getMessage());
} }
} }
public function download(Request $request, TeamFile $teamFile) public function download(Request $request, TeamFile $teamFile)
{ {
$this->authorize('download', TeamFile::class); $this->authorize('download', TeamFile::class);
try try {
{
return Storage::download($teamFile->fs_location, $teamFile->name); return Storage::download($teamFile->fs_location, $teamFile->name);
} } catch (FileNotFoundException $ex) {
catch (FileNotFoundException $ex)
{
$request->session()->flash('error', __('Sorry, but the requested file could not be found in storage. Sometimes, files may be physically deleted by admins, but not from the app\'s database.')); $request->session()->flash('error', __('Sorry, but the requested file could not be found in storage. Sometimes, files may be physically deleted by admins, but not from the app\'s database.'));
return redirect()->back();
return redirect()->back();
} }
} }
@ -117,22 +99,18 @@ class TeamFileController extends Controller
{ {
$this->authorize('delete', $teamFile); $this->authorize('delete', $teamFile);
if (config('demo.is_enabled')) if (config('demo.is_enabled')) {
{
return redirect() return redirect()
->back() ->back()
->with('error', __('This feature is disabled')); ->with('error', __('This feature is disabled'));
} }
try try {
{
Storage::delete($teamFile->fs_location); Storage::delete($teamFile->fs_location);
$teamFile->delete(); $teamFile->delete();
$request->session()->flash('success', __('File deleted successfully.')); $request->session()->flash('success', __('File deleted successfully.'));
} } catch (\Exception $ex) {
catch (\Exception $ex)
{
$request->session()->flash('error', __('There was an error deleting the file: :msg', ['msg' => $ex->getMessage()])); $request->session()->flash('error', __('There was an error deleting the file: :msg', ['msg' => $ex->getMessage()]));
} }

View File

@ -22,7 +22,6 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Ban; use App\Ban;
use App\Facades\IP;
use App\Facades\Options; use App\Facades\Options;
use App\Http\Requests\Add2FASecretRequest; use App\Http\Requests\Add2FASecretRequest;
use App\Http\Requests\AddDobRequest; use App\Http\Requests\AddDobRequest;
@ -44,7 +43,6 @@ use App\Services\AccountSuspensionService;
use App\Services\DiscordService; use App\Services\DiscordService;
use App\Traits\DisablesFeatures; use App\Traits\DisablesFeatures;
use App\Traits\HandlesAccountDeletion; use App\Traits\HandlesAccountDeletion;
use App\Traits\ReceivesAccountTokens;
use App\User; use App\User;
use Google2FA; use Google2FA;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
@ -61,11 +59,11 @@ class UserController extends Controller
{ {
use HandlesAccountDeletion, DisablesFeatures; use HandlesAccountDeletion, DisablesFeatures;
/** /**
* Shows list of users * Shows list of users
* *
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function showUsers() public function showUsers()
@ -80,13 +78,14 @@ class UserController extends Controller
]); ]);
} }
/** /**
* Searches for a player with the given search query. * Searches for a player with the given search query.
* *
* @deprecated Until Algolia implementation * @deprecated Until Algolia implementation
*
* @param SearchPlayerRequest $request * @param SearchPlayerRequest $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function showPlayersLike(SearchPlayerRequest $request) public function showPlayersLike(SearchPlayerRequest $request)
@ -115,12 +114,12 @@ class UserController extends Controller
} }
} }
/** /**
* Shows the user account's settings page * Shows the user account's settings page
* *
* @param Request $request * @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
@ -149,7 +148,6 @@ class UserController extends Controller
->with('twofaQRCode', $QRCode); ->with('twofaQRCode', $QRCode);
} }
/** /**
* Show account management screen * Show account management screen
* *
@ -157,11 +155,11 @@ class UserController extends Controller
* @param Request $request * @param Request $request
* @param User $user * @param User $user
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function showAcocuntManagement(AccountSuspensionService $suspensionService, Request $request, User $user) public function showAcocuntManagement(AccountSuspensionService $suspensionService, Request $request, User $user)
{ {
$this->authorize('adminEdit', $user); $this->authorize('adminEdit', $user);
$systemRoles = Role::all()->pluck('name')->all(); $systemRoles = Role::all()->pluck('name')->all();
@ -190,7 +188,7 @@ class UserController extends Controller
'suspensionReason' => $suspensionService->getSuspensionReason($user), 'suspensionReason' => $suspensionService->getSuspensionReason($user),
'suspensionDuration' => $suspensionService->getSuspensionDuration($user), 'suspensionDuration' => $suspensionService->getSuspensionDuration($user),
'has2FA' => $user->has2FA(), 'has2FA' => $user->has2FA(),
'applications' => $user->applications()->get() 'applications' => $user->applications()->get(),
]); ]);
} }
@ -199,6 +197,7 @@ class UserController extends Controller
* *
* @param FlushSessionsRequest $request * @param FlushSessionsRequest $request
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\AuthenticationException * @throws \Illuminate\Auth\AuthenticationException
*/ */
public function flushSessions(FlushSessionsRequest $request) public function flushSessions(FlushSessionsRequest $request)
@ -219,8 +218,6 @@ class UserController extends Controller
return redirect()->back(); return redirect()->back();
} }
/** /**
* Change the current user's password * Change the current user's password
* *
@ -255,17 +252,15 @@ class UserController extends Controller
} }
} }
/** /**
* Sets a new password for the user. * Sets a new password for the user.
* *
* @param SetNewPasswordRequest $request * @param SetNewPasswordRequest $request
* @return Application|RedirectResponse|Redirector * @return Application|RedirectResponse|Redirector
*/ */
public function setPassword(SetNewPasswordRequest $request) { public function setPassword(SetNewPasswordRequest $request)
{
if (! Auth::user()->hasPassword()) { if (! Auth::user()->hasPassword()) {
Auth::user()->password = Hash::make($request->newpass); Auth::user()->password = Hash::make($request->newpass);
Auth::user()->save(); Auth::user()->save();
@ -281,7 +276,6 @@ class UserController extends Controller
->with('error', __('Your account already has a password.')); ->with('error', __('Your account already has a password.'));
} }
/** /**
* Sets a user's password and removes their discord information from storage * Sets a user's password and removes their discord information from storage
* *
@ -295,31 +289,30 @@ class UserController extends Controller
try { try {
$discordService->revokeAccountTokens(Auth::user()); $discordService->revokeAccountTokens(Auth::user());
Log::warning('Revoking social account tokens, user initiated', [ Log::warning('Revoking social account tokens, user initiated', [
'user' => Auth::user()->email 'user' => Auth::user()->email,
]); ]);
} catch (RequestException $requestException) { } catch (RequestException $requestException) {
if ($requestException->getCode() == 401) { if ($requestException->getCode() == 401) {
return redirect(route('discordRedirect')); return redirect(route('discordRedirect'));
} }
Log::error('Error while trying to revoke Discord credentials', [$requestException->getMessage()]); Log::error('Error while trying to revoke Discord credentials', [$requestException->getMessage()]);
return redirect() return redirect()
->back() ->back()
->with('error', __('An unknown error ocurred. Please try again later.')); ->with('error', __('An unknown error ocurred. Please try again later.'));
} }
$request->session()->flash('success', __('Discord account unlinked successfully. Link it again by re-authorizing the app with the same account in the login screen, or through your account settings.')); $request->session()->flash('success', __('Discord account unlinked successfully. Link it again by re-authorizing the app with the same account in the login screen, or through your account settings.'));
return redirect()->back(); return redirect()->back();
} }
return redirect() return redirect()
->back() ->back()
->with('error', __('Please set a password for your account first before trying to unlink Discord.')); ->with('error', __('Please set a password for your account first before trying to unlink Discord.'));
} }
/** /**
* Change the current user's email address * Change the current user's email address
* *
@ -351,16 +344,16 @@ class UserController extends Controller
return redirect()->back(); return redirect()->back();
} }
/** /**
* Removes the user's password and notifies them. * Removes the user's password and notifies them.
* *
* @param User $user The user to remove the password for * @param User $user The user to remove the password for
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function forcePasswordReset(User $user) { public function forcePasswordReset(User $user)
{
$this->authorize('adminEdit', $user); $this->authorize('adminEdit', $user);
if ($user->hasPassword()) { if ($user->hasPassword()) {
@ -369,10 +362,9 @@ class UserController extends Controller
$user->password = null; $user->password = null;
$user->save(); $user->save();
Log::alert('Removed account password', [
Log::alert("Removed account password", [
'target' => $user, 'target' => $user,
'actor' => Auth::user() 'actor' => Auth::user(),
]); ]);
return redirect() return redirect()
@ -385,15 +377,14 @@ class UserController extends Controller
->with('error', __('This user doesn\'t have a password to reset.')); ->with('error', __('This user doesn\'t have a password to reset.'));
} }
/** /**
* Adds a user's date of birth if they don't have one. * Adds a user's date of birth if they don't have one.
* *
* @param AddDobRequest $request * @param AddDobRequest $request
* @return RedirectResponse * @return RedirectResponse
*/ */
public function addDob(AddDobRequest $request) { public function addDob(AddDobRequest $request)
{
Auth::user()->dob = $request->dob; Auth::user()->dob = $request->dob;
Auth::user()->save(); Auth::user()->save();
@ -401,13 +392,13 @@ class UserController extends Controller
->back(); ->back();
} }
/** /**
* Delete the given user's account * Delete the given user's account
* *
* @param DeleteUserRequest $request * @param DeleteUserRequest $request
* @param User $user * @param User $user
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function delete(DeleteUserRequest $request, User $user) public function delete(DeleteUserRequest $request, User $user)
@ -426,13 +417,13 @@ class UserController extends Controller
return redirect()->route('registeredPlayerList'); return redirect()->route('registeredPlayerList');
} }
/** /**
* Update a given user's details * Update a given user's details
* *
* @param UpdateUserRequest $request * @param UpdateUserRequest $request
* @param User $user * @param User $user
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function update(UpdateUserRequest $request, User $user) public function update(UpdateUserRequest $request, User $user)
@ -470,12 +461,12 @@ class UserController extends Controller
return redirect()->back(); return redirect()->back();
} }
/** /**
* Generate and add a 2FA secret for the current user * Generate and add a 2FA secret for the current user
* *
* @param Add2FASecretRequest $request * @param Add2FASecretRequest $request
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
@ -522,7 +513,6 @@ class UserController extends Controller
return redirect()->back(); return redirect()->back();
} }
/** /**
* Remove the current user's two factor secret key * Remove the current user's two factor secret key
* *
@ -544,7 +534,6 @@ class UserController extends Controller
return redirect()->back(); return redirect()->back();
} }
/** /**
* Remove the given user's two factor secret key * Remove the given user's two factor secret key
* *
@ -552,7 +541,8 @@ class UserController extends Controller
* @param User $user * @param User $user
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*/ */
public function reset2FASecret(Reset2FASecretRequest $request, User $user) { public function reset2FASecret(Reset2FASecretRequest $request, User $user)
{
// note: could invalidate other sessions for increased security // note: could invalidate other sessions for increased security
if ($user->has2FA()) { if ($user->has2FA()) {
Log::warning('SECURITY: Disabling two factor authentication (admin initiated)', [ Log::warning('SECURITY: Disabling two factor authentication (admin initiated)', [
@ -584,6 +574,7 @@ class UserController extends Controller
* @param BanUserRequest $request * @param BanUserRequest $request
* @param User $user * @param User $user
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function suspend(AccountSuspensionService $suspensionService, BanUserRequest $request, User $user) public function suspend(AccountSuspensionService $suspensionService, BanUserRequest $request, User $user)
@ -591,17 +582,15 @@ class UserController extends Controller
$this->authorize('create', [Ban::class, $user]); $this->authorize('create', [Ban::class, $user]);
$this->disable(); $this->disable();
if ($suspensionService->isSuspended($user)) if ($suspensionService->isSuspended($user)) {
{
return redirect() return redirect()
->back() ->back()
->with('error', __('Account already suspended.')); ->with('error', __('Account already suspended.'));
} }
if ($request->suspensionType = "on") { if ($request->suspensionType = 'on') {
$suspensionService->suspend($user, $request->reason, $request->duration); $suspensionService->suspend($user, $request->reason, $request->duration);
} } else {
else {
$suspensionService->suspend($user, $request->reason); $suspensionService->suspend($user, $request->reason);
} }
@ -615,6 +604,7 @@ class UserController extends Controller
* @param Request $request * @param Request $request
* @param User $user * @param User $user
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException * @throws \Illuminate\Auth\Access\AuthorizationException
*/ */
public function unsuspend(AccountSuspensionService $suspensionService, Request $request, User $user) public function unsuspend(AccountSuspensionService $suspensionService, Request $request, User $user)
@ -623,15 +613,12 @@ class UserController extends Controller
$this->disable(); $this->disable();
if ($suspensionService->isSuspended($user)) { if ($suspensionService->isSuspended($user)) {
$suspensionService->unsuspend($user); $suspensionService->unsuspend($user);
$request->session()->flash('success', __('Account unsuspended successfully!')); $request->session()->flash('success', __('Account unsuspended successfully!'));
} else { } else {
$request->session()->flash('error', __('This account isn\'t suspended!')); $request->session()->flash('error', __('This account isn\'t suspended!'));
} }
return redirect()->back(); return redirect()->back();
} }
} }

View File

@ -21,7 +21,6 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Facades\JSON;
use App\Form; use App\Form;
use App\Http\Requests\VacancyEditRequest; use App\Http\Requests\VacancyEditRequest;
use App\Http\Requests\VacancyRequest; use App\Http\Requests\VacancyRequest;
@ -50,8 +49,6 @@ class VacancyController extends Controller
$messageIsError = false; $messageIsError = false;
$this->authorize('create', Vacancy::class); $this->authorize('create', Vacancy::class);
$form = Form::find($request->vacancyFormID); $form = Form::find($request->vacancyFormID);
if (! is_null($form)) { if (! is_null($form)) {
@ -71,12 +68,11 @@ class VacancyController extends Controller
'vacancyFormID' => $request->vacancyFormID, 'vacancyFormID' => $request->vacancyFormID,
'vacancyCount' => $request->vacancyCount, 'vacancyCount' => $request->vacancyCount,
'requiresDiscord' => $request->requireDiscordAccount == 'on', 'requiresDiscord' => $request->requireDiscordAccount == 'on',
'requiredAge' => $request->requiredAge 'requiredAge' => $request->requiredAge,
]); ]);
$message = __('Vacancy successfully opened. It will now show in the home page.'); $message = __('Vacancy successfully opened. It will now show in the home page.');
} else { } else {
$message = __('You cannot create a vacancy without a valid form.'); $message = __('You cannot create a vacancy without a valid form.');
$messageIsError = true; $messageIsError = true;
@ -108,12 +104,9 @@ class VacancyController extends Controller
break; break;
default: default:
$message = __("Please do not tamper with the URLs. To report a bug, please contact an administrator."); $message = __('Please do not tamper with the URLs. To report a bug, please contact an administrator.');
$type = 'error'; $type = 'error';
} }
} else { } else {
$message = __("The position you're trying to update doesn't exist!"); $message = __("The position you're trying to update doesn't exist!");
$type = 'error'; $type = 'error';
@ -126,7 +119,6 @@ class VacancyController extends Controller
return redirect() return redirect()
->back() ->back()
->with($type, $message); ->with($type, $message);
} }
public function edit(Request $request, Vacancy $vacancy) public function edit(Request $request, Vacancy $vacancy)
@ -159,7 +151,6 @@ class VacancyController extends Controller
$this->authorize('delete', $vacancy); $this->authorize('delete', $vacancy);
if ($vacancy->teams->isEmpty()) { if ($vacancy->teams->isEmpty()) {
$vacancy->delete(); $vacancy->delete();
return redirect() return redirect()

View File

@ -23,7 +23,6 @@ namespace App\Http\Middleware;
use App\Application; use App\Application;
use App\User; use App\User;
use Carbon\Carbon;
use Closure; use Closure;
use Exception; use Exception;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -38,9 +37,11 @@ class ApplicationEligibility
* *
* @deprecated Deprecated in 0.9.0 * @deprecated Deprecated in 0.9.0
* @see User::isEligible() * @see User::isEligible()
*
* @param Request $request * @param Request $request
* @param Closure $next * @param Closure $next
* @return mixed * @return mixed
*
* @throws Exception * @throws Exception
*/ */
public function handle($request, Closure $next) public function handle($request, Closure $next)
@ -49,7 +50,6 @@ class ApplicationEligibility
$daysRemaining = __('N/A'); $daysRemaining = __('N/A');
if (Auth::check()) { if (Auth::check()) {
$lastApplication = Application::where('applicantUserID', Auth::user()->id)->latest()->first(); $lastApplication = Application::where('applicantUserID', Auth::user()->id)->latest()->first();
if (is_null($lastApplication)) { if (is_null($lastApplication)) {
@ -61,7 +61,6 @@ class ApplicationEligibility
$daysRemaining = $lastApplication->created_at->addMonth()->diffInDays(now()); $daysRemaining = $lastApplication->created_at->addMonth()->diffInDays(now());
if ($lastApplication->created_at->diffInMonths(now()) > 1 && in_array($lastApplication->applicationStatus, ['DENIED', 'APPROVED'])) { if ($lastApplication->created_at->diffInMonths(now()) > 1 && in_array($lastApplication->applicationStatus, ['DENIED', 'APPROVED'])) {
$eligible = true; $eligible = true;
} }
@ -69,7 +68,7 @@ class ApplicationEligibility
'eligible' => $eligible, 'eligible' => $eligible,
'daysRemaining' => $daysRemaining, 'daysRemaining' => $daysRemaining,
'ipAddress' => Auth::user()->originalIP, 'ipAddress' => Auth::user()->originalIP,
'checkUserID' => Auth::user()->id 'checkUserID' => Auth::user()->id,
]); ]);
View::share('isEligibleForApplication', $eligible); View::share('isEligibleForApplication', $eligible);

View File

@ -31,12 +31,11 @@ class Bancheck
{ {
private AccountSuspensionService $suspensionService; private AccountSuspensionService $suspensionService;
public function __construct(AccountSuspensionService $suspensionService)
public function __construct(AccountSuspensionService $suspensionService) { {
$this->suspensionService = $suspensionService; $this->suspensionService = $suspensionService;
} }
/** /**
* Handle an incoming request. * Handle an incoming request.
* *

View File

@ -36,7 +36,6 @@ class ForceLogoutMiddleware
*/ */
public function handle($request, Closure $next) public function handle($request, Closure $next)
{ {
if ((new AccountSuspensionService())->isSuspended(Auth::user())) { if ((new AccountSuspensionService())->isSuspended(Auth::user())) {
Auth::logout(); Auth::logout();
$request->session()->flash('error', __('Your account is suspended. If you think this was a mistake, please contact an admin.')); $request->session()->flash('error', __('Your account is suspended. If you think this was a mistake, please contact an admin.'));

View File

@ -19,20 +19,15 @@ class PasswordExpirationMiddleware
*/ */
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
if(Auth::check()) if (Auth::check()) {
{
$sinceUpdate = Carbon::parse(Auth::user()->password_last_updated)->diffInDays(now()); $sinceUpdate = Carbon::parse(Auth::user()->password_last_updated)->diffInDays(now());
$updateThreshold = Options::getOption('password_expiry'); $updateThreshold = Options::getOption('password_expiry');
if ($updateThreshold !== 0 && $sinceUpdate > $updateThreshold) if ($updateThreshold !== 0 && $sinceUpdate > $updateThreshold) {
{
session()->put('passwordExpired', true); session()->put('passwordExpired', true);
} } else {
else
{
session()->put('passwordExpired', false); session()->put('passwordExpired', false);
} }
} }
return $next($request); return $next($request);

View File

@ -17,8 +17,7 @@ class PasswordExpirationRedirectMiddleware
*/ */
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
if (Auth::check() && session('passwordExpired')) if (Auth::check() && session('passwordExpired')) {
{
// WARNING!! Routes under the profile group must not have this middleware, because it'll result in an infinite redirect loop. // WARNING!! Routes under the profile group must not have this middleware, because it'll result in an infinite redirect loop.
return redirect(route('showAccountSettings')); return redirect(route('showAccountSettings'));
} }

View File

@ -24,7 +24,6 @@ namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware; use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class TrustProxies extends Middleware class TrustProxies extends Middleware
{ {
/** /**
@ -45,5 +44,4 @@ class TrustProxies extends Middleware
Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB; Request::HEADER_X_FORWARDED_AWS_ELB;
} }

View File

@ -53,7 +53,7 @@ class BanUserRequest extends FormRequest
public function messages() public function messages()
{ {
return [ return [
'duration.required_if' => __('You must provide a duration if the suspension is temporary.') 'duration.required_if' => __('You must provide a duration if the suspension is temporary.'),
]; ];
} }
} }

View File

@ -24,7 +24,7 @@ class CancelAppointmentRequest extends FormRequest
public function rules() public function rules()
{ {
return [ return [
'reason' => 'string|required' 'reason' => 'string|required',
]; ];
} }
} }

View File

@ -28,7 +28,7 @@ class SaveSecuritySettings extends FormRequest
'graceperiod' => 'required|integer', 'graceperiod' => 'required|integer',
'pwExpiry' => 'required|integer', 'pwExpiry' => 'required|integer',
'enforce2fa' => 'required|boolean', 'enforce2fa' => 'required|boolean',
'requirePMC' => 'required|boolean' 'requirePMC' => 'required|boolean',
]; ];
} }
} }

View File

@ -5,7 +5,6 @@ namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
class StoreAbsenceRequest extends FormRequest class StoreAbsenceRequest extends FormRequest
{ {
/** /**
@ -30,7 +29,7 @@ class StoreAbsenceRequest extends FormRequest
'start_date' => 'required|date', 'start_date' => 'required|date',
'predicted_end' => 'required|date|after:start_date', 'predicted_end' => 'required|date|after:start_date',
'available_assist' => 'required|string', 'available_assist' => 'required|string',
'invalidAbsenceAgreement' => 'required|accepted' 'invalidAbsenceAgreement' => 'required|accepted',
]; ];
} }
} }

View File

@ -26,7 +26,7 @@ class UploadFileRequest extends FormRequest
return [ return [
'caption' => 'required|string|max:100', 'caption' => 'required|string|max:100',
'description' => 'required|string|max:800', 'description' => 'required|string|max:800',
'file' => 'required|file|mimes:jpeg,jpg,png,bmp,tiff,docx,doc,odt,ott,xls,xlsx,ods,ots,gif,pdf,mp3,mp4,pptx,ppt,odp,ppsx,pub,psd,svg' 'file' => 'required|file|mimes:jpeg,jpg,png,bmp,tiff,docx,doc,odt,ott,xls,xlsx,ods,ots,gif,pdf,mp3,mp4,pptx,ppt,odp,ppsx,pub,psd,svg',
]; ];
} }
} }

View File

@ -48,7 +48,7 @@ class VacancyEditRequest extends FormRequest
'vacancyFullDescription' => 'nullable|string', 'vacancyFullDescription' => 'nullable|string',
'vacancyCount' => 'required|integer|min:1', 'vacancyCount' => 'required|integer|min:1',
'requireDiscordAccount' => 'required|string', 'requireDiscordAccount' => 'required|string',
'requiredAge' => 'required|integer|numeric|min:13|max:100' 'requiredAge' => 'required|integer|numeric|min:13|max:100',
]; ];
} }
} }

View File

@ -53,7 +53,7 @@ class VacancyRequest extends FormRequest
'vacancyCount' => 'required|integer', 'vacancyCount' => 'required|integer',
'vacancyFormID' => 'required|integer', 'vacancyFormID' => 'required|integer',
'requireDiscordAccount' => 'required|string', 'requireDiscordAccount' => 'required|string',
'requiredAge' => 'required|integer|numeric|min:13|max:100' 'requiredAge' => 'required|integer|numeric|min:13|max:100',
]; ];
} }
} }

View File

@ -22,7 +22,7 @@ class ApplicationResource extends JsonResource
'applicant' => new UserResource(User::findOrFail($this->applicantUserID)), 'applicant' => new UserResource(User::findOrFail($this->applicantUserID)),
'response' => new ResponseResource(Response::findOrFail($this->applicantFormResponseID)), 'response' => new ResponseResource(Response::findOrFail($this->applicantFormResponseID)),
'created_at' => $this->created_at, 'created_at' => $this->created_at,
'updated_at' => $this->updated_at 'updated_at' => $this->updated_at,
]; ];
} }
} }

View File

@ -20,7 +20,7 @@ class FormResource extends JsonResource
'formStructure' => json_decode($this->formStructure), 'formStructure' => json_decode($this->formStructure),
'formStatus' => $this->formStatus, 'formStatus' => $this->formStatus,
'created_at' => $this->created_at, 'created_at' => $this->created_at,
'updated_at' => $this->updated_at 'updated_at' => $this->updated_at,
]; ];
} }
} }

View File

@ -22,7 +22,7 @@ class ResponseResource extends JsonResource
'responseData' => json_decode($this->responseData), 'responseData' => json_decode($this->responseData),
'vacancy' => new VacancyResource(Vacancy::findOrFail($this->associatedVacancyID)), 'vacancy' => new VacancyResource(Vacancy::findOrFail($this->associatedVacancyID)),
'created_at' => $this->created_at, 'created_at' => $this->created_at,
'updated_at' => $this->updated_at 'updated_at' => $this->updated_at,
]; ];
} }
} }

View File

@ -22,7 +22,7 @@ class UserResource extends JsonResource
'username' => $this->username, 'username' => $this->username,
'created_at' => $this->created_at, 'created_at' => $this->created_at,
'updated_at' => $this->updated_at, 'updated_at' => $this->updated_at,
'current_team_id' => $this->current_team_id 'current_team_id' => $this->current_team_id,
]; ];
} }
} }

View File

@ -6,7 +6,6 @@ use App\Notifications\AccountDeleted;
use App\Notifications\UserDeletedAccount; use App\Notifications\UserDeletedAccount;
use App\User; use App\User;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
@ -25,7 +24,6 @@ class ProcessAccountDelete implements ShouldQueue
*/ */
protected User $user; protected User $user;
/** /**
* Create a new job instance. * Create a new job instance.
* *
@ -44,7 +42,7 @@ class ProcessAccountDelete implements ShouldQueue
public function handle() public function handle()
{ {
Log::alert('[Worker] Processing account deletion request', [ Log::alert('[Worker] Processing account deletion request', [
'email' => $this->user->email 'email' => $this->user->email,
]); ]);
$email = $this->user->email; $email = $this->user->email;
@ -52,7 +50,7 @@ class ProcessAccountDelete implements ShouldQueue
if ($this->user->delete()) { if ($this->user->delete()) {
Notification::route('mail', [ Notification::route('mail', [
$email => $name $email => $name,
])->notify(new AccountDeleted($name)); ])->notify(new AccountDeleted($name));
// Notify admins // Notify admins

View File

@ -21,9 +21,7 @@
namespace App\Jobs; namespace App\Jobs;
use App\Ban;
use App\Services\AccountSuspensionService; use App\Services\AccountSuspensionService;
use Carbon\Carbon;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;

View File

@ -4,7 +4,6 @@ namespace App\Jobs;
use App\Services\AbsenceService; use App\Services\AbsenceService;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;

View File

@ -2,9 +2,6 @@
namespace App\Listeners; namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class NewUser class NewUser
{ {
/** /**

View File

@ -54,6 +54,5 @@ class OnUserRegistration
})->get()->each(function ($user, $key) use ($event) { })->get()->each(function ($user, $key) use ($event) {
$user->notify(new NewUser($event->user)); $user->notify(new NewUser($event->user));
}); });
} }
} }

View File

@ -48,7 +48,7 @@ class PromoteUser
Log::info('User promoted automatically (application approved)', [ Log::info('User promoted automatically (application approved)', [
'user' => $event->application->user->name, 'user' => $event->application->user->name,
'vacancy' => $event->application->response->vacancy->vacancyName, 'vacancy' => $event->application->response->vacancy->vacancyName,
'role' => 'staff' 'role' => 'staff',
]); ]);
$event->application->setStatus('APPROVED'); $event->application->setStatus('APPROVED');

View File

@ -31,11 +31,16 @@ class UserAccountDeleteConfirmation extends Mailable
use Queueable, SerializesModels; use Queueable, SerializesModels;
public string public string
$approveLink, $approveLink;
$cancelLink,
$name,
$userID;
public string
$cancelLink;
public string
$name;
public string
$userID;
/** /**
* Create a new message instance. * Create a new message instance.

View File

@ -35,13 +35,11 @@ class ApplicationApproved extends Notification implements ShouldQueue
{ {
use Queueable, Cancellable; use Queueable, Cancellable;
/** /**
* @var Application The application we're notifying about * @var Application The application we're notifying about
*/ */
public Application $application; public Application $application;
/** /**
* @var User The candidate * @var User The candidate
*/ */

View File

@ -4,7 +4,6 @@ namespace App\Notifications;
use App\Application; use App\Application;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;

View File

@ -46,15 +46,16 @@ class ApplicationMoved extends Notification implements ShouldQueue
public function channels() public function channels()
{ {
Log::debug('Application moved notification: channels chosen', [ Log::debug('Application moved notification: channels chosen', [
'channels' => $this->chooseChannelsViaOptions() 'channels' => $this->chooseChannelsViaOptions(),
]); ]);
return $this->chooseChannelsViaOptions(); return $this->chooseChannelsViaOptions();
} }
public function optOut($notifiable) public function optOut($notifiable)
{ {
Log::debug('Application moved notification: opt out verified', [ Log::debug('Application moved notification: opt out verified', [
'opt-out' => Options::getOption('notify_application_status_change') != 1 'opt-out' => Options::getOption('notify_application_status_change') != 1,
]); ]);
return Options::getOption('notify_application_status_change') != 1; return Options::getOption('notify_application_status_change') != 1;

View File

@ -5,7 +5,6 @@ namespace App\Notifications;
use App\Application; use App\Application;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
@ -14,7 +13,9 @@ class AppointmentCancelled extends Notification
use Queueable; use Queueable;
private $application; private $application;
private $reason; private $reason;
private $appointmentDate; private $appointmentDate;
/** /**
@ -51,7 +52,7 @@ class AppointmentCancelled extends Notification
// TODO: Switch to HTML & Blade. // TODO: Switch to HTML & Blade.
return (new MailMessage) return (new MailMessage)
->greeting("Hi " . $notifiable->name . ",") ->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name')) ->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - interview cancelled') ->subject(config('app.name').' - interview cancelled')
->line('The interview that was previously scheduled with you has been cancelled.') ->line('The interview that was previously scheduled with you has been cancelled.')

View File

@ -31,7 +31,6 @@ class AppointmentFinished extends Notification implements ShouldQueue
{ {
use Queueable; use Queueable;
public $appointment; public $appointment;
/** /**
@ -64,14 +63,13 @@ class AppointmentFinished extends Notification implements ShouldQueue
public function toMail($notifiable) public function toMail($notifiable)
{ {
return (new MailMessage) return (new MailMessage)
->greeting("Hi " . $notifiable->name . ",") ->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name')) ->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - appointment completed') ->subject(config('app.name').' - appointment completed')
->line('Your appointment, "'.$this->appointment->appointmentDescription.'", has been marked as completed!') ->line('Your appointment, "'.$this->appointment->appointmentDescription.'", has been marked as completed!')
->line('Please allow an additional day for your application to be fully processed.') ->line('Please allow an additional day for your application to be fully processed.')
->action('View applications', url(route('showUserApps'))) ->action('View applications', url(route('showUserApps')))
->salutation('The team at '.config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -36,7 +36,6 @@ class VacancyStatusUpdated extends Notification implements ShouldQueue
protected string $status; protected string $status;
protected Vacancy $vacancy; protected Vacancy $vacancy;
/** /**
@ -49,7 +48,7 @@ class VacancyStatusUpdated extends Notification implements ShouldQueue
// there's no simpler solution to this for now, but an array works // there's no simpler solution to this for now, but an array works
$statusDict = [ $statusDict = [
'open' => 'opened', 'open' => 'opened',
'close' => 'closed' 'close' => 'closed',
]; ];
$this->vacancy = $vacancy; $this->vacancy = $vacancy;
@ -69,7 +68,6 @@ class VacancyStatusUpdated extends Notification implements ShouldQueue
*/ */
public function toMail($notifiable) public function toMail($notifiable)
{ {
return (new MailMessage) return (new MailMessage)
->greeting('Hi '.$notifiable->name.',') ->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name')) ->from(config('notification.sender.address'), config('notification.sender.name'))

View File

@ -23,7 +23,6 @@ namespace App\Observers;
use App\Exceptions\ProfileAlreadyExistsException; use App\Exceptions\ProfileAlreadyExistsException;
use App\Exceptions\ProfileCreationFailedException; use App\Exceptions\ProfileCreationFailedException;
use App\Profile;
use App\Services\ProfileService; use App\Services\ProfileService;
use App\User; use App\User;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@ -45,20 +44,15 @@ class UserObserver
{ {
$profileService = new ProfileService(); $profileService = new ProfileService();
try try {
{
$profileService->createProfile($user); $profileService->createProfile($user);
} } catch (ProfileAlreadyExistsException $exception) {
catch (ProfileAlreadyExistsException $exception)
{
Log::error('Attempting to create profile that already exists!', [ Log::error('Attempting to create profile that already exists!', [
'trace' => $exception->getTrace() 'trace' => $exception->getTrace(),
]); ]);
} } catch (ProfileCreationFailedException $e) {
catch (ProfileCreationFailedException $e)
{
Log::error('Failed creating a new profile!', [ Log::error('Failed creating a new profile!', [
'trace' => $e->getTrace() 'trace' => $e->getTrace(),
]); ]);
} }
} }

View File

@ -14,4 +14,3 @@ class OneoffApplicant extends Model
return $this->belongsTo('App\Application', 'id', 'application_id'); return $this->belongsTo('App\Application', 'id', 'application_id');
} }
} }

View File

@ -3,7 +3,6 @@
namespace App\Policies; namespace App\Policies;
use App\Absence; use App\Absence;
use App\Response;
use App\User; use App\User;
use Illuminate\Auth\Access\HandlesAuthorization; use Illuminate\Auth\Access\HandlesAuthorization;
@ -19,15 +18,13 @@ class AbsencePolicy
*/ */
public function viewAny(User $user) public function viewAny(User $user)
{ {
if ($user->hasPermissionTo('admin.viewAllAbsences')) if ($user->hasPermissionTo('admin.viewAllAbsences')) {
{
return true; return true;
} }
return false; return false;
} }
public function viewOwn(User $user): bool public function viewOwn(User $user): bool
{ {
if ($user->hasPermissionTo('reviewer.viewAbsence')) { if ($user->hasPermissionTo('reviewer.viewAbsence')) {
@ -46,8 +43,7 @@ class AbsencePolicy
*/ */
public function view(User $user, Absence $absence) public function view(User $user, Absence $absence)
{ {
if ($user->hasPermissionTo('reviewer.viewAbsence') && $user->is($absence->requester) || $user->hasPermissionTo('admin.manageAbsences')) if ($user->hasPermissionTo('reviewer.viewAbsence') && $user->is($absence->requester) || $user->hasPermissionTo('admin.manageAbsences')) {
{
return true; return true;
} }
@ -65,7 +61,6 @@ class AbsencePolicy
return $user->hasPermissionTo('reviewer.requestAbsence'); return $user->hasPermissionTo('reviewer.requestAbsence');
} }
/** /**
* Determine whether the user can approve the absence request * Determine whether the user can approve the absence request
* *
@ -75,19 +70,16 @@ class AbsencePolicy
*/ */
public function approve(User $user, Absence $absence): bool public function approve(User $user, Absence $absence): bool
{ {
if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester)) if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester)) {
{
return true; return true;
} }
return false; return false;
} }
public function decline(User $user, Absence $absence): bool public function decline(User $user, Absence $absence): bool
{ {
if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester)) if ($user->can('admin.manageAbsences') && $user->isNot($absence->requester)) {
{
return true; return true;
} }
@ -101,8 +93,8 @@ class AbsencePolicy
* @param Absence $absence * @param Absence $absence
* @return bool * @return bool
*/ */
public function cancel(User $user, Absence $absence): bool { public function cancel(User $user, Absence $absence): bool
{
if ($user->is($absence->requester) && $user->can('reviewer.withdrawAbsence')) { if ($user->is($absence->requester) && $user->can('reviewer.withdrawAbsence')) {
return true; return true;
} }
@ -121,6 +113,4 @@ class AbsencePolicy
{ {
return $user->hasPermissionTo('admin.manageAbsences'); return $user->hasPermissionTo('admin.manageAbsences');
} }
} }

View File

@ -18,13 +18,13 @@ class ApiKeyPolicy
*/ */
public function viewAny(User $user) public function viewAny(User $user)
{ {
if ($user->hasRole('admin')) if ($user->hasRole('admin')) {
return true; return true;
}
return false; return false;
} }
/** /**
* Determine whether the user can create models. * Determine whether the user can create models.
* *
@ -33,8 +33,9 @@ class ApiKeyPolicy
*/ */
public function create(User $user) public function create(User $user)
{ {
if ($user->hasRole('admin')) if ($user->hasRole('admin')) {
return true; return true;
}
return false; return false;
} }
@ -48,8 +49,9 @@ class ApiKeyPolicy
*/ */
public function update(User $user, ApiKey $apiKey) public function update(User $user, ApiKey $apiKey)
{ {
if ($user->hasRole('admin')) if ($user->hasRole('admin')) {
return true; return true;
}
return false; return false;
} }
@ -63,10 +65,10 @@ class ApiKeyPolicy
*/ */
public function delete(User $user, ApiKey $apiKey) public function delete(User $user, ApiKey $apiKey)
{ {
if ($user->hasRole('admin')) if ($user->hasRole('admin')) {
return true; return true;
}
return false; return false;
} }
} }

View File

@ -37,11 +37,9 @@ class TeamPolicy
return $user->isOwnerOfTeam($team) || $user->hasPermissionTo('teams.update'); return $user->isOwnerOfTeam($team) || $user->hasPermissionTo('teams.update');
} }
public function invite(User $user, Team $team) public function invite(User $user, Team $team)
{ {
if (!$team->openJoin && $user->isOwnerOfTeam($team) || !$team->openJoin && $user->hasPermissionTo('teams.invite')) if (! $team->openJoin && $user->isOwnerOfTeam($team) || ! $team->openJoin && $user->hasPermissionTo('teams.invite')) {
{
return true; return true;
} }

View File

@ -21,24 +21,17 @@
namespace App\Providers; namespace App\Providers;
use App\Facades\Options;
use App\Application; use App\Application;
use App\Observers\ApplicationObserver;
use App\Observers\UserObserver; use App\Observers\UserObserver;
use App\Observers\VacancyObserver;
use App\User; use App\User;
use App\Vacancy;
use Illuminate\Pagination\Paginator; use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\View; use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Sentry; use Sentry;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
{ {
/** /**
* Register any application services. * Register any application services.
* *
@ -66,18 +59,17 @@ class AppServiceProvider extends ServiceProvider
$https = ($this->app->environment() != 'local'); $https = ($this->app->environment() != 'local');
$collect = true; $collect = true;
if(config('app.force_secure') && $this->app->environment() != 'production') if (config('app.force_secure') && $this->app->environment() != 'production') {
$https = true; $https = true;
}
if (config('app.hide_ips') || config('demo.is_enabled')) if (config('app.hide_ips') || config('demo.is_enabled')) {
{
$collect = false; $collect = false;
} }
// Initialize user observer // Initialize user observer
User::observe(UserObserver::class); User::observe(UserObserver::class);
$this->app['request']->server->set('HTTPS', $https); $this->app['request']->server->set('HTTPS', $https);
View::share('shouldCollect', $collect); View::share('shouldCollect', $collect);

View File

@ -22,13 +22,11 @@
namespace App\Providers; namespace App\Providers;
use App\Absence; use App\Absence;
use App\ApiKey;
use App\Application; use App\Application;
use App\Appointment; use App\Appointment;
use App\Ban; use App\Ban;
use App\Form; use App\Form;
use App\Policies\AbsencePolicy; use App\Policies\AbsencePolicy;
use App\Policies\ApiKeyPolicy;
use App\Policies\ApplicationPolicy; use App\Policies\ApplicationPolicy;
use App\Policies\AppointmentPolicy; use App\Policies\AppointmentPolicy;
use App\Policies\BanPolicy; use App\Policies\BanPolicy;
@ -69,7 +67,7 @@ class AuthServiceProvider extends ServiceProvider
Appointment::class => AppointmentPolicy::class, Appointment::class => AppointmentPolicy::class,
Team::class => TeamPolicy::class, Team::class => TeamPolicy::class,
TeamFile::class => TeamFilePolicy::class, TeamFile::class => TeamFilePolicy::class,
Absence::class => AbsencePolicy::class Absence::class => AbsencePolicy::class,
]; ];
/** /**
@ -82,14 +80,12 @@ class AuthServiceProvider extends ServiceProvider
$this->registerPolicies(); $this->registerPolicies();
VerifyEmail::toMailUsing(function ($notifiable, $url) { VerifyEmail::toMailUsing(function ($notifiable, $url) {
return (new MailMessage) return (new MailMessage)
->greeting("Hi {$notifiable->name}! Welcome to " . config('app.name') . ".") ->greeting("Hi {$notifiable->name}! Welcome to ".config('app.name').'.')
->line('To finish setting up your account, you must verify your email. This is to ensure only real users access our website.') ->line('To finish setting up your account, you must verify your email. This is to ensure only real users access our website.')
->line('If you didn\'t sign up for an account, you can safely ignore this email.') ->line('If you didn\'t sign up for an account, you can safely ignore this email.')
->action('Verify account', $url) ->action('Verify account', $url)
->salutation('The team at '.config('app.name')); ->salutation('The team at '.config('app.name'));
}); });
Gate::define('viewLogViewer', function (?User $user) { Gate::define('viewLogViewer', function (?User $user) {

View File

@ -2,8 +2,8 @@
namespace App\Providers; namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App; use App;
use Illuminate\Support\ServiceProvider;
class DigitalStorageProvider extends ServiceProvider class DigitalStorageProvider extends ServiceProvider
{ {

View File

@ -25,11 +25,6 @@ use App\Application;
use App\Listeners\LogAuthenticationFailure; use App\Listeners\LogAuthenticationFailure;
use App\Listeners\LogAuthenticationSuccess; use App\Listeners\LogAuthenticationSuccess;
use App\Listeners\OnUserRegistration; use App\Listeners\OnUserRegistration;
use App\Observers\ApplicationObserver;
use App\Observers\UserObserver;
use App\Observers\VacancyObserver;
use App\User;
use App\Vacancy;
use Illuminate\Auth\Events\Failed; use Illuminate\Auth\Events\Failed;
use Illuminate\Auth\Events\Login; use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Events\Registered;

View File

@ -15,29 +15,24 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Spatie\Permission\Models\Role;
class AbsenceService class AbsenceService
{ {
/** /**
* Determines whether someone already has an active leave of absence request * Determines whether someone already has an active leave of absence request
* *
* @param User $user The user to check * @param User $user The user to check
* @return bool Their status * @return bool Their status
*/ */
public function hasActiveRequest(Authenticatable $user): bool { public function hasActiveRequest(Authenticatable $user): bool
{
$absences = Absence::where('requesterID', $user->id)->get(); $absences = Absence::where('requesterID', $user->id)->get();
foreach ($absences as $absence) { foreach ($absences as $absence) {
// Or we could adjust the query (using a model scope) to only return valid absences; // Or we could adjust the query (using a model scope) to only return valid absences;
// If there are any, refuse to store more, but this approach also works // If there are any, refuse to store more, but this approach also works
// A model scope that only returns cancelled, declined and ended absences could also be implemented for future use // A model scope that only returns cancelled, declined and ended absences could also be implemented for future use
if (in_array($absence->getRawOriginal('status'), ['PENDING', 'APPROVED'])) if (in_array($absence->getRawOriginal('status'), ['PENDING', 'APPROVED'])) {
{
return true; return true;
} }
} }
@ -47,12 +42,11 @@ class AbsenceService
public function createAbsence(Authenticatable $requester, Request $request) public function createAbsence(Authenticatable $requester, Request $request)
{ {
$absence = Absence::create([ $absence = Absence::create([
'requesterID' => $requester->id, 'requesterID' => $requester->id,
'start' => $request->start_date, 'start' => $request->start_date,
'predicted_end' => $request->predicted_end, 'predicted_end' => $request->predicted_end,
'available_assist' => $request->available_assist == "on", 'available_assist' => $request->available_assist == 'on',
'reason' => $request->reason, 'reason' => $request->reason,
'status' => 'PENDING', 'status' => 'PENDING',
]); ]);
@ -65,22 +59,21 @@ class AbsenceService
} }
}); });
Log::info('Processing new leave of absence request.', [ Log::info('Processing new leave of absence request.', [
'requesting_user' => $requester->email, 'requesting_user' => $requester->email,
'absenceid' => $absence->id, 'absenceid' => $absence->id,
'reason' => $request->reason 'reason' => $request->reason,
]); ]);
return $absence; return $absence;
} }
/** /**
* Sets an absence as Approved. * Sets an absence as Approved.
* *
* @param Absence $absence The absence to approve. * @param Absence $absence The absence to approve.
* @return Absence The approved absence. * @return Absence The approved absence.
*
* @throws AbsenceNotActionableException * @throws AbsenceNotActionableException
*/ */
public function approveAbsence(Absence $absence) public function approveAbsence(Absence $absence)
@ -88,19 +81,19 @@ class AbsenceService
Log::info('An absence request has just been approved.', [ Log::info('An absence request has just been approved.', [
'absenceid' => $absence->id, 'absenceid' => $absence->id,
'reviewing_admim' => Auth::user()->email, 'reviewing_admim' => Auth::user()->email,
'new_status' => 'APPROVED' 'new_status' => 'APPROVED',
]); ]);
$absence->setApproved() $absence->setApproved()
->requester->notify(new AbsenceRequestApproved($absence)); ->requester->notify(new AbsenceRequestApproved($absence));
} }
/** /**
* Sets an absence as Declined. * Sets an absence as Declined.
* *
* @param Absence $absence The absence to decline. * @param Absence $absence The absence to decline.
* @return Absence The declined absence. * @return Absence The declined absence.
*
* @throws AbsenceNotActionableException * @throws AbsenceNotActionableException
*/ */
public function declineAbsence(Absence $absence) public function declineAbsence(Absence $absence)
@ -108,26 +101,26 @@ class AbsenceService
Log::warning('An absence request has just been declined.', [ Log::warning('An absence request has just been declined.', [
'absenceid' => $absence->id, 'absenceid' => $absence->id,
'reviewing_admim' => Auth::user()->email, 'reviewing_admim' => Auth::user()->email,
'new_status' => 'DECLINED' 'new_status' => 'DECLINED',
]); ]);
$absence->setDeclined() $absence->setDeclined()
->requester->notify(new AbsenceRequestDeclined($absence)); ->requester->notify(new AbsenceRequestDeclined($absence));
} }
/** /**
* Sets an absence as Cancelled. * Sets an absence as Cancelled.
* *
* @param Absence $absence The absence to cancel. * @param Absence $absence The absence to cancel.
* @return Absence The cancelled absence. * @return Absence The cancelled absence.
*
* @throws AbsenceNotActionableException * @throws AbsenceNotActionableException
*/ */
public function cancelAbsence(Absence $absence) public function cancelAbsence(Absence $absence)
{ {
Log::warning('An absence request has just been cancelled (only cancellable by requester).', [ Log::warning('An absence request has just been cancelled (only cancellable by requester).', [
'absenceid' => $absence->id, 'absenceid' => $absence->id,
'new_status' => 'CANCELLED' 'new_status' => 'CANCELLED',
]); ]);
$absence->setCancelled() $absence->setCancelled()
@ -144,7 +137,7 @@ class AbsenceService
{ {
Log::info('An absence request has just expired.', [ Log::info('An absence request has just expired.', [
'absenceid' => $absence->id, 'absenceid' => $absence->id,
'new_status' => 'ENDED' 'new_status' => 'ENDED',
]); ]);
$absence->setEnded() $absence->setEnded()
@ -169,20 +162,16 @@ class AbsenceService
/** /**
* End all expired absences in the application * End all expired absences in the application
*
* @return void * @return void
*/ */
public function endExpired(): void public function endExpired(): void
{ {
foreach (Absence::all() as $absence) foreach (Absence::all() as $absence) {
{
// tell the absence we want to check for cancelability // tell the absence we want to check for cancelability
if (! Carbon::parse($absence->predicted_end)->isFuture() && $absence->isActionable(true)) { if (! Carbon::parse($absence->predicted_end)->isFuture() && $absence->isActionable(true)) {
$this->endAbsence($absence); $this->endAbsence($absence);
} }
} }
} }
} }

View File

@ -1,5 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace App\Services; namespace App\Services;
@ -13,7 +14,6 @@ use Illuminate\Support\Facades\Log;
class AccountSuspensionService class AccountSuspensionService
{ {
/** /**
* Suspends a user account, with given $reason. * Suspends a user account, with given $reason.
* Permanent if no duration given. * Permanent if no duration given.
@ -23,12 +23,12 @@ class AccountSuspensionService
* @param int|null $duration Duration in days * @param int|null $duration Duration in days
* @return Ban The ban itself * @return Ban The ban itself
*/ */
public function suspend(User $target, string $reason, int $duration = null): Ban { public function suspend(User $target, string $reason, int $duration = null): Ban
{
Log::alert("An user account has just been suspended.", [ Log::alert('An user account has just been suspended.', [
'taget_email' => $target->email, 'taget_email' => $target->email,
'suspended_by' => Auth::user()->email, 'suspended_by' => Auth::user()->email,
'reason' => $reason 'reason' => $reason,
]); ]);
if ($duration > 0) { if ($duration > 0) {
@ -40,7 +40,7 @@ class AccountSuspensionService
'reason' => $reason, 'reason' => $reason,
'bannedUntil' => ($duration > 0) ? $expiryDate->format('Y-m-d H:i:s') : null, 'bannedUntil' => ($duration > 0) ? $expiryDate->format('Y-m-d H:i:s') : null,
'authorUserID' => Auth::user()->id, 'authorUserID' => Auth::user()->id,
'isPermanent' => ($duration == 0) ? true : false 'isPermanent' => ($duration == 0) ? true : false,
]); ]);
} }
@ -49,9 +49,9 @@ class AccountSuspensionService
* *
* @param User $user The user to unsuspend * @param User $user The user to unsuspend
*/ */
public function unsuspend(User $user): void { public function unsuspend(User $user): void
{
Log::alert("A suspension has just been lifted.", [ Log::alert('A suspension has just been lifted.', [
'target_email' => $user->email, 'target_email' => $user->email,
]); ]);
@ -64,13 +64,11 @@ class AccountSuspensionService
* @param User $user The user to check * @param User $user The user to check
* @return bool Whether the mentioned user is suspended * @return bool Whether the mentioned user is suspended
*/ */
public function isSuspended(User $user): bool { public function isSuspended(User $user): bool
{
return ! is_null($user->bans); return ! is_null($user->bans);
} }
/** /**
* Sets an administrative lock on a user account. * Sets an administrative lock on a user account.
* Used to prevent logins after a deletion process is initiated, but may be used for * Used to prevent logins after a deletion process is initiated, but may be used for
@ -83,7 +81,7 @@ class AccountSuspensionService
public function lockAccount(User $user): bool public function lockAccount(User $user): bool
{ {
Log::alert('User account locked!', [ Log::alert('User account locked!', [
'email' => $user->email 'email' => $user->email,
]); ]);
$user->administratively_locked = 1; $user->administratively_locked = 1;
@ -92,7 +90,6 @@ class AccountSuspensionService
return $user->save(); return $user->save();
} }
/** /**
* Unlocks a user account. Reverse of lockAccount(). * Unlocks a user account. Reverse of lockAccount().
* *
@ -102,7 +99,7 @@ class AccountSuspensionService
public function unlockAccount(User $user): bool public function unlockAccount(User $user): bool
{ {
Log::alert('User account unlocked!', [ Log::alert('User account unlocked!', [
'email' => $user->email 'email' => $user->email,
]); ]);
$user->administratively_locked = 0; $user->administratively_locked = 0;
@ -117,7 +114,8 @@ class AccountSuspensionService
* @param User $user The user to check * @param User $user The user to check
* @return bool Whether the mentioned account is locked * @return bool Whether the mentioned account is locked
*/ */
public function isLocked(User $user): bool { public function isLocked(User $user): bool
{
return $user->administratively_locked == 1; return $user->administratively_locked == 1;
} }
@ -127,11 +125,13 @@ class AccountSuspensionService
* @param User $user The user account to check * @param User $user The user account to check
* @return string|bool Reason for the suspension, false if not suspended * @return string|bool Reason for the suspension, false if not suspended
*/ */
public function getSuspensionReason(User $user): string|bool { public function getSuspensionReason(User $user): string|bool
{
return ($this->isSuspended($user)) ? $user->bans->reason : false; return ($this->isSuspended($user)) ? $user->bans->reason : false;
} }
public function getSuspensionDuration(User $user): string|null { public function getSuspensionDuration(User $user): string|null
{
if ($this->isSuspended($user) && ! is_null($user->bans->bannedUntil)) { if ($this->isSuspended($user) && ! is_null($user->bans->bannedUntil)) {
return $user->bans->bannedUntil->diffForHumans(); return $user->bans->bannedUntil->diffForHumans();
} }
@ -149,6 +149,4 @@ class AccountSuspensionService
// Unban on the last day, not on the exact time (with Carbon::now()). // Unban on the last day, not on the exact time (with Carbon::now()).
return (bool) Ban::whereDate('bannedUntil', '=', Carbon::today())->delete(); return (bool) Ban::whereDate('bannedUntil', '=', Carbon::today())->delete();
} }
} }

View File

@ -1,26 +1,24 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Exceptions\DiscordAccountRequiredException;
use App\Exceptions\IncompatibleAgeException;
use App\Exceptions\InvalidAgeException;
use App\Notifications\ApplicationConfirmed;
use Carbon\Carbon;
use ContextAwareValidator;
use App\Application; use App\Application;
use App\Events\ApplicationDeniedEvent; use App\Events\ApplicationDeniedEvent;
use App\Exceptions\ApplicationNotFoundException; use App\Exceptions\ApplicationNotFoundException;
use App\Exceptions\DiscordAccountRequiredException;
use App\Exceptions\IncompatibleAgeException;
use App\Exceptions\IncompleteApplicationException; use App\Exceptions\IncompleteApplicationException;
use App\Exceptions\InvalidAgeException;
use App\Exceptions\UnavailableApplicationException; use App\Exceptions\UnavailableApplicationException;
use App\Exceptions\VacancyNotFoundException; use App\Exceptions\VacancyNotFoundException;
use App\Notifications\ApplicationConfirmed;
use App\Notifications\ApplicationMoved; use App\Notifications\ApplicationMoved;
use App\Notifications\NewApplicant; use App\Notifications\NewApplicant;
use App\Response; use App\Response;
use App\User; use App\User;
use App\Vacancy; use App\Vacancy;
use Illuminate\Auth\Authenticatable; use Carbon\Carbon;
use ContextAwareValidator;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@ -37,12 +35,11 @@ class ApplicationService
$firstVacancy = $vacancyWithForm->first(); $firstVacancy = $vacancyWithForm->first();
if (is_null(Auth::user()->dob)) { if (is_null(Auth::user()->dob)) {
throw new InvalidAgeException("User must have added their age to apply for this vacancy."); throw new InvalidAgeException('User must have added their age to apply for this vacancy.');
} elseif (Carbon::parse(Auth::user()->dob)->age < $firstVacancy->requiredAge) { } elseif (Carbon::parse(Auth::user()->dob)->age < $firstVacancy->requiredAge) {
throw new IncompatibleAgeException("Sorry, you must be {$firstVacancy->requiredAge} or older to apply to {$firstVacancy->vacancyName}."); throw new IncompatibleAgeException("Sorry, you must be {$firstVacancy->requiredAge} or older to apply to {$firstVacancy->vacancyName}.");
} }
if ($firstVacancy->requiresDiscord && ! Auth::user()->hasDiscordConnection()) { if ($firstVacancy->requiresDiscord && ! Auth::user()->hasDiscordConnection()) {
throw new DiscordAccountRequiredException('A discord account is required beyond this point.'); throw new DiscordAccountRequiredException('A discord account is required beyond this point.');
} }
@ -54,9 +51,7 @@ class ApplicationService
'preprocessedForm' => json_decode($vacancyWithForm->first()->forms->formStructure, true), 'preprocessedForm' => json_decode($vacancyWithForm->first()->forms->formStructure, true),
]); ]);
} else { } else {
throw new ApplicationNotFoundException(__('The application you\'re looking for could not be found or it is currently unavailable.'), 404); throw new ApplicationNotFoundException(__('The application you\'re looking for could not be found or it is currently unavailable.'), 404);
} }
} }
@ -72,14 +67,11 @@ class ApplicationService
$vacancy = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get(); $vacancy = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get();
if ($vacancy->isEmpty()) { if ($vacancy->isEmpty()) {
throw new VacancyNotFoundException('This vacancy doesn\'t exist; Please use the proper buttons to apply to one.', 404); throw new VacancyNotFoundException('This vacancy doesn\'t exist; Please use the proper buttons to apply to one.', 404);
} }
if ($vacancy->first()->vacancyCount == 0 || $vacancy->first()->vacancyStatus !== 'OPEN') { if ($vacancy->first()->vacancyCount == 0 || $vacancy->first()->vacancyStatus !== 'OPEN') {
throw new UnavailableApplicationException('This application is unavailable.');
throw new UnavailableApplicationException("This application is unavailable.");
} }
Log::info('Processing new application!'); Log::info('Processing new application!');
@ -87,7 +79,6 @@ class ApplicationService
$formStructure = json_decode($vacancy->first()->forms->formStructure, true); $formStructure = json_decode($vacancy->first()->forms->formStructure, true);
$responseValidation = ContextAwareValidator::getResponseValidator($formData, $formStructure); $responseValidation = ContextAwareValidator::getResponseValidator($formData, $formStructure);
Log::info('Built response & validator structure!'); Log::info('Built response & validator structure!');
if (! $responseValidation->get('validator')->fails()) { if (! $responseValidation->get('validator')->fails()) {
@ -99,7 +90,7 @@ class ApplicationService
Log::info('Registered form response!', [ Log::info('Registered form response!', [
'applicant' => $applicant->name, 'applicant' => $applicant->name,
'vacancy' => $vacancy->first()->vacancyName 'vacancy' => $vacancy->first()->vacancyName,
]); ]);
$application = Application::create([ $application = Application::create([
@ -110,7 +101,7 @@ class ApplicationService
Log::info('Submitted an application!', [ Log::info('Submitted an application!', [
'responseID' => $response->id, 'responseID' => $response->id,
'applicant' => $applicant->name 'applicant' => $applicant->name,
]); ]);
User::whereHas('roles', function ($q) { User::whereHas('roles', function ($q) {
@ -122,7 +113,6 @@ class ApplicationService
$application->user->notify(new ApplicationConfirmed($application)); $application->user->notify(new ApplicationConfirmed($application));
return true; return true;
} }
Log::warning('Application form for '.$applicant->name.' contained errors, resetting!'); Log::warning('Application form for '.$applicant->name.' contained errors, resetting!');
@ -136,7 +126,7 @@ class ApplicationService
case 'deny': case 'deny':
event(new ApplicationDeniedEvent($application)); event(new ApplicationDeniedEvent($application));
$message = __("Application denied successfully."); $message = __('Application denied successfully.');
break; break;
@ -150,7 +140,7 @@ class ApplicationService
break; break;
default: default:
throw new \LogicException("Wrong status parameter. Please notify a developer."); throw new \LogicException('Wrong status parameter. Please notify a developer.');
} }
return $message; return $message;
@ -164,7 +154,6 @@ class ApplicationService
return $application->delete(); return $application->delete();
} }
public function canVote($votes): bool public function canVote($votes): bool
{ {
$allvotes = collect([]); $allvotes = collect([]);

View File

@ -1,13 +1,10 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Application; use App\Application;
use App\Appointment; use App\Appointment;
use App\Exceptions\InvalidAppointmentStatusException; use App\Exceptions\InvalidAppointmentStatusException;
use App\Notifications\ApplicationMoved;
use App\Notifications\AppointmentCancelled; use App\Notifications\AppointmentCancelled;
use App\Notifications\AppointmentFinished; use App\Notifications\AppointmentFinished;
use App\Notifications\AppointmentScheduled; use App\Notifications\AppointmentScheduled;
@ -53,22 +50,20 @@ class AppointmentService
$application->user->notify(new AppointmentScheduled($appointment)); $application->user->notify(new AppointmentScheduled($appointment));
return true; return true;
} }
/** /**
* Cancels an appointment for the provided application. * Cancels an appointment for the provided application.
* *
* @param Application $application The target application. * @param Application $application The target application.
* @param string $reason The reason for cancelling the appointment. * @param string $reason The reason for cancelling the appointment.
*
* @throws \Exception Thrown when there's no appointment to cancel * @throws \Exception Thrown when there's no appointment to cancel
*/ */
public function deleteAppointment(Application $application, string $reason): bool public function deleteAppointment(Application $application, string $reason): bool
{ {
if (!empty($application->appointment)) if (! empty($application->appointment)) {
{
$application->user->notify(new AppointmentCancelled($application, Carbon::parse($application->appointment->appointmentDate), $reason)); $application->user->notify(new AppointmentCancelled($application, Carbon::parse($application->appointment->appointmentDate), $reason));
$application->appointment->delete(); $application->appointment->delete();
@ -77,14 +72,13 @@ class AppointmentService
Log::info('An interview appointment has just been cancelled.', [ Log::info('An interview appointment has just been cancelled.', [
'actor' => Auth::user()->name, 'actor' => Auth::user()->name,
'applicant' => $application->user->name, 'applicant' => $application->user->name,
'reason' => $reason 'reason' => $reason,
]); ]);
return true; return true;
} }
throw new \Exception("This application doesn't have an appointment!"); throw new \Exception("This application doesn't have an appointment!");
} }
/** /**
@ -97,22 +91,17 @@ class AppointmentService
*/ */
public function updateAppointment(Application $application, $status, $updateApplication = true) public function updateAppointment(Application $application, $status, $updateApplication = true)
{ {
if ($status == 'SCHEDULED' || $status == 'concluded') if ($status == 'SCHEDULED' || $status == 'concluded') {
{
$application->appointment->appointmentStatus = strtoupper($status); $application->appointment->appointmentStatus = strtoupper($status);
$application->appointment->save(); $application->appointment->save();
if ($updateApplication) if ($updateApplication) {
{
$application->setStatus('STAGE_PEERAPPROVAL'); $application->setStatus('STAGE_PEERAPPROVAL');
$application->user->notify(new AppointmentFinished($application->appointment)); $application->user->notify(new AppointmentFinished($application->appointment));
} }
} else {
throw new InvalidAppointmentStatusException('Invalid appointment status!');
} }
else
{
throw new InvalidAppointmentStatusException("Invalid appointment status!");
}
} }
/** /**
@ -122,5 +111,4 @@ class AppointmentService
{ {
return $this->allowedPlatforms; return $this->allowedPlatforms;
} }
} }

View File

@ -1,17 +1,15 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Application; use App\Application;
use App\Comment; use App\Comment;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
class CommentService class CommentService
{ {
public function addComment(Application $application, $comment): Comment
public function addComment(Application $application, $comment): Comment { {
return Comment::create([ return Comment::create([
'authorID' => Auth::user()->id, 'authorID' => Auth::user()->id,
'applicationID' => $application->id, 'applicationID' => $application->id,
@ -23,5 +21,4 @@ class CommentService
{ {
return $comment->delete(); return $comment->delete();
} }
} }

View File

@ -1,28 +1,21 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Exceptions\InvalidGamePreferenceException; use App\Exceptions\InvalidGamePreferenceException;
use App\Exceptions\OptionNotFoundException; use App\Exceptions\OptionNotFoundException;
use App\Facades\Options; use App\Facades\Options;
use Illuminate\Auth\Authenticatable;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class ConfigurationService class ConfigurationService
{ {
/** /**
* @throws OptionNotFoundException|\Exception * @throws OptionNotFoundException|\Exception
*
*/ */
public function saveConfiguration($configuration) { public function saveConfiguration($configuration)
{
foreach ($configuration as $optionName => $option) { foreach ($configuration as $optionName => $option) {
try { try {
Log::debug('Going through option '.$optionName); Log::debug('Going through option '.$optionName);
if (Options::optionExists($optionName)) { if (Options::optionExists($optionName)) {
Log::debug('Option exists, updating to new values', [ Log::debug('Option exists, updating to new values', [
@ -31,9 +24,7 @@ class ConfigurationService
]); ]);
Options::changeOption($optionName, $option); Options::changeOption($optionName, $option);
} }
} catch (\Exception $ex) { } catch (\Exception $ex) {
Log::error('Unable to update options!', [ Log::error('Unable to update options!', [
'msg' => $ex->getMessage(), 'msg' => $ex->getMessage(),
'trace' => $ex->getTraceAsString(), 'trace' => $ex->getTraceAsString(),
@ -49,27 +40,26 @@ class ConfigurationService
* Saves the chosen game integration * Saves the chosen game integration
* *
* @throws InvalidGamePreferenceException * @throws InvalidGamePreferenceException
*
* @returns bool * @returns bool
*/ */
public function saveGameIntegration($gamePreference): bool public function saveGameIntegration($gamePreference): bool
{ {
// TODO: Find solution to dynamically support games // TODO: Find solution to dynamically support games
$supportedGames = [ $supportedGames = [
'RUST', 'RUST',
'MINECRAFT', 'MINECRAFT',
'SE', 'SE',
'GMOD' 'GMOD',
]; ];
if (!is_null($gamePreference) && in_array($gamePreference, $supportedGames)) if (! is_null($gamePreference) && in_array($gamePreference, $supportedGames)) {
{
Options::changeOption('currentGame', $gamePreference); Options::changeOption('currentGame', $gamePreference);
return true; return true;
} }
throw new InvalidGamePreferenceException("Unsupported game " . $gamePreference); throw new InvalidGamePreferenceException('Unsupported game '.$gamePreference);
} }
} }

View File

@ -1,9 +1,7 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Exceptions\FailedCaptchaException; use App\Exceptions\FailedCaptchaException;
use App\Notifications\NewContact; use App\Notifications\NewContact;
use App\User; use App\User;
@ -11,7 +9,6 @@ use Illuminate\Support\Facades\Http;
class ContactService class ContactService
{ {
/** /**
* Sends a message to all admins. * Sends a message to all admins.
* *
@ -42,6 +39,4 @@ class ContactService
} }
} }
} }
} }

View File

@ -1,11 +1,11 @@
<?php <?php
namespace App\Services; namespace App\Services;
class DemoService { class DemoService
{
public function isDemoEnabled(): bool { public function isDemoEnabled(): bool
{
return config('demo.is_enabled'); return config('demo.is_enabled');
} }
} }

View File

@ -4,19 +4,19 @@ namespace App\Services;
use App\User; use App\User;
use Illuminate\Http\Client\RequestException; use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
class DiscordService class DiscordService
{ {
/** /**
* Sends a token revocation request to Discord to invalidate a specific $user's tokens. * Sends a token revocation request to Discord to invalidate a specific $user's tokens.
* Please ensure you have the user set a password for their account after this, or request new tokens. * Please ensure you have the user set a password for their account after this, or request new tokens.
* *
* @see https://www.rfc-editor.org/rfc/rfc7009 * @see https://www.rfc-editor.org/rfc/rfc7009
*
* @param User $user * @param User $user
* @return bool * @return bool
*
* @throws RequestException * @throws RequestException
*/ */
public function revokeAccountTokens(User $user): bool public function revokeAccountTokens(User $user): bool
@ -27,8 +27,6 @@ class DiscordService
'token' => $user->discord_token, 'token' => $user->discord_token,
])->throw(); ])->throw();
$user->discord_token = null; $user->discord_token = null;
$user->discord_user_id = null; $user->discord_user_id = null;
$user->discord_refresh_token = null; $user->discord_refresh_token = null;
@ -37,6 +35,4 @@ class DiscordService
return $req->ok(); return $req->ok();
} }
} }

View File

@ -1,6 +1,5 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Exceptions\EmptyFormException; use App\Exceptions\EmptyFormException;
@ -10,9 +9,8 @@ use ContextAwareValidator;
class FormManagementService class FormManagementService
{ {
public function addForm($fields)
public function addForm($fields) { {
if (count($fields) == 2) { if (count($fields) == 2) {
// form is probably empty, since forms with fields will always have more than 2 items // form is probably empty, since forms with fields will always have more than 2 items
throw new EmptyFormException('Sorry, but you may not create empty forms.'); throw new EmptyFormException('Sorry, but you may not create empty forms.');
@ -30,13 +28,15 @@ class FormManagementService
'formStatus' => 'ACTIVE', 'formStatus' => 'ACTIVE',
] ]
); );
return true; return true;
} }
return $contextValidation->get('validator')->errors()->getMessages(); return $contextValidation->get('validator')->errors()->getMessages();
} }
public function deleteForm(Form $form) { public function deleteForm(Form $form)
{
$deletable = true; $deletable = true;
if (! is_null($form->vacancies) && $form->vacancies->count() !== 0 || ! is_null($form->responses)) { if (! is_null($form->vacancies) && $form->vacancies->count() !== 0 || ! is_null($form->responses)) {
@ -44,19 +44,16 @@ class FormManagementService
} }
if ($deletable) { if ($deletable) {
$form->delete(); $form->delete();
return true; return true;
} else { } else {
throw new FormHasConstraintsException(__('You cannot delete this form because it\'s tied to one or more applications and ranks, or because it doesn\'t exist.')); throw new FormHasConstraintsException(__('You cannot delete this form because it\'s tied to one or more applications and ranks, or because it doesn\'t exist.'));
} }
} }
public function updateForm(Form $form, $fields) { public function updateForm(Form $form, $fields)
{
$contextValidation = ContextAwareValidator::getValidator($fields, true); $contextValidation = ContextAwareValidator::getValidator($fields, true);
if (! $contextValidation->get('validator')->fails()) { if (! $contextValidation->get('validator')->fails()) {
@ -67,10 +64,8 @@ class FormManagementService
$form->save(); $form->save();
return $form; return $form;
} else { } else {
return $contextValidation->get('validator')->errors()->getMessages(); return $contextValidation->get('validator')->errors()->getMessages();
} }
} }
} }

View File

@ -1,9 +1,7 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Application; use App\Application;
use App\Exceptions\InvalidAppointmentException; use App\Exceptions\InvalidAppointmentException;
@ -15,10 +13,11 @@ class MeetingNoteService
* @param Application $application * @param Application $application
* @param $noteText * @param $noteText
* @return bool * @return bool
*
* @throws InvalidAppointmentException Thrown when an application doesn't have an appointment to save notes to * @throws InvalidAppointmentException Thrown when an application doesn't have an appointment to save notes to
*/ */
public function addToApplication(Application $application, $noteText): bool { public function addToApplication(Application $application, $noteText): bool
{
if (! is_null($application)) { if (! is_null($application)) {
$application->load('appointment'); $application->load('appointment');
@ -26,11 +25,8 @@ class MeetingNoteService
$application->appointment->save(); $application->appointment->save();
return true; return true;
} else { } else {
throw new InvalidAppointmentException('There\'s no appointment to save notes to!'); throw new InvalidAppointmentException('There\'s no appointment to save notes to!');
} }
} }
} }

View File

@ -1,33 +1,29 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Exceptions\ProfileAlreadyExistsException; use App\Exceptions\ProfileAlreadyExistsException;
use App\Exceptions\ProfileCreationFailedException; use App\Exceptions\ProfileCreationFailedException;
use App\Exceptions\ProfileNotFoundException; use App\Exceptions\ProfileNotFoundException;
use App\Profile; use App\Profile;
use App\User; use App\User;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class ProfileService class ProfileService
{ {
/** /**
* Creates a new profile for the specified $targetUser. * Creates a new profile for the specified $targetUser.
* *
* @param User $targetUser The user to create the profile for. * @param User $targetUser The user to create the profile for.
* @return bool * @return bool
*
* @throws ProfileAlreadyExistsException * @throws ProfileAlreadyExistsException
* @throws ProfileCreationFailedException * @throws ProfileCreationFailedException
*/ */
public function createProfile(User $targetUser): Profile { public function createProfile(User $targetUser): Profile
{
if (is_null($targetUser->profile)) { if (is_null($targetUser->profile)) {
$profile = Profile::create([ $profile = Profile::create([
'profileShortBio' => 'Write a one-liner about you here!', 'profileShortBio' => 'Write a one-liner about you here!',
@ -42,7 +38,7 @@ class ProfileService
} }
Log::info('Created profile for new user', [ Log::info('Created profile for new user', [
'userid' => $targetUser->id 'userid' => $targetUser->id,
]); ]);
return $profile; return $profile;
@ -56,7 +52,8 @@ class ProfileService
* *
* @throws ProfileNotFoundException * @throws ProfileNotFoundException
*/ */
public function updateProfile($userID, Request $request) { public function updateProfile($userID, Request $request)
{
$profile = User::find($userID)->profile; $profile = User::find($userID)->profile;
$social = []; $social = [];
@ -85,7 +82,7 @@ class ProfileService
return $profile->save(); return $profile->save();
} }
throw new ProfileNotFoundException("This profile does not exist."); throw new ProfileNotFoundException('This profile does not exist.');
} }
/** /**
@ -93,15 +90,14 @@ class ProfileService
* *
* @param User $targetUser * @param User $targetUser
* @return bool * @return bool
*
* @throws ProfileNotFoundException * @throws ProfileNotFoundException
*/ */
public function deleteProfile(User $targetUser): bool public function deleteProfile(User $targetUser): bool
{ {
if (! is_null($targetUser->profile)) { if (! is_null($targetUser->profile)) {
Log::alert('Deleted user profile', [ Log::alert('Deleted user profile', [
'userid' => $targetUser->id 'userid' => $targetUser->id,
]); ]);
return $targetUser->profile->delete(); return $targetUser->profile->delete();
@ -109,5 +105,4 @@ class ProfileService
throw new ProfileNotFoundException(__('Attempting to delete non-existant profile!')); throw new ProfileNotFoundException(__('Attempting to delete non-existant profile!'));
} }
} }

View File

@ -1,15 +1,12 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Facades\Options; use App\Facades\Options;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class SecuritySettingsService class SecuritySettingsService
{ {
/** /**
* Saves the app security settings. * Saves the app security settings.
* *
@ -17,28 +14,25 @@ class SecuritySettingsService
* @param array $options * @param array $options
* @return bool * @return bool
*/ */
public function save($policy, $options = []) { public function save($policy, $options = [])
{
$validPolicies = [ $validPolicies = [
'off', 'off',
'low', 'low',
'medium', 'medium',
'high' 'high',
]; ];
if (in_array($policy, $validPolicies)) if (in_array($policy, $validPolicies)) {
{
Options::changeOption('pw_security_policy', $policy); Options::changeOption('pw_security_policy', $policy);
Log::debug('[Options] Changing option pw_security_policy', [ Log::debug('[Options] Changing option pw_security_policy', [
'new_value' => $policy 'new_value' => $policy,
]); ]);
} } else {
else
{
Log::debug('[WARN] Ignoring bogus policy', [ Log::debug('[WARN] Ignoring bogus policy', [
'avaliable' => $validPolicies, 'avaliable' => $validPolicies,
'given' => $policy 'given' => $policy,
]); ]);
} }
@ -48,7 +42,5 @@ class SecuritySettingsService
Options::changeOption('requireGameLicense', $options['requirePMC']); Options::changeOption('requireGameLicense', $options['requirePMC']);
return true; return true;
} }
} }

View File

@ -1,19 +1,15 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Exceptions\FileUploadException; use App\Exceptions\FileUploadException;
use App\TeamFile; use App\TeamFile;
use Illuminate\Http\UploadedFile; use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Auth;
class TeamFileService class TeamFileService
{ {
public function addFile(UploadedFile $upload, $uploader, $team, $caption, $description)
public function addFile(UploadedFile $upload, $uploader, $team, $caption, $description) { {
$file = $upload->store('uploads'); $file = $upload->store('uploads');
$originalFileName = $upload->getClientOriginalName(); $originalFileName = $upload->getClientOriginalName();
$originalFileExtension = $upload->extension(); $originalFileExtension = $upload->extension();
@ -27,16 +23,13 @@ class TeamFileService
'description' => $description, 'description' => $description,
'fs_location' => $file, 'fs_location' => $file,
'extension' => $originalFileExtension, 'extension' => $originalFileExtension,
'size' => $originalFileSize 'size' => $originalFileSize,
]); ]);
if ($fileEntry && !is_bool($file)) if ($fileEntry && ! is_bool($file)) {
{
return $fileEntry; return $fileEntry;
} }
throw new FileUploadException("There was an unknown error whilst trying to upload your file."); throw new FileUploadException('There was an unknown error whilst trying to upload your file.');
} }
} }

View File

@ -1,9 +1,7 @@
<?php <?php
namespace App\Services; namespace App\Services;
use App\Exceptions\InvalidInviteException; use App\Exceptions\InvalidInviteException;
use App\Exceptions\PublicTeamInviteException; use App\Exceptions\PublicTeamInviteException;
use App\Exceptions\UserAlreadyInvitedException; use App\Exceptions\UserAlreadyInvitedException;
@ -18,7 +16,6 @@ use Mpociot\Teamwork\TeamInvite;
class TeamService class TeamService
{ {
/** /**
* Create a team * Create a team
* *
@ -26,8 +23,8 @@ class TeamService
* @param $ownerID * @param $ownerID
* @return Team * @return Team
*/ */
public function createTeam($teamName, $ownerID): Team { public function createTeam($teamName, $ownerID): Team
{
$team = Team::create([ $team = Team::create([
'name' => $teamName, 'name' => $teamName,
'owner_id' => $ownerID, 'owner_id' => $ownerID,
@ -40,7 +37,6 @@ class TeamService
public function updateTeam(Team $team, $teamDescription, $joinType): bool public function updateTeam(Team $team, $teamDescription, $joinType): bool
{ {
$team->description = $teamDescription; $team->description = $teamDescription;
$team->openJoin = $joinType; $team->openJoin = $joinType;
@ -55,7 +51,6 @@ class TeamService
*/ */
public function inviteUser(Team $team, $userID): bool public function inviteUser(Team $team, $userID): bool
{ {
$user = User::findOrFail($userID); $user = User::findOrFail($userID);
if (! $team->openJoin) { if (! $team->openJoin) {
@ -63,6 +58,7 @@ class TeamService
Teamwork::inviteToTeam($user, $team, function (TeamInvite $invite) use ($user) { Teamwork::inviteToTeam($user, $team, function (TeamInvite $invite) use ($user) {
Mail::to($user)->send(new InviteToTeam($invite)); Mail::to($user)->send(new InviteToTeam($invite));
}); });
return true; return true;
} else { } else {
throw new UserAlreadyInvitedException('This user has already been invited.'); throw new UserAlreadyInvitedException('This user has already been invited.');
@ -70,7 +66,6 @@ class TeamService
} else { } else {
throw new PublicTeamInviteException('You can\'t invite users to public teams.'); throw new PublicTeamInviteException('You can\'t invite users to public teams.');
} }
} }
/** /**
@ -80,10 +75,11 @@ class TeamService
* @param $action * @param $action
* @param $token * @param $token
* @return bool True on success or exception on failure * @return bool True on success or exception on failure
*
* @throws InvalidInviteException Thrown when the invite code / url is invalid * @throws InvalidInviteException Thrown when the invite code / url is invalid
*/ */
public function processInvite(Authenticatable $user, $action, $token): bool { public function processInvite(Authenticatable $user, $action, $token): bool
{
switch ($action) { switch ($action) {
case 'accept': case 'accept':
@ -91,9 +87,7 @@ class TeamService
if ($invite && $invite->user->is($user)) { if ($invite && $invite->user->is($user)) {
Teamwork::acceptInvite($invite); Teamwork::acceptInvite($invite);
} else { } else {
throw new InvalidInviteException('Invalid or expired invite URL.'); throw new InvalidInviteException('Invalid or expired invite URL.');
} }
@ -104,11 +98,8 @@ class TeamService
$invite = Teamwork::getInviteFromDenyToken($token); $invite = Teamwork::getInviteFromDenyToken($token);
if ($invite && $invite->user->is($user)) { if ($invite && $invite->user->is($user)) {
Teamwork::denyInvite($invite); Teamwork::denyInvite($invite);
} else { } else {
throw new InvalidInviteException('Invalid or expired invite URL.'); throw new InvalidInviteException('Invalid or expired invite URL.');
} }
@ -119,10 +110,8 @@ class TeamService
} }
return true; return true;
} }
/** /**
* @param Team $team * @param Team $team
* @param $associatedVacancies * @param $associatedVacancies
@ -130,7 +119,6 @@ class TeamService
*/ */
public function updateVacancies(Team $team, $associatedVacancies): string public function updateVacancies(Team $team, $associatedVacancies): string
{ {
// P.S. To future developers // P.S. To future developers
// This method gave me a lot of trouble lol. It's hard to write code when you're half asleep. // This method gave me a lot of trouble lol. It's hard to write code when you're half asleep.
// There may be an n+1 query in the view and I don't think there's a way to avoid that without writing a lot of extra code. // There may be an n+1 query in the view and I don't think there's a way to avoid that without writing a lot of extra code.
@ -160,6 +148,7 @@ class TeamService
} else { } else {
$team->vacancies()->attach($requestVacancies); $team->vacancies()->attach($requestVacancies);
} }
return 'Assignments changed successfully.'; return 'Assignments changed successfully.';
} }
} }

View File

@ -37,8 +37,6 @@ class Team extends TeamworkTeam
return $this->belongsToMany('App\Vacancy', 'team_has_vacancy'); return $this->belongsToMany('App\Vacancy', 'team_has_vacancy');
} }
public function files() public function files()
{ {
return $this->hasMany('App\TeamFile', 'team_id'); return $this->hasMany('App\TeamFile', 'team_id');

View File

@ -11,7 +11,6 @@ class TeamFile extends Model
{ {
use HasFactory, UsedByTeams; use HasFactory, UsedByTeams;
protected $fillable = [ protected $fillable = [
'uploaded_by', 'uploaded_by',
'team_id', 'team_id',
@ -20,7 +19,7 @@ class TeamFile extends Model
'extension', 'extension',
'size', 'size',
'caption', 'caption',
'description' 'description',
]; ];
public function uploader() public function uploader()
@ -33,7 +32,6 @@ class TeamFile extends Model
return $this->belongsTo('App\Team'); return $this->belongsTo('App\Team');
} }
public function getSizeAttribute($value) public function getSizeAttribute($value)
{ {
return DigitalStorageHelper::setValue($value)->formatBytes(2, true); return DigitalStorageHelper::setValue($value)->formatBytes(2, true);

View File

@ -37,7 +37,7 @@ trait Cancellable
} }
Log::debug('Cancellable: current channels list', [ Log::debug('Cancellable: current channels list', [
'channels' => $channels 'channels' => $channels,
]); ]);
return $channels; return $channels;

View File

@ -6,7 +6,6 @@ use Illuminate\Http\RedirectResponse;
trait DisablesFeatures trait DisablesFeatures
{ {
/** /**
* Checks if demo mode is active. If so, it stops any more logic from running. * Checks if demo mode is active. If so, it stops any more logic from running.
* *
@ -19,7 +18,7 @@ trait DisablesFeatures
->back() ->back()
->with('error', __('This feature is disabled')); ->with('error', __('This feature is disabled'));
} }
return null; return null;
} }
} }

View File

@ -35,7 +35,6 @@ use Illuminate\Support\Facades\URL;
trait HandlesAccountDeletion trait HandlesAccountDeletion
{ {
/** /**
* Starts the user account deletion process. * Starts the user account deletion process.
* *
@ -45,8 +44,7 @@ trait HandlesAccountDeletion
*/ */
public function userDelete(AccountSuspensionService $suspensionService, UserDeleteRequest $request) public function userDelete(AccountSuspensionService $suspensionService, UserDeleteRequest $request)
{ {
if (config('demo.is_enabled')) if (config('demo.is_enabled')) {
{
return redirect() return redirect()
->back() ->back()
->with('error', 'This feature is disabled'); ->with('error', 'This feature is disabled');
@ -58,7 +56,7 @@ trait HandlesAccountDeletion
), ),
'cancelURL' => URL::temporarySignedRoute( 'cancelURL' => URL::temporarySignedRoute(
'processDeleteConfirmation', now()->addDays(7), ['accountID' => $request->user()->id, 'action' => 'cancel'] 'processDeleteConfirmation', now()->addDays(7), ['accountID' => $request->user()->id, 'action' => 'cancel']
) ),
]; ];
Mail::to($request->user()) Mail::to($request->user())
@ -69,10 +67,10 @@ trait HandlesAccountDeletion
Auth::logout(); Auth::logout();
$request->session()->flash('success', __('Please check your email to finish deleting your account.')); $request->session()->flash('success', __('Please check your email to finish deleting your account.'));
return redirect()->to('/'); return redirect()->to('/');
} }
/** /**
* Dispatches the correct jobs and events to delete the specified user account * Dispatches the correct jobs and events to delete the specified user account
* *
@ -84,8 +82,7 @@ trait HandlesAccountDeletion
*/ */
public function processDeleteConfirmation(Request $request, AccountSuspensionService $suspensionService, $accountID, $action) public function processDeleteConfirmation(Request $request, AccountSuspensionService $suspensionService, $accountID, $action)
{ {
if (config('demo.is_enabled') || !$request->hasValidSignature()) if (config('demo.is_enabled') || ! $request->hasValidSignature()) {
{
abort(403); abort(403);
} }
@ -93,8 +90,7 @@ trait HandlesAccountDeletion
// The request URL can't be tampered with and the request can't be initiated without a valid account in the first place // The request URL can't be tampered with and the request can't be initiated without a valid account in the first place
$account = User::find($accountID); $account = User::find($accountID);
if (!is_null($account)) if (! is_null($account)) {
{
if (! $suspensionService->isLocked($account)) { if (! $suspensionService->isLocked($account)) {
abort(403); abort(403);
} }
@ -125,13 +121,11 @@ trait HandlesAccountDeletion
return redirect() return redirect()
->route('login'); ->route('login');
} }
Log::error("Cannot delete account that doesn't exist!", [ Log::error("Cannot delete account that doesn't exist!", [
'validSignature' => $request->hasValidSignature() 'validSignature' => $request->hasValidSignature(),
]); ]);
abort(400); abort(400);
} }
} }

View File

@ -44,7 +44,6 @@ class UUID
// Note: Caching could simply be assigning the username to it's UUID, however, to make this work, we'd need to loop over all cache items, which would be slighly ineffective // Note: Caching could simply be assigning the username to it's UUID, however, to make this work, we'd need to loop over all cache items, which would be slighly ineffective
public function toUsername(string $uuid) public function toUsername(string $uuid)
{ {
$shortUUID = substr($uuid, 0, 8); $shortUUID = substr($uuid, 0, 8);
$username = Cache::remember('uuid_'.$shortUUID, now()->addDays(30), function () use ($shortUUID, $uuid) { $username = Cache::remember('uuid_'.$shortUUID, now()->addDays(30), function () use ($shortUUID, $uuid) {
$response = json_decode(Http::get(trim(config('general.urls.mojang.session')).'/session/minecraft/profile/'.$uuid)->body(), true); $response = json_decode(Http::get(trim(config('general.urls.mojang.session')).'/session/minecraft/profile/'.$uuid)->body(), true);

View File

@ -21,18 +21,10 @@
namespace App; namespace App;
use App\Services\AccountSuspensionService;
use App\Traits\HandlesAccountTokens;
use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\View;
use Mpociot\Teamwork\Traits\UserHasTeams; use Mpociot\Teamwork\Traits\UserHasTeams;
use Spatie\Permission\Traits\HasRoles; use Spatie\Permission\Traits\HasRoles;
@ -58,7 +50,7 @@ class User extends Authenticatable implements MustVerifyEmail
'currentIp', 'currentIp',
'discord_user_id', 'discord_user_id',
'discord_token', 'discord_token',
'discord_refresh_token' 'discord_refresh_token',
]; ];
/** /**
@ -67,7 +59,7 @@ class User extends Authenticatable implements MustVerifyEmail
* @var array * @var array
*/ */
protected $hidden = [ protected $hidden = [
'password', 'remember_token', 'discord_token', 'discord_refresh_token' 'password', 'remember_token', 'discord_token', 'discord_refresh_token',
]; ];
/** /**
@ -78,7 +70,7 @@ class User extends Authenticatable implements MustVerifyEmail
protected $casts = [ protected $casts = [
'email_verified_at' => 'datetime', 'email_verified_at' => 'datetime',
'discord_token' => 'encrypted', 'discord_token' => 'encrypted',
'discord_refresh_token' => 'encrypted' 'discord_refresh_token' => 'encrypted',
]; ];
// RELATIONSHIPS // RELATIONSHIPS
@ -91,7 +83,6 @@ class User extends Authenticatable implements MustVerifyEmail
public function votes() public function votes()
{ {
return $this->hasMany('App\Vote', 'userID', 'id'); return $this->hasMany('App\Vote', 'userID', 'id');
} }
public function profile() public function profile()
@ -119,8 +110,8 @@ class User extends Authenticatable implements MustVerifyEmail
return $this->hasMany('App\Absence', 'requesterID'); return $this->hasMany('App\Absence', 'requesterID');
} }
public function isEligible(): bool
public function isEligible(): bool { {
$lastApplication = Application::where('applicantUserID', $this->getAttribute('id'))->latest()->first(); $lastApplication = Application::where('applicantUserID', $this->getAttribute('id'))->latest()->first();
if (is_null($lastApplication)) { if (is_null($lastApplication)) {
@ -134,8 +125,8 @@ class User extends Authenticatable implements MustVerifyEmail
return false; return false;
} }
public function isVerified(): bool
public function isVerified(): bool { {
return ! is_null($this->email_verified_at); return ! is_null($this->email_verified_at);
} }
@ -143,6 +134,7 @@ class User extends Authenticatable implements MustVerifyEmail
* Checks if user is staff * Checks if user is staff
* *
* @deprecated This method is being replaced by a better way of checking permissions, rather than checking for group name. * @deprecated This method is being replaced by a better way of checking permissions, rather than checking for group name.
*
* @return bool * @return bool
*/ */
public function isStaffMember(): bool public function isStaffMember(): bool
@ -168,12 +160,9 @@ class User extends Authenticatable implements MustVerifyEmail
*/ */
public function hasTeam($team): bool public function hasTeam($team): bool
{ {
if ($team instanceof Team || is_int($team)) if ($team instanceof Team || is_int($team)) {
{
return $this->teams->contains($team); return $this->teams->contains($team);
} } else {
else
{
/** /**
* In PHP 8, we can just use union types and let PHP enforce this for us. * In PHP 8, we can just use union types and let PHP enforce this for us.
*/ */
@ -186,18 +175,18 @@ class User extends Authenticatable implements MustVerifyEmail
* *
* @return bool * @return bool
*/ */
public function hasDiscordConnection(): bool { public function hasDiscordConnection(): bool
{
return ! is_null($this->discord_token) && ! is_null($this->discord_refresh_token); return ! is_null($this->discord_token) && ! is_null($this->discord_refresh_token);
} }
/** /**
* Check if user has a password * Check if user has a password
* *
* @return bool * @return bool
*/ */
public function hasPassword(): bool { public function hasPassword(): bool
{
return ! is_null($this->password); return ! is_null($this->password);
} }
} }

View File

@ -45,7 +45,7 @@ class Vacancy extends Model
'vacancySlug', 'vacancySlug',
'team_id', 'team_id',
'requiresDiscord', 'requiresDiscord',
'requiredAge' 'requiredAge',
]; ];
@ -94,15 +94,14 @@ class Vacancy extends Model
public function decrease() public function decrease()
{ {
if ($this->vacancyCount !== 0) if ($this->vacancyCount !== 0) {
{
$this->update([ $this->update([
'vacancyCount' => $this->vacancyCount - 1 'vacancyCount' => $this->vacancyCount - 1,
]); ]);
Log::info('Vacancies: Decreased vacancy slots by one.', [ Log::info('Vacancies: Decreased vacancy slots by one.', [
'vacancyId' => $this->id, 'vacancyId' => $this->id,
'vacancyName' => $this->vacancyName 'vacancyName' => $this->vacancyName,
]); ]);
} }
} }

View File

@ -2,17 +2,26 @@
namespace App\View\Components; namespace App\View\Components;
use App\User;
use Illuminate\View\Component; use Illuminate\View\Component;
class AccountStatus extends Component class AccountStatus extends Component
{ {
public bool public bool
$isVerified, $isVerified;
$isSuspended,
$isLocked, public bool
$has2FA, $isSuspended;
$hasDiscord,
public bool
$isLocked;
public bool
$has2FA;
public bool
$hasDiscord;
public bool
$hasPassword; $hasPassword;
/** /**

View File

@ -25,11 +25,13 @@ use Illuminate\View\Component;
class Alert extends Component class Alert extends Component
{ {
public public $alertType;
$alertType,
$extraStyling, public $extraStyling;
$title,
$icon; public $title;
public $icon;
/** /**
* Create a new component instance. * Create a new component instance.

View File

@ -7,13 +7,27 @@ use Illuminate\View\Component;
class Button extends Component class Button extends Component
{ {
public string public string
$type, $type;
$icon,
$link, public string
$target, $icon;
$size,
$color, public string
$disabled, $link;
public string
$target;
public string
$size;
public string
$color;
public string
$disabled;
public string
$id; $id;
public function __construct($id, $color, $type = 'button', $disabled = false, $size = '', $target = '', $link = '', $icon = '') public function __construct($id, $color, $type = 'button', $disabled = false, $size = '', $target = '', $link = '', $icon = '')

View File

@ -40,6 +40,7 @@
"barryvdh/laravel-debugbar": "^3.3", "barryvdh/laravel-debugbar": "^3.3",
"barryvdh/laravel-ide-helper": "^2.12", "barryvdh/laravel-ide-helper": "^2.12",
"fakerphp/faker": "^1.19", "fakerphp/faker": "^1.19",
"laravel/pint": "^1.4",
"laravel/sail": "^1.15", "laravel/sail": "^1.15",
"mockery/mockery": "^1.3.1", "mockery/mockery": "^1.3.1",
"nunomaduro/collision": "^6.1", "nunomaduro/collision": "^6.1",

68
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "04e34fbbef2bf9b12382145e6a9f4fb4", "content-hash": "9ebe2207f617199a090bd8d2c19e1597",
"packages": [ "packages": [
{ {
"name": "almasaeed2010/adminlte", "name": "almasaeed2010/adminlte",
@ -9740,6 +9740,72 @@
], ],
"time": "2022-01-07T12:00:00+00:00" "time": "2022-01-07T12:00:00+00:00"
}, },
{
"name": "laravel/pint",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "0e7ffdb0af871be10d798e234772ea5d4020ae4a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/0e7ffdb0af871be10d798e234772ea5d4020ae4a",
"reference": "0e7ffdb0af871be10d798e234772ea5d4020ae4a",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"ext-tokenizer": "*",
"ext-xml": "*",
"php": "^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~3.13.1",
"illuminate/view": "^9.32.0",
"laravel-zero/framework": "^9.2.0",
"mockery/mockery": "^1.5.1",
"nunomaduro/larastan": "^2.2.0",
"nunomaduro/termwind": "^1.14.0",
"pestphp/pest": "^1.22.1"
},
"bin": [
"builds/pint"
],
"type": "project",
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Seeders\\": "database/seeders/",
"Database\\Factories\\": "database/factories/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nuno Maduro",
"email": "enunomaduro@gmail.com"
}
],
"description": "An opinionated code formatter for PHP.",
"homepage": "https://laravel.com",
"keywords": [
"format",
"formatter",
"lint",
"linter",
"php"
],
"support": {
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2023-01-10T20:03:42+00:00"
},
{ {
"name": "laravel/sail", "name": "laravel/sail",
"version": "v1.15.4", "version": "v1.15.4",

View File

@ -235,7 +235,7 @@ return [
[ [
'text' => 'Dashboard', 'text' => 'Dashboard',
'icon' => 'fas fa-tachometer-alt', 'icon' => 'fas fa-tachometer-alt',
'url' => '/dashboard' 'url' => '/dashboard',
], ],
[ [
'header' => 'h_applications', 'header' => 'h_applications',
@ -269,7 +269,7 @@ return [
], ],
[ [
'header' => 'Human Resources', 'header' => 'Human Resources',
'can' => 'reviewer.requestAbsence' 'can' => 'reviewer.requestAbsence',
], ],
[ [
'text' => 'Absence Management', 'text' => 'Absence Management',
@ -280,13 +280,13 @@ return [
'text' => 'New request', 'text' => 'New request',
'icon' => 'fas fa-plus', 'icon' => 'fas fa-plus',
'can' => 'reviewer.requestAbsence', 'can' => 'reviewer.requestAbsence',
'route' => 'absences.create' 'route' => 'absences.create',
], ],
[ [
'text' => 'My requests', 'text' => 'My requests',
'icon' => 'fas fa-business-time', 'icon' => 'fas fa-business-time',
'can' => 'reviewer.viewAbsence', 'can' => 'reviewer.viewAbsence',
'route' => 'showUserAbsences' 'route' => 'showUserAbsences',
], ],
], ],
@ -295,7 +295,7 @@ return [
'text' => 'Absence requests', 'text' => 'Absence requests',
'icon' => 'fas fa-address-card', 'icon' => 'fas fa-address-card',
'can' => 'admin.manageAbsences', 'can' => 'admin.manageAbsences',
'route' => 'absences.index' 'route' => 'absences.index',
], ],
[ [
'header' => 'h_app_management', 'header' => 'h_app_management',
@ -317,15 +317,15 @@ return [
'text' => 'Available Teams', 'text' => 'Available Teams',
'icon' => 'fas fa-clipboard', 'icon' => 'fas fa-clipboard',
'url' => 'teams', 'url' => 'teams',
'can' => 'teams.view' 'can' => 'teams.view',
], ],
[ [
'text' => 'Files', 'text' => 'Files',
'icon' => 'fas fa-file-alt', 'icon' => 'fas fa-file-alt',
'url' => 'team/files', 'url' => 'team/files',
'can' => 'teams.view' 'can' => 'teams.view',
],
], ],
]
], ],
[ [
'header' => 'h_admin', 'header' => 'h_admin',
@ -624,14 +624,14 @@ return [
[ [
'type' => 'css', 'type' => 'css',
'asset' => false, 'asset' => false,
'location' => 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css' 'location' => 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css',
], ],
[ [
'type' => 'js', 'type' => 'js',
'asset' => false, 'asset' => false,
'location' => 'https://cdn.jsdelivr.net/npm/flatpickr' 'location' => 'https://cdn.jsdelivr.net/npm/flatpickr',
] ],
] ],
], ],
[ [
'name' => 'Pusher', 'name' => 'Pusher',
@ -640,9 +640,9 @@ return [
[ [
'type' => 'js', 'type' => 'js',
'asset' => false, 'asset' => false,
'location' => 'https://js.pusher.com/beams/1.0/push-notifications-cdn.js' 'location' => 'https://js.pusher.com/beams/1.0/push-notifications-cdn.js',
] ],
] ],
] ],
], ],
]; ];

View File

@ -46,9 +46,6 @@ return [
*/ */
'sitehomepage' => env('APP_SITEHOMEPAGE', 'https://google.com'), 'sitehomepage' => env('APP_SITEHOMEPAGE', 'https://google.com'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Application Version | Application Version
@ -77,7 +74,6 @@ return [
*/ */
'force_secure' => env('NONPROD_FORCE_SECURE', false), 'force_secure' => env('NONPROD_FORCE_SECURE', false),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| IP address anonymity | IP address anonymity
@ -94,7 +90,6 @@ return [
*/ */
'hide_ips' => env('HIDE_IPS'), 'hide_ips' => env('HIDE_IPS'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Legal documents & source code | Legal documents & source code
@ -351,7 +346,7 @@ return [
'ContextAwareValidator' => App\Facades\ContextAwareValidation::class, 'ContextAwareValidator' => App\Facades\ContextAwareValidation::class,
'Settings' => App\Facades\Options::class, 'Settings' => App\Facades\Options::class,
'JSON' => App\Facades\JSON::class, 'JSON' => App\Facades\JSON::class,
'DiscordOauth' => App\Facades\Discord::class 'DiscordOauth' => App\Facades\Discord::class,
], ],

Some files were not shown because too many files have changed in this diff Show More