Skip to content

feat(reddit): refresh through the dos.me broker, drop Reddit client creds - #63

Merged
JOY (JOY) merged 1 commit into
devfrom
feat/reddit-broker-refresh
Sep 25, 2026
Merged

JOY (JOY) merged 1 commit into
devfrom
feat/reddit-broker-refresh

Conversation

@JOY

@JOY JOY (JOY) commented Sep 25, 2026 •

Copy link
Copy Markdown

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.
  • If the response omits 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).
  • With refresh brokered, REDDIT_CLIENT_ID/SECRET are removed from .env.example and the compose template; the running VM envs get cleaned at deploy time (tracked separately).

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_ID and REDDIT_CLIENT_SECRET in the application environment. It simplifies credential management and ensures consistent broker usage for both connection and refresh flows.

🎯 Type of Change

  • 🚀 New feature
  • 🐛 Bugfix
  • 🧹 Refactor
  • ⚡ Performance
  • 📚 Documentation
  • ⚙️ CI / Configuration

🔍 Changes Walkthrough

File Summary of Changes
.env.example Removed REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET variables and updated comments to clarify that the broker handles all OAuth operations.
docker-compose.yaml Removed the corresponding environment variable definitions for Reddit credentials from the service configuration.
libraries/nestjs-libraries/src/integrations/social/reddit.provider.ts Refactored refreshToken to call the new broker endpoint instead of Reddit's API directly. Extracted common response parsing logic into a parseBundle helper and added a fetchRefreshBundle method 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
Loading

…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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +256 to +271
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;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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;
    }

@JOY
JOY (JOY) merged commit fca1258 into dev Sep 25, 2026
11 checks passed
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.

1 participant