From f6318409a740d576570a08c9d9b1027357e1a949 Mon Sep 17 00:00:00 2001 From: Joseph Cohen Date: Sat, 31 Oct 2015 15:33:11 -0600 Subject: [PATCH 1/7] Start working on the invite system for users --- app/Commands/User/InviteTeamMemberCommand.php | 43 +++++++++++++ app/Events/User/UserWasInvitedEvent.php | 34 ++++++++++ .../User/InviteTeamMemberCommandHandler.php | 37 +++++++++++ .../User/SendInviteUserEmailHandler.php | 62 +++++++++++++++++++ .../Controllers/Dashboard/TeamController.php | 33 ++++++++++ app/Http/Routes/DashboardRoutes.php | 5 ++ app/Models/Invite.php | 48 ++++++++++++++ app/Providers/EventServiceProvider.php | 3 + .../2015_10_31_211944_CreateInvitesTable.php | 35 +++++++++++ .../views/dashboard/team/index.blade.php | 11 +++- .../views/dashboard/team/invite.blade.php | 47 ++++++++++++++ .../views/emails/users/invite-html.blade.php | 13 ++++ .../views/emails/users/invite-text.blade.php | 5 ++ 13 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 app/Commands/User/InviteTeamMemberCommand.php create mode 100644 app/Events/User/UserWasInvitedEvent.php create mode 100644 app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php create mode 100644 app/Handlers/Events/User/SendInviteUserEmailHandler.php create mode 100644 app/Models/Invite.php create mode 100644 database/migrations/2015_10_31_211944_CreateInvitesTable.php create mode 100644 resources/views/dashboard/team/invite.blade.php create mode 100644 resources/views/emails/users/invite-html.blade.php create mode 100644 resources/views/emails/users/invite-text.blade.php diff --git a/app/Commands/User/InviteTeamMemberCommand.php b/app/Commands/User/InviteTeamMemberCommand.php new file mode 100644 index 00000000..d97d9d2b --- /dev/null +++ b/app/Commands/User/InviteTeamMemberCommand.php @@ -0,0 +1,43 @@ + 'required|array|email', + ]; + + /** + * Create a new invite team member command instance. + * + * @param array $email + * + * @return void + */ + public function __construct($emails) + { + $this->emails = $emails; + } +} diff --git a/app/Events/User/UserWasInvitedEvent.php b/app/Events/User/UserWasInvitedEvent.php new file mode 100644 index 00000000..fa083f27 --- /dev/null +++ b/app/Events/User/UserWasInvitedEvent.php @@ -0,0 +1,34 @@ +invite = $invite; + } +} diff --git a/app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php b/app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php new file mode 100644 index 00000000..2692c546 --- /dev/null +++ b/app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php @@ -0,0 +1,37 @@ +emails as $email) { + $invite = Invite::create([ + 'email' => $command->email, + ]); + + event(new UserWasInvitedEvent($invite)); + } + } +} diff --git a/app/Handlers/Events/User/SendInviteUserEmailHandler.php b/app/Handlers/Events/User/SendInviteUserEmailHandler.php new file mode 100644 index 00000000..d8ebd21d --- /dev/null +++ b/app/Handlers/Events/User/SendInviteUserEmailHandler.php @@ -0,0 +1,62 @@ +mailer = $mailer; + } + + /** + * Handle the event. + * + * @param \CachetHQ\Cachet\Events\UserWasInvitedEvent $event + * + * @return void + */ + public function handle(UserWasInvitedEvent $event) + { + $mail = [ + 'email' => $event->invite->email, + 'subject' => 'You have been invited.', + 'link' => route('invite.signup', ['code' => $event->invite->code]), + 'app_url' => env('APP_URL'), + ]; + + $this->mailer->queue([ + 'html' => 'emails.users.invite-html', + 'text' => 'emails.users.invite-text', + ], $mail, function (Message $message) use ($mail) { + $message->to($mail['email'])->subject($mail['subject']); + }); + } +} diff --git a/app/Http/Controllers/Dashboard/TeamController.php b/app/Http/Controllers/Dashboard/TeamController.php index 1635bb0e..8f6ff744 100644 --- a/app/Http/Controllers/Dashboard/TeamController.php +++ b/app/Http/Controllers/Dashboard/TeamController.php @@ -62,6 +62,17 @@ class TeamController extends Controller ->withPageTitle(trans('dashboard.team.add.title').' - '.trans('dashboard.dashboard')); } + /** + * Shows the invite team member view. + * + * @return \Illuminate\View\View + */ + public function showInviteTeamMemberView() + { + return View::make('dashboard.team.invite') + ->withPageTitle(trans('dashboard.team.invite.title').' - '.trans('dashboard.dashboard')); + } + /** * Creates a new team member. * @@ -111,6 +122,28 @@ class TeamController extends Controller ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.edit.success'))); } + /** + * Creates a new team member. + * + * @return \Illuminate\Http\RedirectResponse + */ + public function postInviteUser() + { + try { + $this->dispatch(new InviteTeamMemberCommand( + array_unique(array_filter((array) Binput::get('emails'))) + )); + } catch (ValidationException $e) { + return Redirect::route('dashboard.team.invite') + ->withInput(Binput::except('password')) + ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.invite.failure'))) + ->withErrors($e->getMessageBag()); + } + + return Redirect::route('dashboard.team.invite') + ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.invite.success'))); + } + /** * Delete a user. * diff --git a/app/Http/Routes/DashboardRoutes.php b/app/Http/Routes/DashboardRoutes.php index da7c938e..1aa77721 100644 --- a/app/Http/Routes/DashboardRoutes.php +++ b/app/Http/Routes/DashboardRoutes.php @@ -202,8 +202,13 @@ class DashboardRoutes 'as' => 'add', 'uses' => 'TeamController@showAddTeamMemberView', ]); + $router->get('invite', [ + 'as' => 'invite', + 'uses' => 'TeamController@showInviteTeamMemberView', + ]); $router->get('{user}', 'TeamController@showTeamMemberView'); $router->post('add', 'TeamController@postAddUser'); + $router->post('invite', 'TeamController@postInviteUser'); $router->post('{user}', 'TeamController@postUpdateUser'); $router->delete('{user}/delete', 'TeamController@deleteUser'); }); diff --git a/app/Models/Invite.php b/app/Models/Invite.php new file mode 100644 index 00000000..8fcf38e7 --- /dev/null +++ b/app/Models/Invite.php @@ -0,0 +1,48 @@ + 'string', + ]; + + /** + * The fillable properties. + * + * @var string[] + */ + protected $fillable = ['email']; + + /** + * Overrides the models boot method. + */ + public static function boot() + { + parent::boot(); + + self::creating(function ($invite) { + if (!$invite->code) { + $invite->code = self::generateVerifyCode(); + } + }); + } +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 89baec7e..c163b674 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -30,6 +30,9 @@ class EventServiceProvider extends ServiceProvider 'CachetHQ\Cachet\Events\Subscriber\SubscriberHasSubscribedEvent' => [ 'CachetHQ\Cachet\Handlers\Events\Subscriber\SendSubscriberVerificationEmailHandler', ], + 'CachetHQ\Cachet\Events\User\UserWasInvitedEvent' => [ + 'CachetHQ\Cachet\Handlers\Events\User\SendInviteEmailHandler', + ], 'CachetHQ\Cachet\Events\User\UserWasAddedEvent' => [ // ], diff --git a/database/migrations/2015_10_31_211944_CreateInvitesTable.php b/database/migrations/2015_10_31_211944_CreateInvitesTable.php new file mode 100644 index 00000000..e72bc657 --- /dev/null +++ b/database/migrations/2015_10_31_211944_CreateInvitesTable.php @@ -0,0 +1,35 @@ +engine = 'InnoDB'; + + $table->increments('id'); + $table->string('code')->unique(); + $table->string('email'); + $table->timestamp('claimed_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('invites'); + } +} diff --git a/resources/views/dashboard/team/index.blade.php b/resources/views/dashboard/team/index.blade.php index 4f39922e..960dfb4e 100644 --- a/resources/views/dashboard/team/index.blade.php +++ b/resources/views/dashboard/team/index.blade.php @@ -9,9 +9,14 @@ {{ trans('dashboard.team.team') }} @if($current_user->isAdmin) - - {{ trans('dashboard.team.add.title') }} - +
+ + {{ trans('dashboard.team.invite.title') }} + + + {{ trans('dashboard.team.add.title') }} + +
@endif
diff --git a/resources/views/dashboard/team/invite.blade.php b/resources/views/dashboard/team/invite.blade.php new file mode 100644 index 00000000..377548ee --- /dev/null +++ b/resources/views/dashboard/team/invite.blade.php @@ -0,0 +1,47 @@ +@extends('layout.dashboard') + +@section('content') +
+ + + {{ trans('dashboard.team.team') }} + +
+
+
+
+ @include('dashboard.partials.errors') +
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+
+
+
+@stop diff --git a/resources/views/emails/users/invite-html.blade.php b/resources/views/emails/users/invite-html.blade.php new file mode 100644 index 00000000..5b429e6d --- /dev/null +++ b/resources/views/emails/users/invite-html.blade.php @@ -0,0 +1,13 @@ +@extends('layout.emails') + +@section('preheader') +{!! trans('cachet.users.email.invite.html-preheader', ['app_name' => Setting::get('app_name')]) !!} +@stop + +@section('content') + {!! trans('cachet.users.email.invite.html', ['app_name' => Setting::get('app_name'), 'link' => $link]) !!} + + @if(Setting::get('show_support')) +

{!! trans('cachet.powered_by', ['app' => Setting::get('app_name')]) !!}

+ @endif +@stop diff --git a/resources/views/emails/users/invite-text.blade.php b/resources/views/emails/users/invite-text.blade.php new file mode 100644 index 00000000..04a4b68c --- /dev/null +++ b/resources/views/emails/users/invite-text.blade.php @@ -0,0 +1,5 @@ +{{ trans('cachet.users.email.invite.text', ['app_name' => Setting::get('app_name'), 'link' => $link]) }} + +@if(Setting::get('show_support')) +{!! trans('cachet.powered_by', ['app' => Setting::get('app_name')]) !!} +@endif From 448f13e6716fc1c57b6fa873e304f70e8cea7ac7 Mon Sep 17 00:00:00 2001 From: Joseph Cohen Date: Sun, 8 Nov 2015 13:43:45 -0600 Subject: [PATCH 2/7] Handle the signup invite --- app/Commands/Invite/ClaimInviteCommand.php | 34 +++++++ app/Commands/User/SignupUserCommand.php | 73 +++++++++++++++ app/Events/Invite/InviteWasClaimed.php | 34 +++++++ .../Invite/ClaimInviteCommandHandler.php | 36 ++++++++ .../User/InviteTeamMemberCommandHandler.php | 4 +- .../User/SignupUserCommandHandler.php | 40 +++++++++ .../User/SendInviteUserEmailHandler.php | 4 +- .../Controllers/Dashboard/TeamController.php | 1 + app/Http/Controllers/SignupController.php | 88 +++++++++++++++++++ app/Http/Routes/SignupRoutes.php | 45 ++++++++++ app/Models/Invite.php | 22 ++++- app/Providers/ComposerServiceProvider.php | 4 +- app/Providers/EventServiceProvider.php | 2 +- resources/views/signup.blade.php | 48 ++++++++++ 14 files changed, 427 insertions(+), 8 deletions(-) create mode 100644 app/Commands/Invite/ClaimInviteCommand.php create mode 100644 app/Commands/User/SignupUserCommand.php create mode 100644 app/Events/Invite/InviteWasClaimed.php create mode 100644 app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php create mode 100644 app/Handlers/Commands/User/SignupUserCommandHandler.php create mode 100644 app/Http/Controllers/SignupController.php create mode 100644 app/Http/Routes/SignupRoutes.php create mode 100644 resources/views/signup.blade.php diff --git a/app/Commands/Invite/ClaimInviteCommand.php b/app/Commands/Invite/ClaimInviteCommand.php new file mode 100644 index 00000000..7e49c0f7 --- /dev/null +++ b/app/Commands/Invite/ClaimInviteCommand.php @@ -0,0 +1,34 @@ +invite = $invite; + } +} diff --git a/app/Commands/User/SignupUserCommand.php b/app/Commands/User/SignupUserCommand.php new file mode 100644 index 00000000..597950ba --- /dev/null +++ b/app/Commands/User/SignupUserCommand.php @@ -0,0 +1,73 @@ + '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; + } +} diff --git a/app/Events/Invite/InviteWasClaimed.php b/app/Events/Invite/InviteWasClaimed.php new file mode 100644 index 00000000..18e89e9a --- /dev/null +++ b/app/Events/Invite/InviteWasClaimed.php @@ -0,0 +1,34 @@ +invite = $invite; + } +} diff --git a/app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php b/app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php new file mode 100644 index 00000000..fd1bac34 --- /dev/null +++ b/app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php @@ -0,0 +1,36 @@ +invite; + + $invite->claimed_at = Carbon::now(); + $invite->save(); + + event(new InviteWasClaimed($invite)); + } +} diff --git a/app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php b/app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php index 2692c546..28b6b718 100644 --- a/app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php +++ b/app/Handlers/Commands/User/InviteTeamMemberCommandHandler.php @@ -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)); diff --git a/app/Handlers/Commands/User/SignupUserCommandHandler.php b/app/Handlers/Commands/User/SignupUserCommandHandler.php new file mode 100644 index 00000000..71a8d126 --- /dev/null +++ b/app/Handlers/Commands/User/SignupUserCommandHandler.php @@ -0,0 +1,40 @@ + $command->username, + 'password' => $command->password, + 'email' => $command->email, + 'level' => 2, + ]); + + event(new UserWasAddedEvent($user)); + + return $user; + } +} diff --git a/app/Handlers/Events/User/SendInviteUserEmailHandler.php b/app/Handlers/Events/User/SendInviteUserEmailHandler.php index d8ebd21d..ccb78df4 100644 --- a/app/Handlers/Events/User/SendInviteUserEmailHandler.php +++ b/app/Handlers/Events/User/SendInviteUserEmailHandler.php @@ -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'), ]; diff --git a/app/Http/Controllers/Dashboard/TeamController.php b/app/Http/Controllers/Dashboard/TeamController.php index 8f6ff744..c8da2d28 100644 --- a/app/Http/Controllers/Dashboard/TeamController.php +++ b/app/Http/Controllers/Dashboard/TeamController.php @@ -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; diff --git a/app/Http/Controllers/SignupController.php b/app/Http/Controllers/SignupController.php new file mode 100644 index 00000000..2a7d9448 --- /dev/null +++ b/app/Http/Controllers/SignupController.php @@ -0,0 +1,88 @@ +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('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed'))); + } +} diff --git a/app/Http/Routes/SignupRoutes.php b/app/Http/Routes/SignupRoutes.php new file mode 100644 index 00000000..6777d666 --- /dev/null +++ b/app/Http/Routes/SignupRoutes.php @@ -0,0 +1,45 @@ + + */ +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', + ]); + }); + } +} diff --git a/app/Models/Invite.php b/app/Models/Invite.php index 8fcf38e7..752439f5 100644 --- a/app/Models/Invite.php +++ b/app/Models/Invite.php @@ -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); + } } diff --git a/app/Providers/ComposerServiceProvider.php b/app/Providers/ComposerServiceProvider.php index d6e410fd..54dcc96c 100644 --- a/app/Providers/ComposerServiceProvider.php +++ b/app/Providers/ComposerServiceProvider.php @@ -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); } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index c163b674..5ae75828 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -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' => [ // diff --git a/resources/views/signup.blade.php b/resources/views/signup.blade.php new file mode 100644 index 00000000..64fe08de --- /dev/null +++ b/resources/views/signup.blade.php @@ -0,0 +1,48 @@ +@extends('layout.master') + +@section('content') +
+

+
+ +
+ + @if($bannerImage = Setting::get('app_banner')) +
+
+ + @if($app_url = Setting::get('app_domain')) + + @else + + @endif +
+
+ @endif + + @include('dashboard.partials.errors') + +
+
+ {{ trans('cachet.subscriber.subscribe') }} +
+
+
+ +
+ + +
+
+ + +
+
+ + +
+ +
+
+
+@stop From d82bc577961f31f031d54d2583f0dd65bd708b95 Mon Sep 17 00:00:00 2001 From: Joe Cohen Date: Sun, 8 Nov 2015 14:46:05 -0500 Subject: [PATCH 3/7] Applied fixes from StyleCI --- .../Commands/Invite/ClaimInviteCommandHandler.php | 2 +- app/Http/Controllers/SignupController.php | 3 +-- app/Models/Invite.php | 1 - .../2015_10_31_211944_CreateInvitesTable.php | 11 ++++++++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php b/app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php index fd1bac34..d7b60a5e 100644 --- a/app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php +++ b/app/Handlers/Commands/Invite/ClaimInviteCommandHandler.php @@ -11,9 +11,9 @@ namespace CachetHQ\Cachet\Handlers\Commands\Invite; -use Carbon\Carbon; use CachetHQ\Cachet\Commands\Invite\ClaimInviteCommand; use CachetHQ\Cachet\Events\Invite\InviteWasClaimed; +use Carbon\Carbon; class ClaimInviteCommandHandler { diff --git a/app/Http/Controllers/SignupController.php b/app/Http/Controllers/SignupController.php index 2a7d9448..178a2ac7 100644 --- a/app/Http/Controllers/SignupController.php +++ b/app/Http/Controllers/SignupController.php @@ -11,9 +11,8 @@ namespace CachetHQ\Cachet\Http\Controllers; -use AltThree\Validator\ValidationException; -use CachetHQ\Cachet\Commands\User\SignupUserCommand; use CachetHQ\Cachet\Commands\Invite\ClaimInviteCommand; +use CachetHQ\Cachet\Commands\User\SignupUserCommand; use CachetHQ\Cachet\Facades\Setting; use CachetHQ\Cachet\Models\Invite; use GrahamCampbell\Binput\Facades\Binput; diff --git a/app/Models/Invite.php b/app/Models/Invite.php index 752439f5..84bf5d93 100644 --- a/app/Models/Invite.php +++ b/app/Models/Invite.php @@ -12,7 +12,6 @@ namespace CachetHQ\Cachet\Models; use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Str; class Invite extends Model { diff --git a/database/migrations/2015_10_31_211944_CreateInvitesTable.php b/database/migrations/2015_10_31_211944_CreateInvitesTable.php index e72bc657..ae839be8 100644 --- a/database/migrations/2015_10_31_211944_CreateInvitesTable.php +++ b/database/migrations/2015_10_31_211944_CreateInvitesTable.php @@ -1,7 +1,16 @@ Date: Sun, 8 Nov 2015 13:59:46 -0600 Subject: [PATCH 4/7] Update event listeners order --- app/Providers/EventServiceProvider.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 5ae75828..502a1acf 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -30,11 +30,11 @@ class EventServiceProvider extends ServiceProvider 'CachetHQ\Cachet\Events\Subscriber\SubscriberHasSubscribedEvent' => [ 'CachetHQ\Cachet\Handlers\Events\Subscriber\SendSubscriberVerificationEmailHandler', ], - 'CachetHQ\Cachet\Events\User\UserWasInvitedEvent' => [ - 'CachetHQ\Cachet\Handlers\Events\User\SendInviteUserEmailHandler', - ], 'CachetHQ\Cachet\Events\User\UserWasAddedEvent' => [ // ], + 'CachetHQ\Cachet\Events\User\UserWasInvitedEvent' => [ + 'CachetHQ\Cachet\Handlers\Events\User\SendInviteUserEmailHandler', + ], ]; } From 0b12d4e0c373e64773c72d6119778013d06d88e6 Mon Sep 17 00:00:00 2001 From: Joseph Cohen Date: Sun, 8 Nov 2015 20:12:52 -0600 Subject: [PATCH 5/7] Add validation to signup and trans strings --- app/Http/Controllers/SignupController.php | 26 ++++++++++++++++------- resources/lang/en/cachet.php | 9 ++++++++ resources/lang/en/dashboard.php | 7 +++++- resources/lang/en/forms.php | 2 ++ resources/views/signup.blade.php | 14 ++++++------ 5 files changed, 42 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/SignupController.php b/app/Http/Controllers/SignupController.php index 178a2ac7..b865a1b9 100644 --- a/app/Http/Controllers/SignupController.php +++ b/app/Http/Controllers/SignupController.php @@ -11,6 +11,7 @@ namespace CachetHQ\Cachet\Http\Controllers; +use AltThree\Validator\ValidationException; use CachetHQ\Cachet\Commands\Invite\ClaimInviteCommand; use CachetHQ\Cachet\Commands\User\SignupUserCommand; use CachetHQ\Cachet\Facades\Setting; @@ -50,7 +51,9 @@ class SignupController extends Controller return View::make('signup') ->withPageTitle(Setting::get('app_name')) ->withAboutApp(Markdown::convertToHtml(Setting::get('app_about'))) - ->withCode($invite->code); + ->withCode($invite->code) + ->withUsername(Binput::old('username')) + ->withEmail(Binput::old('emai', $invite->email)); } /** @@ -72,16 +75,23 @@ class SignupController extends Controller throw new BadRequestHttpException(); } - $this->dispatch(new SignupUserCommand( - Binput::get('username'), - Binput::get('password'), - Binput::get('email'), - 2 - )); + try { + $this->dispatch(new SignupUserCommand( + Binput::get('username'), + Binput::get('password'), + Binput::get('email'), + 2 + )); + } catch (ValidationException $e) { + return Redirect::route('signup.invite', ['code' => $invite->code]) + ->withInput(Binput::except('password')) + ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.signup.failure'))) + ->withErrors($e->getMessageBag()); + } $this->dispatch(new ClaimInviteCommand($invite)); return Redirect::route('status-page') - ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed'))); + ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.signup.unsubscribed'))); } } diff --git a/resources/lang/en/cachet.php b/resources/lang/en/cachet.php index e72106ce..73028119 100755 --- a/resources/lang/en/cachet.php +++ b/resources/lang/en/cachet.php @@ -87,6 +87,15 @@ return [ ], ], + 'signup' => [ + 'title' => 'Sign Up', + 'username' => 'Username', + 'email' => 'Email', + 'password' => 'Password', + 'success' => 'Your account has been created.', + 'failure' => 'Something went wrong with the signup.', + ], + // Other 'powered_by' => ':app Status Page is powered by Cachet.', 'about_this_site' => 'About This Site', diff --git a/resources/lang/en/dashboard.php b/resources/lang/en/dashboard.php index db440c2d..1a63d36a 100755 --- a/resources/lang/en/dashboard.php +++ b/resources/lang/en/dashboard.php @@ -142,7 +142,7 @@ return [ 'add' => [ 'title' => 'Add a New Team Member', 'success' => 'Team member added.', - 'failure' => 'Something went wrong with the component.', + 'failure' => 'Something went wrong with the user.', ], 'edit' => [ 'title' => 'Update Profile', @@ -153,6 +153,11 @@ return [ 'success' => 'User deleted.', 'failure' => 'Something went wrong when deleting this user.', ], + 'invite' => [ + 'title' => 'Invite a New Team Member', + 'success' => 'The users invited.', + 'failure' => 'Something went wrong with the invite.', + ], ], // Settings diff --git a/resources/lang/en/forms.php b/resources/lang/en/forms.php index 8b7478a0..123d1883 100755 --- a/resources/lang/en/forms.php +++ b/resources/lang/en/forms.php @@ -165,6 +165,8 @@ return [ 'submit' => 'Submit', 'cancel' => 'Cancel', 'remove' => 'Remove', + 'invite' => 'Invite', + 'signup' => 'Sign Up', // Other 'optional' => '* Optional', diff --git a/resources/views/signup.blade.php b/resources/views/signup.blade.php index 64fe08de..48f6b121 100644 --- a/resources/views/signup.blade.php +++ b/resources/views/signup.blade.php @@ -24,24 +24,24 @@
- {{ trans('cachet.subscriber.subscribe') }} + {{ trans('cachet.signup.title') }}
- - + +
- - + +
- +
- +
From 29c3bcf183b4e0137799febf3958ed4264df94f8 Mon Sep 17 00:00:00 2001 From: Joseph Cohen Date: Sun, 8 Nov 2015 20:21:23 -0600 Subject: [PATCH 6/7] Add email strings --- app/Http/Controllers/SignupController.php | 2 +- resources/lang/en/cachet.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/SignupController.php b/app/Http/Controllers/SignupController.php index b865a1b9..d471bf33 100644 --- a/app/Http/Controllers/SignupController.php +++ b/app/Http/Controllers/SignupController.php @@ -92,6 +92,6 @@ class SignupController extends Controller $this->dispatch(new ClaimInviteCommand($invite)); return Redirect::route('status-page') - ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.signup.unsubscribed'))); + ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.signup.success'))); } } diff --git a/resources/lang/en/cachet.php b/resources/lang/en/cachet.php index 73028119..566444a5 100755 --- a/resources/lang/en/cachet.php +++ b/resources/lang/en/cachet.php @@ -87,6 +87,16 @@ return [ ], ], + 'users' => [ + 'email' => [ + 'invite' => [ + 'text' => "You have been invited to the team :app_name status page, to sign up follow the next link.\n:link\nThank you, :app_name", + 'html-preheader' => 'You have been invited to the team :app_name.', + 'html' => '

You have been invited to the team :app_name status page, to sign up follow the next link.

:link

Thank you, :app_name

', + ], + ], + ], + 'signup' => [ 'title' => 'Sign Up', 'username' => 'Username', From 77cec21dc5a23ebf9ae8a3238f987526ec9bb3aa Mon Sep 17 00:00:00 2001 From: James Brooks Date: Mon, 9 Nov 2015 18:38:26 +0000 Subject: [PATCH 7/7] Update invitation system language text --- resources/lang/da/forms.php | 4 ++++ resources/lang/de/forms.php | 4 ++++ resources/lang/en/forms.php | 4 ++++ resources/lang/es/forms.php | 4 ++++ resources/lang/fr/forms.php | 4 ++++ resources/lang/id/forms.php | 4 ++++ resources/lang/it/forms.php | 4 ++++ resources/lang/ko/forms.php | 4 ++++ resources/lang/nl/forms.php | 4 ++++ resources/lang/pl/forms.php | 4 ++++ resources/lang/pt-BR/forms.php | 4 ++++ resources/lang/ru/forms.php | 4 ++++ resources/lang/zh-CN/forms.php | 4 ++++ resources/views/dashboard/team/invite.blade.php | 15 ++++++--------- 14 files changed, 58 insertions(+), 9 deletions(-) diff --git a/resources/lang/da/forms.php b/resources/lang/da/forms.php index be06567d..90074c32 100755 --- a/resources/lang/da/forms.php +++ b/resources/lang/da/forms.php @@ -153,6 +153,10 @@ return [ '2fa' => [ 'help' => 'Brug Two-Factor login for større sikkerhed på din konto. Du skal så nok installere Google Authenticator eller lignende på din mobile enked for at kunne logge ind med nøgler fra appen.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/de/forms.php b/resources/lang/de/forms.php index 3535a5d2..75dd4ceb 100755 --- a/resources/lang/de/forms.php +++ b/resources/lang/de/forms.php @@ -138,6 +138,10 @@ return [ '2fa' => [ 'help' => 'Die Zwei-Faktor-Authentifizierung erhöht die Sicherheit Ihres Kontos. Sie benötigen Google Authenticator oder eine ähnliche App auf Ihrem Mobilgerät. Beim Anmelden werden sie aufgefordert, einen Token einzugeben, der von der App generiert wird.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/en/forms.php b/resources/lang/en/forms.php index 123d1883..bdf31581 100755 --- a/resources/lang/en/forms.php +++ b/resources/lang/en/forms.php @@ -153,6 +153,10 @@ return [ '2fa' => [ 'help' => 'Enabling two factor authentication increases security of your account. You will need to download Google Authenticator or a similar app on to your mobile device. When you login you will be asked to provide a token generated by the app.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/es/forms.php b/resources/lang/es/forms.php index 24834110..45faba9d 100755 --- a/resources/lang/es/forms.php +++ b/resources/lang/es/forms.php @@ -130,6 +130,10 @@ return [ '2fa' => [ 'help' => 'Habilitar autenticación de dos pasos aumenta la seguridad de tu cuenta. Necesitarás descargar Google Authenticator o una aplicación similar en tu dispositivo móvil. Al iniciar sesión te pedirá proporcionar un token generado por la aplicación.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/fr/forms.php b/resources/lang/fr/forms.php index 6d8bbaa5..3bdb0762 100755 --- a/resources/lang/fr/forms.php +++ b/resources/lang/fr/forms.php @@ -138,6 +138,10 @@ return [ '2fa' => [ 'help' => 'Habilitante authentification à deux facteurs augmente la sécurité de votre compte. Vous aurez besoin de télécharger Google Authenticator ou une application similaire sur votre appareil mobile. Lorsque vous vous connectez vous sera demandé de fournir un jeton généré par l\'application.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/id/forms.php b/resources/lang/id/forms.php index bbeead19..7c9dfc0b 100755 --- a/resources/lang/id/forms.php +++ b/resources/lang/id/forms.php @@ -138,6 +138,10 @@ return [ '2fa' => [ 'help' => 'Mengaktifkan otentikasi dua faktor akan memperkuat keamanan akun anda. Anda perlu mengunduh Google Authenticator atau app sejenis di gadget anda. Saat login anda akan ditanyakan untuk mengisi token yang dibuat oleh app tersebut.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/it/forms.php b/resources/lang/it/forms.php index 616c3c48..7f71fe93 100644 --- a/resources/lang/it/forms.php +++ b/resources/lang/it/forms.php @@ -144,6 +144,10 @@ return [ '2fa' => [ 'help' => 'L\'abilitazione della verifica in 2 passaggi aumenta la sicurezza del tuo account. Sarà necessario scaricare Google Authenticator o un\'applicazione simile sul tuo dispositivo mobile. Quando accederai, ti verrà chiesto di fornire un token generato dall\'app.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/ko/forms.php b/resources/lang/ko/forms.php index c8b620d4..9842f60e 100755 --- a/resources/lang/ko/forms.php +++ b/resources/lang/ko/forms.php @@ -139,6 +139,10 @@ return [ '2fa' => [ 'help' => '2단계 인증을 활성화하면 계정 보안이 강화됩니다. Google Authenticator 또는 유사한 앱을 모바일 기기에 다운로드 받아야 합니다. 로그인 할 때, 해당 앱에서 생성된 토큰을 입력해야합니다.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/nl/forms.php b/resources/lang/nl/forms.php index 20a02df6..a10caad0 100755 --- a/resources/lang/nl/forms.php +++ b/resources/lang/nl/forms.php @@ -138,6 +138,10 @@ return [ '2fa' => [ 'help' => 'Het inschakelen van two-factor authenticatie verhoogt de veiligheid van uw account. U zult een applicatie zoals Google Authenticator of een vergelijkbare applicatie moeten downloaden op uw mobiele apparaat. Wanneer u inlogt wordt u gevraagd om een token in te voeren welke door de applicatie wordt gegenereerd.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/pl/forms.php b/resources/lang/pl/forms.php index 09a22577..ef2843c6 100755 --- a/resources/lang/pl/forms.php +++ b/resources/lang/pl/forms.php @@ -132,6 +132,10 @@ return [ '2fa' => [ 'help' => 'Aktywacja dwuetapowej autentykacji zwiększą bezpieczeństwo twojego konta. Musisz ściągnąć Google Authenticator lub podobną aplikację na swój telefon. Przy logowaniu będziesz proszony o podanie kodu wygenerowanego przez tą aplikację.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/pt-BR/forms.php b/resources/lang/pt-BR/forms.php index adc593a5..bb034a5e 100755 --- a/resources/lang/pt-BR/forms.php +++ b/resources/lang/pt-BR/forms.php @@ -153,6 +153,10 @@ return [ '2fa' => [ 'help' => 'Ativar a autenticação de dois fatores aumenta a segurança de sua conta. Você vai precisar baixar Google Authenticator ou um app similar em seu dispositivo móvel. Quando você entrar, será solicitado um token gerado pelo app.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/ru/forms.php b/resources/lang/ru/forms.php index bd7bba7b..2173f5bb 100644 --- a/resources/lang/ru/forms.php +++ b/resources/lang/ru/forms.php @@ -139,6 +139,10 @@ return [ '2fa' => [ 'help' => 'Включение двухфакторной аутентификации увеличивает безопасность вашей учетной записи. Вам понадобится скачать Google Authenticator или аналогичное приложение на свой смартфон. Когда в следующий раз вы войдете в панель управления, вам понадобится токен, выданный этим приложением.', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/lang/zh-CN/forms.php b/resources/lang/zh-CN/forms.php index 6f617455..f64bf4a4 100755 --- a/resources/lang/zh-CN/forms.php +++ b/resources/lang/zh-CN/forms.php @@ -139,6 +139,10 @@ return [ '2fa' => [ 'help' => '启用双因素身份验证会增加您的帐户安全。您将需要下载 Google Authenticator 或类似的应用到您的移动设备。当您登录时将会要求您提供由应用程序生成的一个短码。', ], + 'team' => [ + 'description' => 'Invite your team members by entering their email addresses here.', + 'email' => 'Email #:id', + ], ], // Buttons diff --git a/resources/views/dashboard/team/invite.blade.php b/resources/views/dashboard/team/invite.blade.php index 377548ee..e6b76558 100644 --- a/resources/views/dashboard/team/invite.blade.php +++ b/resources/views/dashboard/team/invite.blade.php @@ -17,23 +17,20 @@
- - + +
- +
- +
- +
- -
-
- +