aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Lœuillet <nicolas@loeuillet.org>2016-01-21 12:27:47 +0100
committerNicolas Lœuillet <nicolas@loeuillet.org>2016-01-21 12:27:47 +0100
commit9aa66d6244935fe86a5598fbdbe518cf6204af2e (patch)
treea616f79e642b9683b3c7b597ed9c4072c0af5cdf
parente72a943ad244f8b6349e31eb9a148808045b224b (diff)
parentabd454c45633e335d9d63bcd250e760b968f8138 (diff)
downloadwallabag-9aa66d6244935fe86a5598fbdbe518cf6204af2e.tar.gz
wallabag-9aa66d6244935fe86a5598fbdbe518cf6204af2e.tar.zst
wallabag-9aa66d6244935fe86a5598fbdbe518cf6204af2e.zip
Merge pull request #1565 from wallabag/v2-2fa-html
Use HTML email for 2FA
-rw-r--r--app/config/config_dev.yml3
-rw-r--r--src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php58
-rw-r--r--src/Wallabag/UserBundle/Resources/config/services.yml3
-rw-r--r--src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml13
-rw-r--r--src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml13
-rw-r--r--src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig117
-rw-r--r--src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php25
7 files changed, 179 insertions, 53 deletions
diff --git a/app/config/config_dev.yml b/app/config/config_dev.yml
index 6b077fdb..2813e369 100644
--- a/app/config/config_dev.yml
+++ b/app/config/config_dev.yml
@@ -42,6 +42,3 @@ swiftmailer:
42 transport: smtp 42 transport: smtp
43 host: 'localhost' 43 host: 'localhost'
44 port: 1025 44 port: 1025
45 username: null
46 password: null
47
diff --git a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
index be370e71..6b108dd3 100644
--- a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
+++ b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
@@ -4,7 +4,6 @@ namespace Wallabag\UserBundle\Mailer;
4 4
5use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; 5use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
6use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface; 6use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;
7use Symfony\Component\Translation\TranslatorInterface;
8 7
9/** 8/**
10 * Custom mailer for TwoFactorBundle email. 9 * Custom mailer for TwoFactorBundle email.
@@ -20,11 +19,11 @@ class AuthCodeMailer implements AuthCodeMailerInterface
20 private $mailer; 19 private $mailer;
21 20
22 /** 21 /**
23 * Translator for email content. 22 * Twig to render the html's email.
24 * 23 *
25 * @var TranslatorInterface 24 * @var \Twig_Environment
26 */ 25 */
27 private $translator; 26 private $twig;
28 27
29 /** 28 /**
30 * Sender email address. 29 * Sender email address.
@@ -48,21 +47,30 @@ class AuthCodeMailer implements AuthCodeMailerInterface
48 private $supportUrl; 47 private $supportUrl;
49 48
50 /** 49 /**
50 * Url for the wallabag instance.
51 *
52 * @var string
53 */
54 private $wallabagUrl;
55
56 /**
51 * Initialize the auth code mailer with the SwiftMailer object. 57 * Initialize the auth code mailer with the SwiftMailer object.
52 * 58 *
53 * @param \Swift_Mailer $mailer 59 * @param \Swift_Mailer $mailer
54 * @param TranslatorInterface $translator 60 * @param \Twig_Environment $twig
55 * @param string $senderEmail 61 * @param string $senderEmail
56 * @param string $senderName 62 * @param string $senderName
57 * @param string $supportUrl 63 * @param string $supportUrl
64 * @param string $wallabagUrl
58 */ 65 */
59 public function __construct(\Swift_Mailer $mailer, TranslatorInterface $translator, $senderEmail, $senderName, $supportUrl) 66 public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig, $senderEmail, $senderName, $supportUrl, $wallabagUrl)
60 { 67 {
61 $this->mailer = $mailer; 68 $this->mailer = $mailer;
62 $this->translator = $translator; 69 $this->twig = $twig;
63 $this->senderEmail = $senderEmail; 70 $this->senderEmail = $senderEmail;
64 $this->senderName = $senderName; 71 $this->senderName = $senderName;
65 $this->supportUrl = $supportUrl; 72 $this->supportUrl = $supportUrl;
73 $this->wallabagUrl = $wallabagUrl;
66 } 74 }
67 75
68 /** 76 /**
@@ -72,20 +80,28 @@ class AuthCodeMailer implements AuthCodeMailerInterface
72 */ 80 */
73 public function sendAuthCode(TwoFactorInterface $user) 81 public function sendAuthCode(TwoFactorInterface $user)
74 { 82 {
83 $template = $this->twig->loadTemplate('@WallabagUserBundle/Resources/views/TwoFactor/email_auth_code.html.twig');
84
85 $subject = $template->renderBlock('subject', array());
86 $bodyHtml = $template->renderBlock('body_html', [
87 'user' => $user->getName(),
88 'code' => $user->getEmailAuthCode(),
89 'support_url' => $this->supportUrl,
90 'wallabag_url' => $this->wallabagUrl,
91 ]);
92 $bodyText = $template->renderBlock('body_text', [
93 'user' => $user->getName(),
94 'code' => $user->getEmailAuthCode(),
95 'support_url' => $this->supportUrl,
96 ]);
97
75 $message = new \Swift_Message(); 98 $message = new \Swift_Message();
76 $message 99 $message
77 ->setTo($user->getEmail()) 100 ->setTo($user->getEmail())
78 ->setFrom($this->senderEmail, $this->senderName) 101 ->setFrom($this->senderEmail, $this->senderName)
79 ->setSubject($this->translator->trans('auth_code.mailer.subject', array(), 'wallabag_user')) 102 ->setSubject($subject)
80 ->setBody($this->translator->trans( 103 ->setBody($bodyText, 'text/plain')
81 'auth_code.mailer.body', 104 ->addPart($bodyHtml, 'text/html')
82 [
83 '%user%' => $user->getName(),
84 '%code%' => $user->getEmailAuthCode(),
85 '%support%' => $this->supportUrl,
86 ],
87 'wallabag_user'
88 ))
89 ; 105 ;
90 106
91 $this->mailer->send($message); 107 $this->mailer->send($message);
diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml
index 9109b6a3..93e04d59 100644
--- a/src/Wallabag/UserBundle/Resources/config/services.yml
+++ b/src/Wallabag/UserBundle/Resources/config/services.yml
@@ -3,7 +3,8 @@ services:
3 class: Wallabag\UserBundle\Mailer\AuthCodeMailer 3 class: Wallabag\UserBundle\Mailer\AuthCodeMailer
4 arguments: 4 arguments:
5 - "@mailer" 5 - "@mailer"
6 - "@translator" 6 - "@twig"
7 - "%scheb_two_factor.email.sender_email%" 7 - "%scheb_two_factor.email.sender_email%"
8 - "%scheb_two_factor.email.sender_name%" 8 - "%scheb_two_factor.email.sender_name%"
9 - "%wallabag_support_url%" 9 - "%wallabag_support_url%"
10 - "%wallabag_url%"
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml
index f806d1d6..4da6075f 100644
--- a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml
+++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml
@@ -1,10 +1,7 @@
1# Two factor mail 1# Two factor mail
2auth_code.mailer.subject: 'Wallabag authentication Code' 2auth_code.mailer.subject: 'Wallabag authentication Code'
3auth_code.mailer.body: | 3auth_code.mailer.body.hello: "Hi %user%,"
4 Hi %user%, 4auth_code.mailer.body.first_para: "Since you enable two factor authentication on your wallabag account and you just logged in from a new device (computer, phone, etc.), we send you a code to validate your connection."
5 5auth_code.mailer.body.second_para: "Here is the code:"
6 Since you enable two factor authentication on your wallabag account and you just logged in from a new device (computer, phone, etc.), we send you a code to validate your connection. 6auth_code.mailer.body.support: "Please don't hesitate to contact us if you have any problems:"
7 Here is the code: %code% 7auth_code.mailer.body.signature: "The wallabag team"
8
9 Please don't hesitate to contact us if you have any problems: %support%
10 The wallabag team
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
index 386b2d9e..b4448d3a 100644
--- a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
+++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
@@ -1,10 +1,7 @@
1# Two factor mail 1# Two factor mail
2auth_code.mailer.subject: "Code d'authentification wallabag" 2auth_code.mailer.subject: "Code d'authentification wallabag"
3auth_code.mailer.body: | 3auth_code.mailer.body.hello: "Bonjour %user%,"
4 Bonjour %user%, 4auth_code.mailer.body.first_para: "Comme vous avez activé la double authentification sur votre compte wallabag et que vous venez de vous connecter depuis un nouvel appareil (ordinateur, téléphone, etc.), nous vous envoyons un code pour valider votre connexion."
5 5auth_code.mailer.body.second_para: "Voici le code à renseigner :"
6 Comme vous avez activé la double authentification sur votre compte wallabag et que vous venez de vous connecter depuis un nouvel appareil (ordinateur, téléphone, etc.), nous vous envoyons un code pour valider votre connexion. 6auth_code.mailer.body.support: "Si vous avez un problème de connexion, n'hésitez pas à contacter le support :"
7 Voici le code à renseigner: %code% 7auth_code.mailer.body.signature: "L'équipe wallabag"
8
9 Si vous avez un problème de connexion, n'hésitez pas à contacter le support: %support%
10 L'équipe wallabag
diff --git a/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig b/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig
new file mode 100644
index 00000000..69d23160
--- /dev/null
+++ b/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig
@@ -0,0 +1,117 @@
1{% block subject %}
2{{ "auth_code.mailer.subject"|trans({}, 'wallabag_user') }}
3{% endblock %}
4
5{% block body_text %}
6{{ "auth_code.mailer.body.hello"|trans({'%user%': user}, 'wallabag_user') }}
7
8{{ "auth_code.mailer.body.first_para"|trans({}, 'wallabag_user') }}
9{{ "auth_code.mailer.body.second_para"|trans({}, 'wallabag_user') }} {{ code }}
10
11{{ "auth_code.mailer.body.support"|trans({}, 'wallabag_user') }} {{ support_url }}
12
13{{ "auth_code.mailer.body.signature"|trans({}, 'wallabag_user') }}
14{% endblock %}
15
16{% block body_html %}
17<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
18
19<html xmlns="http://www.w3.org/1999/xhtml">
20<head>
21 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
22 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
23 <title>{{ "auth_code.mailer.subject"|trans({}, 'wallabag_user') }}</title>
24 <style type="text/css">
25 #outlook a {padding:0;}
26 body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0; font-family: Helvetica, Arial, sans-serif; background: #c6d4e0;}
27 .ExternalClass {width:100%;}
28 .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
29 #backgroundTable {margin:0; padding:0; width:100% !important; line-height: 100% !important; background: #c6d4e0;}
30 img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;}
31 a img {border:none;}
32 .image_fix {display:block;}
33 p {margin: 1em 0;}
34 h1, h2, h3, h4, h5, h6 {color: black !important;}
35 h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color: blue !important;}
36 h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {
37 color: red !important;
38 }
39 h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
40 color: purple !important;
41 }
42 table td {border-collapse: collapse;}
43 table { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }
44 a {color: #373737;}
45
46 #card {
47 background: #ffffff;
48 border: 1px solid #c5c5c5;
49 width: 89%;
50 margin: 5%;
51 }
52 #cell_desc h1, h5 {
53 display: block;
54 margin: 0;
55 }
56 #cell_desc h1 {
57 line-height: 35px;
58 margin-bottom: 10px;
59 }
60 #bg {background: #f2f2f2}
61
62 </style>
63</head>
64<body>
65
66 <!-- hidden text for preview -->
67 <div style="display:none;font-size:1px;color:#333333;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">
68 {{ "auth_code.mailer.body.hello"|trans({'%user%': user}, 'wallabag_user') }}
69 </div>
70
71 <table cellpadding="0" cellspacing="0" border="0" id="backgroundTable">
72 <tr>
73 <td>
74
75 <table cellpadding="0" cellspacing="0" border="0" align="center" id="card">
76 <tr>
77 <td style="padding: 20px;" width="96px" valign="top"><img class="image_fix" src="{{ wallabag_url }}/themes/material/img/logo-other_themes.png" alt="logo" title="{{ wallabag_url }}" style="width: 96px; height: 96px;" /></td>
78 <td style="padding: 20px; padding-left: 0;" valign="top" id="cell_desc">
79 <h1>wallabag</h1>
80 <h5>{% trans %}on{% endtrans %} {{ wallabag_url }}</h5>
81 </td>
82 </tr>
83 <tr><td colspan="2" style="padding: 0;"><div style="height: 0; border-top: 1px solid #c5c5c5;">&nbsp;</div></td></tr>
84 <tr id="bg">
85 <td style="padding: 20px;" colspan="2" valign="top">
86
87 <p><b>{{ "auth_code.mailer.body.hello"|trans({'%user%': user}, 'wallabag_user') }}</b></p>
88
89 <p>{{ "auth_code.mailer.body.first_para"|trans({}, 'wallabag_user') }}</p>
90 <p>{{ "auth_code.mailer.body.second_para"|trans({}, 'wallabag_user') }} <b>{{ code }}</b></p>
91
92 <p>{{ "auth_code.mailer.body.support"|trans({}, 'wallabag_user') }} <a href="{{ support_url }}">{{ support_url }}</a></p>
93 <p>{{ "auth_code.mailer.body.signature"|trans({}, 'wallabag_user') }}</p>
94 </td>
95 </tr>
96 <tr><td colspan="2" style="padding: 0;"><div style="height: 0; border-top: 1px solid #c5c5c5;">&nbsp;</div></td></tr>
97 <tr>
98 <td colspan="2">
99
100 <table cellpadding="0" cellspacing="0" border="0" width="100%">
101 <tr>
102 <td valign="top" style="padding: 20px; text-align: center"><a href="{{ wallabag_url }}">{{ wallabag_url }}</a></td>
103 <td valign="top" style="padding: 20px; text-align: center">Powered by <a href="https://www.wallabag.org/">wallabag</a></td>
104 </tr>
105 </table>
106
107 </td>
108 </tr>
109 </table>
110
111 </td>
112 </tr>
113 </table>
114
115</body>
116</html>
117{% endblock %}
diff --git a/src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php b/src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php
index 61e960f9..e3f43a7e 100644
--- a/src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php
+++ b/src/Wallabag/UserBundle/Tests/Mailer/AuthCodeMailerTest.php
@@ -4,8 +4,6 @@ namespace Wallabag\UserBundle\Tests\Mailer;
4 4
5use Wallabag\UserBundle\Entity\User; 5use Wallabag\UserBundle\Entity\User;
6use Wallabag\UserBundle\Mailer\AuthCodeMailer; 6use Wallabag\UserBundle\Mailer\AuthCodeMailer;
7use Symfony\Component\Translation\Translator;
8use Symfony\Component\Translation\Loader\ArrayLoader;
9 7
10/** 8/**
11 * @see https://www.pmg.com/blog/integration-testing-swift-mailer/ 9 * @see https://www.pmg.com/blog/integration-testing-swift-mailer/
@@ -27,7 +25,7 @@ class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
27{ 25{
28 protected $mailer; 26 protected $mailer;
29 protected $spool; 27 protected $spool;
30 protected $translator; 28 protected $twig;
31 29
32 protected function setUp() 30 protected function setUp()
33 { 31 {
@@ -38,12 +36,13 @@ class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
38 ); 36 );
39 $this->mailer = new \Swift_Mailer($transport); 37 $this->mailer = new \Swift_Mailer($transport);
40 38
41 $this->translator = new Translator('en'); 39 $twigTemplate = <<<TWIG
42 $this->translator->addLoader('array', new ArrayLoader()); 40{% block subject %}subject{% endblock %}
43 $this->translator->addResource('array', array( 41{% block body_html %}html body {{ code }}{% endblock %}
44 'auth_code.mailer.subject' => 'auth_code subject', 42{% block body_text %}text body {{ support_url }}{% endblock %}
45 'auth_code.mailer.body' => 'Hi %user%, here is the code: %code% and the support: %support%', 43TWIG;
46 ), 'en', 'wallabag_user'); 44
45 $this->twig = new \Twig_Environment(new \Twig_Loader_Array(array('@WallabagUserBundle/Resources/views/TwoFactor/email_auth_code.html.twig' => $twigTemplate)));
47 } 46 }
48 47
49 public function testSendEmail() 48 public function testSendEmail()
@@ -56,9 +55,10 @@ class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
56 55
57 $authCodeMailer = new AuthCodeMailer( 56 $authCodeMailer = new AuthCodeMailer(
58 $this->mailer, 57 $this->mailer,
59 $this->translator, 58 $this->twig,
60 'nobody@test.io', 59 'nobody@test.io',
61 'wallabag test', 60 'wallabag test',
61 'http://0.0.0.0/support',
62 'http://0.0.0.0' 62 'http://0.0.0.0'
63 ); 63 );
64 64
@@ -69,7 +69,8 @@ class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
69 $msg = $this->spool->getMessages()[0]; 69 $msg = $this->spool->getMessages()[0];
70 $this->assertArrayHasKey('test@wallabag.io', $msg->getTo()); 70 $this->assertArrayHasKey('test@wallabag.io', $msg->getTo());
71 $this->assertEquals(array('nobody@test.io' => 'wallabag test'), $msg->getFrom()); 71 $this->assertEquals(array('nobody@test.io' => 'wallabag test'), $msg->getFrom());
72 $this->assertEquals('auth_code subject', $msg->getSubject()); 72 $this->assertEquals('subject', $msg->getSubject());
73 $this->assertContains('Hi Bob, here is the code: 666666 and the support: http://0.0.0.0', $msg->toString()); 73 $this->assertContains('text body http://0.0.0.0/support', $msg->toString());
74 $this->assertContains('html body 666666', $msg->toString());
74 } 75 }
75} 76}