Skip to content

Commit

Permalink
feat: implement OTP over email (#582)
Browse files Browse the repository at this point in the history
Implements nhost/nhost#2651

example:

```
curl -X POST \
    -H "Content-Type: application/json" \
    -d '{"email": "[email protected]"}' \
    http://localhost:4000/signin/otp/email

# get OTP from email

curl -X POST \
    -H "Content-Type: application/json" \
    -d '{"email": "[email protected]","otp":"129746"}' \
    http://localhost:4000/signin/otp/email/verify
```

### **PR Type**
Enhancement, Tests


___

### **Description**
- Added new OTP email sign-in and verification endpoints.
- Defined new request and response types for OTP email sign-in and
verification.
- Added configuration and command-line flags for enabling OTP email.
- Implemented controller logic for OTP email sign-in.
- Added tests for OTP email sign-in functionality.
- Updated OpenAPI documentation for new endpoints.



___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>8
files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>server.gen.go</strong><dd><code>Add OTP email sign-in
and verification endpoints</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

go/api/server.gen.go

<li>Added new endpoints for OTP email sign-in and verification.<br> <li>
Updated interface and middleware to handle new OTP routes.<br> <li>
Registered new OTP routes in the router.<br>


</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-ebca0209f464067ebb38f8fad9dd352058e15702563f575d649434a1e7722b3d">+206/-64</a></td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>types.gen.go</strong><dd><code>Define OTP email sign-in
and verification types</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

go/api/types.gen.go

<li>Defined new request and response types for OTP email sign-in and
<br>verification.<br>


</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-086764bd76c1416b0d0ddedcc804c3e6983907886215f9bb51162df91e823254">+27/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>get_verify.go</strong><dd><code>Add OTP ticket type
handling</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

go/controller/get_verify.go

- Added OTP ticket type handling in verification logic.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-e64106bbe29a6baf928dd3f91fdfbaf6607ebc51b1a5bf57632718137db9ef9c">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>post_signin_otp_email.go</strong><dd><code>Implement
OTP email sign-in logic</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

go/controller/post_signin_otp_email.go

- Implemented controller logic for OTP email sign-in.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-5c2341d0b9cc04c12b83fb8a97a2c9d942dcfbb02e0bd802f035ea73e3efbdcc">+52/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>post_signin_otp_verify.go</strong><dd><code>Add
placeholder for OTP verification logic</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

go/controller/post_signin_otp_verify.go

- Added placeholder for OTP verification logic.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-34b399d52c93703b4829213e118b29a22204847d130bdfb3dff2d9c91f30c415">+14/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>

<summary><strong>post_signin_passwordless_email.go</strong><dd><code>Refactor
passwordless email sign-in logic</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

go/controller/post_signin_passwordless_email.go

<li>Refactored existing passwordless email sign-in logic.<br> <li>
Extracted common email sign-in validation and ticket generation
logic.<br> <br>


</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-b84756f7f1b9ced640c9a925f5e2b2b00a8bd3b6d47ae9d820cc03e42a65e0ae">+67/-40</a>&nbsp;
</td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>workflows_tickets.go</strong><dd><code>Add OTP ticket
type and generation logic</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

go/controller/workflows_tickets.go

- Added OTP ticket type and OTP generation logic.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-a4d16eaab24ba5b8c7b93fb112b8dd7a7ff7a70308e2d334b1ba6ba38df8b1ee">+17/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>templates.go</strong><dd><code>Add OTP email
notification template</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

go/notifications/templates.go

- Added template name for OTP email notifications.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-7200e4e0d06dc71060ca7becfdd9ad2e684ca90426c8de883e8d59fa2b1c767f">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>3 files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>config.go</strong><dd><code>Add OTP email configuration
flag</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

go/cmd/config.go

- Added configuration flag for enabling OTP email.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-6ed50c9d309f6e7cf03742253995dfc65ae67702ae9c4aeb650b24a9b87cf377">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>serve.go</strong><dd><code>Add command-line flag for
OTP email</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

go/cmd/serve.go

- Added command-line flag for enabling OTP email.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-a900f3187c126bacf5c9c5b1745b5d14bc583c01ab8f1ca84ae449751c224b68">+9/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>config.go</strong><dd><code>Add OTP email enabled field
to config</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

go/controller/config.go

- Added OTP email enabled field to configuration struct.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-77fe34a234b413cd5f46aa02ee1cb93864fc387e765cd7dd1a54efd7ac9a4eb0">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Error
handling</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>errors.go</strong><dd><code>Add error response handlers
for OTP email</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

go/controller/errors.go

- Added error response handlers for OTP email endpoints.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-d2ebd3582b320c6db8161b6f3f90931cee507a68d9667ca1f6c88e8108ede569">+8/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>3
files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>main_test.go</strong><dd><code>Update ticket comparison
logic for OTP</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

go/controller/main_test.go

- Updated ticket comparison logic to handle OTP tickets.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-a13f50ba7fee39bdeff8c7f63e51af45b3e837d359608a042d7e2e8d50fb8b89">+13/-6</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>post_signin_otp_email_test.go</strong><dd><code>Add
tests for OTP email sign-in</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

go/controller/post_signin_otp_email_test.go

- Added tests for OTP email sign-in functionality.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-8b00ba05ca046df6350ea7ebd3e3537b752b009847691497eb5d09c09f265b5c">+596/-0</a>&nbsp;
</td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>validator_test.go</strong><dd><code>Update
configuration for OTP email tests</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

go/controller/validator_test.go

- Updated configuration for OTP email tests.



</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-3f42f5f887ad54ac2f169b2629a4d17be0917e55ca60bfac885300953c8cd5f2">+32/-33</a>&nbsp;
</td>

</tr>

</table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>1
files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>openapi.yaml</strong><dd><code>Add OpenAPI docs for OTP
email endpoints</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

go/api/openapi.yaml

<li>Added OpenAPI documentation for OTP email sign-in and verification
<br>endpoints.<br>


</details>


  </td>
<td><a
href="https://github.com/nhost/hasura-auth/pull/582/files#diff-9fe8f7da727ff26c02939aa060e0348d870e6dd95ba433f9f4d53a9a6967aca0">+85/-3</a>&nbsp;
&nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information

---------

Co-authored-by: Hassan Ben Jobrane <[email protected]>
  • Loading branch information
dbarrosop and onehassan authored Nov 18, 2024
1 parent 7a092ca commit a199f4e
Show file tree
Hide file tree
Showing 61 changed files with 2,577 additions and 709 deletions.
3 changes: 2 additions & 1 deletion docs/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
| AUTH_LOCALE_DEFAULT | | `en` |
| AUTH_LOCALE_ALLOWED_LOCALES | | `en` |
| AUTH_LOG_LEVEL | Define the log level of the application:. Accepted values: `debug`, `info`, `warn`, `error`, `silent`. | `info` |
| AUTH_EMAIL_PASSWORDLESS_ENABLED | Enables passwordless authentication by email. The SMTP server must then be configured. | `false` |
| AUTH_EMAIL_PASSWORDLESS_ENABLED | Enables passwordless authentication by email using magic links. The SMTP server must then be configured. | `false` |
| AUTH_OTP_EMAIL_ENABLED | Enables passwordless authentication by email using OTP. The SMTP server must then be configured. | `false` |
| AUTH_SMS_PASSWORDLESS_ENABLED | Enables passwordless authentication by SMS. An SMS provider must then be configured. | `false` |
| AUTH_SHOW_LOG_QUERY_PARAMS | Shows all query parameters in the logs. Make sure you know what you do because this setting can potentially reveal secure information. | `false` |
| AUTH_SMS_PROVIDER | SMS provider name. Only `twilio` is possible as an option for now. | |
Expand Down
60 changes: 34 additions & 26 deletions email-templates/bg/email-confirm-change/body.html
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
<!DOCTYPE html>
<html dir="ltr" lang="bg">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<meta charset="UTF-8" />
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
</head>
<body style="background-color:#f5f5f5;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;padding:20px;">
<div style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0">
Потвърдете смяната на вашия имейл
</div>
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="max-width:560px;margin:0 auto;background-color:#ffffff;padding:20px;border-radius:8px;border:1px solid #ececec;">
<body style="background-color: #f5f5f5; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif">
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation" style="max-width: 560px; margin: 20px auto 0 auto; padding: 20px; background-color: #ffffff; border-radius: 8px; border: 1px solid #ececec">
<tbody>
<tr style="width:100%">
<tr style="width: 100%">
<td>
<h1 style="font-size:24px;letter-spacing:-0.5px;line-height:1.3;font-weight:400;color:#484848;padding:0;margin-top:0px;">Потвърдете смяната на вашия имейл</h1>
<p style="font-size:15px;line-height:1.4;margin:10px 0;color:#3c4149">Използвайте посочения линк, за да повърдите смяната на имейл:</p>
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="padding:20px 0 20px">
<h1 style="font-size: 24px; letter-spacing: -0.5px; line-height: 1.3; font-weight: 400; color: #484848; margin-top: 0">Потвърдете смяната на вашия имейл</h1>
<p style="font-size: 15px; line-height: 1.4; margin: 0 0 10px; color: #3c4149">Използвайте посочения линк, за да повърдите смяната на имейл:</p>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation" style="padding: 10px 0 0px">
<tbody>
<tr>
<td>
<a href="${link}" style="line-height:100%;text-decoration:none;display:block;max-width:100%;background-color:#0052CD;border-radius:6px;font-weight:600;color:#fff;font-size:15px;text-align:center;padding:11px 23px" target="_blank">
Смени имейл
</a>
<a href="${link}" style="line-height: 100%; text-decoration: none; display: block; max-width: 100%; background-color: #0052cd; border-radius: 3px; font-weight: 600; color: #fff; font-size: 15px; text-align: center; padding: 11px 23px 11px 23px" target="_blank"
><span
><!--[if mso]><i style="mso-font-width: 383.33333333333337%; mso-text-raise: 16.5" hidden>&#8202;&#8202;&#8202;</i><![endif]--></span
><span style="max-width: 100%; display: inline-block; line-height: 120%; mso-padding-alt: 0px; mso-text-raise: 8.25px">Смени имейл</span
><span
><!--[if mso]><i style="mso-font-width: 383.33333333333337%" hidden>&#8202;&#8202;&#8202;&#8203;</i><![endif]--></span
></a
>
</td>
</tr>
</tbody>
</table>
<hr style="width:100%;border:none;border-top:1px solid #eaeaea;border-color:#dfe1e4;margin:10px 0" />
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="margin-top: 10px;">
<tr>
<td style="padding-right: 8px;">
<img alt="Nhost Logo" height="20" src="https://nhost.io/images/emails/icon.png" style="display:block;outline:none;border:none;text-decoration:none;width:20px;height:20px;" width="20" />
</td>
<td>
<a href="https://nhost.io" style="color:#b4becc;text-decoration:none;font-size:14px" target="_blank">Powered by Nhost</a>
</td>
</tr>
<hr style="width: 100%; border: none; border-top: 1px solid #eaeaea; border-color: #dfe1e4; margin: 20px 0 20px" />
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody style="width: 100%">
<tr style="width: 100%">
<td data-id="__react-email-column" style="width: 30px"><img alt="Nhost Logo" height="20" src="https://nhost.io/images/emails/icon.png" style="display: block; outline: none; border: none; text-decoration: none; border-radius: 0; width: 20px; height: 20px" width="20" /></td>
<td data-id="__react-email-column" style="margin: 0"><a href="https://nhost.io" style="color: #b4becc; text-decoration: none; font-size: 14px" target="_blank">Powered by Nhost</a></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
</html>
60 changes: 34 additions & 26 deletions email-templates/bg/email-verify/body.html
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
<!DOCTYPE html>
<html dir="ltr" lang="bg">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<meta charset="UTF-8" />
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
</head>
<body style="background-color:#f5f5f5;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;padding:20px;">
<div style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0">
Потвърдете вашия имейл
</div>
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="max-width:560px;margin:0 auto;background-color:#ffffff;padding:20px;border-radius:8px;border:1px solid #ececec;">
<body style="background-color: #f5f5f5; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif">
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation" style="max-width: 560px; margin: 20px auto 0 auto; padding: 20px; background-color: #ffffff; border-radius: 8px; border: 1px solid #ececec">
<tbody>
<tr style="width:100%">
<tr style="width: 100%">
<td>
<h1 style="font-size:24px;letter-spacing:-0.5px;line-height:1.3;font-weight:400;color:#484848;padding:0;margin-top:0px;">Потвърдете вашия имейл</h1>
<p style="font-size:15px;line-height:1.4;margin:10px 0;color:#3c4149">Използвайте посочения линк, за да потвърдите вашия имейл:</p>
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="padding:20px 0 20px">
<h1 style="font-size: 24px; letter-spacing: -0.5px; line-height: 1.3; font-weight: 400; color: #484848; margin-top: 0">Потвърдете вашия имейл</h1>
<p style="font-size: 15px; line-height: 1.4; margin: 0 0 10px; color: #3c4149">Използвайте посочения линк, за да потвърдите вашия имейл:</p>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation" style="padding: 10px 0 0px">
<tbody>
<tr>
<td>
<a href="${link}" style="line-height:100%;text-decoration:none;display:block;max-width:100%;background-color:#0052CD;border-radius:6px;font-weight:600;color:#fff;font-size:15px;text-align:center;padding:11px 23px" target="_blank">
Потвърдете имейл
</a>
<a href="${link}" style="line-height: 100%; text-decoration: none; display: block; max-width: 100%; background-color: #0052cd; border-radius: 3px; font-weight: 600; color: #fff; font-size: 15px; text-align: center; padding: 11px 23px 11px 23px" target="_blank"
><span
><!--[if mso]><i style="mso-font-width: 383.33333333333337%; mso-text-raise: 16.5" hidden>&#8202;&#8202;&#8202;</i><![endif]--></span
><span style="max-width: 100%; display: inline-block; line-height: 120%; mso-padding-alt: 0px; mso-text-raise: 8.25px">Потвърдете имейл</span
><span
><!--[if mso]><i style="mso-font-width: 383.33333333333337%" hidden>&#8202;&#8202;&#8202;&#8203;</i><![endif]--></span
></a
>
</td>
</tr>
</tbody>
</table>
<hr style="width:100%;border:none;border-top:1px solid #eaeaea;border-color:#dfe1e4;margin:10px 0" />
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="margin-top: 10px;">
<tr>
<td style="padding-right: 8px;">
<img alt="Nhost Logo" height="20" src="https://nhost.io/images/emails/icon.png" style="display:block;outline:none;border:none;text-decoration:none;width:20px;height:20px;" width="20" />
</td>
<td>
<a href="https://nhost.io" style="color:#b4becc;text-decoration:none;font-size:14px" target="_blank">Powered by Nhost</a>
</td>
</tr>
<hr style="width: 100%; border: none; border-top: 1px solid #eaeaea; border-color: #dfe1e4; margin: 20px 0 20px" />
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody style="width: 100%">
<tr style="width: 100%">
<td data-id="__react-email-column" style="width: 30px"><img alt="Nhost Logo" height="20" src="https://nhost.io/images/emails/icon.png" style="display: block; outline: none; border: none; text-decoration: none; border-radius: 0; width: 20px; height: 20px" width="20" /></td>
<td data-id="__react-email-column" style="margin: 0"><a href="https://nhost.io" style="color: #b4becc; text-decoration: none; font-size: 14px" target="_blank">Powered by Nhost</a></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
</html>
Loading

0 comments on commit a199f4e

Please sign in to comment.