feat: Add confirmation email for form respondents#3289
feat: Add confirmation email for form respondents#3289dtretyakov wants to merge 10 commits intonextcloud:mainfrom
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|
@Chartman123 I also tried to streamline UX for the feature. Now the form looks like that:
|
|
@dtretyakov looks good :) I'll ping the design specialists to see what they think about it :) |
b111145 to
9452b76
Compare
|
For app code here, |
|
No problem, just ignore this. For the next release we will no longer support NC31 |
363a0cb to
9cb9c09
Compare
|
@Chartman123 the branch is rebased on the fresh main and uses |
Chartman123
left a comment
There was a problem hiding this comment.
I did a quick review and found some parts that should be changed in my opinion.
Please also add the new fields to FormsMigrator.php.
Also not sure about the frontend part, especially in the sidebar as I'm no vue expert. I added @susnux and @pringelmann as reviewers :)
Btw no need to hurry, the next release is not yet directly around the corner. We'll get it merged once it's ready :)
|
One thing I want to flag before this lands: as written, this turns any public form into an unauthenticated outbound mailer. A submitter controls the recipient address (it's just whatever they typed into the email field), so an attacker can script submissions with a victim's address and use the instance to mailbox-bomb them. Worst case it also burns the operator's MX reputation. A few options, not mutually exclusive:
I'd be more comfortable with at least one of these in place before we ship. Could also be worth a line in the PR description spelling out which mitigations apply, since this is a new outbound channel. |
@pringelmann Perhaps we should also add an admin setting that can turn the feature on/off and that should be off by default? |
| if (!$table->hasColumn('confirmation_email_enabled')) { | ||
| $table->addColumn('confirmation_email_enabled', Types::BOOLEAN, [ | ||
| 'notnull' => false, | ||
| 'default' => 0, |
There was a problem hiding this comment.
This means existing rows on upgrade might end up as NULL rather than false. It happens to look right because of the casting, but the column doesn't actually reflect the domain - it's a flag, not tri-state. I'd just make it notnull => true, default => false then we can drop all the bool casting.
There was a problem hiding this comment.
We have default => 0 everywhere for booleans. I think this is because one of the DB systems (sqlite?)...
There was a problem hiding this comment.
Ah ok, good to know thnx :)
There was a problem hiding this comment.
But yes, notnull => true would make sense. Every row should have a value here.
Yeah good idea, default-off admin toggle is a sensible safety net and I'd vote for adding it. That said, I don't think it replaces a per-form/per-recipient mitigation. Once an admin flips it on (which many likely will, because it is a very useful feature for users), the abuse surface is fully open again on every public form on the instance. So it protects the instances that don't need the feature but does nothing for the ones that do. I'd still suggest at least one of: rate limit per recipient, gate it behind authentication, or pace via a queued job. The admin toggle then becomes a global kill switch on top of that, which is genuinely useful (e.g. an admin can disable the feature instance-wide if they spot abuse in their mail logs) |
c7f7327 to
4950eb3
Compare
|
To mitigate the risks associated with automated emails now we have implemented a 4-layer defense strategy:
If you see this combination is excessive please let me know and we could relax it. |
4950eb3 to
33d9af9
Compare
|
@Chartman123 or @pringelmann please let me know if it requires some extra changes. |
|
Hello there, We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 Thank you for contributing to Nextcloud and we hope to hear from you soon! (If you believe you should not receive this message, you can add yourself to the blocklist.) |
9e90ee1 to
394afb8
Compare
b2c5303 to
1f60973
Compare
|
Other question: should we add a check if sending mails is generally available for the server? In my dev instance, I don't have the mail settings configured, but could enable the confirmation mails... |
Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
- Relocate confirmationEmailRecipient from Question extraSettings to Form - Centralize email question validation in Question model and FormsService - Simplify SettingsSidebarTab component logic - Ensure correct recipient ID mapping during form cloning - Add comprehensive unit tests for validation and notification logic Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
- Add test for globally disabled confirmation emails - Fix rate limiting on APCu-only installs - Optimize formMapper updates and refactor sendConfirmationEmail - Fix PHPDoc, typings and UI validations Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
- Move confirmation email logic from FormsService to ConfirmationEmailService - Implement configurable rate limiting for confirmation emails - Use EMailTemplate in SendConfirmationMailJob for consistent styling - Improve UI with proper Nextcloud Vue components (NcInputField, NcTextArea) - Add comprehensive unit tests for the new service - Clean up Question and ApiController validation logic Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
Signed-off-by: Dmitry Tretyakov <dtretyakov@gmail.com>
1f60973 to
a285496
Compare
|
@Chartman123 I rebased the branch and applied the changes.
Now there is a check whether Email is configured by introducing |
|
@dtretyakov from my side it looks good now, just the little suggestion for the migration step regarding |
|
|
||
| &__rate-limit { | ||
| margin-top: calc(var(--default-grid-baseline) * 3); | ||
| max-width: 300px; | ||
| } |
There was a problem hiding this comment.
This max width causes the helper text to be split into new lines within the word boundaries. Do we really need this css rule?


Closes #525 - Send confirmation emails to form respondents after submission.
Features:
Technical changes: