Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local kratos email verification with mailslurper #1648

Merged
merged 11 commits into from
Dec 13, 2022

Conversation

thehabbos007
Copy link
Contributor

@thehabbos007 thehabbos007 commented Dec 12, 2022

🌟 What is the purpose of this PR?

This PR adds email verification flows to Kratos, configuring the code method and custom mail templates.
There are some potential type issues with the kratos SDK for typescript, see ory/kratos#2943 which means the current implementation casts a type in a place where it isn't expected.

The current setup allows for verification through the UI, but it isn't neatly integreated/expected. I've included the UI scaffold for prettifying

🔗 Related links

🚫 Blocked by

🔍 What does this change?

  • Kratos dev config (and anticipation for prod config)
  • Adds new frontend endpoint to receive verification tokens
  • Email sending through mailslurper locally
  • Email templates for HTML and plaintext

📜 Does this require a change to the docs?

⚠️ Known issues

  • The typescript types on the frontend for submitting the verification flow seems to be incorrect, hence some casting to get it to work.
  • Production does not have this enabled yet

🐾 Next steps

  • Prettier email templates
  • Enabling n production

🛡 What tests cover this?

none

❓ How to test this?

  1. Checkout the branch as you would normally (external-service + yarn dev)
  2. Sign up a new user and choose a shortname/preferred name
  3. Go to http://localhost:4436/# to access mailslurper
  4. open network explorer tab in dev tools
  5. Click verification link and verify email
  6. Observe next whoami request contains a verified mail

📹 Demo

mail_verify.mp4

@codecov
Copy link

codecov bot commented Dec 12, 2022

Codecov Report

Attention: Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Project coverage is 56.85%. Comparing base (1a3de5f) to head (8ff88d9).
Report is 3448 commits behind head on main.

Files with missing lines Patch % Lines
packages/hash/api/src/auth/index.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1648      +/-   ##
==========================================
+ Coverage   56.76%   56.85%   +0.08%     
==========================================
  Files         224      224              
  Lines       15850    15826      -24     
  Branches      388      384       -4     
==========================================
  Hits         8998     8998              
+ Misses       6847     6823      -24     
  Partials        5        5              
Flag Coverage Δ
backend-integration-tests 2.70% <ø> (ø)
unit-tests 1.74% <0.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@benwerner01 benwerner01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ahmad. Here are some comments, still need to test this out locally.

Comment on lines +27 to +36
config:
# The URL for verification emails are set through the link method
# but we're using the code method, so we disable this method for usage.
enabled: false
# Set through SELFSERVICE_METHODS_LINK_CONFIG_BASE_URL
base_url: http://localhost:3000/api/ory
code:
config:
# and make sure to enable the code method.
enabled: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, should we make an effort from here on to start copying in the documentation from the ory kratos website?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's very helpful for values that we know we will inject new values into such as this and the UI_URLs. Fortunately their env naming matches the path of the yaml but in upper case and with underscores. I think it's helpful to have the env var to be easily-copied, though

courier:
template_override_path: /etc/config/kratos/templates
smtp:
connection_uri: set-through-env-arg-COURIER_SMTP_CONNECTION_URI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you able to set this dummy value because the environment variable overrides whatever we specify in the config?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly, I think for dev mode, we should maybe just let it be the mailslurper url and add a comment as we do for SELFSERVICE_METHODS_LINK_CONFIG_BASE_URL above. I will do this now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,9 @@
Hi,

you (or someone else) entered this email address when trying to recover access to an account.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make it less ambiguous for now what these emails are referring to if we refer to a "HASH account" rather than just "account". (this suggestion applies to most templates)

Suggested change
you (or someone else) entered this email address when trying to recover access to an account.
you (or someone else) entered this email address when trying to recover access to a HASH account.

cc @nonparibus for thoughts on the initial phrasing here

Copy link
Member

@vilkinsons vilkinsons Dec 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed "HASH account" preferable.

I would like to do a big pass at all of our transactional email copy soon.

Not necessarily as part of this PR, but could we consider how we might centrally collect all of our transactional email text in one place?

This could be creating an index pointing to the relevant lines of files like this, it could be a single directory that contains the actual emails themselves, or something like else (better) entirely. Either way we're not well set up for this at the moment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nonparibus for now all the kratos transactional emails are in this folder https://github.com/hashintel/hash/tree/e98a86be821317929dfaa15edfd255af51222726/packages/hash/external-services/kratos/templates
for emails that we will send through HASH, we have to consider what we do to either co-locate them together or make them easily searchable. For now I think this kratos grouping is a nice start

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to flag that this suggestion also applies to the remaining email templates (including email subjects). Let me know if you intend on addressing this @thehabbos007

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, missed that this was for all: f710e62

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks -- wasn't aware we had the dir already. This is great.

I don't know what ultimate best-practice looks like here, but I would be happy with either:

  • somewhere I can go that links out to all the different collections of transactional emails (like this), provided we actually keep it up to date;
  • a single directory in which we store all transactional emails from across the app.

My sense is the latter probably makes marginally more sense, and will be easier to track.

I'll review/update Kratos email copy in a separate PR. Please make any adjustments between the two of you that you think make sense in the meantime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that a single directory would make most sense, it may be difficult to do currently without knowing how we structure mails in the HASH api. I'll make an index that links to the email templates in-use from /packages/hash/README.md where we already have a seciton on sending emails. Does that sound good for now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thehabbos007 and others added 2 commits December 13, 2022 10:57
…/invalid/email.body.plaintext.gotmpl

Co-authored-by: Ben Werner <42802102+benwerner01@users.noreply.github.com>
packages/hash/frontend/src/pages/verification.page.tsx Outdated Show resolved Hide resolved
})
.then(({ data }) => {
setFlow(data);
extractFlowCodeValue(data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we programmatically submit the form when it is populated from the query params for the first time? This would prevent the user from having to click anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could, yes. But the reason to use these codes in the first place is to prevent mail apps to auto-open the links on the user's behalf. I appreciate that we'd gate this behind the /login interface and not submit, but I think we're better off not automating it for now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I hadn't considered that, let's keep it as is for now then.

Co-authored-by: Ben Werner <42802102+benwerner01@users.noreply.github.com>
benwerner01
benwerner01 previously approved these changes Dec 13, 2022
Copy link
Contributor

@benwerner01 benwerner01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ahmad, this is working locally for me 👍

@thehabbos007 thehabbos007 deleted the asa/kratos-mail-sending branch December 13, 2022 13:25
@kachkaev
Copy link
Contributor

@thehabbos007 I got CI failing in #1644 after merging main with this change:

@hashintel/hash-frontend:lint:eslint: /home/runner/work/hash/hash/packages/hash/frontend/src/pages/verification.page.tsx
@hashintel/hash-frontend:lint:eslint:    55:36  error  Unnecessary optional chain on a non-nullish value  @typescript-eslint/no-unnecessary-condition
@hashintel/hash-frontend:lint:eslint:   114:51  error  Unnecessary optional chain on a non-nullish value  @typescript-eslint/no-unnecessary-condition
@hashintel/hash-frontend:lint:eslint:   118:26  error  Unnecessary optional chain on a non-nullish value  @typescript-eslint/no-unnecessary-condition
@hashintel/hash-frontend:lint:eslint:   133:35  error  Unnecessary optional chain on a non-nullish value  @typescript-eslint/no-unnecessary-condition
@hashintel/hash-frontend:lint:eslint:   171:18  error  Unnecessary optional chain on a non-nullish value  @typescript-eslint/no-unnecessary-condition
@hashintel/hash-frontend:lint:eslint: 

I’ve removed a few ? instances, but this may break things if typings are incorrect. Could you please comment on #1644 if you see potential issues?

@vilkinsons vilkinsons added type/eng > frontend Owned by the @frontend team and removed area: frontend labels Jul 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/apps > hash* Affects HASH (a `hash-*` app) area/apps > hash-api Affects the HASH API (app) type/eng > frontend Owned by the @frontend team
Development

Successfully merging this pull request may close these issues.

4 participants