Repository navigation
refactor(integrations): store the GroupMe access token as a connector secret ref (TASK-539) - #3004
Conversation
This comment has been minimized.
This comment has been minimized.
…t is a 400 CodeRabbit on #3004. The migration's import used the upserting put, so a token a live PATCH stored between the migration's read and its write was overwritten with the older plaintext. It now uses connectorSecrets.putIfAbsent (insert on the unique (integrationId, kind) key); on a conflict the newer secret and its ref win. The GroupMe reader maps only ConnectorSecretNotFoundError to the missing-token 400; key-ring, decryption and database errors reach the route's 500. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Keel <WyJrZWVsIiwiZGVmYXVsdCJd@agents.commonly.invalid> Agent-Model: claude/claude-opus-5-5/high
This comment has been minimized.
This comment has been minimized.
… secret ref (TASK-539) - New connector-secret kind groupme-access-token. The integration row keeps config.accessTokenRef, declared in the schema, managed by the server and left out of JSON projections like the other refs. - services/chatConnectorTokens.ts: the GroupMe and Slack counterparts of services/feedCredentials, used by the generic create and edit routes. A blank token on an edit keeps the stored one. Unused accessToken and refreshToken config keys are no longer kept on Slack rows. - The agent integration-messages read for GroupMe resolves the ref. A missing secret is a 400; any other failure is a 500. - connectorSecrets.putIfAbsent: an insert-only write for imports, so an import never replaces a secret written after it read the row. - scripts/migrate-chat-token-copies.ts moves existing rows onto refs (dry run by default, counts-only output). Runbook: docs/runbooks/migrate-chat-token-copies.md. Deploy first, then migrate. Written by Keel, a Commonly agent — https://commonly.me/v2/pods/6addc5e87f8fc798a6f2f5d2 Co-authored-by: Keel <WyJrZWVsIiwiZGVmYXVsdCJd@agents.commonly.invalid> Agent-Model: claude/claude-opus-5-5/high Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4VWLEBieQcBxrJwwQF9Py
04d35af to
dd1c9a3
Compare
|
Re #3004 (comment): fixed in 3bcf78e. The import now goes through Written by Keel, a Commonly agent — https://commonly.me/v2/pods/6addc5e87f8fc798a6f2f5d2 |
…k reads the ref only (TASK-539) - groupmeService.fetchMessages rethrows a failed request as an error with the status only, and the integration-messages handler logs the message rather than the error object. - slackProvider tokenFor resolves botTokenRef only; a row's own botToken copy is no longer a source. - Direct unit tests for connectorSecrets.putIfAbsent (insert, and an existing pair returned with created false). Written by Keel, a Commonly agent — https://commonly.me/v2/pods/6addc5e87f8fc798a6f2f5d2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Record for reviewers (not addressed to CodeRabbit): the review-body item at |
@coderabbitai ignore
TASK-539. This moves the GroupMe access token onto the same connector-secret storage that the X and Instagram feed tokens use (#2692 / #2719). It also stops a Slack row from keeping
accessToken/refreshTokenconfig keys that no code reads.Change
groupme-access-token. The row keepsconfig.accessTokenRef, which is declared in the schema, managed by the server, and left out of JSON projections like the other refs.services/chatConnectorTokens.ts: the GroupMe and Slack counterparts ofservices/feedCredentials. The generic create and edit routes use it. A blank token on an edit keeps the stored token.connectorSecrets.putIfAbsent: an insert-only store that a migration uses, so it never replaces a secret written after it read the row.scripts/migrate-chat-token-copies.ts: dry run by default, with counts-only output. It moves GroupMe tokens to the new storage, keeps any existing ref, and removes the unused keys on both types. Runbook:docs/runbooks/migrate-chat-token-copies.md.Deploy order: deploy first, then the migration. The runbook has the steps.
Tests
chatConnectorTokens.test.js: routes against real Mongo.migrateChatTokenCopies.test.js: dry run, apply, idempotency, an interleaved write, a missing key ring, and the CLI output.agentsRuntime.integrations.messages.test.js: four GroupMe reader cases.integrations-e2e.test.js: seeds its GroupMe row through the new storage.The new cases were mutation-checked locally, and each fails against its mutant. The neighbouring suites pass, tsc stays at its baseline, and there are no new lint errors.
Tier 2.
🤖 Generated with Claude Code