diff --git a/js/forum/dist/app.js b/js/forum/dist/app.js index 59ed6c9d8..75a07d09f 100644 --- a/js/forum/dist/app.js +++ b/js/forum/dist/app.js @@ -18236,8 +18236,8 @@ $('#el').spin('flower', 'red'); ; 'use strict'; -System.register('flarum/app', ['flarum/ForumApp', 'flarum/initializers/store', 'flarum/initializers/preload', 'flarum/initializers/routes', 'flarum/initializers/components', 'flarum/initializers/humanTime', 'flarum/initializers/boot'], function (_export, _context) { - var ForumApp, store, preload, routes, components, humanTime, boot, app; +System.register('flarum/app', ['flarum/ForumApp', 'flarum/initializers/store', 'flarum/initializers/preload', 'flarum/initializers/routes', 'flarum/initializers/components', 'flarum/initializers/humanTime', 'flarum/initializers/boot', 'flarum/initializers/alertEmailConfirmation'], function (_export, _context) { + var ForumApp, store, preload, routes, components, humanTime, boot, alertEmailConfirmation, app; return { setters: [function (_flarumForumApp) { ForumApp = _flarumForumApp.default; @@ -18253,6 +18253,8 @@ System.register('flarum/app', ['flarum/ForumApp', 'flarum/initializers/store', ' humanTime = _flarumInitializersHumanTime.default; }, function (_flarumInitializersBoot) { boot = _flarumInitializersBoot.default; + }, function (_flarumInitializersAlertEmailConfirmation) { + alertEmailConfirmation = _flarumInitializersAlertEmailConfirmation.default; }], execute: function () { app = new ForumApp(); @@ -18265,6 +18267,7 @@ System.register('flarum/app', ['flarum/ForumApp', 'flarum/initializers/store', ' app.initializers.add('preload', preload, -100); app.initializers.add('boot', boot, -100); + app.initializers.add('alertEmailConfirmation', alertEmailConfirmation, -100); _export('default', app); } @@ -28383,6 +28386,49 @@ System.register('flarum/helpers/userOnline', ['flarum/helpers/icon'], function ( });; 'use strict'; +System.register('flarum/initializers/alertEmailConfirmation', ['flarum/components/Alert', 'flarum/components/Button'], function (_export, _context) { + var Alert, Button; + function alertEmailConfirmation(app) { + var user = app.session.user; + + if (!user || user.isActivated()) return; + + var alert = void 0; + + var resendButton = Button.component({ + className: 'Button Button--link', + children: app.translator.trans('core.forum.user_confirmation.resend_button'), + onclick: function onclick() { + app.request({ + method: 'POST', + url: app.forum.attribute('apiUrl') + '/users/' + user.id() + '/send-confirmation' + }).then(function () { + return app.alerts.dismiss(alert); + }); + } + }); + + app.alerts.show(alert = new Alert({ + type: 'error', + dismissible: false, + children: app.translator.trans('core.forum.user_confirmation.alert_message'), + controls: [resendButton] + })); + } + + _export('default', alertEmailConfirmation); + + return { + setters: [function (_flarumComponentsAlert) { + Alert = _flarumComponentsAlert.default; + }, function (_flarumComponentsButton) { + Button = _flarumComponentsButton.default; + }], + execute: function () {} + }; +});; +'use strict'; + System.register('flarum/initializers/boot', ['flarum/utils/ScrollListener', 'flarum/utils/Pane', 'flarum/utils/Drawer', 'flarum/utils/mapRoutes', 'flarum/helpers/icon', 'flarum/components/Navigation', 'flarum/components/HeaderPrimary', 'flarum/components/HeaderSecondary', 'flarum/components/Composer', 'flarum/components/ModalManager', 'flarum/components/AlertManager'], function (_export, _context) { var ScrollListener, Pane, Drawer, mapRoutes, icon, Navigation, HeaderPrimary, HeaderSecondary, Composer, ModalManager, AlertManager; function boot(app) { diff --git a/js/forum/src/app.js b/js/forum/src/app.js index 9436a7725..c930964fe 100644 --- a/js/forum/src/app.js +++ b/js/forum/src/app.js @@ -5,6 +5,7 @@ import routes from 'flarum/initializers/routes'; import components from 'flarum/initializers/components'; import humanTime from 'flarum/initializers/humanTime'; import boot from 'flarum/initializers/boot'; +import alertEmailConfirmation from 'flarum/initializers/alertEmailConfirmation'; const app = new ForumApp(); @@ -15,5 +16,6 @@ app.initializers.add('humanTime', humanTime); app.initializers.add('preload', preload, -100); app.initializers.add('boot', boot, -100); +app.initializers.add('alertEmailConfirmation', alertEmailConfirmation, -100); export default app; diff --git a/js/forum/src/initializers/alertEmailConfirmation.js b/js/forum/src/initializers/alertEmailConfirmation.js new file mode 100644 index 000000000..658347f82 --- /dev/null +++ b/js/forum/src/initializers/alertEmailConfirmation.js @@ -0,0 +1,36 @@ +import Alert from 'flarum/components/Alert'; +import Button from 'flarum/components/Button'; + +/** + * The `alertEmailConfirmation` initializer shows an Alert if loggend in + * user's email is not confirmed + * + * @param {ForumApp} app + */ +export default function alertEmailConfirmation(app) { + const user = app.session.user; + + if (!user || user.isActivated()) return; + + let alert; + + const resendButton = Button.component({ + className: 'Button Button--link', + children: app.translator.trans('core.forum.user_confirmation.resend_button'), + onclick: () => { + app.request({ + method: 'POST', + url: app.forum.attribute('apiUrl') + '/users/' + user.id() + '/send-confirmation', + }).then(() => app.alerts.dismiss(alert)); + } + }); + + app.alerts.show( + alert = new Alert({ + type: 'error', + dismissible: false, + children: app.translator.trans('core.forum.user_confirmation.alert_message'), + controls: [resendButton] + }) + ); +} diff --git a/src/Api/ApiServiceProvider.php b/src/Api/ApiServiceProvider.php index b45d443e0..7cd77bc39 100644 --- a/src/Api/ApiServiceProvider.php +++ b/src/Api/ApiServiceProvider.php @@ -179,6 +179,13 @@ class ApiServiceProvider extends AbstractServiceProvider $toController('Flarum\Api\Controller\DeleteAvatarController') ); + // send confirmation email + $routes->post( + '/users/{id}/send-confirmation', + 'users.confirmation.send', + $toController('Flarum\Api\Controller\SendConfirmationEmailController') + ); + /* |-------------------------------------------------------------------------- | Notifications diff --git a/src/Api/Controller/SendConfirmationEmailController.php b/src/Api/Controller/SendConfirmationEmailController.php new file mode 100644 index 000000000..be771a2ef --- /dev/null +++ b/src/Api/Controller/SendConfirmationEmailController.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Api\Controller; + +use Flarum\Core\Access\AssertPermissionTrait; +use Flarum\Core\EmailToken; +use Flarum\Core\Exception\PermissionDeniedException; +use Flarum\Http\Controller\ControllerInterface; +use Flarum\Forum\UrlGenerator; +use Flarum\Settings\SettingsRepositoryInterface; +use Illuminate\Contracts\Mail\Mailer; +use Illuminate\Mail\Message; +use Psr\Http\Message\ServerRequestInterface; +use Symfony\Component\Translation\TranslatorInterface; +use Zend\Diactoros\Response\EmptyResponse; + +class SendConfirmationEmailController implements ControllerInterface +{ + use AssertPermissionTrait; + + /** + * @var SettingsRepositoryInterface + */ + protected $settings; + + /** + * @var Mailer + */ + protected $mailer; + + /** + * @var UrlGenerator + */ + protected $url; + + /** + * @var TranslatorInterface + */ + protected $translator; + + /** + * @param \Flarum\Settings\SettingsRepositoryInterface $settings + * @param Mailer $mailer + * @param UrlGenerator $url + * @param TranslatorInterface $translator + */ + public function __construct(SettingsRepositoryInterface $settings, Mailer $mailer, UrlGenerator $url, TranslatorInterface $translator) + { + $this->settings = $settings; + $this->mailer = $mailer; + $this->url = $url; + $this->translator = $translator; + } + + /** + * {@inheritdoc} + */ + public function handle(ServerRequestInterface $request) + { + $id = array_get($request->getQueryParams(), 'id'); + $actor = $request->getAttribute('actor'); + + $this->assertRegistered($actor); + + if ($actor->id != $id || $actor->is_activated) { + throw new PermissionDeniedException; + } + + $token = EmailToken::generate($actor->email, $actor->id); + $token->save(); + + $data = [ + '{username}' => $actor->username, + '{url}' => $this->url->toRoute('confirmEmail', ['token' => $token->id]), + '{forum}' => $this->settings->get('forum_title') + ]; + + $body = $this->translator->trans('core.email.activate_account.body', $data); + + $this->mailer->raw($body, function (Message $message) use ($actor, $data) { + $message->to($actor->email); + $message->subject('['.$data['{forum}'].'] '.$this->translator->trans('core.email.activate_account.subject')); + }); + + return new EmptyResponse; + } +}