Auth: Passwordless Login Option Using Magic Links (#95436)
* initial passwordless client * passwordless login page * Working basic e2e flow * Add todo comments * Improve the passwordless login flow * improved passwordless login, backend for passwordless signup * add expiration to emails * update email templates & render username & name fields on signup * improve email templates * change login page text while awaiting passwordless code * fix merge conflicts * use claims.TypeUser * add initial passwordless tests * better error messages * simplified error name * remove completed TODOs * linting & minor test improvements & rename passwordless routes * more linting fixes * move code generation to its own func, use locationService to get query params * fix ampersand in email templates & use passwordless api routes in LoginCtrl * txt emails more closely match html email copy * move passwordless auth behind experimental feature toggle * fix PasswordlessLogin property failing typecheck * make update-workspace * user correct placeholder * Update emails/templates/passwordless_verify_existing_user.txt Co-authored-by: Dan Cech <dcech@grafana.com> * Update emails/templates/passwordless_verify_existing_user.mjml Co-authored-by: Dan Cech <dcech@grafana.com> * Update emails/templates/passwordless_verify_new_user.txt Co-authored-by: Dan Cech <dcech@grafana.com> * Update emails/templates/passwordless_verify_new_user.txt Co-authored-by: Dan Cech <dcech@grafana.com> * Update emails/templates/passwordless_verify_new_user.mjml Co-authored-by: Dan Cech <dcech@grafana.com> * use & in email templates * Update emails/templates/passwordless_verify_existing_user.txt Co-authored-by: Dan Cech <dcech@grafana.com> * remove IP address validation * struct for passwordless settings * revert go.work.sum changes * mock locationService.getSearch in failing test --------- Co-authored-by: Mihaly Gyongyosi <mgyongyosi@users.noreply.github.com> Co-authored-by: Dan Cech <dcech@grafana.com>
This commit is contained in:
co-authored by
Dan Cech
Mihaly Gyongyosi
parent
c865958292
commit
6abe99efd6
@@ -0,0 +1,51 @@
|
||||
<mjml>
|
||||
<!-- global variables -->
|
||||
<mj-include path="./partials/_globals.mjml" />
|
||||
<!-- css styling -->
|
||||
<mj-include path="./partials/layout/theme.css" type="css" css-inline="inline" />
|
||||
<mj-head>
|
||||
<!-- ⬇ Don't forget to specify an email subject below! ⬇ -->
|
||||
<mj-title> {{ Subject .Subject .TemplateData "Verify your email" }} </mj-title>
|
||||
<mj-include path="./partials/layout/head.mjml" />
|
||||
</mj-head>
|
||||
<mj-body>
|
||||
<mj-section>
|
||||
<mj-include path="./partials/layout/header.mjml" />
|
||||
</mj-section>
|
||||
<mj-wrapper css-class="background" padding="0">
|
||||
<mj-section padding="0">
|
||||
<mj-column>
|
||||
<mj-text>
|
||||
<h2>Please verify your email</h2>
|
||||
</mj-text>
|
||||
<mj-text>
|
||||
Copy and paste the confirmation code into the login form to verify your email address. This confirmation code
|
||||
will expire in {{ .Expire }} minutes.
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding="10px 25px">
|
||||
<mj-column css-class="well">
|
||||
<mj-text font-size="22px" font-weight="bold" align="center"> {{ .ConfirmationCode }} </mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding="0">
|
||||
<mj-column>
|
||||
<mj-text> Alternatively, you can use the button below to verify your email address. </mj-text>
|
||||
<mj-button href="{{ .AppUrl }}login/?code={{ .Code }}&confirmationCode={{ .ConfirmationCode }}">
|
||||
Verify your email
|
||||
</mj-button>
|
||||
<mj-text> You can also copy and paste this link into your browser directly: </mj-text>
|
||||
<mj-text>
|
||||
<a rel="noopener" href="{{ .AppUrl }}login?code={{ .Code }}&confirmationCode={{ .ConfirmationCode }}"
|
||||
>{{ .AppUrl }}login?code={{ .Code }}&confirmationCode={{ .ConfirmationCode }}</a
|
||||
>
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
</mj-wrapper>
|
||||
<mj-section>
|
||||
<mj-include path="./partials/layout/footer.mjml" />
|
||||
</mj-section>
|
||||
</mj-body>
|
||||
</mjml>
|
||||
@@ -0,0 +1,10 @@
|
||||
[[HiddenSubject .Subject "Verify your email"]]
|
||||
|
||||
Hi,
|
||||
|
||||
Copy and paste the email verification code:
|
||||
[[.ConfirmationCode]]
|
||||
into the login form to verify your email address. This confirmation code will expire in {{ .Expire }} minutes.
|
||||
Alternatively, you can use the button below to verify your email address.
|
||||
|
||||
[[.AppUrl]]login/?code=[[.Code]]&confirmationCode=[[.ConfirmationCode]]
|
||||
@@ -0,0 +1,53 @@
|
||||
<mjml>
|
||||
<!-- global variables -->
|
||||
<mj-include path="./partials/_globals.mjml" />
|
||||
<!-- css styling -->
|
||||
<mj-include path="./partials/layout/theme.css" type="css" css-inline="inline" />
|
||||
<mj-head>
|
||||
<!-- ⬇ Don't forget to specify an email subject below! ⬇ -->
|
||||
<mj-title> {{ Subject .Subject .TemplateData "Welcome to Grafana, please complete your sign up!" }} </mj-title>
|
||||
<mj-include path="./partials/layout/head.mjml" />
|
||||
</mj-head>
|
||||
<mj-body>
|
||||
<mj-section>
|
||||
<mj-include path="./partials/layout/header.mjml" />
|
||||
</mj-section>
|
||||
<mj-wrapper css-class="background" padding="0">
|
||||
<mj-section padding="0">
|
||||
<mj-column>
|
||||
<mj-text>
|
||||
<h2>Please complete your signup</h2>
|
||||
</mj-text>
|
||||
<mj-text>
|
||||
Copy and paste the confirmation code into the sign up form to verify your email address. This confirmation
|
||||
code will expire in {{ .Expire }} minutes.
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding="10px 25px">
|
||||
<mj-column css-class="well">
|
||||
<mj-text font-size="22px" font-weight="bold" align="center"> {{ .ConfirmationCode }} </mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding="0">
|
||||
<mj-column>
|
||||
<mj-text> Alternatively, you can use the button below to complete your sign up. </mj-text>
|
||||
<mj-button href="{{ .AppUrl }}login/?code={{ .Code }}&confirmationCode={{ .ConfirmationCode }}&signup=true">
|
||||
Complete Sign Up
|
||||
</mj-button>
|
||||
<mj-text> You can also copy and paste this link into your browser directly: </mj-text>
|
||||
<mj-text>
|
||||
<a
|
||||
rel="noopener"
|
||||
href="{{ .AppUrl }}login?code={{ .Code }}&confirmationCode={{ .ConfirmationCode }}&signup=true"
|
||||
>{{ .AppUrl }}login?code={{ .Code }}&confirmationCode={{ .ConfirmationCode }}&signup=true</a
|
||||
>
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
</mj-wrapper>
|
||||
<mj-section>
|
||||
<mj-include path="./partials/layout/footer.mjml" />
|
||||
</mj-section>
|
||||
</mj-body>
|
||||
</mjml>
|
||||
@@ -0,0 +1,10 @@
|
||||
[[HiddenSubject .Subject "Welcome to Grafana, please complete your signup!"]]
|
||||
|
||||
Hi,
|
||||
|
||||
Copy and paste the email verification code:
|
||||
[[.ConfirmationCode]]
|
||||
into the sign up form to verify your email address. This confirmation code will expire in {{ .Expire }} minutes.
|
||||
Alternatively, you can use the button below to verify your email address.
|
||||
|
||||
[[.AppUrl]]login/?code=[[.Code]]&confirmationCode=[[.ConfirmationCode]]
|
||||
Reference in New Issue
Block a user