Commit f8f02ff
authored
[POSTMAN-UNSUPPORTED-ATTACHMENT-1] PLU-482: Filter unsupported Postman attachments before sending (#1019)
### TL;DR
Added validation for email attachments in Postman to filter out unsupported file types and notify users.
**Key things to note**:
1. Unsupported attachments: file type(s) that Postman does not accept
1. Password-protected: files that are password-protected and rejected by Postman
1. Postman throws the same "invalid_template" error regardless of whether they are unsupported or password-protected attachments
_Retry to strip attachments will be in the next PR_
### What changed?
- Created a list of accepted file extensions for Postman email attachments (https://postman-v1.guides.gov.sg/email-api-guide/programmatic-email-api/send-email-api/attachments#supported-attachment-file-types)
- Implemented a filtering mechanism to check attachments before sending emails
- Added functionality to send notification emails to users when unsupported attachments are detected
- Enhanced error handling to provide clear guidance when attachments are removed
- Created a form admin link to help users access their original attachments
- Update error message for password-protected files
- since we use the same list as postman to filter attachments, invalid_template should only throw when users attempt to send password-protected attachments
### Why make this change?
Postman has restrictions on which file types can be sent as email attachments. Previously, users are unable to send emails when attachments include unsupported file types. This change improves the user experience by:
1. Proactively filtering out unsupported attachments
2. Clearly communicating which files were removed and why
3. Providing a way for users to access their original files through the form admin interface
### How to test?
Pre-setup: prepare a form that accepts attachments and connect this form to your pipe + turn on notifications for every failed execution
Make form(s) submission with varying types of attachments:
1. supported attachment
1. unsupported attachment e.g., `svg`
1. password-protected attachment
There are 3 types of notification emails:
1. Error (failed) execution
1. Blacklisted recipient notification
1. Unsupported attachment notification
**Test cases**
- [ ] Blacklisted recipient (can use `[email protected]`)
- [ ] Same behaviour as current implementation
- [ ] Blacklisted recipient notification sent (same as current behaviour)
- [ ] Unsupported attachment
- [ ] Execution marked as partial success
- [ ] Email sent without unsupported attachment
- [ ] Unsupported attachment notification (new) sent with details of unsupported attachment, submission id, execution id, link to form admin
- [ ] Execution page shows link and opens to form responses
- [ ] Password-protected attachment
- [ ] Execution fails with "Password-protected" error
- [ ] Error notification sent
- [ ] Execution page shows error with "Password-protected attachment(s)"
- [ ] Blacklisted + Unsupported
- [ ] Execution partial success
- [ ] Email not sent to blacklisted recipient
- [ ] Email sent to non-blacklisted recipient without the unsupported attachment
- [ ] **TWO** notificiation email sent
- [ ] Blacklisted recipient notification (same as current behaviour)
- [ ] Unsupported attachment notification (new)
- [ ] Blacklisted + Unsupported + Password-protected
- [ ] Execution fails
- [ ] Error notification sent
- [ ] Unsupported + Password-protected
- [ ] Execution fails
- [ ] Error notification sent
- [ ] Execution page shows error with "Password-protected attachment(s)"
### Screenshots
**Execution with unsupported attachment**
[Screen Recording 2025-06-04 at 11.29.32 AM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/Wrwhm8Mmhv1Z2GwlSb7V/7ff6ca5a-5fe7-45e4-9938-d9420325b56a.mov" />](https://app.graphite.dev/media/video/Wrwhm8Mmhv1Z2GwlSb7V/7ff6ca5a-5fe7-45e4-9938-d9420325b56a.mov)


**Execution with unsupported attachment and blacklisted recipient**
[Screen Recording 2025-06-04 at 11.32.02 AM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/Wrwhm8Mmhv1Z2GwlSb7V/e4791c22-085b-4bc9-9847-393bf58a92c1.mov" />](https://app.graphite.dev/media/video/Wrwhm8Mmhv1Z2GwlSb7V/e4791c22-085b-4bc9-9847-393bf58a92c1.mov)
**Password-protected attachments**
1 parent cc603d7 commit f8f02ff
File tree
8 files changed
+356
-29
lines changed- packages/backend/src
- apps/postman
- __tests__/actions
- actions/send-transactional-email
- common
- helpers
8 files changed
+356
-29
lines changedLines changed: 124 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
15 | 22 | | |
| 23 | + | |
| 24 | + | |
16 | 25 | | |
17 | 26 | | |
18 | 27 | | |
| |||
28 | 37 | | |
29 | 38 | | |
30 | 39 | | |
| 40 | + | |
31 | 41 | | |
32 | 42 | | |
33 | 43 | | |
34 | 44 | | |
35 | 45 | | |
36 | 46 | | |
37 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
38 | 53 | | |
39 | 54 | | |
40 | 55 | | |
| |||
137 | 152 | | |
138 | 153 | | |
139 | 154 | | |
140 | | - | |
| 155 | + | |
141 | 156 | | |
142 | 157 | | |
143 | 158 | | |
| |||
570 | 585 | | |
571 | 586 | | |
572 | 587 | | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
573 | 696 | | |
Lines changed: 43 additions & 20 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | 8 | | |
10 | 9 | | |
11 | 10 | | |
| |||
14 | 13 | | |
15 | 14 | | |
16 | 15 | | |
17 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
18 | 20 | | |
| 21 | + | |
19 | 22 | | |
20 | 23 | | |
21 | 24 | | |
| |||
71 | 74 | | |
72 | 75 | | |
73 | 76 | | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
| 77 | + | |
| 78 | + | |
86 | 79 | | |
87 | 80 | | |
88 | 81 | | |
| |||
165 | 158 | | |
166 | 159 | | |
167 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
168 | 174 | | |
169 | 175 | | |
| 176 | + | |
170 | 177 | | |
171 | 178 | | |
172 | 179 | | |
173 | 180 | | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
| 181 | + | |
178 | 182 | | |
179 | 183 | | |
180 | 184 | | |
| |||
188 | 192 | | |
189 | 193 | | |
190 | 194 | | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
191 | 213 | | |
192 | 214 | | |
193 | 215 | | |
194 | 216 | | |
195 | | - | |
| 217 | + | |
196 | 218 | | |
197 | 219 | | |
198 | 220 | | |
199 | 221 | | |
200 | | - | |
| 222 | + | |
201 | 223 | | |
| 224 | + | |
202 | 225 | | |
203 | 226 | | |
204 | 227 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
Lines changed: 38 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
1 | 4 | | |
2 | 5 | | |
| 6 | + | |
| 7 | + | |
3 | 8 | | |
4 | 9 | | |
5 | 10 | | |
6 | 11 | | |
7 | 12 | | |
8 | 13 | | |
9 | 14 | | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
9 | 11 | | |
10 | 12 | | |
11 | 13 | | |
| |||
81 | 83 | | |
82 | 84 | | |
83 | 85 | | |
84 | | - | |
85 | | - | |
| 86 | + | |
86 | 87 | | |
87 | 88 | | |
88 | 89 | | |
| |||
0 commit comments