feat(reddit): refresh through the dos.me broker, drop Reddit client creds - #63
Conversation
…reds refreshToken() now calls POST /oauth/reddit/refresh on the broker (same ApiKeyGuard and token bundle shape as token-delivery) instead of running the refresh grant against Reddit with REDDIT_CLIENT_ID/SECRET. When the broker omits refreshToken (Reddit did not rotate), the stored token is kept - a blank refresh token would break every later refresh. With refresh brokered, no Reddit client credentials are needed in Crove env at all: REDDIT_CLIENT_ID/SECRET are removed from .env.example and the compose template. VM env cleanup happens at deploy time.
There was a problem hiding this comment.
Code Review
This pull request refactors the Reddit integration to route both connection and token refresh flows through the dos.me Reddit OAuth broker, eliminating the need for local Reddit client credentials. In reddit.provider.ts, the refreshToken method has been updated to fetch the refresh bundle from the broker, and the token parsing logic has been consolidated into a reusable parseBundle helper. A review comment suggests enhancing parseBundle to explicitly check for and throw errors when the broker returns an unsuccessful response, which would prevent masking the root cause with a generic missing access token error.
| private parseBundle(body: any): { | ||
| accessToken: string; | ||
| refreshToken?: string; | ||
| expiresIn: number; | ||
| scopes: string[]; | ||
| } { | ||
| // dos.me wraps some endpoints in { success, data } - unwrap defensively. | ||
| if ( | ||
| body && | ||
| typeof body === 'object' && | ||
| 'success' in body && | ||
| 'data' in body && | ||
| body.data | ||
| ) { | ||
| body = body.data; | ||
| } |
There was a problem hiding this comment.
When the broker returns an unsuccessful response (e.g., { success: false, error: "..." }), parseBundle currently fails to unwrap it and subsequently throws a generic 'token bundle has no access token' error. Checking for success === false explicitly and throwing the returned error message (or a fallback) will prevent masking the actual error and make debugging much easier.
private parseBundle(body: any): {
accessToken: string;
refreshToken?: string;
expiresIn: number;
scopes: string[];
} {
if (body && typeof body === 'object' && 'success' in body && body.success === false) {
throw new Error(body.error || body.message || 'Broker returned an unsuccessful response');
}
// dos.me wraps some endpoints in { success, data } - unwrap defensively.
if (
body &&
typeof body === 'object' &&
'success' in body &&
'data' in body &&
body.data
) {
body = body.data;
}
Completes the Reddit broker integration. DOS-Me shipped
POST /oauth/reddit/refresh(ApiKeyGuard, same bundle shape as token-delivery, live 23/09):RedditProvider.refreshToken()now calls the broker instead of running the refresh grant directly against Reddit with app credentials.refreshToken(Reddit did not rotate), the stored token is kept - falling back to the input, never blanking it (the result is persisted by RefreshIntegrationService, so a blank would poison the next refresh).Deploy notes: envs already carry DOS_ME_INTERNAL_API_KEY (both). Beta UAT: trigger a real refresh against a connected Reddit channel, then drop the creds from the VM env.
📌 TL;DR
This PR refactors the Reddit integration to route token refreshes through the dos.me OAuth broker, eliminating the need for
REDDIT_CLIENT_IDandREDDIT_CLIENT_SECRETin the application environment. It simplifies credential management and ensures consistent broker usage for both connection and refresh flows.🎯 Type of Change
🔍 Changes Walkthrough
.env.exampleREDDIT_CLIENT_IDandREDDIT_CLIENT_SECRETvariables and updated comments to clarify that the broker handles all OAuth operations.docker-compose.yamllibraries/nestjs-libraries/src/integrations/social/reddit.provider.tsrefreshTokento call the new broker endpoint instead of Reddit's API directly. Extracted common response parsing logic into aparseBundlehelper and added afetchRefreshBundlemethod to handle the broker's refresh request.📊 Architectural Flow
sequenceDiagram participant Crove as Crove App participant Broker as dos.me Broker participant Reddit as Reddit API Note over Crove, Broker: Token Refresh Flow Crove->>Broker: POST /oauth/reddit/refresh (with refresh_token) Broker->>Reddit: POST /api/v1/access_token (with client credentials) Reddit-->>Broker: New Access Token Broker-->>Crove: Token Bundle (access_token, expires_in) Note over Crove: Parse Bundle & Update State Crove->>Reddit: GET /api/v1/me (with new access_token) Reddit-->>Crove: User Profile