super-productivity/docs/wiki
Parman Mohammadalizadeh 7fba6f55e2
fix(tasks): decode multipart and transfer-encoded eml bodies #8975 (#8999)
* fix(tasks): decode multipart and transfer-encoded eml bodies #8975

Dropping a real-world .eml (e.g. saved from Outlook) onto the add-task
button created a title-only task: the parser only accepted a single,
unencoded text/plain body, but most clients send multipart/alternative
(plain + HTML) with quoted-printable or base64 transfer encoding on the
plain part.

eml-parser.ts now walks multipart/* structures (bounded recursion depth)
for the first supported text/plain leaf, and decodes quoted-printable/
base64 transfer encodings on it. HTML bodies and non-UTF-8/ASCII
charsets are still never decoded, matching the existing threat model
for this untrusted, inert note content.

* fix(tasks): keep unsupported-encoding eml test accurate after decode support

The service-level test for "unsupported body encoding" used a base64
fixture, which the eml-parser fix now legitimately decodes. Switch it
to a genuinely unsupported transfer-encoding token, and add a
dedicated test asserting base64 bodies decode and wrap in the notes
code fence as expected.

* fix(tasks): skip Content-Disposition: attachment parts in eml import

_extractPlainText() picked the first supported text/plain leaf in wire
order regardless of Content-Disposition, so a text/plain attachment
could be imported as the note when the real body was HTML, or shadow
the real body if it appeared first in the multipart structure. Skip
any part (leaf or multipart container) marked as an attachment before
inspecting it further.

Addresses review feedback from @johannesjo on PR #8999.

* fix(tasks): treat non-inline disposition and legacy name= as attachment

Content-Disposition is optional (legacy mail marks a filename via
Content-Type's name= parameter instead), and RFC 2183 §2.8 requires
any disposition type other than inline — recognized or not — to be
treated as attachment. The previous fix only matched the literal
token "attachment", so a text/plain part identified solely by a
legacy name= parameter, or one with an unrecognized disposition type
(e.g. x-download), still shadowed the real body.

_isAttachmentPart() now treats any present disposition other than
inline as an attachment, and falls back to the Content-Type name=
hint only when Content-Disposition is absent entirely.

Addresses further review feedback from @johannesjo on PR #8999.

* fix(tasks): recognize RFC 2231 name*/name*0 attachment filename hints

The legacy Content-Type name= fallback (used when Content-Disposition
is absent) only matched the literal key "name", missing RFC 2231's
encoded (name*) and continuation (name*0, name*0*, name*1, ...)
spellings of the same parameter. A part identified solely by a
continued name*0/name*1 filename hint slipped through undetected and
could be imported as the note instead of producing a title-only task.

_parseContentType() now matches any RFC 2231 spelling of name via a
presence-only regex; the value is never decoded or reassembled since
only the filename hint's existence matters.

Addresses further review feedback from @johannesjo on PR #8999.

* fix(tasks): recognize RFC 2231 filename*/filename*0 disposition hints

Content-Disposition's hasFilename fallback (used when the disposition
type token fails to parse, e.g. a type-less "; filename=...") only
matched the literal key "filename=", missing RFC 2231's encoded
(filename*) and continuation (filename*0, filename*0*, ...) spellings
of the same parameter -- the mirror of the name*/name*0 gap fixed for
Content-Type.

_parseContentDisposition() now matches any RFC 2231 spelling of
filename via a presence-only regex, symmetric to _NAME_PARAM_KEY_RE.

Addresses further review feedback from @johannesjo on PR #8999.
2026-07-15 09:55:39 +02:00
..
assets docs(wiki): initial revision (v0.1) 2026-01-20 03:04:08 -08:00
0.-Meta-Diataxis.md docs(wiki) v0.2: refactor and populate meta notes (#6134) 2026-01-24 21:14:29 +01:00
0.00-Wiki-Structure-and-Organization.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
0.01-Style-Guide.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
0.02-Wiki-QA-and-Maintenance.md docs(wiki) v0.2: refactor and populate meta notes (#6134) 2026-01-24 21:14:29 +01:00
1.00-Quickstarts.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
1.01-First-Steps.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
1.02-Configure-Data-Synchronization.md fix(sync): support separate Nextcloud login name 2026-05-18 13:43:23 +02:00
2.00-How_To.md feat(plugins): add Todoist import plugin with Import/Export launcher (#8882) 2026-07-10 13:30:03 +02:00
2.01-Downloads and Install.md docs/wiki content v0.8 (#7068) 2026-04-01 12:40:28 +02:00
2.02-Restore-Data-From-Backup.md docs(backup): document Android automatic restore (#8193) 2026-06-09 11:27:43 +02:00
2.03-Add-Tasks.md fix(tasks): decode multipart and transfer-encoded eml bodies #8975 (#8999) 2026-07-15 09:55:39 +02:00
2.04-Manage-Subtasks.md docs(wiki): lint headings and lists 2026-02-16 16:23:32 +01:00
2.05-Manage-Scheduled-Tasks.md refactor(tasks): restructure reminder dialog footer into primary + overflow (#8517) 2026-06-22 15:42:44 +02:00
2.06-Manage-Repeating-Tasks.md fix(task-repeat): allow selecting day-of-month recurrence (#8896) 2026-07-10 13:55:23 +02:00
2.07-Manage-Task-Integrations.md Merge pull request #8519 from archit-goyal/codex/caldav-empty-dropdown-guidance 2026-07-13 12:46:55 +02:00
2.08-Choose-Sync-Backend.md docs(sync): document Proton Drive via rclone WebDAV (#8064) 2026-06-19 11:05:30 +02:00
2.09-Configure-Sync-Backend.md fix(sync): surface OneDrive OAuth token errors and document Entra setup (#8580) 2026-06-24 16:18:46 +02:00
2.10-Configure-Obsidian-for-Wiki-Contributions.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
2.11-Run-the-Development-Server.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
2.12-Package-the-App.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
2.13-Run-with-Docker.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
2.14-Build-for-Android.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
2.15-Develop-a-Plugin.md fix(plugins): allow iframe-only plugin installs 2026-05-18 13:43:22 +02:00
2.16-Set-Up-Development-Environment.md docs(development): add instructions for setting up local tests with Chromium (#8887) 2026-07-11 13:25:02 +02:00
2.17-Add-a-New-Issue-Integration.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
2.18-Contribute-Translations.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
2.19-Sync-Proton-Drive-via-rclone.md docs(wiki): add Proton Drive via rclone + WebDAV guide 2026-06-18 15:18:15 +02:00
2.20-Import-from-Todoist.md feat(plugins): add Todoist import plugin with Import/Export launcher (#8882) 2026-07-10 13:30:03 +02:00
3.00-Reference.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
3.01-API.md fix(tasks): keep REST project moves atomic across replay (#9001) 2026-07-14 17:25:37 +02:00
3.02-Settings-and-Preferences.md feat: suppress idle dialog during active work sessions (#8965) 2026-07-14 16:45:49 +02:00
3.03-Keyboard-Shortcuts.md feat(tasks): navigate from empty add-subtask input (#8916) 2026-07-11 13:33:35 +02:00
3.04-Short-Syntax.md feat(help): add create task how-to #8015 (#8079) 2026-06-08 11:40:14 +02:00
3.05-Web-App-vs-Desktop.md fix(app): hide donation page on macOS (#8915) 2026-07-11 13:02:19 +02:00
3.06-User-Data.md fix(sync): enforce conflict-journal retention mid-session, not only at start (#8948) 2026-07-14 10:26:10 +02:00
3.07-Issue-Integration-Comparison.md feat(plainspace): Collaborate-on-Plainspace discovery + smoother connect (#8649) 2026-07-01 16:39:34 +02:00
3.08-Sync-Integration-Comparison.md fix(sync): file-based provider atomicity & conflict UX (#8960) (#9004) 2026-07-14 19:23:24 +02:00
3.09-Theming.md feat(theme): add Plainspace built-in theme 2026-06-15 14:06:21 +02:00
3.97-Obsidian-Linter-Config-MD.md docs/wiki content v0.4 (#6257) 2026-01-29 17:35:38 +01:00
3.98-Obsidian-Linter-Config-YAML.md docs/wiki content v0.4 (#6257) 2026-01-29 17:35:38 +01:00
3.99-Other.md docs(wiki) v0.2: refactor and populate meta notes (#6134) 2026-01-24 21:14:29 +01:00
4.00-Concepts.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
4.01-The-Today-View.md docs(wiki): normalize tables and rework ToC 2026-02-04 14:45:00 +01:00
4.02-Inbox-View.md docs/wiki content v0.3 (#6231) 2026-01-28 16:11:22 +01:00
4.03-Planner-View.md docs(wiki): normalize tables and rework ToC 2026-02-04 14:45:00 +01:00
4.04-Schedule-View.md fix(schedule): indicate tasks beyond available time 2026-05-11 14:30:55 +02:00
4.05-Board-View.md feat(boards): enhance project selection with multi-select and sidebar… (#8069) 2026-06-09 18:33:09 +02:00
4.06-Project-View.md feat(project): project completion experience (#8036) 2026-06-08 13:43:38 +02:00
4.07-Tag-View.md docs(wiki): normalize tables and rework ToC 2026-02-04 14:45:00 +01:00
4.07a-Tags_Eat-the-Frog.md docs/wiki content v0.3 (#6231) 2026-01-28 16:11:22 +01:00
4.07b-Tags_Ordinal-Priorities.md docs/wiki content v0.3 (#6231) 2026-01-28 16:11:22 +01:00
4.08-Time-Estimates.md docs(wiki): add How Time Is Logged section 2026-02-04 14:45:00 +01:00
4.09-Task-Attributes.md docs(wiki): substantial addition of integrations (issue and sync) 2026-02-04 14:45:00 +01:00
4.10-Task-Notes.md feat(search): include note content in global search and support folde… (#8044) 2026-06-09 19:18:10 +02:00
4.11-Subtasks.md docs(wiki): add Repeating Tasks section and update references across multiple documents 2026-02-04 14:45:00 +01:00
4.12-Scheduled-Tasks.md docs(wiki): added Scheduled Tasks; updated references in multiple sections 2026-02-04 14:45:00 +01:00
4.13-Repeating-Tasks.md feat(task-repeat): default skip-overdue for new everyday recurring tasks (#8861) 2026-07-08 19:55:37 +02:00
4.14-How-Time-Is-Logged.md docs(wiki): lint style 2026-02-04 14:45:00 +01:00
4.15-Timers-and-Focus-Mode.md feat(focus-mode): make preparation opt-in, smooth start transition (#8639) 2026-06-29 19:44:53 +02:00
4.16-Break-Reminders.md docs(wiki): add Reminders and Idle Time 2026-02-04 14:45:00 +01:00
4.17-Idle-Time.md feat(work-view): show break time today (#8909) 2026-07-11 15:37:57 +02:00
4.18-Reflection.md docs(wiki): add Metrics 2026-02-04 14:45:00 +01:00
4.19-Metrics.md [codex] Hide global metric charts outside Today (#8019) 2026-06-05 10:53:57 +02:00
4.20-Task-Archiving.md docs(wiki): add Task Archiving section and update references across multiple documents 2026-02-04 14:45:00 +01:00
4.21-Worklog.md fix(worklog): avoid misleading export start/end times (#8090) 2026-06-08 20:44:47 +02:00
4.22-Quick-History.md feat(history): merge Quick History and Worklog into a unified History view (#8033) 2026-06-05 18:10:56 +02:00
4.23-Managing-Your-Data.md feat(sync): conflict journal + disjoint-field auto-merge + review UI (#8874) 2026-07-11 17:48:46 +02:00
4.24-Integrations.md docs(caldav): clarify bidirectional VTODO sync (#8196) 2026-06-09 11:27:39 +02:00
_Footer.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00
_Sidebar.md docs(sync): document Proton Drive via rclone WebDAV (#8064) 2026-06-19 11:05:30 +02:00
Home.md docs/wiki content v0.7 (#6568) 2026-02-20 21:13:38 +01:00