fix(onepassword): validate integration against API docs, add file downloads#5365
Conversation
…nloads
- add onepassword_get_item_file tool + route for downloading item file
attachments (SDK items.files.read / Connect files/{id}/content), backed
by newly-exposed item.files metadata on get/create/replace/update item
- fix update_item JSON Patch applying array indices instead of 1Password's
documented field-ID addressing (/fields/{fieldId}/...), which silently
dropped field edits in Service Account mode
- fix Service Account mode's list-vaults/list-items filter to honor SCIM
`eq` exact-match semantics instead of always substring-matching
- expand the create-item category dropdown from 9 to 19 real, creatable
1Password categories (was missing SOFTWARE_LICENSE, EMAIL_ACCOUNT,
MEMBERSHIP, PASSPORT, REWARD_PROGRAM, DRIVER_LICENSE, BANK_ACCOUNT,
MEDICAL_RECORD, OUTDOOR_LICENSE, WIRELESS_ROUTER, SOCIAL_SECURITY_NUMBER)
- replace the block's single opaque `response: json` output with typed,
per-operation output fields matching repo convention
- remove incorrect password-masking on the Vault ID field (not a secret)
- re-export tool types from the onepassword barrel
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Service Account fixes: Block/UI: Per-operation typed outputs replace the generic Connect proxy: Reviewed by Cursor Bugbot for commit e78839e. Configure here. |
Greptile SummaryThis PR adds a new
Confidence Score: 5/5Safe to merge; the core bug fixes are well-reasoned, the new file-download route is correctly gated behind auth, and both Connect and Service Account modes are covered. All three bug fixes (PATCH field addressing, SCIM eq filter, category list) are validated by tests and cross-checked against API docs. The new connectItemToSdkItem helper correctly preserves SDK-only field metadata via spread. Two minor observations — null coercion via || vs ?? on field values, and a silent no-op when add targets a non-existent array element by ID — do not affect correctness for any documented 1Password PATCH usage pattern. apps/sim/app/api/tools/onepassword/utils.ts (connectItemToSdkItem field value coercion) and apps/sim/app/api/tools/onepassword/update-item/route.ts (applyPatch add-at-specific-id silent drop). Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Client
participant GetItemFileRoute
participant OnePasswordSDK
participant ConnectServer
Client->>GetItemFileRoute: POST /api/tools/onepassword/get-item-file
GetItemFileRoute->>GetItemFileRoute: checkInternalAuth + parseRequest
alt Service Account mode
GetItemFileRoute->>OnePasswordSDK: client.items.get(vaultId, itemId)
OnePasswordSDK-->>GetItemFileRoute: Item (with files[] / document)
GetItemFileRoute->>GetItemFileRoute: findItemFileAttributes(item, fileId)
alt file found
GetItemFileRoute->>OnePasswordSDK: client.items.files.read(vaultId, itemId, attr)
OnePasswordSDK-->>GetItemFileRoute: binary content
GetItemFileRoute-->>Client: "{ file: { name, mimeType, data: base64, size } }"
else not found
GetItemFileRoute-->>Client: 404 File not found
end
else Connect mode
GetItemFileRoute->>ConnectServer: "GET /v1/vaults/{v}/items/{i}/files/{f}"
ConnectServer-->>GetItemFileRoute: "file metadata { name, size }"
GetItemFileRoute->>ConnectServer: "GET /v1/vaults/{v}/items/{i}/files/{f}/content"
ConnectServer-->>GetItemFileRoute: binary response (content-type header)
GetItemFileRoute-->>Client: "{ file: { name, mimeType, data: base64, size } }"
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Client
participant GetItemFileRoute
participant OnePasswordSDK
participant ConnectServer
Client->>GetItemFileRoute: POST /api/tools/onepassword/get-item-file
GetItemFileRoute->>GetItemFileRoute: checkInternalAuth + parseRequest
alt Service Account mode
GetItemFileRoute->>OnePasswordSDK: client.items.get(vaultId, itemId)
OnePasswordSDK-->>GetItemFileRoute: Item (with files[] / document)
GetItemFileRoute->>GetItemFileRoute: findItemFileAttributes(item, fileId)
alt file found
GetItemFileRoute->>OnePasswordSDK: client.items.files.read(vaultId, itemId, attr)
OnePasswordSDK-->>GetItemFileRoute: binary content
GetItemFileRoute-->>Client: "{ file: { name, mimeType, data: base64, size } }"
else not found
GetItemFileRoute-->>Client: 404 File not found
end
else Connect mode
GetItemFileRoute->>ConnectServer: "GET /v1/vaults/{v}/items/{i}/files/{f}"
ConnectServer-->>GetItemFileRoute: "file metadata { name, size }"
GetItemFileRoute->>ConnectServer: "GET /v1/vaults/{v}/items/{i}/files/{f}/content"
ConnectServer-->>GetItemFileRoute: binary response (content-type header)
GetItemFileRoute-->>Client: "{ file: { name, mimeType, data: base64, size } }"
end
Reviews (4): Last reviewed commit: "fix(onepassword): preserve field metadat..." | Re-trigger Greptile |
matchesFilter always compared against name/title regardless of the attribute named in the eq expression, so `id eq "..."` incorrectly matched against the display name instead of the id.
…audit - restore a deprecated no-op 'response' output so pre-existing saved workflows referencing it fail soft (empty) instead of hard-erroring now that per-operation outputs replace it - add missing block outputs (urls, favorite, version, state, lastEditedBy) for get/create/replace/update item so all real FULL_ITEM fields are discoverable as <Block.field> references - hide Connect Server credential fields for Resolve Secret (Service Account only) instead of leaving them selectable and silently ignored - correct two doc-string enum lists that advertised values the API doesn't return (vault type TRANSFER, item state DELETED)
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 5a1d535. Configure here.
…t mode)
update_item applied user JSON Patch ops (documented/typed against the
Connect-shaped vocabulary get_item returns: label/type/section.id)
directly onto the raw SDK item, whose vocabulary differs (title/
fieldType/sectionId, and SDK category enum strings vs Connect's
SCREAMING_SNAKE_CASE). Most patches beyond /title, /tags/-, and
/fields/{id}/value silently no-opped or could corrupt the item while
still reporting success.
Extracted the Connect->SDK item conversion already used by replace_item
into a shared connectItemToSdkItem helper. update_item now normalizes
the fetched item to Connect shape, applies patches to that, then
converts back before calling items.put() -- matching create/replace's
existing translation pattern.
Found via an adversarial final-verification pass that traced concrete
patch operations by hand against the SDK's actual field vocabulary.
|
@cursor review |
connectItemToSdkItem rebuilt every field as a bare object, dropping SDK-only metadata (e.g. password-generation details) that a raw patch/replace previously left untouched. Now merges onto the existing SDK field by id before applying the translated properties, and only starts fields bare when they're genuinely new. Also restored the || (not ??) fallback on title to match replace_item's prior behavior of treating an explicitly empty title as "not provided".
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e78839e. Configure here.
Summary
onepassword_get_item_filetool + route to download file attachments on 1Password items (Service Account SDKitems.files.read/ Connectfiles/{id}/content), and exposed attachment metadata (files) on get/create/replace/update item outputs so a file's ID is discoverableupdate_itemin Service Account mode: JSON Patch paths were resolved as literal array indices instead of 1Password's documented field-ID addressing (/fields/{fieldId}/...), so field edits silently no-op'dfilterparam in Service Account mode to honor SCIMeqexact-match semantics instead of always doing a substring matchresponse: jsonoutput with typed, per-operation output fields, matching repo conventiononepasswordtools barrelType of Change
Testing
bun run type-check— cleanbunx biome check— cleanbun run check:api-validation:strict— passesbunx vitest run app/api/tools/onepassword/utils.test.ts— 18/18 passingChecklist