FusionAuth / fusionauth-issues

FusionAuth issue submission project
https://fusionauth.io
91 stars 12 forks source link

Template render crash on Setup password tenant email sendinf #1437

Open soullivaneuh opened 3 years ago

soullivaneuh commented 3 years ago

Template render crash on Setup password tenant email sendinf

Description

We have numerous logs with template crashes on the template rendering

Affects versions

1.30.1

Steps to reproduce

  1. Trigger a send of the Setup Password email

Expected behavior

Sent email without error.

Screenshots

An error occurred while sending an email to [xxx@xxx.com].

Email template Id: 352f5059-d5a2-4a6b-b737-eafa6bdc5c9f
Email template name: Setup Password
TenantId: 93e032b5-37d0-5176-0c95-0e324d3eb5b8

The following error was returned:
Email send failure. See reasons below.

Render Errors
---------------
html : freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
==> changePasswordId  [in nameless template at line 81, column 60]

----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use [#if myOptionalVar??]when-present[#else]when-missing[/#if]. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
    - Failed at: ${changePasswordId}  [in nameless template at line 81, column 58]
----

text : freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
==> changePasswordId  [in nameless template at line 10, column 47]

----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use [#if myOptionalVar??]when-present[#else]when-missing[/#if]. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
    - Failed at: ${changePasswordId}  [in nameless template at line 10, column 45]
----

Below is the email request in JSON:
{
  "attachments" : [ ],
  "bcc" : [ ],
  "cc" : [ ],
  "from" : {
    "address" : "no-reply@company.com",
    "display" : "Company"
  },
  "html" : "<!DOCTYPE html>\n<html>\n  <head>\n    <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap\" rel=\"stylesheet\">\n    <style>\n      * {\n        margin: 0;\n        padding: 0;\n      }\n\n      body {\n        font-family: Inter, sans-serif;\n        text-align: center;\n      }\n\n      p {\n        margin: 15px 0;\n      }\n\n      .container {\n        max-width: 700px;\n        margin: auto;\n      }\n\n      .logo {\n        max-width: 150px;\n        margin: 15px 0;\n      }\n\n      .nexy-gradient {\n        background: rgb(72,211,170);\n        background: linear-gradient(90deg, rgba(72,211,170,1) 0%, rgba(95,74,227,1) 100%);\n        width: 100%;\n        height: 5px;\n      }\n\n      /* Use to space different mail content parts. */\n      .content {\n        margin: 50px 0;\n      }\n\n      .footer {\n        margin: 15px 0;\n      }\n      .footer > p {\n        margin: 0;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"container\">\n      <div>\n        <img\n          src=\"https://design.company.dev/img/logo/text.png\"\n          alt=\"Company Logo\"\n          class=\"logo\"\n        />\n      </div>\n      <div class=\"nexy-gradient\"></div>\n<div class=\"content\">\n  <p>\n    Bonjour,\n  </p>\n</div>\n\n<div class=\"content\">\n  <p>\n    Vous faites maintenant partie des utilisateurs de Company : nous vous remercions\n    chaleureusement pour votre confiance et sommes très heureux de vous compter parmi nos clients.\n  </p>\n\n  <p>\n    Votre compte Company <b>xxx@xxx.com</b> a été créé par nos soins.\n  </p>\n\n  <p>\n    <b>\n      Pour finaliser son activation cliquez ici :\n    </b>\n    <br />\n    <a href=\"https://connect.company.com/password/change/",
  "subject" : "Configuration du mot de passe",
  "text" : "Bonjour,\n\nVous faites maintenant partie des utilisateurs de Company : nous vous remercions\nchaleureusement pour votre confiance et sommes très heureux de vous compter parmi nos clients.\n\nVotre compte Company xxx@xxx.com a été créé par nos soins.\n\nPour finaliser son activation cliquez ici :\n\nhttps://connect.company.com/password/change/",
  "to" : [ {
    "address" : "xxx@xxx.com"
  } ]
}

Platform

(Please complete the following information)

Community guidelines

All issues filed in this repository must abide by the FusionAuth community guidelines.

Additional context

mooreds commented 3 years ago

Hmmm. Can you cut and paste the entire template with Id 352f5059-d5a2-4a6b-b737-eafa6bdc5c9f?

soullivaneuh commented 3 years ago

HTML templates

English

<!DOCTYPE html>
<html>
  <head>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      body {
        font-family: Inter, sans-serif;
        text-align: center;
      }

      p {
        margin: 15px 0;
      }

      .container {
        max-width: 700px;
        margin: auto;
      }

      .logo {
        max-width: 150px;
        margin: 15px 0;
      }

      .nexy-gradient {
        background: rgb(72,211,170);
        background: linear-gradient(90deg, rgba(72,211,170,1) 0%, rgba(95,74,227,1) 100%);
        width: 100%;
        height: 5px;
      }

      /* Use to space different mail content parts. */
      .content {
        margin: 50px 0;
      }

      .footer {
        margin: 15px 0;
      }
      .footer > p {
        margin: 0;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div>
        <img
          src="https://design.company.dev/img/logo/text.png"
          alt="Company Logo"
          class="logo"
        />
      </div>
      <div class="nexy-gradient"></div>
<div class="content">
  <p>
    Hello,
  </p>
</div>

<div class="content">
  <p>
    You are now part of the Company hosting users: we warmly thank you
    for your trust and are very happy to count you among our customers.
  </p>

  <p>
    We have created your Company account <b>${user.email}.</b>
  </p>

  <p>
    <b>
      Please click on the link below to finalize its activation:
    </b>
    <br />
    <a href="https://connect.company.com/password/change/${changePasswordId}?tenantId=${user.tenantId}">
      https://connect.company.com/password/change/${changePasswordId}?tenantId=${user.tenantId}
    </a>
  </p>

  <p>
    <b>
      Need help ?
    </b>
    <br />
    You can find all of our documentation here:
    <a href="https://docs.company.com/">https://docs.company.com/</a>
  </p>
</div>

<div class="content">
  <p>
    You have any questions? Do not hesitate to send us an email at support@company.com
  </p>

  <p>
    See you soon,
    The Company team
  </p>
</div>
      <div class="nexy-gradient"></div>
      <div class="footer">
        <p>
          <b>Company</b> // Bla bla
        </p>
        <p>
          03 00 00 00 00
          - contact@company.com
          - <a href="https://www.company.com/">www.company.com</a>
        </p>
      </div>
    </div>
  </body>
</html>

French

<!DOCTYPE html>
<html>
  <head>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      body {
        font-family: Inter, sans-serif;
        text-align: center;
      }

      p {
        margin: 15px 0;
      }

      .container {
        max-width: 700px;
        margin: auto;
      }

      .logo {
        max-width: 150px;
        margin: 15px 0;
      }

      .nexy-gradient {
        background: rgb(72,211,170);
        background: linear-gradient(90deg, rgba(72,211,170,1) 0%, rgba(95,74,227,1) 100%);
        width: 100%;
        height: 5px;
      }

      /* Use to space different mail content parts. */
      .content {
        margin: 50px 0;
      }

      .footer {
        margin: 15px 0;
      }
      .footer > p {
        margin: 0;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div>
        <img
          src="https://design.company.dev/img/logo/text.png"
          alt="Company Logo"
          class="logo"
        />
      </div>
      <div class="nexy-gradient"></div>
<div class="content">
  <p>
    Bonjour,
  </p>
</div>

<div class="content">
  <p>
    Vous faites maintenant partie des utilisateurs de Company : nous vous remercions
    chaleureusement pour votre confiance et sommes très heureux de vous compter parmi nos clients.
  </p>

  <p>
    Votre compte Company <b>${user.email}</b> a été créé par nos soins.
  </p>

  <p>
    <b>
      Pour finaliser son activation cliquez ici :
    </b>
    <br />
    <a href="https://connect.company.com/password/change/${changePasswordId}?tenantId=${user.tenantId}">
      https://connect.company.com/password/change/${changePasswordId}?tenantId=${user.tenantId}
    </a>
  </p>
</div>

<div class="content">
  <p>
    <b>
      Besoin d’aide ?
    </b>
    <br />
    Retrouvez toute notre doc par ici :
    <a href="https://docs.company.com/">https://docs.company.com/</a>
  </p>

  <p>
    Vous avez des questions ? N’hésitez pas à nous envoyer un mail à support@company.com
  </p>

  <p>
    À très vite,
    L’équipe Company
  </p>
</div>
      <div class="nexy-gradient"></div>
      <div class="footer">
        <p>
          <b>Company</b> // Bla bla bla
        </p>
        <p>
          03 00 00 00 00
          - contact@company.com
          - <a href="https://www.company.com/">www.company.com</a>
        </p>
      </div>
    </div>
  </body>
</html>

Text templates

English

Hello,

You are now part of the Company hosting users: we warmly thank you
for your trust and are very happy to count you among our customers.

We have created your Company account ${user.email}.

Please click on the link below to finalize its activation:

https://connect.company.com/password/change/${changePasswordId}?tenantId=${user.tenantId}

Need help ?
You can find all of our documentation here: https://docs.company.com/

You have any questions? Do not hesitate to send us an email at support@company.com

See you soon,
The Company team

Company // Bla bla bla
03 00 00 00 00 - contact@company.com - www.company.com

French

Bonjour,

Vous faites maintenant partie des utilisateurs de Company : nous vous remercions
chaleureusement pour votre confiance et sommes très heureux de vous compter parmi nos clients.

Votre compte Company ${user.email} a été créé par nos soins.

Pour finaliser son activation cliquez ici :

https://connect.company.com/password/change/${changePasswordId}?tenantId=${user.tenantId}

Besoin d’aide ?
Retrouvez toute notre doc par ici : https://docs.company.com/

Vous avez des questions ? N’hésitez pas à nous envoyer un mail à support@company.com

À très vite,
L’équipe Company

Company // Bla bla bla
03 00 00 00 00 - contact@company.com - www.company.com
soullivaneuh commented 2 years ago

@mooreds Do you have any clue about this issue? Thanks!

mooreds commented 2 years ago

Hmmm. I don't have any ideas. Looks like your template contain the changePasswordId which is a valid variable here: https://fusionauth.io/docs/v1/tech/themes/template-variables/#oauth-change-password-form

Is there anything in the event log? Sometimes useful info shows up there.

Additional steps you could take:

I am unfortunately too slammed to try to replicate right now, but can put it on the (somewhat long) list.

soullivaneuh commented 2 years ago

@mooreds Going back to the issue.

First, please know we still have the same error under v1.40.0. We recently updated to v1.40.2, we will monitor that.

provide a docker file we can use to replicate locally

That will be quite difficult, giving you only the Dockerfile won't help at is needs several file for the setup script and template generation. However, we may invite you to our private project so you should be able to take a look.

Also, please note this error does happen only for some of the account creation and I didn't yet find the reproducible context, so it may not help.

see if changePasswordId is used in any other template for which it isn't defined

The changePasswordId if used by the following template we override:

They are expected and used the same way. However, I am not sure about the question as the error come clearly from the setup_password template.

wrap any calls to changePasswordId in the nullsafe operator ( ${changePasswordId!"missingchangepasswordid"} ) and see if you get a different error message.

Well, I won't do that for an obvious reason: This will lead to the error being gone but broken URLs would be silenced dispatch across our customer, which is a not acceptable situation for us.

robotdan commented 1 year ago

Trigger a send of the Setup Password email

Are you using the Send API, or beginning the workflow by using the Change Password API?