Repository navigation
feat(todo): rewrite on Microsoft Graph with Service Principal, Each user signs in and n8n operations; fix secret leak in validation (1.0.0) - #4167
Open
ForeignKeyCN wants to merge 1 commit into
Conversation
…ser signs in, national clouds and n8n operations (1.0.0)
3 of 5 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the To Do plugin in line with Outlook (#4163), Teams (#4164), OneDrive (#4165) and Excel (#4166), and with n8n's Microsoft To Do node. The plugin was built on two third-party packages (
pymstodo,dify-easy) and onrequests-oauthlib; this PR replaces them with direct Microsoft Graph calls through a sharedtools/graph_client.py.Fixed: credential validation always failed and put secrets in its message.
_validate_credentialsended with a debugging leftover that raised unconditionally withf"token: {token} ... credentials: {credentials}", i.e. the access and refresh tokens and the client secret, shown wherever the validation error is displayed. Validation now reads the task lists and reports a plain message; a test checks that no secret appears in it.1. Base (existing workflows keep working)
{"data": [...]}/ the object injson,str()of it intext), including the historical quirks:get_tasksreturns the task lists, and the task tools return only tasks that are not completed by default. Dates keep their previous text form.token; tools read it, the refresh accepts it and writes the new fields (access_token,refresh_token,graph_base_url). The refresh no longer sendsscope. The OAuth scopes are unchanged (openid offline_access Tasks.ReadWrite, the onespymstodorequested).ToDoConnection._redirectglobally on every request.common, as before) and Microsoft Cloud; scopes are qualified outside the global cloud (openid/offline_accessexcepted).zh_CN, which Dify does not show; nowzh_Hans.2. Auth modes (API Key credential)
Tasks.ReadWrite.All; tools work on/users/{owner}/todo, the owner coming from the tool's Task Owner setting (form-only, never chosen by the LLM) or the credential's default. Saving with a default owner reads their lists to check the permission.GET /todo/callback) that never holds the secret; per-user tokens Fernet-encrypted in plugin storage, keyed by a hash ofclient_id | Dify user ID; never in tool output or logs. Scopes: OAuth's plusUser.Read(to name the signed-in account). Sign Out of To Do (todo_sign_out).3. n8n parity (new tools carry a
todo_prefix: the new Agent rejects duplicate tool names across plugins)get_lists/get_list_by_id(existing)todo_create_list/todo_update_list/todo_delete_listget_tasks_by_list_id(newstatus_filter,limit) /get_task_by_id(existing)create_task, now with n8n'sreminder_datetime,importance,statusbesidesdue_dateandbody_texttodo_update_task/todo_delete_tasktodo_create_linked_resource/todo_get_linked_resource/todo_list_linked_resources/todo_update_linked_resource/todo_delete_linked_resourceget_all_tasksandcomplete_taskstay;get_all_taskstakes the same options and adds each task'slist_id/list_name.Version 0.0.8 → 1.0.0. README rewritten (the existing setup screenshots are kept; it now also lists the API permissions to add, which it did not before) and PRIVACY updated. Dependencies:
pymstodo,dify-easy,requests-oauthlib,structlog,pydanticremoved;cryptographyadded.Release Notes
Change Type
Screenshots / Videos
The setup screenshots in the README are the existing ones. The per-user flow is the same as in #4163–#4166 (screenshots there).
Testing
pytest; the plugin had none). They cover: the Graph context for OAuth (new and pre-1.0.0tokenJSON credentials), Service Principal and per-user, national clouds and the Graph-host check; ID encoding; every tool's output variables on success and on a Graph error (a test checks every tool in the provider is covered); the pre-1.0.0 output shapes (task fields, date texts,get_tasksreturning lists); the default "not completed" filter and the other filters; paging staying on the Graph host; the n8n task fields and their validation; linked resources (fields, URL check); OAuth URLs per tenant and cloud with the old scopes; refreshing a pre-1.0.0 credential; validation messages without secrets (and a working token now passing); the per-user sign-in flow and validation.Checklist
manifest.yaml(0.0.8 → 1.0.0)