Improved subscriber handling

- Signed routes
- Manage subscriptions now sends an email link
This commit is contained in:
James Brooks
2019-07-12 11:39:13 +01:00
parent 29d640e74b
commit 7f53a7e9df
8 changed files with 112 additions and 22 deletions

View File

@@ -21,6 +21,7 @@ use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\Subscription;
use CachetHQ\Cachet\Notifications\Subscriber\ManageSubscriptionNotification;
use GrahamCampbell\Binput\Facades\Binput;
use GrahamCampbell\Markdown\Facades\Markdown;
use Illuminate\Contracts\Auth\Guard;
@@ -88,12 +89,12 @@ class SubscribeController extends Controller
->withErrors($e->getMessageBag());
}
if ($subscription->is_verified) {
return cachet_redirect('status-page')->withSuccess(trans('cachet.subscriber.email.already-subscribed', ['email' => $email]));
}
// Send the subscriber a link to manage their subscription.
$subscription->notify(new ManageSubscriptionNotification);
return cachet_redirect('subscribe.manage', $subscription->verify_code)
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
return redirect()->back()->withSuccess(
sprintf('%s %s', trans('dashboard.notifications.awesome'),
trans('cachet.subscriber.email.manage_subscription')));
}
/**
@@ -119,8 +120,8 @@ class SubscribeController extends Controller
execute(new VerifySubscriberCommand($subscriber));
}
return cachet_redirect('status-page')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.verified')));
return cachet_redirect('subscribe.manage', $code)
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
}
/**

View File

@@ -27,6 +27,7 @@ use CachetHQ\Cachet\Http\Middleware\TrustProxies;
use Illuminate\Auth\Middleware\Authorize;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
use Illuminate\Routing\Middleware\ValidateSignature;
class Kernel extends HttpKernel
{
@@ -57,6 +58,7 @@ class Kernel extends HttpKernel
'localize' => Localize::class,
'ready' => ReadyForUse::class,
'setup' => SetupAlreadyCompleted::class,
'signed' => ValidateSignature::class,
'subscribers' => SubscribersConfigured::class,
'throttle' => Throttler::class,
];

View File

@@ -49,8 +49,9 @@ class SubscribeRoutes
]);
$router->get('subscribe/manage/{code}', [
'as' => 'get:subscribe.manage',
'uses' => 'SubscribeController@showManage',
'as' => 'get:subscribe.manage',
'middleware' => ['signed'],
'uses' => 'SubscribeController@showManage',
]);
$router->post('subscribe/manage/{code}', [
'as' => 'post:subscribe.manage',
@@ -58,8 +59,9 @@ class SubscribeRoutes
]);
$router->get('subscribe/verify/{code}', [
'as' => 'get:subscribe.verify',
'uses' => 'SubscribeController@getVerify',
'as' => 'get:subscribe.verify',
'middleware' => ['signed'],
'uses' => 'SubscribeController@getVerify',
]);
$router->get('unsubscribe/{code}/{subscription?}', [

View File

@@ -0,0 +1,53 @@
<?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\Notifications\Subscriber;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\URL;
class ManageSubscriptionNotification extends Notification
{
use Queueable;
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
*
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
*
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$route = URL::signedRoute(cachet_route_generator('subscribe.manage'), ['code' => $notifiable->verify_code]);
return (new MailMessage())
->subject(trans('notifications.subscriber.manage.mail.subject'))
->greeting(trans('notifications.subscriber.manage.mail.title', ['app_name' => setting('app_name')]))
->action(trans('notifications.subscriber.manage.mail.action'), $route)
->line(trans('notifications.subscriber.manage.mail.content', ['app_name' => setting('app_name')]));
}
}

View File

@@ -15,6 +15,7 @@ use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\URL;
/**
* This is the verify subscription notification class.
@@ -46,10 +47,12 @@ class VerifySubscriptionNotification extends Notification
*/
public function toMail($notifiable)
{
$route = URL::signedRoute(cachet_route_generator('subscribe.verify'), ['code' => $notifiable->verify_code]);
return (new MailMessage())
->subject(trans('notifications.subscriber.verify.mail.subject'))
->greeting(trans('notifications.subscriber.verify.mail.title', ['app_name' => Config::get('setting.app_name')]))
->action(trans('notifications.subscriber.verify.mail.action'), cachet_route('subscribe.verify', ['code' => $notifiable->verify_code]))
->action(trans('notifications.subscriber.verify.mail.action'), $route)
->line(trans('notifications.subscriber.verify.mail.content', ['app_name' => Config::get('setting.app_name')]));
}
}

View File

@@ -123,6 +123,22 @@ if (!function_exists('color_contrast')) {
}
}
if (!function_exists('cachet_route_generator')) {
/**
* Generate the route string.
*
* @param string $name
* @param string $method
* @param string $domain
*
* @return string
*/
function cachet_route_generator($name, $method = 'get', $domain = 'core')
{
return "{$domain}::{$method}:{$name}";
}
}
if (!function_exists('cachet_route')) {
/**
* Generate a URL to a named route, which resides in a given domain.
@@ -136,7 +152,11 @@ if (!function_exists('cachet_route')) {
*/
function cachet_route($name, $parameters = [], $method = 'get', $domain = 'core')
{
return app('url')->route("{$domain}::{$method}:{$name}", $parameters, true);
return app('url')->route(
cachet_route_generator($name, $method, $domain),
$parameters,
true
);
}
}