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

@ -13,14 +13,14 @@ class Absence extends Model
use HasFactory;
protected $fillable = [
'requesterID',
'start',
'predicted_end',
'available_assist',
'reason',
'status',
'reviewer',
'reviewed_date'
'requesterID',
'start',
'predicted_end',
'available_assist',
'reason',
'status',
'reviewer',
'reviewed_date',
];
public function requester(): BelongsTo
@ -28,72 +28,69 @@ class Absence extends Model
return $this->belongsTo('App\User', 'requesterID', 'id');
}
/**
* Determines whether this model can be setApproved(), setDeclined() or setCancelled()
*
* @param bool $toCancel Switch the check to cancellability check
* @param bool $toCancel Switch the check to cancellability check
* @return bool
*/
public function isActionable(bool $toCancel = false): bool
{
if ($toCancel)
{
if ($toCancel) {
return in_array($this->getRawOriginal('status'), ['PENDING', 'APPROVED']);
}
return $this->getRawOriginal('status') == 'PENDING';
}
/**
* Sets the Absence's status as approved
*
* @return Absence
*
* @throws AbsenceNotActionableException
*/
public function setApproved(): Absence
{
if ($this->isActionable())
{
if ($this->isActionable()) {
return tap($this)->update([
'status' => 'APPROVED'
'status' => 'APPROVED',
]);
}
throw new AbsenceNotActionableException('This absence is not actionable!');
}
/**
* Sets the absence's status as declined
*
* @return Absence
*
* @throws AbsenceNotActionableException
*/
public function setDeclined(): Absence
{
if ($this->isActionable()) {
return tap($this)->update([
'status' => 'DECLINED'
'status' => 'DECLINED',
]);
}
throw new AbsenceNotActionableException('This absence is not actionable!');
}
/**
* Sets the absence's status as cancelled
*
* @return Absence
*
* @throws AbsenceNotActionableException Thrown when the switch to this status would be invalid
*/
public function setCancelled(): Absence
{
if ($this->isActionable(true)) {
return tap($this)->update([
'status' => 'CANCELLED'
'status' => 'CANCELLED',
]);
}
@ -108,18 +105,16 @@ class Absence extends Model
public function setEnded(): Absence
{
return tap($this)->update([
'status' => 'ENDED'
'status' => 'ENDED',
]);
}
// Look out when retrieving this value;
//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(
get: fn($value) => ucfirst(strtolower($value))
get: fn ($value) => ucfirst(strtolower($value))
);
}
}

View File

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

View File

@ -39,103 +39,89 @@ class Install extends Command
public function handle()
{
$basePath = base_path();
if (Storage::disk('local')->missing('INSTALLED'))
{
if (Storage::disk('local')->missing('INSTALLED')) {
$this->info('[!! Welcome to Rasberry Teams !!]');
$this->info('>> Installing...');
$this->call('down', [
'--message' => 'Down for maintenance. We\'ll be right back!',
]);
copy($basePath.'/.env.example', $basePath.'/.env');
$this->call('key:generate');
$this->info('[!! Welcome to Rasberry Teams !!]');
$this->info('>> Installing...');
$this->call('down', [
'--message' => 'Down for maintenance. We\'ll be right back!'
]);
$this->info('>> Installing and preparing dependencies. This may take a while, depending on your computer.');
copy($basePath . '/.env.example', $basePath . '/.env');
$this->call('key:generate');
$npmOut = 0;
$npmMessages = [];
$this->info('>> Installing and preparing dependencies. This may take a while, depending on your computer.');
$npmBuildOut = 0;
$npmBuildMessages = [];
$npmOut = 0;
$npmMessages = [];
exec('cd '.$basePath.' && npm install --silent', $npmBuildOut, $npmOut);
exec('cd '.$basePath.'&& npm run dev --silent', $npmBuildMessages, $npmBuildOut);
$npmBuildOut = 0;
$npmBuildMessages = [];
if ($npmOut !== 0 && $npmBuildOut !== 0) {
$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.');
exec('cd ' . $basePath . ' && npm install --silent', $npmBuildOut, $npmOut);
exec('cd ' . $basePath . '&& npm run dev --silent', $npmBuildMessages, $npmBuildOut);
return false;
}
$settings = [];
if($npmOut !== 0 && $npmBuildOut !== 0)
{
$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->info('>> Configuring application - We\'re going to ask a few questions here!');
do {
$this->info('== Database Settings (1/6) ==');
return false;
}
$settings['DB_USERNAME'] = $this->ask('Database username');
$settings['DB_PASSWORD'] = $this->secret('Database password (Input won\'t be seen)');
$settings['DB_DATABASE'] = $this->ask('Database name');
$settings['DB_PORT'] = $this->ask('Database port');
$settings['DB_HOST'] = $this->ask('Database hostname');
$this->info('== Antispam Settings (2/6) (Recaptcha v2) ==');
$settings['RECAPTCHA_SITE_KEY'] = $this->ask('Site key');
$settings['RECAPTCHA_PRIVATE_KEY'] = $this->ask('Private site key');
$this->info('== IP Geolocation Settings (3/6) (refer to README.md) ==');
$settings['IPGEO_API_KEY'] = $this->ask('API Key');
$settings = [];
$this->info('== Notification Settings (4/6) (Email) ==');
$settings['MAIL_USERNAME'] = $this->ask('SMTP Username');
$settings['MAIL_PASSWORD'] = $this->secret('SMTP Password (Input won\'t be seen)');
$settings['MAIL_PORT'] = $this->ask('SMTP Server Port');
$settings['MAIL_HOST'] = $this->ask('SMTP Server Hostname');
$settings['MAIL_FROM_ADDRESS'] = $this->ask('E-mail address to send from');
$this->info('>> Configuring application - We\'re going to ask a few questions here!');
do
{
$this->info('== Database Settings (1/6) ==');
$this->info('== Notification Settings (5/6) (Slack) ==');
$settings['SLACK_INTEGRATION_WEBHOOK'] = $this->ask('Integration webhook URL');
$settings['DB_USERNAME'] = $this->ask('Database username');
$settings['DB_PASSWORD'] = $this->secret('Database password (Input won\'t be seen)');
$settings['DB_DATABASE'] = $this->ask('Database name');
$settings['DB_PORT'] = $this->ask('Database port');
$settings['DB_HOST'] = $this->ask('Database hostname');
$this->info('== Web Settings (6/6) ==');
$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_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.'));
$this->info('== Antispam Settings (2/6) (Recaptcha v2) ==');
$settings['RECAPTCHA_SITE_KEY'] = $this->ask('Site key');
$settings['RECAPTCHA_PRIVATE_KEY'] = $this->ask('Private site key');
foreach ($settings as $keyname => $value) {
$this->call('environment:modify', [
'key' => $keyname,
'value' => $value,
]);
}
$this->info('== IP Geolocation Settings (3/6) (refer to README.md) ==');
$settings['IPGEO_API_KEY'] = $this->ask('API Key');
$this->info('>> Saved configuration settings!');
$this->info('>> Preparing database...');
$this->info('== Notification Settings (4/6) (Email) ==');
$settings['MAIL_USERNAME'] = $this->ask('SMTP Username');
$settings['MAIL_PASSWORD'] = $this->secret('SMTP Password (Input won\'t be seen)');
$settings['MAIL_PORT'] = $this->ask('SMTP Server Port');
$settings['MAIL_HOST'] = $this->ask('SMTP Server Hostname');
$settings['MAIL_FROM_ADDRESS'] = $this->ask('E-mail address to send from');
$this->callSilent('config:cache');
$this->call('migrate');
$this->call('db:seed');
$this->info('== Notification Settings (5/6) (Slack) ==');
$settings['SLACK_INTEGRATION_WEBHOOK'] = $this->ask('Integration webhook URL');
touch($basePath.'/INSTALLED');
$this->info('== Web Settings (6/6) ==');
$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_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)
{
$this->call('environment:modify', [
'key' => $keyname,
'value' => $value
]);
}
$this->info('>> Saved configuration settings!');
$this->info('>> Preparing database...');
$this->callSilent('config:cache');
$this->call('migrate');
$this->call('db:seed');
touch($basePath . '/INSTALLED');
$this->call('up');
$this->info('>> All done! Visit ' . $basePath . ' to start using your brand new installation of Raspberry Teams!');
}
else
{
$this->error('[!] The application is already installed!');
$this->call('up');
$this->info('>> All done! Visit '.$basePath.' to start using your brand new installation of Raspberry Teams!');
} else {
$this->error('[!] The application is already installed!');
}
}
}

View File

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

View File

@ -23,7 +23,6 @@ namespace App\CustomFacades;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class IP
{
@ -31,14 +30,14 @@ class IP
// 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.
*
* @return bool Whether you should collect/display IPs, in the context in which this is called
*/
public function shouldCollect(): bool
{
// 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!
}
@ -47,7 +46,8 @@ class IP
/**
* 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
*/
public function lookup(string $IP): object
@ -58,19 +58,17 @@ class IP
];
if ($this->shouldCollect()) {
return json_decode(Cache::remember($IP, 3600, function () use ($IP) {
return Http::get(config('general.urls.ipapi.ipcheck'), [
'apiKey' => config('general.keys.ipapi.apikey'),
'ip' => $IP,
])->body();
}));
}
return new class {
public $message = "This feature is disabled.";
return new class
{
public $message = 'This feature is disabled.';
};
}
}

View File

@ -35,7 +35,7 @@ class ApplicationApprovedEvent
/**
* Create a new event instance.
*
* @param Application $application
* @param Application $application
*/
public function __construct(Application $application)
{

View File

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

View File

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

View File

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

View File

@ -1,17 +1,13 @@
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class JSON extends Facade
{
protected static function getFacadeAccessor()
{
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.
*
* @var array
*/
private $excludedNames = [
@ -39,7 +40,7 @@ class ContextAwareValidator
/**
* Utility wrapper for json_encode.
*
* @param array $value The array to be converted.
* @param array $value The array to be converted.
* @return string The JSON representation of $value
*/
private function encode(array $value): string
@ -60,9 +61,9 @@ class ContextAwareValidator
*
* P.S This method automatically ignores the CSRF token for validation.
*
* @param array $fields The request form fields
* @param bool $generateStructure Whether to incldue a JSON-ready form structure for rendering
* @param bool $includeFormName Whether to include formName in the list of validation rules
* @param array $fields The request form fields
* @param bool $generateStructure Whether to incldue a JSON-ready form structure for rendering
* @param bool $includeFormName Whether to include formName in the list of validation rules
* @return Validator|Collection A validator instance you can use to check for validity, or a Collection with a validator and structure (validator, structure)
*/
public function getValidator(array $fields, bool $generateStructure = false, bool $includeFormName = false)
@ -103,9 +104,9 @@ class ContextAwareValidator
*
* Also generates the storable response structure if you tell it to.
*
* @param array $fields The received fields
* @param array $formStructure The form structure - You must supply this if you want the response structure
* @param bool $generateResponseStructure Whether to generate the response structure
* @param array $fields The received fields
* @param array $formStructure The form structure - You must supply this if you want the response structure
* @param bool $generateResponseStructure Whether to generate the response structure
* @return Validator|Collection A collection or a validator, depending on the args. Will return validatior if only fields are supplied.
*/
public function getResponseValidator(array $fields, array $formStructure = [], bool $generateResponseStructure = true)

View File

@ -1,5 +1,6 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);
namespace App\Helpers;
@ -10,31 +11,29 @@ namespace App\Helpers;
* 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.
* @package App\Helpers
*/
class DigitalStorageHelper
{
/**
* The digital storage value to be manipulated.
* @var $value
*
* @var
*/
protected $value;
/**
* Sets the digital storage value for manipulation.
*
* @param int $value The digital storage value in bytes
* @param int $value The digital storage value in bytes
* @return $this The current instance
*/
public function setValue(int $value): DigitalStorageHelper
{
$this->value = $value;
return $this;
}
/**
* Converts the digital storage value to kilobytes.
*
@ -45,7 +44,6 @@ class DigitalStorageHelper
return $this->value / 1000;
}
/**
* 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
}
/**
* Convert the digital storage value to gigabytes. Might be an approximation
*
@ -67,7 +64,6 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 9));
}
/**
* Convert the digital storage value to terabytes.
*
@ -78,22 +74,23 @@ class DigitalStorageHelper
return $this->value / (1 * pow(10, 12));
}
/**
* 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.
*
* @param int $precision The rounding precision
* @param bool $si Use international system units. Defaults to false
* @param int $precision The rounding precision
* @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
*
* @see https://stackoverflow.com/a/2510459/11540218 StackOverflow question regarding unit conversion
* @since 7.3.23
*/
public function formatBytes($precision = 2, $si = false): string
{
$units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
if ($si)
if ($si) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
}
$bytes = max($this->value, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(($si) ? 1000 : 1024));
@ -101,7 +98,6 @@ class DigitalStorageHelper
$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/>.
*/
namespace App\Helpers;
use App\Exceptions\AccountNotLinkedException;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Http;
// Small wrapper for the necessary sections of the Discord API; A library is overkill here
class Discord
{
/**
* The current working guild. Default is Home guild from app config
*
* @var string
*/
protected string $workingGuild;
/**
* Current user.
*
@ -50,42 +45,43 @@ class Discord
*/
protected User $user;
public function __construct() {
public function __construct()
{
if (isset($this->workingGuild)) {
$this->setWorkingGuild(config('services.discord.home_guild'));
}
}
/**
* Sets the working guild
*
* @param string $workingGuild
* @param string $workingGuild
* @return Discord
*/
public function setWorkingGuild(string $workingGuild): Discord
{
$this->workingGuild = $workingGuild;
return $this;
}
/**
* Sets the current user, upon validation
*
* @param User $user
* @param User $user
* @return Discord
*
* @throws AccountNotLinkedException
*/
public function setUser(User $user): Discord
{
if ($user->hasDiscordConnection()) {
$this->user = $user;
return $this;
}
if ($user->hasDiscordConnection()) {
$this->user = $user;
throw new AccountNotLinkedException('Specified website user has not linked their Discord account yet.');
return $this;
}
throw new AccountNotLinkedException('Specified website user has not linked their Discord account yet.');
}
/**
@ -93,16 +89,16 @@ class Discord
* preventing unnecessary API requests.
*
* @return object Current user's authentication info (has no sensitive fields)
*
* @throws RequestException
*/
public function getAuthorizationInfo(): object {
public function getAuthorizationInfo(): object
{
if (Cache::has($this->user->discord_user_id)) {
return unserialize(Cache::get($this->user->discord_user_id));
}
else {
} else {
$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()
->json();
@ -112,43 +108,42 @@ class Discord
}
}
/**
* Checks if the user's token is close to expiring.
* Tokens should be refreshed the day before they expire.
*
* @return bool Whether the user's token needs to be refreshed
*
* @throws RequestException
*/
public function needsRefresh(): bool {
public function needsRefresh(): bool
{
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
*
* @return object|bool A GuildMember object; false if member is already in guild
*
* @throws RequestException Any client and server errors
*
* @see https://discord.com/developers/docs/resources/guild#guild-member-object
*/
public function addGuildMember(): object|bool
{
$params = [
'access_token' => $this->user->discord_token
'access_token' => $this->user->discord_token,
];
$member = Http::withBody(json_encode($params), 'application/json')
->withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token')
])->put(config('services.discord.base_url') . "/guilds/{$this->workingGuild}/members/{$this->user->discord_user_id}")
'Authorization' => 'Bot '.config('services.discord.token'),
])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/members/{$this->user->discord_user_id}")
->throw();
if ($member->successful() && $member->status() == 204) {
@ -158,42 +153,45 @@ class Discord
}
}
/**
* Bans a specified user from the guild.
* 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
*
* @throws RequestException
* @throws AccountNotLinkedException
*/
public function addGuildBan(string $reason): void {
public function addGuildBan(string $reason): void
{
Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token'),
'X-Audit-Log-Reason' => $reason
])->put(config('services.discord.base_url') . "/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
'Authorization' => 'Bot '.config('services.discord.token'),
'X-Audit-Log-Reason' => $reason,
])->put(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
->throw();
throw new AccountNotLinkedException('Specified website user has not linked their Discord account yet.');
}
/**
* @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
*
* @throws RequestException
*/
public function removeGuildBan(string $reason): null|bool {
public function removeGuildBan(string $reason): null|bool
{
if ($this->getGuildBan($this->user)) {
Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token'),
'X-Audit-Log-Reason' => $reason
])->delete(config('services.discord.base_url') . "/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
'Authorization' => 'Bot '.config('services.discord.token'),
'X-Audit-Log-Reason' => $reason,
])->delete(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}")
->throw();
return null;
}
return false;
}
@ -201,14 +199,16 @@ class Discord
* Gets (possible) ban for current user.
*
* @return object|bool Ban object if user is banned. Null
*
* @throws RequestException
*
* @see https://discord.com/developers/docs/resources/guild#ban-object
*/
public function getGuildBan(): object|bool
{
$ban = Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token')
])->get(config('services.discord.base_url') . "/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}");
'Authorization' => 'Bot '.config('services.discord.token'),
])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/bans/{$this->user->discord_user_id}");
if ($ban->status() == 404) {
return false;
@ -217,20 +217,21 @@ class Discord
return ($ban->successful()) ? (object) $ban->json() : $ban->throwIf($ban->status() !== 404);
}
/**
* Retrieves list of Role objects
*
* @see https://discord.com/developers/docs/topics/permissions#role-object
*
* @return array List of role objects
*
* @throws RequestException
*/
public function getGuildRoles(): array {
public function getGuildRoles(): array
{
return Http::withHeaders([
'Authorization' => 'Bot ' . config('services.discord.token')
])->get(config('services.discord.base_url') . "/guilds/{$this->workingGuild}/roles")
'Authorization' => 'Bot '.config('services.discord.token'),
])->get(config('services.discord.base_url')."/guilds/{$this->workingGuild}/roles")
->throw()
->json();
}
}

View File

@ -1,32 +1,41 @@
<?php
namespace App\Helpers;
/**
* Class JSON - Used for JSON responses.
* @package App\Helpers
*/
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
*/
public function setResponseType($type): JSON
{
$this->type = $type;
return $this;
}
/**
* @param mixed $additional
* @param mixed $additional
*/
public function setAdditional($additional)
{
$this->additional = $additional;
return $this;
}
@ -55,12 +64,13 @@ class JSON
}
/**
* @param mixed $status
* @param mixed $status
* @return JSON
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
@ -73,12 +83,13 @@ class JSON
}
/**
* @param mixed $message
* @param mixed $message
* @return JSON
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
@ -91,12 +102,13 @@ class JSON
}
/**
* @param mixed $code
* @param mixed $code
* @return JSON
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
@ -109,12 +121,13 @@ class JSON
}
/**
* @param mixed $data
* @param mixed $data
* @return JSON
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
@ -126,17 +139,15 @@ class JSON
'meta' => [
'status' => $this->getStatus(),
'message' => $this->getMessage(),
]
],
];
if (!empty($this->additional))
{
foreach($this->additional as $additionalKeyName => $key)
{
if (! empty($this->additional)) {
foreach ($this->additional as $additionalKeyName => $key) {
$response[$additionalKeyName] = $key;
}
}
return response($response, $this->getCode(), $headers);
}
}

View File

@ -33,30 +33,28 @@ use Illuminate\Support\Facades\Log;
*/
class Options
{
/**
* 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
*
* @throws EmptyOptionsException
*/
public function getCategory(string $category): Collection
{
$options = Option::where('option_category', $category)->get();
if ($options->isEmpty())
{
throw new EmptyOptionsException('There are no options in category ' . $category);
if ($options->isEmpty()) {
throw new EmptyOptionsException('There are no options in category '.$category);
}
return $options;
}
public function getOption(string $option): string
{
$value = Cache::get($option);
if (is_null($value)) {
Log::debug('Option '.$option.'not found in cache, refreshing from database');
$value = Option::where('option_name', $option)->first();
@ -79,7 +77,7 @@ class Options
'option_name' => $option,
'option_value' => $value,
'friendly_name' => $description,
'option_category' => $category
'option_category' => $category,
]);
Cache::put($option, $value, now()->addDay());
@ -115,9 +113,9 @@ class Options
$dbOptionInstance->save();
Log::debug('New db configuration option saved',
[
'option' => $dbOptionInstance->option_value,
]);
[
'option' => $dbOptionInstance->option_value,
]);
Cache::put('option_name', $newValue, now()->addDay());
} else {

View File

@ -5,24 +5,20 @@ namespace App\Http\Controllers;
use App\Absence;
use App\Exceptions\AbsenceNotActionableException;
use App\Http\Requests\StoreAbsenceRequest;
use App\Http\Requests\UpdateAbsenceRequest;
use App\Services\AbsenceService;
use App\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
class AbsenceController extends Controller
{
private AbsenceService $absenceService;
public function __construct (AbsenceService $absenceService) {
public function __construct(AbsenceService $absenceService)
{
$this->absenceService = $absenceService;
}
/**
@ -38,11 +34,11 @@ class AbsenceController extends Controller
->with('absences', Absence::paginate(6));
}
/**
* Display a listing of absences belonging to the current user.
*
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws AuthorizationException
*/
public function showUserAbsences()
@ -54,11 +50,8 @@ class AbsenceController extends Controller
return view('dashboard.absences.own')
->with('absences', $absences);
}
/**
* Show the form for creating a new absence request.
*
@ -98,7 +91,8 @@ class AbsenceController extends Controller
/**
* Display the specified absence request.
*
* @param \App\Absence $absence
* @param \App\Absence $absence
*
* @throws AuthorizationException
*/
public function show(Absence $absence)
@ -107,28 +101,26 @@ class AbsenceController extends Controller
return view('dashboard.absences.view')
->with([
'absence' => $absence,
'totalDays' => Carbon::parse($absence->start)->diffInDays($absence->predicted_end)
'absence' => $absence,
'totalDays' => Carbon::parse($absence->start)->diffInDays($absence->predicted_end),
]);
}
/**
* Approve the specified absence.
*
* @param Absence $absence
* @param Absence $absence
* @return RedirectResponse
*
* @throws AuthorizationException
*/
public function approveAbsence(Absence $absence): RedirectResponse
{
$this->authorize('approve', $absence);
try
{
try {
$this->absenceService->approveAbsence($absence);
}
catch (AbsenceNotActionableException $notActionableException)
{
} catch (AbsenceNotActionableException $notActionableException) {
return redirect()
->back()
->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.'));
}
/**
* Decline the specified absence.
*
* @param Absence $absence
* @param Absence $absence
* @return RedirectResponse
*
* @throws AuthorizationException
*/
public function declineAbsence(Absence $absence): RedirectResponse
{
$this->authorize('decline', $absence);
try
{
try {
$this->absenceService->declineAbsence($absence);
} catch (AbsenceNotActionableException $notActionableException)
{
} catch (AbsenceNotActionableException $notActionableException) {
return redirect()
->back()
->with('error', $notActionableException->getMessage());
@ -166,24 +156,21 @@ class AbsenceController extends Controller
->with('success', __('Absence request successfully declined.'));
}
/**
* Cancel the specified absence.
*
* @param Absence $absence
* @param Absence $absence
* @return \Illuminate\Http\RedirectResponse
*
* @throws AuthorizationException
*/
public function cancelAbsence(Absence $absence): \Illuminate\Http\RedirectResponse
public function cancelAbsence(Absence $absence): RedirectResponse
{
$this->authorize('cancel', $absence);
try
{
try {
$this->absenceService->cancelAbsence($absence);
}
catch (AbsenceNotActionableException $notActionableException)
{
} catch (AbsenceNotActionableException $notActionableException) {
return redirect()
->back()
->with('error', $notActionableException->getMessage());

View File

@ -29,23 +29,19 @@ use App\Exceptions\IncompleteApplicationException;
use App\Exceptions\InvalidAgeException;
use App\Exceptions\UnavailableApplicationException;
use App\Exceptions\VacancyNotFoundException;
use App\Facades\IP;
use App\Services\ApplicationService;
use App\Vacancy;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ApplicationController extends Controller
{
private $applicationService;
public function __construct(ApplicationService $applicationService) {
public function __construct(ApplicationService $applicationService)
{
$this->applicationService = $applicationService;
}
public function showUserApps()
{
return view('dashboard.user.applications')
@ -67,7 +63,6 @@ class ApplicationController extends Controller
'canVote' => $this->applicationService->canVote($application->votes),
]
);
}
public function showAllApps(Request $request)
@ -76,42 +71,36 @@ class ApplicationController extends Controller
return view('dashboard.appmanagement.all')
->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);
return redirect(route('discordRedirect'));
return redirect(route('discordRedirect'));
}
public function renderApplicationForm($vacancySlug)
{
try {
return $this->applicationService->renderForm($vacancySlug);
}
catch (ApplicationNotFoundException $ex) {
} catch (ApplicationNotFoundException $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
} catch (DiscordAccountRequiredException $e) {
\Log::info('Redirecting user: ' . $e->getMessage(), [
'user' => Auth::user()->email
\Log::info('Redirecting user: '.$e->getMessage(), [
'user' => Auth::user()->email,
]);
request()->session()->put('discordApplicationRedirectedSlug', $vacancySlug);
return redirect(route('discordRedirect'));
} catch (IncompatibleAgeException $e) {
return redirect()
->to(route('dashboard'))
->with('error', $e->getMessage());
} catch (InvalidAgeException $e) {
return view('dashboard.application-rendering.add-age');
}
}
@ -121,9 +110,7 @@ class ApplicationController extends Controller
if (Auth::user()->isEligible()) {
try {
$this->applicationService->fillForm(Auth::user(), $request->all(), $vacancySlug);
} catch (VacancyNotFoundException | IncompleteApplicationException | UnavailableApplicationException $e) {
} catch (VacancyNotFoundException|IncompleteApplicationException|UnavailableApplicationException $e) {
return redirect()
->back()
->with('error', $e->getMessage());
@ -146,8 +133,7 @@ class ApplicationController extends Controller
try {
$status = $this->applicationService->updateStatus($application, $newStatus);
} catch (\LogicException $ex)
{
} catch (\LogicException $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
@ -170,6 +156,5 @@ class ApplicationController extends Controller
return redirect()
->back()
->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
{
private $appointmentService;
private $meetingNoteService;
public function __construct(AppointmentService $appointmentService, MeetingNoteService $meetingNoteService) {
public function __construct(AppointmentService $appointmentService, MeetingNoteService $meetingNoteService)
{
$this->appointmentService = $appointmentService;
$this->meetingNoteService = $meetingNoteService;
}
@ -56,7 +55,7 @@ class AppointmentController extends Controller
return redirect()
->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()
->back()
->with('success', __("Interview finished! Staff members can now vote on it."));
}
catch (InvalidAppointmentStatusException $ex) {
->with('success', __('Interview finished! Staff members can now vote on it.'));
} catch (InvalidAppointmentStatusException $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
@ -86,35 +83,26 @@ class AppointmentController extends Controller
$this->authorize('update', $application->appointment);
try {
$this->appointmentService->deleteAppointment($application, $request->reason);
return redirect()
->back()
->with('success', __('Appointment cancelled.'));
}
catch (\Exception $ex) {
} catch (\Exception $ex) {
return redirect()
->back()
->with('error', $ex->getMessage());
}
}
public function saveNotes(SaveNotesRequest $request, Application $application)
{
try {
$this->meetingNoteService->addToApplication($application, $request->noteText);
return redirect()
->back()
->with('success', __('Saved notes.'));
} catch (InvalidAppointmentException $ex) {
return redirect()
->back()

View File

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

View File

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

View File

@ -21,15 +21,12 @@
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\Options;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
@ -74,8 +71,7 @@ class RegisterController extends Controller
{
$password = ['required', 'string', 'confirmed'];
switch (Options::getOption('pw_security_policy'))
{ // this could be better structured, switch doesn't feel right
switch (Options::getOption('pw_security_policy')) { // this could be better structured, switch doesn't feel right
case 'off':
$password = ['required', 'string', 'confirmed'];
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.required' => __('Please enter your date of birth.'),
'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';
$user = User::create([
'uuid' => $data['uuid'] ?? "disabled",
'uuid' => $data['uuid'] ?? 'disabled',
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'registrationIp' => $ip,
'currentIp' => $ip,
'dob' => $data['dob']
'dob' => $data['dob'],
]);
$user->assignRole('user');

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,46 +4,38 @@ 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
use App\Exceptions\FileUploadException;
use App\Http\Requests\UploadFileRequest;
use App\Services\TeamFileService;
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\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
{
private $fileService;
public function __construct(TeamFileService $fileService) {
public function __construct(TeamFileService $fileService)
{
$this->fileService = $fileService;
}
/**
* Display a listing of the resource.
*
* @param Request $request
* @param Request $request
*/
public function index(Request $request)
{
$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.'));
return redirect()->to(route('teams.index'));
}
@ -51,19 +43,17 @@ class TeamFileController extends Controller
->with('files', TeamFile::with('team', 'uploader')->paginate(6));
}
/**
* Store a newly created resource in storage.
*
* @param UploadFileRequest $request
* @param UploadFileRequest $request
* @return RedirectResponse
*/
public function store(UploadFileRequest $request)
{
$this->authorize('store', TeamFile::class);
if (config('demo.is_enabled'))
{
if (config('demo.is_enabled')) {
return redirect()
->back()
->with('error', __('This feature is disabled'));
@ -78,61 +68,49 @@ class TeamFileController extends Controller
return redirect()
->back()
->with('success', __('File uploaded successfully.'));
} catch (FileUploadException $uploadException) {
return redirect()
->back()
->with('error', $uploadException->getMessage());
}
}
public function download(Request $request, TeamFile $teamFile)
{
$this->authorize('download', TeamFile::class);
try
{
try {
return Storage::download($teamFile->fs_location, $teamFile->name);
}
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.'));
return redirect()->back();
} 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.'));
return redirect()->back();
}
}
/**
* Remove the specified resource from storage.
*
* @param Request $request
* @param \App\TeamFile $teamFile
* @param Request $request
* @param \App\TeamFile $teamFile
* @return RedirectResponse
*/
public function destroy(Request $request, TeamFile $teamFile)
{
$this->authorize('delete', $teamFile);
if (config('demo.is_enabled'))
{
if (config('demo.is_enabled')) {
return redirect()
->back()
->with('error', __('This feature is disabled'));
}
try
{
try {
Storage::delete($teamFile->fs_location);
$teamFile->delete();
$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()]));
}

View File

@ -22,7 +22,6 @@
namespace App\Http\Controllers;
use App\Ban;
use App\Facades\IP;
use App\Facades\Options;
use App\Http\Requests\Add2FASecretRequest;
use App\Http\Requests\AddDobRequest;
@ -44,7 +43,6 @@ use App\Services\AccountSuspensionService;
use App\Services\DiscordService;
use App\Traits\DisablesFeatures;
use App\Traits\HandlesAccountDeletion;
use App\Traits\ReceivesAccountTokens;
use App\User;
use Google2FA;
use Illuminate\Contracts\Foundation\Application;
@ -61,11 +59,11 @@ class UserController extends Controller
{
use HandlesAccountDeletion, DisablesFeatures;
/**
* Shows list of users
*
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function showUsers()
@ -80,13 +78,14 @@ class UserController extends Controller
]);
}
/**
* Searches for a player with the given search query.
*
* @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
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function showPlayersLike(SearchPlayerRequest $request)
@ -115,12 +114,12 @@ class UserController extends Controller
}
}
/**
* 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
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
@ -138,9 +137,9 @@ class UserController extends Controller
}
$QRCode = Google2FA::getQRCodeInline(
config('app.name'),
$request->user()->email,
$twoFactorSecret
config('app.name'),
$request->user()->email,
$twoFactorSecret
);
}
@ -149,19 +148,18 @@ class UserController extends Controller
->with('twofaQRCode', $QRCode);
}
/**
* Show account management screen
*
* @param AccountSuspensionService $suspensionService
* @param Request $request
* @param User $user
* @param AccountSuspensionService $suspensionService
* @param Request $request
* @param User $user
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function showAcocuntManagement(AccountSuspensionService $suspensionService, Request $request, User $user)
{
$this->authorize('adminEdit', $user);
$systemRoles = Role::all()->pluck('name')->all();
@ -179,7 +177,7 @@ class UserController extends Controller
return view('dashboard.user.manage')
->with([
'user' => $user,
'user' => $user,
'roles' => $roleList,
'isVerified' => $user->isVerified(),
'isLocked' => $suspensionService->isLocked($user),
@ -190,15 +188,16 @@ class UserController extends Controller
'suspensionReason' => $suspensionService->getSuspensionReason($user),
'suspensionDuration' => $suspensionService->getSuspensionDuration($user),
'has2FA' => $user->has2FA(),
'applications' => $user->applications()->get()
'applications' => $user->applications()->get(),
]);
}
/**
* Log out other sessions for the current user
*
* @param FlushSessionsRequest $request
* @param FlushSessionsRequest $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function flushSessions(FlushSessionsRequest $request)
@ -208,23 +207,21 @@ class UserController extends Controller
Auth::logoutOtherDevices($request->currentPasswordFlush);
Log::notice('User '.Auth::user()->name.' has logged out other devices in their account',
[
'originIPAddress' => $request->ip(),
'userID' => Auth::user()->id,
'timestamp' => now(),
]);
[
'originIPAddress' => $request->ip(),
'userID' => Auth::user()->id,
'timestamp' => now(),
]);
$request->session()->flash('success', __('Successfully logged out other devices. Remember to change your password if you think you\'ve been compromised.'));
return redirect()->back();
}
/**
* Change the current user's password
*
* @param ChangePasswordRequest $request
* @param ChangePasswordRequest $request
* @return \Illuminate\Http\RedirectResponse|void
*/
public function changePassword(ChangePasswordRequest $request)
@ -255,17 +252,15 @@ class UserController extends Controller
}
}
/**
* Sets a new password for the user.
*
* @param SetNewPasswordRequest $request
* @param SetNewPasswordRequest $request
* @return Application|RedirectResponse|Redirector
*/
public function setPassword(SetNewPasswordRequest $request) {
if (!Auth::user()->hasPassword()) {
public function setPassword(SetNewPasswordRequest $request)
{
if (! Auth::user()->hasPassword()) {
Auth::user()->password = Hash::make($request->newpass);
Auth::user()->save();
@ -281,12 +276,11 @@ class UserController extends Controller
->with('error', __('Your account already has a password.'));
}
/**
* Sets a user's password and removes their discord information from storage
*
* @param User $user
* @param SetNewPasswordRequest $request
* @param User $user
* @param SetNewPasswordRequest $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function unlinkDiscordAccount(Request $request, DiscordService $discordService)
@ -295,40 +289,39 @@ class UserController extends Controller
try {
$discordService->revokeAccountTokens(Auth::user());
Log::warning('Revoking social account tokens, user initiated', [
'user' => Auth::user()->email
'user' => Auth::user()->email,
]);
} catch (RequestException $requestException) {
if ($requestException->getCode() == 401) {
return redirect(route('discordRedirect'));
}
Log::error('Error while trying to revoke Discord credentials', [$requestException->getMessage()]);
return redirect()
->back()
->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.'));
return redirect()->back();
}
return redirect()
->back()
->with('error', __('Please set a password for your account first before trying to unlink Discord.'));
}
/**
* Change the current user's email address
*
* @param ChangeEmailRequest $request
* @param ChangeEmailRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function changeEmail(ChangeEmailRequest $request)
{
$this->disable();
$this->disable();
$user = User::find(Auth::user()->id);
@ -351,16 +344,16 @@ class UserController extends Controller
return redirect()->back();
}
/**
* 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
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function forcePasswordReset(User $user) {
public function forcePasswordReset(User $user)
{
$this->authorize('adminEdit', $user);
if ($user->hasPassword()) {
@ -369,10 +362,9 @@ class UserController extends Controller
$user->password = null;
$user->save();
Log::alert("Removed account password", [
Log::alert('Removed account password', [
'target' => $user,
'actor' => Auth::user()
'actor' => Auth::user(),
]);
return redirect()
@ -385,15 +377,14 @@ class UserController extends Controller
->with('error', __('This user doesn\'t have a password to reset.'));
}
/**
* Adds a user's date of birth if they don't have one.
*
* @param AddDobRequest $request
* @param AddDobRequest $request
* @return RedirectResponse
*/
public function addDob(AddDobRequest $request) {
public function addDob(AddDobRequest $request)
{
Auth::user()->dob = $request->dob;
Auth::user()->save();
@ -401,13 +392,13 @@ class UserController extends Controller
->back();
}
/**
* Delete the given user's account
*
* @param DeleteUserRequest $request
* @param User $user
* @param DeleteUserRequest $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function delete(DeleteUserRequest $request, User $user)
@ -426,13 +417,13 @@ class UserController extends Controller
return redirect()->route('registeredPlayerList');
}
/**
* Update a given user's details
*
* @param UpdateUserRequest $request
* @param User $user
* @param UpdateUserRequest $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(UpdateUserRequest $request, User $user)
@ -470,12 +461,12 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Generate and add a 2FA secret for the current user
*
* @param Add2FASecretRequest $request
* @param Add2FASecretRequest $request
* @return \Illuminate\Http\RedirectResponse
*
* @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
* @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
* @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
@ -522,11 +513,10 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Remove the current user's two factor secret key
*
* @param Remove2FASecretRequest $request
* @param Remove2FASecretRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function remove2FASecret(Remove2FASecretRequest $request)
@ -544,15 +534,15 @@ class UserController extends Controller
return redirect()->back();
}
/**
* Remove the given user's two factor secret key
*
* @param Reset2FASecretRequest $request
* @param User $user
* @param Reset2FASecretRequest $request
* @param User $user
* @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
if ($user->has2FA()) {
Log::warning('SECURITY: Disabling two factor authentication (admin initiated)', [
@ -580,10 +570,11 @@ class UserController extends Controller
/**
* Suspend the given user
*
* @param AccountSuspensionService $suspensionService
* @param BanUserRequest $request
* @param User $user
* @param AccountSuspensionService $suspensionService
* @param BanUserRequest $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function suspend(AccountSuspensionService $suspensionService, BanUserRequest $request, User $user)
@ -591,17 +582,15 @@ class UserController extends Controller
$this->authorize('create', [Ban::class, $user]);
$this->disable();
if ($suspensionService->isSuspended($user))
{
if ($suspensionService->isSuspended($user)) {
return redirect()
->back()
->with('error', __('Account already suspended.'));
}
if ($request->suspensionType = "on") {
if ($request->suspensionType = 'on') {
$suspensionService->suspend($user, $request->reason, $request->duration);
}
else {
} else {
$suspensionService->suspend($user, $request->reason);
}
@ -611,10 +600,11 @@ class UserController extends Controller
/**
* Unsuspend the given user
*
* @param AccountSuspensionService $suspensionService
* @param Request $request
* @param User $user
* @param AccountSuspensionService $suspensionService
* @param Request $request
* @param User $user
* @return \Illuminate\Http\RedirectResponse
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function unsuspend(AccountSuspensionService $suspensionService, Request $request, User $user)
@ -623,15 +613,12 @@ class UserController extends Controller
$this->disable();
if ($suspensionService->isSuspended($user)) {
$suspensionService->unsuspend($user);
$request->session()->flash('success', __('Account unsuspended successfully!'));
} else {
$request->session()->flash('error', __('This account isn\'t suspended!'));
}
return redirect()->back();
}
}

View File

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

View File

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

View File

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

View File

@ -36,7 +36,6 @@ class ForceLogoutMiddleware
*/
public function handle($request, Closure $next)
{
if ((new AccountSuspensionService())->isSuspended(Auth::user())) {
Auth::logout();
$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)
{
if(Auth::check())
{
if (Auth::check()) {
$sinceUpdate = Carbon::parse(Auth::user()->password_last_updated)->diffInDays(now());
$updateThreshold = Options::getOption('password_expiry');
if ($updateThreshold !== 0 && $sinceUpdate > $updateThreshold)
{
if ($updateThreshold !== 0 && $sinceUpdate > $updateThreshold) {
session()->put('passwordExpired', true);
}
else
{
} else {
session()->put('passwordExpired', false);
}
}
return $next($request);

View File

@ -17,8 +17,7 @@ class PasswordExpirationRedirectMiddleware
*/
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.
return redirect(route('showAccountSettings'));
}

View File

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

View File

@ -53,7 +53,7 @@ class BanUserRequest extends FormRequest
public function messages()
{
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()
{
return [
'reason' => 'string|required'
'reason' => 'string|required',
];
}
}

View File

@ -29,7 +29,7 @@ class ProfileSave extends FormRequest
/**
* Determine if the user is authorized to make this request.
*
* @param Profile $profile
* @param Profile $profile
* @return bool
*/
public function authorize(Profile $profile)

View File

@ -28,7 +28,7 @@ class SaveSecuritySettings extends FormRequest
'graceperiod' => 'required|integer',
'pwExpiry' => 'required|integer',
'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\Support\Facades\Auth;
class StoreAbsenceRequest extends FormRequest
{
/**
@ -30,7 +29,7 @@ class StoreAbsenceRequest extends FormRequest
'start_date' => 'required|date',
'predicted_end' => 'required|date|after:start_date',
'available_assist' => 'required|string',
'invalidAbsenceAgreement' => 'required|accepted'
'invalidAbsenceAgreement' => 'required|accepted',
];
}
}

View File

@ -26,7 +26,7 @@ class UploadFileRequest extends FormRequest
return [
'caption' => 'required|string|max:100',
'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',
'vacancyCount' => 'required|integer|min:1',
'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',
'vacancyFormID' => 'required|integer',
'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)),
'response' => new ResponseResource(Response::findOrFail($this->applicantFormResponseID)),
'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),
'formStatus' => $this->formStatus,
'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),
'vacancy' => new VacancyResource(Vacancy::findOrFail($this->associatedVacancyID)),
'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,
'created_at' => $this->created_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\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
@ -25,7 +24,6 @@ class ProcessAccountDelete implements ShouldQueue
*/
protected User $user;
/**
* Create a new job instance.
*
@ -44,7 +42,7 @@ class ProcessAccountDelete implements ShouldQueue
public function handle()
{
Log::alert('[Worker] Processing account deletion request', [
'email' => $this->user->email
'email' => $this->user->email,
]);
$email = $this->user->email;
@ -52,7 +50,7 @@ class ProcessAccountDelete implements ShouldQueue
if ($this->user->delete()) {
Notification::route('mail', [
$email => $name
$email => $name,
])->notify(new AccountDeleted($name));
// Notify admins

View File

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

View File

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

View File

@ -40,7 +40,7 @@ class DenyUser
/**
* Handle the event.
*
* @param ApplicationDeniedEvent $event
* @param ApplicationDeniedEvent $event
* @return void
*/
public function handle(ApplicationDeniedEvent $event)

View File

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

View File

@ -50,10 +50,9 @@ class OnUserRegistration
Log::info('User '.$event->user->name.' has just registered for an account.');
User::whereHas('roles', function ($q) {
$q->where('name', 'admin');
$q->where('name', 'admin');
})->get()->each(function ($user, $key) use ($event) {
$user->notify(new NewUser($event->user));
});
}
}

View File

@ -40,7 +40,7 @@ class PromoteUser
/**
* Handle the event.
*
* @param ApplicationApprovedEvent $event
* @param ApplicationApprovedEvent $event
* @return void
*/
public function handle(ApplicationApprovedEvent $event)
@ -48,7 +48,7 @@ class PromoteUser
Log::info('User promoted automatically (application approved)', [
'user' => $event->application->user->name,
'vacancy' => $event->application->response->vacancy->vacancyName,
'role' => 'staff'
'role' => 'staff',
]);
$event->application->setStatus('APPROVED');

View File

@ -31,11 +31,16 @@ class UserAccountDeleteConfirmation extends Mailable
use Queueable, SerializesModels;
public string
$approveLink,
$cancelLink,
$name,
$userID;
$approveLink;
public string
$cancelLink;
public string
$name;
public string
$userID;
/**
* Create a new message instance.
@ -58,7 +63,7 @@ class UserAccountDeleteConfirmation extends Mailable
*/
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 File

@ -44,13 +44,13 @@ class AbsenceRequestApproved extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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 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])))
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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('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')))
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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('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')))
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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('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')))
->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
return (new MailMessage)
->greeting('Hi ' . $this->name . ',')
->greeting('Hi '.$this->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - account deleted permanently')
->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('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!')
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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('If there\'s anything we can help you with, don\'t hesitate to reach out.')
->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;
/**
* @var Application The application we're notifying about
*/
public Application $application;
/**
* @var User The candidate
*/
@ -76,7 +74,7 @@ class ApplicationApproved extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - application approved')
->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('Good luck and welcome aboard!')
->action('Sign in', url(route('login')))
->salutation('The team at ' . config('app.name'));
->salutation('The team at '.config('app.name'));
}
public function toSlack($notifiable)

View File

@ -4,7 +4,6 @@ namespace App\Notifications;
use App\Application;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
@ -44,13 +43,13 @@ class ApplicationConfirmed extends Notification
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->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('You will receive regular notifications about your application\'s status.')
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - application denied')
->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('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])))
->salutation('The team at ' . config('app.name'));
->salutation('The team at '.config('app.name'));
}
public function toSlack($notifiable)

View File

@ -46,15 +46,16 @@ class ApplicationMoved extends Notification implements ShouldQueue
public function channels()
{
Log::debug('Application moved notification: channels chosen', [
'channels' => $this->chooseChannelsViaOptions()
'channels' => $this->chooseChannelsViaOptions(),
]);
return $this->chooseChannelsViaOptions();
}
public function optOut($notifiable)
{
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;
@ -69,13 +70,13 @@ class ApplicationMoved extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - application updated')
->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.')
->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 Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
@ -14,7 +13,9 @@ class AppointmentCancelled extends Notification
use Queueable;
private $application;
private $reason;
private $appointmentDate;
/**
@ -51,16 +52,16 @@ class AppointmentCancelled extends Notification
// TODO: Switch to HTML & Blade.
return (new MailMessage)
->greeting("Hi " . $notifiable->name . ",")
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - interview cancelled')
->line('The interview that was previously scheduled with you has been cancelled.')
->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('Your application will likely be declined if you do not reschedule an interview.')
->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;
public $appointment;
/**
@ -64,14 +63,13 @@ class AppointmentFinished extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting("Hi " . $notifiable->name . ",")
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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.')
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - Interview scheduled')
->line('An interview has been scheduled for you @ '.$this->appointment->appointmentDate.'.')
->line('With the following details: '.$this->appointment->appointmentDescription)
->line('This meeting will take place @ '.$this->appointment->appointmentLocation.'.')
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - Account password 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.')
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - Email address changed')
->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.')
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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("You are receiving this email because you're a site admin.")
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - New application')
->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').'.')
->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)

View File

@ -60,13 +60,13 @@ class NewComment extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - New comment')
->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.')
->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',
])) {
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('This is what they sent: ')
->line('')
@ -75,7 +75,7 @@ class NewContact extends Notification
->line('')
->line('This message was received from '.$this->message->get('ip').' and submitted by '.$this->message->get('email').'.')
->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!');

View File

@ -66,14 +66,14 @@ class NewUser extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - New user')
->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.')
->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)

View File

@ -67,13 +67,13 @@ class UserBanned extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->line('Hello, ')
->line('Moderators have just suspended user '.$this->user->name.' for '.$this->ban->reason)
->line('This ban will remain in effect until '.$this->ban->bannedUntil.'.')
->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)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->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('You are receiving this email because you\'re a site admin.')
->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 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
$statusDict = [
'open' => 'opened',
'close' => 'closed'
'close' => 'closed',
];
$this->vacancy = $vacancy;
@ -69,16 +68,15 @@ class VacancyStatusUpdated extends Notification implements ShouldQueue
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hi ' . $notifiable->name . ',')
->greeting('Hi '.$notifiable->name.',')
->from(config('notification.sender.address'), config('notification.sender.name'))
->subject(config('app.name').' - Vacancy ' . $this->status)
->line('The vacancy '.$this->vacancy->vacancyName.', with '.$this->vacancy->vacancyCount.' remaining slots, has just been ' . $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('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.')
->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\ProfileCreationFailedException;
use App\Profile;
use App\Services\ProfileService;
use App\User;
use Illuminate\Support\Facades\Log;
@ -45,20 +44,15 @@ class UserObserver
{
$profileService = new ProfileService();
try
{
try {
$profileService->createProfile($user);
}
catch (ProfileAlreadyExistsException $exception)
{
} catch (ProfileAlreadyExistsException $exception) {
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!', [
'trace' => $e->getTrace()
'trace' => $e->getTrace(),
]);
}
}

View File

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

View File

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

View File

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

View File

@ -32,7 +32,7 @@ class AppointmentPolicy
/**
* Determine whether the user can view any models.
*
* @param User $user
* @param User $user
* @return mixed
*/
public function viewAny(User $user)
@ -43,8 +43,8 @@ class AppointmentPolicy
/**
* Determine whether the user can view the model.
*
* @param User $user
* @param Appointment $appointment
* @param User $user
* @param Appointment $appointment
* @return mixed
*/
public function view(User $user, Appointment $appointment)
@ -55,7 +55,7 @@ class AppointmentPolicy
/**
* Determine whether the user can create models.
*
* @param User $user
* @param User $user
* @return mixed
*/
public function create(User $user)
@ -66,8 +66,8 @@ class AppointmentPolicy
/**
* Determine whether the user can update the model.
*
* @param User $user
* @param Appointment $appointment
* @param User $user
* @param Appointment $appointment
* @return mixed
*/
public function update(User $user, Appointment $appointment)
@ -78,8 +78,8 @@ class AppointmentPolicy
/**
* Determine whether the user can delete the model.
*
* @param User $user
* @param Appointment $appointment
* @param User $user
* @param Appointment $appointment
* @return mixed
*/
public function delete(User $user, Appointment $appointment)
@ -90,8 +90,8 @@ class AppointmentPolicy
/**
* Determine whether the user can restore the model.
*
* @param User $user
* @param Appointment $appointment
* @param User $user
* @param Appointment $appointment
* @return mixed
*/
public function restore(User $user, Appointment $appointment)
@ -102,8 +102,8 @@ class AppointmentPolicy
/**
* Determine whether the user can permanently delete the model.
*
* @param User $user
* @param Appointment $appointment
* @param User $user
* @param Appointment $appointment
* @return mixed
*/
public function forceDelete(User $user, Appointment $appointment)

View File

@ -57,8 +57,8 @@ class BanPolicy
/**
* Determine whether the user can create models.
*
* @param \App\User $user
* @param User $targetUser
* @param \App\User $user
* @param User $targetUser
* @return mixed
*/
public function create(User $user, User $targetUser)

View File

@ -37,11 +37,9 @@ class TeamPolicy
return $user->isOwnerOfTeam($team) || $user->hasPermissionTo('teams.update');
}
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;
}

View File

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

View File

@ -22,13 +22,11 @@
namespace App\Providers;
use App\Absence;
use App\ApiKey;
use App\Application;
use App\Appointment;
use App\Ban;
use App\Form;
use App\Policies\AbsencePolicy;
use App\Policies\ApiKeyPolicy;
use App\Policies\ApplicationPolicy;
use App\Policies\AppointmentPolicy;
use App\Policies\BanPolicy;
@ -69,7 +67,7 @@ class AuthServiceProvider extends ServiceProvider
Appointment::class => AppointmentPolicy::class,
Team::class => TeamPolicy::class,
TeamFile::class => TeamFilePolicy::class,
Absence::class => AbsencePolicy::class
Absence::class => AbsencePolicy::class,
];
/**
@ -82,25 +80,23 @@ class AuthServiceProvider extends ServiceProvider
$this->registerPolicies();
VerifyEmail::toMailUsing(function ($notifiable, $url) {
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('If you didn\'t sign up for an account, you can safely ignore this email.')
->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');
});
Gate::define('downloadLogFile', function (User $user){
return $user->hasPermissionTo('admin.developertools.use');
Gate::define('downloadLogFile', function (User $user) {
return $user->hasPermissionTo('admin.developertools.use');
});
Gate::define('deleteLogFile', function (User $user){
Gate::define('deleteLogFile', function (User $user) {
return $user->hasPermissionTo('admin.developertools.use');
});
}

View File

@ -2,8 +2,8 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App;
use Illuminate\Support\ServiceProvider;
class DigitalStorageProvider extends ServiceProvider
{
@ -24,7 +24,7 @@ class DigitalStorageProvider extends ServiceProvider
*/
public function boot()
{
App::bind('digitalStorageHelperFacadeRoot', function (){
App::bind('digitalStorageHelperFacadeRoot', function () {
return new App\Helpers\DigitalStorageHelper();
});
}

View File

@ -25,11 +25,6 @@ use App\Application;
use App\Listeners\LogAuthenticationFailure;
use App\Listeners\LogAuthenticationSuccess;
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\Login;
use Illuminate\Auth\Events\Registered;

View File

@ -26,7 +26,7 @@ class JSONProvider extends ServiceProvider
public function boot()
{
App::bind('json', function () {
return new JSON();
return new JSON();
});
}
}

View File

@ -15,29 +15,24 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Spatie\Permission\Models\Role;
class AbsenceService
{
/**
* 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
*/
public function hasActiveRequest(Authenticatable $user): bool {
public function hasActiveRequest(Authenticatable $user): bool
{
$absences = Absence::where('requesterID', $user->id)->get();
foreach ($absences as $absence) {
// 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
// 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;
}
}
@ -47,12 +42,11 @@ class AbsenceService
public function createAbsence(Authenticatable $requester, Request $request)
{
$absence = Absence::create([
'requesterID' => $requester->id,
'start' => $request->start_date,
'predicted_end' => $request->predicted_end,
'available_assist' => $request->available_assist == "on",
'available_assist' => $request->available_assist == 'on',
'reason' => $request->reason,
'status' => 'PENDING',
]);
@ -65,22 +59,21 @@ class AbsenceService
}
});
Log::info('Processing new leave of absence request.', [
'requesting_user' => $requester->email,
'absenceid' => $absence->id,
'reason' => $request->reason
'reason' => $request->reason,
]);
return $absence;
}
/**
* Sets an absence as Approved.
*
* @param Absence $absence The absence to approve.
* @param Absence $absence The absence to approve.
* @return Absence The approved absence.
*
* @throws AbsenceNotActionableException
*/
public function approveAbsence(Absence $absence)
@ -88,19 +81,19 @@ class AbsenceService
Log::info('An absence request has just been approved.', [
'absenceid' => $absence->id,
'reviewing_admim' => Auth::user()->email,
'new_status' => 'APPROVED'
'new_status' => 'APPROVED',
]);
$absence->setApproved()
->requester->notify(new AbsenceRequestApproved($absence));
}
/**
* Sets an absence as Declined.
*
* @param Absence $absence The absence to decline.
* @param Absence $absence The absence to decline.
* @return Absence The declined absence.
*
* @throws AbsenceNotActionableException
*/
public function declineAbsence(Absence $absence)
@ -108,26 +101,26 @@ class AbsenceService
Log::warning('An absence request has just been declined.', [
'absenceid' => $absence->id,
'reviewing_admim' => Auth::user()->email,
'new_status' => 'DECLINED'
'new_status' => 'DECLINED',
]);
$absence->setDeclined()
->requester->notify(new AbsenceRequestDeclined($absence));
}
/**
* Sets an absence as Cancelled.
*
* @param Absence $absence The absence to cancel.
* @param Absence $absence The absence to cancel.
* @return Absence The cancelled absence.
*
* @throws AbsenceNotActionableException
*/
public function cancelAbsence(Absence $absence)
{
Log::warning('An absence request has just been cancelled (only cancellable by requester).', [
'absenceid' => $absence->id,
'new_status' => 'CANCELLED'
'new_status' => 'CANCELLED',
]);
$absence->setCancelled()
@ -137,14 +130,14 @@ class AbsenceService
/**
* Sets an absence as Ended.
*
* @param Absence $absence
* @param Absence $absence
* @return bool
*/
public function endAbsence(Absence $absence)
{
Log::info('An absence request has just expired.', [
'absenceid' => $absence->id,
'new_status' => 'ENDED'
'new_status' => 'ENDED',
]);
$absence->setEnded()
@ -154,7 +147,7 @@ class AbsenceService
/**
* Removes an absence
*
* @param Absence $absence The absence to remove.
* @param Absence $absence The absence to remove.
* @return bool Whether the absence was removed.
*/
public function removeAbsence(Absence $absence): bool
@ -169,20 +162,16 @@ class AbsenceService
/**
* End all expired absences in the application
*
* @return void
*/
public function endExpired(): void
{
foreach (Absence::all() as $absence)
{
foreach (Absence::all() as $absence) {
// 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);
}
}
}
}

View File

@ -1,5 +1,6 @@
<?php declare(strict_types=1);
<?php
declare(strict_types=1);
namespace App\Services;
@ -13,22 +14,21 @@ use Illuminate\Support\Facades\Log;
class AccountSuspensionService
{
/**
* Suspends a user account, with given $reason.
* Permanent if no duration given.
*
* @param User $target Who to suspend.
* @param string $reason Suspension reason.
* @param int|null $duration Duration in days
* @param User $target Who to suspend.
* @param string $reason Suspension reason.
* @param int|null $duration Duration in days
* @return Ban The ban itself
*/
public function suspend(User $target, string $reason, int $duration = null): Ban {
Log::alert("An user account has just been suspended.", [
public function suspend(User $target, string $reason, int $duration = null): Ban
{
Log::alert('An user account has just been suspended.', [
'taget_email' => $target->email,
'suspended_by' => Auth::user()->email,
'reason' => $reason
'reason' => $reason,
]);
if ($duration > 0) {
@ -40,18 +40,18 @@ class AccountSuspensionService
'reason' => $reason,
'bannedUntil' => ($duration > 0) ? $expiryDate->format('Y-m-d H:i:s') : null,
'authorUserID' => Auth::user()->id,
'isPermanent' => ($duration == 0) ? true : false
'isPermanent' => ($duration == 0) ? true : false,
]);
}
/**
* Lifts someone's suspension
*
* @param User $user The user to unsuspend
* @param User $user The user to unsuspend
*/
public function unsuspend(User $user): void {
Log::alert("A suspension has just been lifted.", [
public function unsuspend(User $user): void
{
Log::alert('A suspension has just been lifted.', [
'target_email' => $user->email,
]);
@ -61,29 +61,27 @@ class AccountSuspensionService
/**
* Checks whether a user is suspended
*
* @param User $user The user to check
* @param User $user The user to check
* @return bool Whether the mentioned user is suspended
*/
public function isSuspended(User $user): bool {
return !is_null($user->bans);
public function isSuspended(User $user): bool
{
return ! is_null($user->bans);
}
/**
* Sets an administrative lock on a user account.
* Used to prevent logins after a deletion process is initiated, but may be used for
* other things where a suspension is not necessary/warranted, such as a security breach event.
* These locks cannot be overridden manually be administrators.
*
* @param User $user The account to lock
* @param User $user The account to lock
* @return bool
*/
public function lockAccount(User $user): bool
{
Log::alert('User account locked!', [
'email' => $user->email
'email' => $user->email,
]);
$user->administratively_locked = 1;
@ -92,17 +90,16 @@ class AccountSuspensionService
return $user->save();
}
/**
* Unlocks a user account. Reverse of lockAccount().
*
* @param User $user
* @param User $user
* @return bool
*/
public function unlockAccount(User $user): bool
{
Log::alert('User account unlocked!', [
'email' => $user->email
'email' => $user->email,
]);
$user->administratively_locked = 0;
@ -114,25 +111,28 @@ class AccountSuspensionService
/**
* Checks whether an account is locked
*
* @param User $user The user to check
* @param User $user The user to check
* @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;
}
/**
* Retrieves the reason for the user's suspension.
*
* @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
*/
public function getSuspensionReason(User $user): string|bool {
public function getSuspensionReason(User $user): string|bool
{
return ($this->isSuspended($user)) ? $user->bans->reason : false;
}
public function getSuspensionDuration(User $user): string|null {
if ($this->isSuspended($user) && !is_null($user->bans->bannedUntil)) {
public function getSuspensionDuration(User $user): string|null
{
if ($this->isSuspended($user) && ! is_null($user->bans->bannedUntil)) {
return $user->bans->bannedUntil->diffForHumans();
}
@ -149,6 +149,4 @@ class AccountSuspensionService
// Unban on the last day, not on the exact time (with Carbon::now()).
return (bool) Ban::whereDate('bannedUntil', '=', Carbon::today())->delete();
}
}

View File

@ -1,26 +1,24 @@
<?php
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\Events\ApplicationDeniedEvent;
use App\Exceptions\ApplicationNotFoundException;
use App\Exceptions\DiscordAccountRequiredException;
use App\Exceptions\IncompatibleAgeException;
use App\Exceptions\IncompleteApplicationException;
use App\Exceptions\InvalidAgeException;
use App\Exceptions\UnavailableApplicationException;
use App\Exceptions\VacancyNotFoundException;
use App\Notifications\ApplicationConfirmed;
use App\Notifications\ApplicationMoved;
use App\Notifications\NewApplicant;
use App\Response;
use App\User;
use App\Vacancy;
use Illuminate\Auth\Authenticatable;
use Carbon\Carbon;
use ContextAwareValidator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
@ -37,26 +35,23 @@ class ApplicationService
$firstVacancy = $vacancyWithForm->first();
if (is_null(Auth::user()->dob)) {
throw new InvalidAgeException("User must have added their age to apply for this vacancy.");
} elseif(Carbon::parse(Auth::user()->dob)->age < $firstVacancy->requiredAge) {
throw new InvalidAgeException('User must have added their age to apply for this vacancy.');
} 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}.");
}
if ($firstVacancy->requiresDiscord && !Auth::user()->hasDiscordConnection()) {
if ($firstVacancy->requiresDiscord && ! Auth::user()->hasDiscordConnection()) {
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')
->with([
'vacancy' => $vacancyWithForm->first(),
'preprocessedForm' => json_decode($vacancyWithForm->first()->forms->formStructure, true),
]);
} else {
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();
if ($vacancy->isEmpty()) {
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') {
throw new UnavailableApplicationException("This application is unavailable.");
throw new UnavailableApplicationException('This application is unavailable.');
}
Log::info('Processing new application!');
@ -87,10 +79,9 @@ class ApplicationService
$formStructure = json_decode($vacancy->first()->forms->formStructure, true);
$responseValidation = ContextAwareValidator::getResponseValidator($formData, $formStructure);
Log::info('Built response & validator structure!');
if (!$responseValidation->get('validator')->fails()) {
if (! $responseValidation->get('validator')->fails()) {
$response = Response::create([
'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
@ -99,7 +90,7 @@ class ApplicationService
Log::info('Registered form response!', [
'applicant' => $applicant->name,
'vacancy' => $vacancy->first()->vacancyName
'vacancy' => $vacancy->first()->vacancyName,
]);
$application = Application::create([
@ -110,7 +101,7 @@ class ApplicationService
Log::info('Submitted an application!', [
'responseID' => $response->id,
'applicant' => $applicant->name
'applicant' => $applicant->name,
]);
User::whereHas('roles', function ($q) {
@ -122,10 +113,9 @@ class ApplicationService
$application->user->notify(new ApplicationConfirmed($application));
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.');
}
@ -136,12 +126,12 @@ class ApplicationService
case 'deny':
event(new ApplicationDeniedEvent($application));
$message = __("Application denied successfully.");
$message = __('Application denied successfully.');
break;
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!');
$application->setStatus('STAGE_INTERVIEW');
@ -150,7 +140,7 @@ class ApplicationService
break;
default:
throw new \LogicException("Wrong status parameter. Please notify a developer.");
throw new \LogicException('Wrong status parameter. Please notify a developer.');
}
return $message;
@ -164,7 +154,6 @@ class ApplicationService
return $application->delete();
}
public function canVote($votes): bool
{
$allvotes = collect([]);
@ -175,6 +164,6 @@ class ApplicationService
}
}
return !(($allvotes->count() == 1));
return ! (($allvotes->count() == 1));
}
}

View File

@ -1,13 +1,10 @@
<?php
namespace App\Services;
use App\Application;
use App\Appointment;
use App\Exceptions\InvalidAppointmentStatusException;
use App\Notifications\ApplicationMoved;
use App\Notifications\AppointmentCancelled;
use App\Notifications\AppointmentFinished;
use App\Notifications\AppointmentScheduled;
@ -30,10 +27,10 @@ class AppointmentService
/**
* Schedules an appointment for the provided application.
*
* @param Application $application The target application.
* @param Carbon $appointmentDate The appointment's date and time.
* @param string $appointmentDescription The appointment description.
* @param string $appointmentLocation The appointment location.
* @param Application $application The target application.
* @param Carbon $appointmentDate The appointment's date and time.
* @param string $appointmentDescription The appointment description.
* @param string $appointmentLocation The appointment location.
* @return bool Whether the appointment was scheduled.
*/
public function createAppointment(Application $application, Carbon $appointmentDate, $appointmentDescription, $appointmentLocation)
@ -53,22 +50,20 @@ class AppointmentService
$application->user->notify(new AppointmentScheduled($appointment));
return true;
}
/**
* Cancels an appointment for the provided application.
*
* @param Application $application The target application.
* @param string $reason The reason for cancelling the appointment.
* @param Application $application The target application.
* @param string $reason The reason for cancelling the appointment.
*
* @throws \Exception Thrown when there's no appointment to cancel
*/
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->appointment->delete();
@ -77,14 +72,13 @@ class AppointmentService
Log::info('An interview appointment has just been cancelled.', [
'actor' => Auth::user()->name,
'applicant' => $application->user->name,
'reason' => $reason
'reason' => $reason,
]);
return true;
}
throw new \Exception("This application doesn't have an appointment!");
}
/**
@ -97,22 +91,17 @@ class AppointmentService
*/
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->save();
if ($updateApplication)
{
if ($updateApplication) {
$application->setStatus('STAGE_PEERAPPROVAL');
$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;
}
}

View File

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

View File

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

View File

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

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