WIP: Road to 1.0.0 #1
|
@ -30,13 +30,13 @@ class Ban extends Model
|
|||
'userID',
|
||||
'reason',
|
||||
'bannedUntil',
|
||||
'userAgent',
|
||||
'isPermanent',
|
||||
'authorUserID',
|
||||
|
||||
];
|
||||
|
||||
public $dates = [
|
||||
'bannedUntil',
|
||||
'suspendedUntil',
|
||||
];
|
||||
|
||||
public function user()
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Jobs\CleanBans;
|
||||
use App\Jobs\ProcessDueSuspensions;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
|
@ -50,7 +50,7 @@ class Kernel extends ConsoleKernel
|
|||
->daily();
|
||||
// Production value: Every day
|
||||
|
||||
$schedule->job(new CleanBans)
|
||||
$schedule->job(new ProcessDueSuspensions)
|
||||
->daily();
|
||||
// Production value: Every day
|
||||
}
|
||||
|
|
|
@ -34,48 +34,26 @@ class BanController extends Controller
|
|||
{
|
||||
$this->authorize('create', [Ban::class, $user]);
|
||||
|
||||
// FIXME: Needs refactoring to a simpler format, e.g. parse the user's given date directly.
|
||||
|
||||
if (is_null($user->bans)) {
|
||||
|
||||
$duration = $request->duration;
|
||||
$reason = $request->reason;
|
||||
$duration = strtolower($request->durationOperator);
|
||||
$durationOperand = $request->durationOperand;
|
||||
$type = $request->suspensionType; // ON: Temporary | OFF: Permanent
|
||||
|
||||
$expiryDate = now();
|
||||
|
||||
if (! empty($duration)) {
|
||||
switch ($duration) {
|
||||
case 'days':
|
||||
$expiryDate->addDays($durationOperand);
|
||||
break;
|
||||
|
||||
case 'weeks':
|
||||
$expiryDate->addWeeks($durationOperand);
|
||||
break;
|
||||
|
||||
case 'months':
|
||||
$expiryDate->addMonths($durationOperand);
|
||||
break;
|
||||
|
||||
case 'years':
|
||||
$expiryDate->addYears($durationOperand);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Essentially permanent
|
||||
$expiryDate->addYears(40);
|
||||
if ($type == "on") {
|
||||
$expiryDate = now()->addDays($duration);
|
||||
}
|
||||
|
||||
$ban = Ban::create([
|
||||
'userID' => $user->id,
|
||||
'reason' => $reason,
|
||||
'bannedUntil' => $expiryDate->format('Y-m-d H:i:s'),
|
||||
'userAgent' => 'Unknown',
|
||||
'bannedUntil' => ($type == "on") ? $expiryDate->format('Y-m-d H:i:s') : null,
|
||||
'authorUserID' => Auth::user()->id,
|
||||
'isPermanent' => ($type == "off") ? true : false
|
||||
]);
|
||||
|
||||
event(new UserBannedEvent($user, $ban));
|
||||
$request->session()->flash('success', __('Account suspended. Suspension ID #:susId', ['susId', $ban->id]));
|
||||
$request->session()->flash('success', __('Account suspended.'));
|
||||
} else {
|
||||
$request->session()->flash('error', __('Account already suspended!'));
|
||||
}
|
||||
|
|
|
@ -71,6 +71,17 @@ class ProfileController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
$suspensionInfo = null;
|
||||
if ($user->isBanned())
|
||||
{
|
||||
$suspensionInfo = [
|
||||
|
||||
'isPermanent' => $user->bans->isPermanent,
|
||||
'reason' => $user->bans->reason,
|
||||
'bannedUntil' => $user->bans->bannedUntil
|
||||
];
|
||||
}
|
||||
|
||||
if (Auth::user()->is($user) || Auth::user()->can('profiles.view.others')) {
|
||||
return view('dashboard.user.profile.displayprofile')
|
||||
->with([
|
||||
|
@ -82,6 +93,7 @@ class ProfileController extends Controller
|
|||
'since' => $createdDate->englishMonth.' '.$createdDate->year,
|
||||
'ipInfo' => IP::lookup($user->originalIP),
|
||||
'roles' => $roleList,
|
||||
'suspensionInfo' => $suspensionInfo
|
||||
]);
|
||||
} else {
|
||||
abort(403, __('You cannot view someone else\'s profile.'));
|
||||
|
|
|
@ -45,8 +45,15 @@ class BanUserRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'reason' => 'required|string',
|
||||
'durationOperand' => 'nullable|string',
|
||||
'durationOperator' => 'nullable|string',
|
||||
'suspensionType' => 'required|string',
|
||||
'duration' => 'required_if:suspensionType,on|nullable|integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'duration.required_if' => __('You must provide a duration if the suspension is temporary.')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ use Illuminate\Queue\InteractsWithQueue;
|
|||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CleanBans implements ShouldQueue
|
||||
class ProcessDueSuspensions implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
|
@ -52,15 +52,15 @@ class CleanBans implements ShouldQueue
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
Log::debug('Running automatic ban cleaner...');
|
||||
Log::debug('Running automatic suspension cleaner...');
|
||||
$bans = Ban::all();
|
||||
|
||||
if (! is_null($bans)) {
|
||||
foreach ($this->bans as $ban) {
|
||||
$bannedUntil = Carbon::parse($ban->bannedUntil);
|
||||
|
||||
if ($bannedUntil->equalTo(now())) {
|
||||
Log::debug('Deleted ban '.$ban->id.' belonging to '.$ban->user->name);
|
||||
if ($bannedUntil->isToday()) {
|
||||
Log::debug('Lifted expired suspension ID '.$ban->id.' for '.$ban->user->name);
|
||||
$ban->delete();
|
||||
}
|
||||
}
|
|
@ -611,5 +611,21 @@ return [
|
|||
],
|
||||
|
||||
],
|
||||
[
|
||||
'name' => 'BootstrapSwitch',
|
||||
'active' => true,
|
||||
'files' => [
|
||||
[
|
||||
'type' => 'js',
|
||||
'asset' => false,
|
||||
'location' => 'https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js'
|
||||
],
|
||||
[
|
||||
'type' => 'css',
|
||||
'asset' => false,
|
||||
'location' => 'https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css'
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
];
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ChangeBansTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('bans', function (Blueprint $table) {
|
||||
|
||||
$table->dropColumn('userAgent');
|
||||
$table->boolean('isPermanent')->default(false);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('bans', function (Blueprint $table) {
|
||||
$table->dropColumn('isPermanent');
|
||||
$table->string('userAgent')->after('bannedUntil');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -411,14 +411,13 @@ return [
|
|||
'title' => ':name\'s profile',
|
||||
'profile' => 'Profile',
|
||||
'users' => 'Users',
|
||||
'account_banned' => 'Account banned',
|
||||
'account_banned_exp' => 'This user has been banned by the moderators.',
|
||||
'ban_confirm' => 'Please confirm that you want to ban this user account. You\'ll need to add a reason and expiration date to confirm this. Bans don\'t transfer to connected Minecraft networks (yet).',
|
||||
'leave_empty' => 'Leave empty for a permanent ban',
|
||||
'account_banned' => 'Account suspended',
|
||||
'account_banned_exp' => 'This user has been suspended by the admins.',
|
||||
'ban_confirm' => 'Please confirm that you want to suspend this account. You\'ll need to add a reason and expiration date to confirm this.',
|
||||
'duration' => 'Duration',
|
||||
'p_duration' => 'Punishment duration',
|
||||
'p_duration' => 'Suspension duration',
|
||||
'p_duration_exp' => 'e.g. Spamming',
|
||||
'ban' => 'Ban',
|
||||
'ban' => 'Suspend',
|
||||
|
||||
'terminate_notice' => 'You are about to terminate a staff member',
|
||||
'terminate_notice_warning' => 'Terminating a staff member will remove their privileges on the team management site and Network.
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
|
||||
@section('content')
|
||||
|
||||
@if ($profile->user->isBanned())
|
||||
@if (is_array($suspensionInfo))
|
||||
|
||||
<div class="alert alert-danger">
|
||||
|
||||
<span><i class="fa fa-ban"></i> <b>{{__('messages.profile.account_banned')}}</b></span>
|
||||
<span><i class="fa fa-ban"></i> <b>{{__('messages.profile.account_banned')}} {{ ($suspensionInfo['isPermanent']) ? __('permanently.') : __('until :date.', ['date' => $suspensionInfo['bannedUntil']]) }}</b></span>
|
||||
|
||||
<p>{{__('messages.profile.account_banned_exp')}}</p>
|
||||
|
||||
<p>
|
||||
<i class="fas fa-chevron-right"></i> <b>{{$profile->user->bans->reason}}</>
|
||||
<i class="fas fa-chevron-right"></i> <b>{{$suspensionInfo['reason']}}</b>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
@ -43,32 +43,33 @@
|
|||
<form id="banAccountForm" name="banAccount" method="POST" action="{{route('banUser', ['user' => $profile->user->id])}}">
|
||||
@csrf
|
||||
|
||||
<label for="reason">{{__('messages.reusable.reason')}}</label>
|
||||
<input type="text" name="reason" id="reason" class="form-control" placeholder="{{__('messages.profile.p_duration_exp')}}">
|
||||
<div class="row">
|
||||
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="durationOperator" aria-label="{{__('messages.profile.p_duration')}}">
|
||||
<div class="input-group-append">
|
||||
<button id="durationDropdown" class="btn btn-outline-secondary dropdown-toggle duration-btn" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{__('messages.profile.duration')}}</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#">Days</a>
|
||||
<a class="dropdown-item" href="#">Weeks</a>
|
||||
<a class="dropdown-item" href="#">Months</a>
|
||||
<div role="separator" class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#">Years</a>
|
||||
<div class="col">
|
||||
<label for="reason">{{__('Public note')}}</label>
|
||||
<input type="text" name="reason" id="reason" class="form-control" placeholder="{{__('messages.profile.p_duration_exp')}}">
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<label for="duration">{{ __('Duration') }}</label>
|
||||
<input type="text" name="duration" id="duration" class="form-control" placeholder="{{ __('in days') }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted text-sm">{{__('messages.profile.leave_empty')}}</p>
|
||||
|
||||
<input id="operator" type="hidden" value="" name="durationOperand" class="duration-operator-fld">
|
||||
|
||||
<div class="mt-2">
|
||||
<input type="hidden" name="suspensionType" value="off">
|
||||
|
||||
<label for="suspensionType">Suspension type</label><br>
|
||||
<input type="checkbox" id="suspensionType" name="suspensionType" checked data-toggle="toggle" data-on="Temporary" data-off="Permanent" data-onstyle="success" data-offstyle="danger" data-width="130" data-height="40">
|
||||
<p class="text-muted text-sm"><i class="fas fa-info-circle"></i> {{ __('Temporary suspensions will be automatically lifted. The suspension note is visible to all users. Suspended users will not be able to login or register.') }}</p>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
<x-slot name="modalFooter">
|
||||
|
||||
<button id="banAccountButton" type="button" class="btn btn-danger"><i class="fa fa-ban"></i> {{__('messages.profile.ban')}}</button>
|
||||
|
||||
<button id="banAccountButton" type="button" class="btn btn-danger"><i class="fa fa-gavel"></i> {{__('Confirm')}}</button>
|
||||
</x-slot>
|
||||
|
||||
</x-modal>
|
||||
|
@ -334,13 +335,13 @@
|
|||
<div class="management-btn text-center">
|
||||
|
||||
@if (!$profile->user->isBanned())
|
||||
<button class="btn btn-danger mb-2" id="banAccountTrigger"><i class="fa fa-ban"></i> {{__('messages.profile.ban_acc')}}</button><br>
|
||||
<button class="btn btn-danger mb-2" id="banAccountTrigger"><i class="fa fa-ban"></i> {{__('Suspend')}}</button><br>
|
||||
@else
|
||||
<form method="post" action="{{route('unbanUser', ['user' => $profile->user->id])}}">
|
||||
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-warning mb-2"><i class="fa fa-check"></i> {{__('messages.profile.unban_acc')}}</button>
|
||||
<button type="submit" class="btn btn-warning mb-2"><i class="fa fa-check"></i> {{__('Lift Suspension')}}</button>
|
||||
|
||||
</form>
|
||||
@endif
|
||||
|
|
Loading…
Reference in New Issue