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,17 +39,14 @@ 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');
$this->call('key:generate'); $this->call('key:generate');
$this->info('>> Installing and preparing dependencies. This may take a while, depending on your computer.'); $this->info('>> Installing and preparing dependencies. This may take a while, depending on your computer.');
@ -60,25 +57,20 @@ class Install extends Command
$npmBuildOut = 0; $npmBuildOut = 0;
$npmBuildMessages = []; $npmBuildMessages = [];
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.'));
foreach ($settings as $keyname => $value) {
} 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)
{
$this->call('environment:modify', [ $this->call('environment:modify', [
'key' => $keyname, 'key' => $keyname,
'value' => $value 'value' => $value,
]); ]);
} }
@ -127,14 +116,11 @@ class Install extends Command
$this->call('migrate'); $this->call('migrate');
$this->call('db:seed'); $this->call('db:seed');
touch($basePath . '/INSTALLED'); touch($basePath.'/INSTALLED');
$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));
@ -101,7 +98,6 @@ class DigitalStorageHelper
$bytes /= pow(($si) ? 1000 : 1024, $pow); $bytes /= pow(($si) ? 1000 : 1024, $pow);
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,16 +89,16 @@ 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()
->json(); ->json();
@ -112,43 +108,42 @@ 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();
if ($member->successful() && $member->status() == 204) { if ($member->successful() && $member->status() == 204) {
@ -158,21 +153,22 @@ 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();
throw new AccountNotLinkedException('Specified website user has not linked their Discord account yet.'); throw new AccountNotLinkedException('Specified website user has not linked their Discord account yet.');
@ -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,14 +199,16 @@ 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) {
return false; return false;
@ -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;
} }
@ -56,7 +55,7 @@ class AppointmentController extends Controller
return redirect() return redirect()
->back() ->back()
->with('success',__('Appointment successfully scheduled @ :appointmentTime', ['appointmentTime', $appointmentDate->toDateTimeString()])); ->with('success', __('Appointment successfully scheduled @ :appointmentTime', ['appointmentTime', $appointmentDate->toDateTimeString()]));
} }
/** /**
@ -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,14 +137,12 @@ 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()
->with('error', $ex->getMessage()); ->with('error', $ex->getMessage());
@ -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.
@ -58,7 +63,7 @@ class UserAccountDeleteConfirmation extends Mailable
*/ */
public function build() public function build()
{ {
return $this->subject(config('app.name') . ' - please confirm account removal (action required)') return $this->subject(config('app.name').' - please confirm account removal (action required)')
->view('mail.deleted-account'); ->view('mail.deleted-account');
} }
} }

View File

@ -44,13 +44,13 @@ class AbsenceRequestApproved 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').' - absence request approved') ->subject(config('app.name').' - absence request approved')
->line("Your recent Leave of Absence request from {$this->absence->created_at} has just been approved by an admin.") ->line("Your recent Leave of Absence request from {$this->absence->created_at} has just been approved by an admin.")
->line('Your inactivity during the period you selected won\'t be counted. You will receive another email notification when your request ends, or if you decide to cancel it.') ->line('Your inactivity during the period you selected won\'t be counted. You will receive another email notification when your request ends, or if you decide to cancel it.')
->action('View your request', url(route('absences.show', ['absence' => $this->absence->id]))) ->action('View your request', url(route('absences.show', ['absence' => $this->absence->id])))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -44,13 +44,13 @@ class AbsenceRequestCancelled 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').' - absence request cancelled') ->subject(config('app.name').' - absence request cancelled')
->line("This notification confirms that your recent Leave of Absence from {$this->absence->created_at} has just been cancelled by you.") ->line("This notification confirms that your recent Leave of Absence from {$this->absence->created_at} has just been cancelled by you.")
->line('Please note that any inactivity will be counted in our activity metrics. You may also make a new request if you wish.') ->line('Please note that any inactivity will be counted in our activity metrics. You may also make a new request if you wish.')
->action('Send new request', url(route('absences.create'))) ->action('Send new request', url(route('absences.create')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -44,13 +44,13 @@ class AbsenceRequestDeclined 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').' - absence request declined') ->subject(config('app.name').' - absence request declined')
->line("Your recent Leave of Absence request from {$this->absence->created_at} has just been declined by an admin.") ->line("Your recent Leave of Absence request from {$this->absence->created_at} has just been declined by an admin.")
->line('Please note that any inactivity will be counted in our activity metrics. You may make a new request, but we recommend you ask your team lead regarding your declined request.') ->line('Please note that any inactivity will be counted in our activity metrics. You may make a new request, but we recommend you ask your team lead regarding your declined request.')
->action('Send new request', url(route('absences.create'))) ->action('Send new request', url(route('absences.create')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -44,13 +44,13 @@ class AbsenceRequestEnded 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').' - absence request expired') ->subject(config('app.name').' - absence request expired')
->line("Your Leave of Absence request from {$this->absence->created_at} (until {$this->absence->predicted_end}) has expired today.") ->line("Your Leave of Absence request from {$this->absence->created_at} (until {$this->absence->predicted_end}) has expired today.")
->line('Please note that any inactivity will be counted in our activity metrics. You may now make a new request if you still need more time.') ->line('Please note that any inactivity will be counted in our activity metrics. You may now make a new request if you still need more time.')
->action('Send new request', url(route('absences.create'))) ->action('Send new request', url(route('absences.create')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -44,14 +44,14 @@ class AccountDeleted extends Notification implements ShouldQueue
{ {
// Adjust to notify external user // Adjust to notify external user
return (new MailMessage) return (new MailMessage)
->greeting('Hi ' . $this->name . ',') ->greeting('Hi '.$this->name.',')
->from(config('notification.sender.address'), config('notification.sender.name')) ->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - account deleted permanently') ->subject(config('app.name').' - account deleted permanently')
->line('Thank you for confirming your account deletion request. We\'re sorry to see you go!') ->line('Thank you for confirming your account deletion request. We\'re sorry to see you go!')
->line('Unless you sign up again, this is the last email you\'ll be receiving from us.') ->line('Unless you sign up again, this is the last email you\'ll be receiving from us.')
->line('Please let us know if there\'s any feedback you\'d like to share. You can use the feedback widget located on the left-hand side of our website, or the chat widget located on the lower right corner.') ->line('Please let us know if there\'s any feedback you\'d like to share. You can use the feedback widget located on the left-hand side of our website, or the chat widget located on the lower right corner.')
->line('See you around!') ->line('See you around!')
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -41,14 +41,14 @@ class AccountUnlocked 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').' - account unlocked') ->subject(config('app.name').' - account unlocked')
->line('We wanted to let you know that your account at ' . config('app.name') . ' is now unlocked. This means the circumstances surrounding your account\'s standing are now resolved.') ->line('We wanted to let you know that your account at '.config('app.name').' is now unlocked. This means the circumstances surrounding your account\'s standing are now resolved.')
->line('You can sign in and use the app normally again.') ->line('You can sign in and use the app normally again.')
->line('If there\'s anything we can help you with, don\'t hesitate to reach out.') ->line('If there\'s anything we can help you with, don\'t hesitate to reach out.')
->action('Sign in', url(route('login'))) ->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

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
*/ */
@ -76,7 +74,7 @@ class ApplicationApproved 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').' - application approved') ->subject(config('app.name').' - application approved')
->line('Congratulations! Your most recent application has been approved by the reviewing team.') ->line('Congratulations! Your most recent application has been approved by the reviewing team.')
@ -84,7 +82,7 @@ class ApplicationApproved extends Notification implements ShouldQueue
->line('You should have received more information about your onboarding process by now.') ->line('You should have received more information about your onboarding process by now.')
->line('Good luck and welcome aboard!') ->line('Good luck and welcome aboard!')
->action('Sign in', url(route('login'))) ->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
public function toSlack($notifiable) public function toSlack($notifiable)

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;
@ -44,13 +43,13 @@ class ApplicationConfirmed extends Notification
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') . ' - application confirmed') ->subject(config('app.name').' - application confirmed')
->line('We\'re writing you to let you know that your recent application with us has been received, and will be processed in 24/48 hours.') ->line('We\'re writing you to let you know that your recent application with us has been received, and will be processed in 24/48 hours.')
->line('You will receive regular notifications about your application\'s status.') ->line('You will receive regular notifications about your application\'s status.')
->action('View active applications', url(route('showUserApps'))) ->action('View active applications', url(route('showUserApps')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -64,14 +64,14 @@ class ApplicationDenied 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').' - application denied') ->subject(config('app.name').' - application denied')
->line('We\'re sorry to inform you that your application with us has been reviewed and declined.') ->line('We\'re sorry to inform you that your application with us has been reviewed and declined.')
->line('Our review team denies applications for several reasons, including poor answers, missing information, or lacking qualifications.') ->line('Our review team denies applications for several reasons, including poor answers, missing information, or lacking qualifications.')
->line('Please review your application and try again later. You can view your account\'s eligibility status in your dashboard.') ->line('Please review your application and try again later. You can view your account\'s eligibility status in your dashboard.')
->action('Review application', url(route('showUserApp', ['application' => $this->application->id]))) ->action('Review application', url(route('showUserApp', ['application' => $this->application->id])))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
public function toSlack($notifiable) public function toSlack($notifiable)

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;
@ -69,13 +70,13 @@ class ApplicationMoved 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').' - application updated') ->subject(config('app.name').' - application updated')
->line('Your application has been moved to the next step.') ->line('Your application has been moved to the next step.')
->line('This means our team has reviewed it and an interview will be scheduled soon.') ->line('This means our team has reviewed it and an interview will be scheduled soon.')
->action('Sign in', url(route('login'))) ->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

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,16 +52,16 @@ 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.')
->line('Date and time of the old appointment: '.$this->appointmentDate) ->line('Date and time of the old appointment: '.$this->appointmentDate)
->line('Your appointment was cancelled for the following reason: ' . $this->reason) ->line('Your appointment was cancelled for the following reason: '.$this->reason)
->line('A team member may contact you to reschedule within a new timeframe - you may also let us know of a date and time that suits you.') ->line('A team member may contact you to reschedule within a new timeframe - you may also let us know of a date and time that suits you.')
->line('Your application will likely be declined if you do not reschedule an interview.') ->line('Your application will likely be declined if you do not reschedule an interview.')
->action('View active applications', url(route('showUserApps'))) ->action('View active applications', url(route('showUserApps')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

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

@ -63,14 +63,14 @@ class AppointmentScheduled 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').' - Interview scheduled') ->subject(config('app.name').' - Interview scheduled')
->line('An interview has been scheduled for you @ '.$this->appointment->appointmentDate.'.') ->line('An interview has been scheduled for you @ '.$this->appointment->appointmentDate.'.')
->line('With the following details: '.$this->appointment->appointmentDescription) ->line('With the following details: '.$this->appointment->appointmentDescription)
->line('This meeting will take place @ '.$this->appointment->appointmentLocation.'.') ->line('This meeting will take place @ '.$this->appointment->appointmentLocation.'.')
->action('Sign in', url(route('login'))) ->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -60,13 +60,13 @@ class ChangedPassword 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').' - Account password changed') ->subject(config('app.name').' - Account password changed')
->line('The password for the account registered to this email address has just been changed.') ->line('The password for the account registered to this email address has just been changed.')
->line('If this was not you, please contact an administrator immediately.') ->line('If this was not you, please contact an administrator immediately.')
->action('Sign in', url(route('login'))) ->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -60,13 +60,13 @@ class EmailChanged 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').' - Email address changed') ->subject(config('app.name').' - Email address changed')
->line('The email address for your account has just been updated.') ->line('The email address for your account has just been updated.')
->line('If this was not you, please change your password immediately. We recommend you also activate multi-factor authentication.') ->line('If this was not you, please change your password immediately. We recommend you also activate multi-factor authentication.')
->action('Sign in', url(route('login'))) ->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -44,13 +44,13 @@ class NewAbsenceRequest 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').' - new absence request pending review') ->subject(config('app.name').' - new absence request pending review')
->line("A new absence request has just been submitted, scheduled to end {$this->absence->predicted_end}. Please review this request and take the appropriate action(s). The requester will be notified of your decision by email.") ->line("A new absence request has just been submitted, scheduled to end {$this->absence->predicted_end}. Please review this request and take the appropriate action(s). The requester will be notified of your decision by email.")
->line("You are receiving this email because you're a site admin.") ->line("You are receiving this email because you're a site admin.")
->action('Review request', url(route('absences.show', ['absence' => $this->absence->id]))) ->action('Review request', url(route('absences.show', ['absence' => $this->absence->id])))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -73,13 +73,13 @@ class NewApplicant 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').' - New application') ->subject(config('app.name').' - New application')
->line('Someone has just applied for a position. Check it out!') ->line('Someone has just applied for a position. Check it out!')
->line('You are receiving this because you\'re a staff member at '.config('app.name').'.') ->line('You are receiving this because you\'re a staff member at '.config('app.name').'.')
->action('View Application', url(route('showUserApp', ['application' => $this->application->id]))) ->action('View Application', url(route('showUserApp', ['application' => $this->application->id])))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
public function toSlack($notifiable) public function toSlack($notifiable)

View File

@ -60,13 +60,13 @@ class NewComment 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').' - New comment') ->subject(config('app.name').' - New comment')
->line('Someone has just posted a new comment on an application you follow.') ->line('Someone has just posted a new comment on an application you follow.')
->line('You\'re receiving this email because you\'ve voted/commented on this application.') ->line('You\'re receiving this email because you\'ve voted/commented on this application.')
->action('Check it out', url(route('showUserApp', ['application' => $this->application->id]))) ->action('Check it out', url(route('showUserApp', ['application' => $this->application->id])))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -67,7 +67,7 @@ class NewContact extends Notification
'email', 'email',
])) { ])) {
return (new MailMessage) return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',') ->greeting('Hi '.$notifiable->name.',')
->line('We\'ve received a new contact form submission in the StaffManagement app center.') ->line('We\'ve received a new contact form submission in the StaffManagement app center.')
->line('This is what they sent: ') ->line('This is what they sent: ')
->line('') ->line('')
@ -75,7 +75,7 @@ class NewContact extends Notification
->line('') ->line('')
->line('This message was received from '.$this->message->get('ip').' and submitted by '.$this->message->get('email').'.') ->line('This message was received from '.$this->message->get('ip').' and submitted by '.$this->message->get('email').'.')
->action('Sign in', url(route('login'))) ->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
throw new \InvalidArgumentException('Invalid arguments supplied to NewContact!'); throw new \InvalidArgumentException('Invalid arguments supplied to NewContact!');

View File

@ -66,14 +66,14 @@ class NewUser 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').' - New user') ->subject(config('app.name').' - New user')
->line($this->user->name.' has created a new account.') ->line($this->user->name.' has created a new account.')
->line('This request came from the IP address ' . $this->user->originalIP . '.') ->line('This request came from the IP address '.$this->user->originalIP.'.')
->line('You are receiving this email because you\'re a site admin, and the app is configured to send new user notifications.') ->line('You are receiving this email because you\'re a site admin, and the app is configured to send new user notifications.')
->action('View user', url(route('showSingleProfile', ['user' => $this->user->id]))) ->action('View user', url(route('showSingleProfile', ['user' => $this->user->id])))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
public function toSlack($notifiable) public function toSlack($notifiable)

View File

@ -67,13 +67,13 @@ class UserBanned 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'))
->line('Hello, ') ->line('Hello, ')
->line('Moderators have just suspended user '.$this->user->name.' for '.$this->ban->reason) ->line('Moderators have just suspended user '.$this->user->name.' for '.$this->ban->reason)
->line('This ban will remain in effect until '.$this->ban->bannedUntil.'.') ->line('This ban will remain in effect until '.$this->ban->bannedUntil.'.')
->action('View profile', url(route('showSingleProfile', ['user' => $this->user->id]))) ->action('View profile', url(route('showSingleProfile', ['user' => $this->user->id])))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.name'));
} }
/** /**

View File

@ -46,13 +46,13 @@ class UserDeletedAccount 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').' - someone deleted their account') ->subject(config('app.name').' - someone deleted their account')
->line("The user {$this->deletedEmail} has just deleted their account. You may wish to review the situation.") ->line("The user {$this->deletedEmail} has just deleted their account. You may wish to review the situation.")
->line('You are receiving this email because you\'re a site admin.') ->line('You are receiving this email because you\'re a site admin.')
->action('View current users', url(route('registeredPlayerList'))) ->action('View current users', url(route('registeredPlayerList')))
->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,16 +68,15 @@ 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'))
->subject(config('app.name').' - Vacancy ' . $this->status) ->subject(config('app.name').' - Vacancy '.$this->status)
->line('The vacancy '.$this->vacancy->vacancyName.', with '.$this->vacancy->vacancyCount.' remaining slots, has just been ' . $this->status . '.') ->line('The vacancy '.$this->vacancy->vacancyName.', with '.$this->vacancy->vacancyCount.' remaining slots, has just been '.$this->status.'.')
->line('Please be aware that this position may be change at any time.') ->line('Please be aware that this position may be change at any time.')
->line('You are receiving this email because you currently have staff/team member privileges. Depending on your access level, you may not be able to view the list of positions on the backoffice.') ->line('You are receiving this email because you currently have staff/team member privileges. Depending on your access level, you may not be able to view the list of positions on the backoffice.')
->action('View positions', url(route('showPositions'))) ->action('View positions', url(route('showPositions')))
->salutation('The team at ' . config('app.name')); ->salutation('The team at '.config('app.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,9 +93,9 @@ 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,25 +80,23 @@ 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) {
return $user->hasPermissionTo('admin.developertools.use'); return $user->hasPermissionTo('admin.developertools.use');
}); });
Gate::define('downloadLogFile', function (User $user){ Gate::define('downloadLogFile', function (User $user) {
return $user->hasPermissionTo('admin.developertools.use'); return $user->hasPermissionTo('admin.developertools.use');
}); });
Gate::define('deleteLogFile', function (User $user){ Gate::define('deleteLogFile', function (User $user) {
return $user->hasPermissionTo('admin.developertools.use'); return $user->hasPermissionTo('admin.developertools.use');
}); });
} }

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
{ {
@ -24,7 +24,7 @@ class DigitalStorageProvider extends ServiceProvider
*/ */
public function boot() public function boot()
{ {
App::bind('digitalStorageHelperFacadeRoot', function (){ App::bind('digitalStorageHelperFacadeRoot', function () {
return new App\Helpers\DigitalStorageHelper(); return new App\Helpers\DigitalStorageHelper();
}); });
} }

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,12 +125,14 @@ 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,26 +35,23 @@ 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.');
} }
if (!$vacancyWithForm->isEmpty() && $firstVacancy->vacancyCount !== 0 && $firstVacancy->vacancyStatus == 'OPEN') { if (! $vacancyWithForm->isEmpty() && $firstVacancy->vacancyCount !== 0 && $firstVacancy->vacancyStatus == 'OPEN') {
return view('dashboard.application-rendering.apply') return view('dashboard.application-rendering.apply')
->with([ ->with([
'vacancy' => $vacancyWithForm->first(), 'vacancy' => $vacancyWithForm->first(),
'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,10 +79,9 @@ 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()) {
$response = Response::create([ $response = Response::create([
'responseFormID' => $vacancy->first()->forms->id, 'responseFormID' => $vacancy->first()->forms->id,
'associatedVacancyID' => $vacancy->first()->id, // Since a form can be used by multiple vacancies, we can only know which specific vacancy this response ties to by using a vacancy ID 'associatedVacancyID' => $vacancy->first()->id, // Since a form can be used by multiple vacancies, we can only know which specific vacancy this response ties to by using a vacancy ID
@ -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,10 +113,9 @@ 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!');
throw new IncompleteApplicationException('There are one or more errors in your application. Please make sure none of your fields are empty, since they are all required.'); throw new IncompleteApplicationException('There are one or more errors in your application. Please make sure none of your fields are empty, since they are all required.');
} }
@ -136,12 +126,12 @@ class ApplicationService
case 'deny': case 'deny':
event(new ApplicationDeniedEvent($application)); event(new ApplicationDeniedEvent($application));
$message = __("Application denied successfully."); $message = __('Application denied successfully.');
break; break;
case 'interview': case 'interview':
Log::info(' Moved application ID ' . $application->id . 'to interview stage!'); Log::info(' Moved application ID '.$application->id.'to interview stage!');
$message = __('Application moved to interview stage!'); $message = __('Application moved to interview stage!');
$application->setStatus('STAGE_INTERVIEW'); $application->setStatus('STAGE_INTERVIEW');
@ -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([]);
@ -175,6 +164,6 @@ class ApplicationService
} }
} }
return !(($allvotes->count() == 1)); return ! (($allvotes->count() == 1));
} }
} }

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,31 +4,29 @@ 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
{ {
$req = Http::asForm()->post(config('services.discord.base_url') . '/oauth2/token/revoke', [ $req = Http::asForm()->post(config('services.discord.base_url').'/oauth2/token/revoke', [
'client_id' => config('services.discord.client_id'), 'client_id' => config('services.discord.client_id'),
'client_secret' => config('services.discord.client_secret'), 'client_secret' => config('services.discord.client_secret'),
'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;
} }
} }

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