Handle the signup invite
This commit is contained in:
34
app/Commands/Invite/ClaimInviteCommand.php
Normal file
34
app/Commands/Invite/ClaimInviteCommand.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Commands\Invite;
|
||||
|
||||
final class ClaimInviteCommand
|
||||
{
|
||||
/**
|
||||
* The invte to mark as claimed.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Model\Invite
|
||||
*/
|
||||
public $invite;
|
||||
|
||||
/**
|
||||
* Create a new claim invite command instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Model\Invite $invite
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invite)
|
||||
{
|
||||
$this->invite = $invite;
|
||||
}
|
||||
}
|
||||
73
app/Commands/User/SignupUserCommand.php
Normal file
73
app/Commands/User/SignupUserCommand.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Commands\User;
|
||||
|
||||
final class SignupUserCommand
|
||||
{
|
||||
/**
|
||||
* The user username.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $username;
|
||||
|
||||
/**
|
||||
* The user password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $password;
|
||||
|
||||
/**
|
||||
* The user email.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $email;
|
||||
|
||||
/**
|
||||
* The user level.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $level;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $rules = [
|
||||
'username' => 'required|string',
|
||||
'password' => 'string',
|
||||
'email' => 'required|string|email',
|
||||
'level' => 'int',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new signup user command instance.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $email
|
||||
* @param int $level
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($username, $password, $email, $level)
|
||||
{
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->email = $email;
|
||||
$this->level = $level;
|
||||
}
|
||||
}
|
||||
34
app/Events/Invite/InviteWasClaimed.php
Normal file
34
app/Events/Invite/InviteWasClaimed.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Events\Invite;
|
||||
|
||||
use CachetHQ\Cachet\Models\Invite;
|
||||
|
||||
final class InviteWasClaimed
|
||||
{
|
||||
/**
|
||||
* The invite that has been claimed.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Models\Invite
|
||||
*/
|
||||
public $invite;
|
||||
|
||||
/**
|
||||
* Create a new invite was claimed event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Invite $invite)
|
||||
{
|
||||
$this->invite = $invite;
|
||||
}
|
||||
}
|
||||
36
app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php
Normal file
36
app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Handlers\Commands\Invite;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use CachetHQ\Cachet\Commands\Invite\ClaimInviteCommand;
|
||||
use CachetHQ\Cachet\Events\Invite\InviteWasClaimed;
|
||||
|
||||
class ClaimInviteCommandHandler
|
||||
{
|
||||
/**
|
||||
* Handle the claim invite command.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Commands\User\ClaimInviteCommand $command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(ClaimInviteCommand $command)
|
||||
{
|
||||
$invite = $command->invite;
|
||||
|
||||
$invite->claimed_at = Carbon::now();
|
||||
$invite->save();
|
||||
|
||||
event(new InviteWasClaimed($invite));
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace CachetHQ\Cachet\Handlers\Commands\User;
|
||||
|
||||
use CachetHQ\Cachet\Commands\User\InviteTeamMemberCommand;
|
||||
use CachetHQ\Cachet\Events\User\UserWasAddedEvent;
|
||||
use CachetHQ\Cachet\Events\User\UserWasInvitedEvent;
|
||||
use CachetHQ\Cachet\Models\Invite;
|
||||
|
||||
class InviteTeamMemberCommandHandler
|
||||
@@ -28,7 +28,7 @@ class InviteTeamMemberCommandHandler
|
||||
{
|
||||
foreach ($command->emails as $email) {
|
||||
$invite = Invite::create([
|
||||
'email' => $command->email,
|
||||
'email' => $email,
|
||||
]);
|
||||
|
||||
event(new UserWasInvitedEvent($invite));
|
||||
|
||||
40
app/Handlers/Commands/User/SignupUserCommandHandler.php
Normal file
40
app/Handlers/Commands/User/SignupUserCommandHandler.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Handlers\Commands\User;
|
||||
|
||||
use CachetHQ\Cachet\Commands\User\SignupUserCommand;
|
||||
use CachetHQ\Cachet\Events\User\UserWasAddedEvent;
|
||||
use CachetHQ\Cachet\Models\User;
|
||||
|
||||
class SignupUserCommandHandler
|
||||
{
|
||||
/**
|
||||
* Handle the signup user command.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Commands\User\SignupUserCommand $command
|
||||
*
|
||||
* @return \CachetHQ\Cachet\Models\User
|
||||
*/
|
||||
public function handle(SignupUserCommand $command)
|
||||
{
|
||||
$user = User::create([
|
||||
'username' => $command->username,
|
||||
'password' => $command->password,
|
||||
'email' => $command->email,
|
||||
'level' => 2,
|
||||
]);
|
||||
|
||||
event(new UserWasAddedEvent($user));
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace CachetHQ\Cachet\Handlers\Events\User;
|
||||
|
||||
use CachetHQ\Cachet\Events\Subscriber\UserWasInvitedEvent;
|
||||
use CachetHQ\Cachet\Events\User\UserWasInvitedEvent;
|
||||
use Illuminate\Contracts\Mail\MailQueue;
|
||||
use Illuminate\Mail\Message;
|
||||
|
||||
@@ -48,7 +48,7 @@ class SendInviteUserEmailHandler
|
||||
$mail = [
|
||||
'email' => $event->invite->email,
|
||||
'subject' => 'You have been invited.',
|
||||
'link' => route('invite.signup', ['code' => $event->invite->code]),
|
||||
'link' => route('signup.invite', ['code' => $event->invite->code]),
|
||||
'app_url' => env('APP_URL'),
|
||||
];
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
|
||||
|
||||
use AltThree\Validator\ValidationException;
|
||||
use CachetHQ\Cachet\Commands\User\AddTeamMemberCommand;
|
||||
use CachetHQ\Cachet\Commands\User\InviteTeamMemberCommand;
|
||||
use CachetHQ\Cachet\Commands\User\RemoveUserCommand;
|
||||
use CachetHQ\Cachet\Models\User;
|
||||
use GrahamCampbell\Binput\Facades\Binput;
|
||||
|
||||
88
app/Http/Controllers/SignupController.php
Normal file
88
app/Http/Controllers/SignupController.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Http\Controllers;
|
||||
|
||||
use AltThree\Validator\ValidationException;
|
||||
use CachetHQ\Cachet\Commands\User\SignupUserCommand;
|
||||
use CachetHQ\Cachet\Commands\Invite\ClaimInviteCommand;
|
||||
use CachetHQ\Cachet\Facades\Setting;
|
||||
use CachetHQ\Cachet\Models\Invite;
|
||||
use GrahamCampbell\Binput\Facades\Binput;
|
||||
use GrahamCampbell\Markdown\Facades\Markdown;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class SignupController extends Controller
|
||||
{
|
||||
use DispatchesJobs;
|
||||
|
||||
/**
|
||||
* Handle the signup with invite.
|
||||
*
|
||||
* @param string|null $code
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function getSignup($code = null)
|
||||
{
|
||||
if (is_null($code)) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
$invite = Invite::where('code', '=', $code)->first();
|
||||
|
||||
if (!$invite || $invite->claimed()) {
|
||||
throw new BadRequestHttpException();
|
||||
}
|
||||
|
||||
return View::make('signup')
|
||||
->withPageTitle(Setting::get('app_name'))
|
||||
->withAboutApp(Markdown::convertToHtml(Setting::get('app_about')))
|
||||
->withCode($invite->code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the unsubscribe.
|
||||
*
|
||||
* @param string|null $code
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function postSignup($code = null)
|
||||
{
|
||||
if (is_null($code)) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
$invite = Invite::where('code', '=', $code)->first();
|
||||
|
||||
if (!$invite || $invite->claimed()) {
|
||||
throw new BadRequestHttpException();
|
||||
}
|
||||
|
||||
$this->dispatch(new SignupUserCommand(
|
||||
Binput::get('username'),
|
||||
Binput::get('password'),
|
||||
Binput::get('email'),
|
||||
2
|
||||
));
|
||||
|
||||
$this->dispatch(new ClaimInviteCommand($invite));
|
||||
|
||||
return Redirect::route('status-page')
|
||||
->withSuccess(sprintf('<strong>%s</strong> %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed')));
|
||||
}
|
||||
}
|
||||
45
app/Http/Routes/SignupRoutes.php
Normal file
45
app/Http/Routes/SignupRoutes.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Http\Routes;
|
||||
|
||||
use Illuminate\Contracts\Routing\Registrar;
|
||||
|
||||
/**
|
||||
* This is the signup routes class.
|
||||
*
|
||||
* @author Joseph Cohen <joe@alt-three.com>
|
||||
*/
|
||||
class SignupRoutes
|
||||
{
|
||||
/**
|
||||
* Define the signup routes.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Routing\Registrar $router
|
||||
*/
|
||||
public function map(Registrar $router)
|
||||
{
|
||||
$router->group([
|
||||
'middleware' => ['app.hasSetting', 'guest'],
|
||||
'setting' => 'app_name',
|
||||
'as' => 'signup.',
|
||||
], function ($router) {
|
||||
$router->get('signup/invite/{code}', [
|
||||
'as' => 'invite',
|
||||
'uses' => 'SignupController@getSignup',
|
||||
]);
|
||||
|
||||
$router->post('signup/invite/{code}', [
|
||||
'uses' => 'SignupController@postSignup',
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,28 @@ class Invite extends Model
|
||||
|
||||
self::creating(function ($invite) {
|
||||
if (!$invite->code) {
|
||||
$invite->code = self::generateVerifyCode();
|
||||
$invite->code = self::generateInviteCode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an invite code.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generateInviteCode()
|
||||
{
|
||||
return str_random(20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the invite was claimed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function claimed()
|
||||
{
|
||||
return !is_null($this->claimed_at);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ class ComposerServiceProvider extends ServiceProvider
|
||||
$factory->composer('*', AppComposer::class);
|
||||
$factory->composer('*', CurrentUserComposer::class);
|
||||
$factory->composer(['index'], MetricsComposer::class);
|
||||
$factory->composer(['index', 'incident', 'subscribe'], StatusPageComposer::class);
|
||||
$factory->composer(['index', 'incident', 'subscribe', 'dashboard.settings.theme'], ThemeComposer::class);
|
||||
$factory->composer(['index', 'incident', 'subscribe', 'signup'], StatusPageComposer::class);
|
||||
$factory->composer(['index', 'incident', 'subscribe', 'signup', 'dashboard.settings.theme'], ThemeComposer::class);
|
||||
$factory->composer('dashboard.*', DashboardComposer::class);
|
||||
$factory->composer(['setup', 'dashboard.settings.localization'], TimezoneLocaleComposer::class);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
'CachetHQ\Cachet\Handlers\Events\Subscriber\SendSubscriberVerificationEmailHandler',
|
||||
],
|
||||
'CachetHQ\Cachet\Events\User\UserWasInvitedEvent' => [
|
||||
'CachetHQ\Cachet\Handlers\Events\User\SendInviteEmailHandler',
|
||||
'CachetHQ\Cachet\Handlers\Events\User\SendInviteUserEmailHandler',
|
||||
],
|
||||
'CachetHQ\Cachet\Events\User\UserWasAddedEvent' => [
|
||||
//
|
||||
|
||||
48
resources/views/signup.blade.php
Normal file
48
resources/views/signup.blade.php
Normal file
@@ -0,0 +1,48 @@
|
||||
@extends('layout.master')
|
||||
|
||||
@section('content')
|
||||
<div class="pull-right">
|
||||
<p><a class="btn btn-success btn-outline" href="/"><i class="ion-home"></i></a></p>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
@if($bannerImage = Setting::get('app_banner'))
|
||||
<div class="row app-banner">
|
||||
<div class="col-md-12 text-center">
|
||||
<?php $bannerType = Setting::get('app_banner_type') ?>
|
||||
@if($app_url = Setting::get('app_domain'))
|
||||
<a href="{{ $app_url }}"><img src="data:{{ $bannerType }};base64, {{ $bannerImage}}" class="banner-image img-responsive"></a>
|
||||
@else
|
||||
<img src="data:{{ $bannerType }};base64, {{ $bannerImage}}" class="banner-image img-responsive">
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('dashboard.partials.errors')
|
||||
|
||||
<div class="panel panel-meassage">
|
||||
<div class="panel-heading">
|
||||
<strong>{{ trans('cachet.subscriber.subscribe') }}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form action="{{ route('signup.invite', ['code' => $code]) }}" method="post" class="form">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||
<div class="form-group">
|
||||
<label for="username">{{ trans('cachet.subscriber.subscribe') }}</label>
|
||||
<input class="form-control" type="text" name="username">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email">{{ trans('cachet.subscriber.subscribe') }}</label>
|
||||
<input class="form-control" type="email" name="email">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">{{ trans('cachet.subscriber.subscribe') }}</label>
|
||||
<input class="form-control" type="password" name="password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">{{ trans('cachet.subscriber.button') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
Reference in New Issue
Block a user