Skip to content

Add escape_json() to all Sync API commands with ID parameters#20

Merged
VincentGuyader merged 2 commits intov4from
copilot/sub-pr-13-093ede1d-44b9-470d-b1c2-523c12ba1949
Feb 10, 2026
Merged

Add escape_json() to all Sync API commands with ID parameters#20
VincentGuyader merged 2 commits intov4from
copilot/sub-pr-13-093ede1d-44b9-470d-b1c2-523c12ba1949

Conversation

Copy link

Copilot AI commented Feb 9, 2026

Thanks for the feedback on #13. I've created this new PR, which merges into #13, to address the review comment about missing JSON escaping in Sync API commands.

Original PR: #13
Triggering review: #13 (comment)

Changes Made

Added escape_json() calls to properly escape ID parameters in JSON command payloads across 11 functions in 5 files:

  • R/projects.R: delete_project(), archive_project(), unarchive_project()
  • R/filters.R: delete_filter()
  • R/labels.R: delete_label()
  • R/section.R: delete_section(), move_section(), archive_section(), unarchive_section()
  • R/tasks.R: add_tasks_in_project(), add_responsible_to_task()

Why These Changes Matter

Without proper escaping, IDs containing special characters (quotes, backslashes, newlines, tabs, or carriage returns) would create malformed JSON payloads, potentially causing API request failures or incorrect data transmission.

Testing

  • ✅ Code review completed - no issues found
  • ✅ Security scan completed - no vulnerabilities detected
  • ✅ All changes follow the existing pattern used in other functions

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@VincentGuyader
Copy link
Member

@copilot tu peux reprendre ici ?

@VincentGuyader
Copy link
Member

@copilot a toi de jouer

Co-authored-by: VincentGuyader <10470699+VincentGuyader@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 10, 2026

@copilot tu peux reprendre ici ?

Done! I've added escape_json() to all Sync API commands that were missing it. The changes are in commit 8ae5da8.

@copilot a toi de jouer

All changes have been completed and pushed. I've added escape_json() to 11 functions across 5 files to ensure all ID parameters in JSON commands are properly escaped. Code review and security scan both passed successfully. Commit: 8ae5da8

Copilot AI changed the title [WIP] Address feedback from PR #13 to enhance test coverage Add escape_json() to all Sync API commands with ID parameters Feb 10, 2026
@VincentGuyader VincentGuyader marked this pull request as ready for review February 10, 2026 22:08
@VincentGuyader VincentGuyader merged commit 9ff355d into v4 Feb 10, 2026
VincentGuyader added a commit that referenced this pull request Feb 13, 2026
* v0.4.0: Improve test coverage, fix bugs, and update CI

- Add comprehensive tests for workspaces, activity, backups, templates, uploads
- Add HTTP error handling with httr2 req_error()
- Fix glue() to character conversion in templates.R
- Remove debug message from call_api()
- Extract API URLs as package constants
- Update GitHub Actions to modern versions (v2/v4)
- Add skip_if_test_project_missing() test helper
- Add NEWS.md changelog

* Update .Rbuildignore
* Fix PR review feedback: security, maintainability and bug fixes

- Remove check/ directory (R CMD check artifact) and add to .gitignore
- Fix tryCatch() syntax in ask_todoist_api_token (interrupt = function(e) NULL)
- Add escape_json() for JSON string interpolation in reminders.R and workspaces.R
- Use TODOIST_REST_URL constant instead of hardcoded URLs in uploads.R and comments.R
- Add req_error() for proper HTTP error handling in comments.R
- Fix DESCRIPTION comment field formatting (named elements)
- Add req_error() for HTTP error handling in:
  - templates.R (import_template, export_template)
  - labels.R (rename_shared_label, remove_shared_label)
  - uploads.R (delete_upload)
  - backups.R (download_backup)

- Use TODOIST_REST_URL constant instead of hardcoded URLs in:
  - templates.R
  - labels.R (shared label functions)

- Fix empty data.frame column consistency:
  - comments.R: add task_id and project_id columns
  - reminders.R: add due_date and minute_offset columns

- Remove unused project_name parameter from unarchive_project()

- Update NEWS.md to document all changes

* Apply consistent patterns across codebase

- Use TODOIST_REST_URL constant in quick_add_task() instead of hardcoded URL
- Add req_error() to quick_add_task() and upload_file() for HTTP error handling
- Fix empty data.frame column consistency in:
  - get_activity_logs(): add initiator_id, parent_project_id, parent_item_id
  - get_tasks_by_filter(): add due_date
  - get_archived_projects(): add color, is_favorite
  - get_all_sections(): add order
  - get_all_workspaces(): add is_default
  - get_workspace_users(): add role

* Add JSON escaping to Sync API command builders (#15)

* Fix JSON escaping in Sync API commands across all modules

* Fix critical API bugs and JSON injection vulnerabilities from PR review (#14)

- Fix call_api() incorrect parameter (base_url -> url)
- Add verbose flag to add_label() existing label message
- Add escape_json() to all Sync API string interpolations

* Fix JSON escaping vulnerabilities in Sync API commands

Apply escape_json() to all user-controlled values in JSON payloads:

- workspaces.R: escape workspace_id in update_workspace()
- tasks.R:
  - escape task_id in delete_task(), close_task(), reopen_task()
  - escape task_id and due_date in update_task()
  - escape labels array values in update_task()
- users.R:
  - escape project_id and email in delete_collaborator()
  - escape invitation_id and invitation_secret in accept_invitation()
  - escape invitation_id and invitation_secret in reject_invitation()
  - escape invitation_id in delete_invitation()

This prevents malformed JSON payloads when inputs contain quotes,
backslashes, or other special characters.

* Add escape_json() to all Sync API commands with ID parameters (#20)

* Add escape_json() to all Sync API commands with ID parameters

* Fix move_task() validation, test dataframe schemas, and URL query encoding (#24)

* Address PR review feedback: validation, test accuracy, and URL handling

* update URL

* cleaning

* Fix CRAN compliance issues before submission

- Add @return tags to add_section() and get_section_id()
- Remove unused httr dependency (replaced by httr2)
- Remove unused lubridate from Suggests
- Update LICENSE file format (2019-2026, ThinkR)
- Remove dead mock_response() code and rename test file
- Add REVIEW.md with pre-submission package audit

* Improve security and robustness (Priority 2 fixes)

- Escape IDs in move_task() with escape_json() to prevent JSON injection
- Add token validation in call_api() and call_api_rest()
- Replace print() with message() in users.R for CRAN compliance

* Update NEWS.md with comprehensive changelog for v0.4.0

Document all 64 new exported functions across 9 new modules:
- Labels, Comments, Filters, Reminders, Workspaces
- Activity logs, Backups, Templates, Uploads

Plus enhancements to Projects, Sections, Tasks, and Collaboration.


* Remove lubridate dependency from vignettes

Replace lubridate::today() and days() with base R Sys.Date() and
arithmetic operations for consistency with removed Suggests dependency.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants