feat: add invite notification emails, functionality to admin dashboard and sign up page
Signed-off-by: Miguel Nogueira <me@nogueira.codes>
This commit is contained in:
147
app/Http/Controllers/InvitationController.php
Normal file
147
app/Http/Controllers/InvitationController.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\InvitationRequest;
|
||||
use App\Invitation;
|
||||
use App\Mail\InviteApprovedMail;
|
||||
use App\Mail\InvitedToApp;
|
||||
use App\Mail\InviteRequestReceived;
|
||||
use App\Response;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Mail;
|
||||
use Session;
|
||||
|
||||
class InvitationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('dashboard.administration.invites', [
|
||||
'invites' => Invitation::all()
|
||||
]);
|
||||
}
|
||||
|
||||
public function requestInvite(InvitationRequest $request)
|
||||
{
|
||||
|
||||
$guest = Auth::guest();
|
||||
$invitation = new Invitation();
|
||||
|
||||
$invitation->requestor_email = $request->input('email');
|
||||
$invitation->requestor_ip_address = $request->ip();
|
||||
$invitation->status = $guest ? 'pending' : 'approved';
|
||||
$invitation->notified = !$guest; // confirmation msg doesn't count
|
||||
$invitation->invitation_code = bin2hex(random_bytes(64));
|
||||
$invitation->expiration = now()->addDays(2);
|
||||
|
||||
try {
|
||||
$invitation->saveOrFail();
|
||||
$addlMessage = ($guest) ? __('Check your email address for a confirmation email.') : '';
|
||||
|
||||
$request->session()->flash('success', __('Invitation request sent. :additionalUnauthenticatedMessage', ['additionalUnauthenticatedMessage' => $addlMessage]));
|
||||
|
||||
if ($guest) {
|
||||
Mail::to($invitation->requestor_email)->send(new InviteRequestReceived());
|
||||
}
|
||||
else {
|
||||
// this is an approved invite
|
||||
Mail::to($invitation->requestor_email)->send(new InvitedToApp($invitation));
|
||||
}
|
||||
|
||||
|
||||
} catch (\Exception $exception) {
|
||||
|
||||
\Log::debug('[INVITES]: Error saving invite request', ['message' => $exception->getMessage(), 'requestor_ip' => $request->ip()]);
|
||||
$request->session()->flash('error', __('Sorry, but we were unable to request an invitation for you. If you already requested one, trying to request another will not be possible, nor will it speed up the process.'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function approveInvite(Request $request, Invitation $invitation)
|
||||
{
|
||||
$approvableStates = [
|
||||
'pending'
|
||||
];
|
||||
|
||||
if ($invitation->expiration && now()->lessThanOrEqualTo($invitation->expiration) && in_array($invitation->status, $approvableStates))
|
||||
{
|
||||
$invitation->status = 'approved';
|
||||
$invitation->notified = true;
|
||||
$invitation->save();
|
||||
|
||||
Mail::to($invitation->requestor_email)->send(new InviteApprovedMail($invitation));
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('success', __('Invite request approved! This user can now sign up.'));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __('This invitation couldn\'t be approved because either it\'s already approved or it is expired.'));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function denyInvite(Request $request, Invitation $invitation)
|
||||
{
|
||||
$declinableStates = [
|
||||
'pending'
|
||||
];
|
||||
|
||||
if ($invitation->expiration && now()->lessThanOrEqualTo($invitation->expiration) && in_array($invitation->status, $declinableStates))
|
||||
{
|
||||
$invitation->status = 'denied';
|
||||
$invitation->save();
|
||||
|
||||
return redirect()
|
||||
->with('success', __('Invitation denied. No notifications were sent. This user cannot be invited again.'))
|
||||
->back();
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->with('error', __('This invitation could not be denied because it is either already approved, expired, or in an otherwise invalid state.'));
|
||||
}
|
||||
|
||||
public function redeemInvite(Request $request)
|
||||
{
|
||||
return view('auth.redeem-invite', ['validationToken' => $request->route('token')]);
|
||||
}
|
||||
|
||||
public function validateInvite(Request $request)
|
||||
{
|
||||
$token = $request->input('validation_token');
|
||||
$email = $request->input('email');
|
||||
|
||||
$invite = Invitation::where('requestor_email', $email)->first();
|
||||
|
||||
|
||||
|
||||
if (!empty($invite) && $token === $invite->invitation_code && 'approved' === $invite->status && $invite->expiration && now()->lessThanOrEqualTo($invite->expiration))
|
||||
{
|
||||
$invite->status = 'completed';
|
||||
$invite->save();
|
||||
|
||||
Session::put('ALLOW_REGISTRATION_OVERRIDE', true);
|
||||
Session::put('REGISTRATION_OVERRIDE_EMAIL', $email);
|
||||
|
||||
return redirect()
|
||||
->route('register')
|
||||
->with('success', __('Invitation code validated! You can now sign up with the email address you were invited with.'));
|
||||
}
|
||||
else
|
||||
{
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __('Something went wrong while validating your invite. Either it does not exist, is expired, has not been approved yet, or the token is wrong (do not edit it).'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
31
app/Http/Requests/InvitationRequest.php
Normal file
31
app/Http/Requests/InvitationRequest.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Facades\Options;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class InvitationRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'email' => ['required', 'email', 'max:254'],
|
||||
];
|
||||
}
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
if (Options::getOption('enable_registrations')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function failedAuthorization()
|
||||
{
|
||||
throw new AuthorizationException(__('You cannot request a new invite for this user/e-mail address right now. Keep in mind that users can only be invited once.'));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user