Skip to content

Conversation

@akanshaaa19
Copy link
Member

@akanshaaa19 akanshaaa19 commented Oct 6, 2025

closes glific/glific-frontend#3547

Summary by CodeRabbit

  • New Features
    • Automatically attaches authorization headers to Flow Editor requests, improving seamless access when signed in.
  • Bug Fixes
    • Ensures consistent authentication behavior across both network methods (axios and fetch) for Flow Editor requests.
  • Improvements
    • Standardizes request defaults (content type, timeout, response handling) to enhance reliability for related network calls.
  • Chores
    • Consolidates network configuration into a single service for easier maintenance, without changing public behavior.

@coderabbitai
Copy link

coderabbitai bot commented Oct 6, 2025

Walkthrough

Relocates Axios default configuration from src/external/index.ts to a new initializer src/services/axios.ts. Adds conditional auth header injection for Flow Editor requests via Axios interceptor and a fetch override. Ensures initialization by importing the new module in src/index.js. Exports getAuthHeaders for reuse.

Changes

Cohort / File(s) Summary
Relocate Axios defaults
src/external/index.ts, src/services/axios.ts
Removes Axios global defaults from external index; re-establishes defaults (POST Content-Type, responseType, timeout) in services/axios initializer.
Flow Editor auth injection
src/services/axios.ts
Adds getAuthHeaders() reading localStorage; detects /flow-editor requests; injects Authorization header via Axios request interceptor and window.fetch override; safe on parse failures or absent session.
App initialization wiring
src/index.js
Imports ./services/axios to activate defaults and interceptors at startup; no other behavior changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as UI
  participant Axios as Axios (interceptor)
  participant Svc as services/axios.getAuthHeaders
  participant API as Flow Editor API

  Note over UI,API: Flow Editor request via Axios
  UI->>Axios: axios.request(url: /flow-editor/..., config)
  alt URL contains "/flow-editor"
    Axios->>Svc: getAuthHeaders()
    Svc-->>Axios: { Authorization: "Bearer ..." } or {}
    Axios->>API: request with merged headers
    API-->>Axios: response
  else Other URLs
    Axios->>API: request unchanged
    API-->>Axios: response
  end
  Axios-->>UI: response
Loading
sequenceDiagram
  autonumber
  participant UI as UI
  participant Fetch as window.fetch (overridden)
  participant Svc as services/axios.getAuthHeaders
  participant API as Flow Editor API

  Note over UI,API: Flow Editor request via fetch
  UI->>Fetch: fetch(url, init)
  alt URL contains "/flow-editor"
    Fetch->>Svc: getAuthHeaders()
    Svc-->>Fetch: { Authorization: "Bearer ..." } or {}
    Fetch->>API: request with merged headers
    API-->>Fetch: response
  else Other URLs
    Fetch->>API: request unchanged
    API-->>Fetch: response
  end
  Fetch-->>UI: response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A whisk of keys, a hop of delight,
Headers now hop only when right.
Axios and fetch, in tandem they go,
Guarding the warren of /flow-editor’s flow.
I stash my token in a clover-green cache—
Then bound through requests with a swift bunny dash. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The removal of global axios default configurations for POST Content-Type, responseType, and timeout in src/external/index.ts is unrelated to the objective of adding Authorization headers and thus constitutes an out-of-scope change. Consider reverting or isolating the changes in src/external/index.ts or providing a clear justification for modifying these defaults to keep the PR focused on implementing authorization headers.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly summarizes the primary change by stating that authentication (authorization headers) is being added to all API requests, which directly reflects the core implementation introduced in the changeset.
Linked Issues Check ✅ Passed The implementation directly addresses issue #3547 by adding FlowEditor-level handling for Authorization headers on every request through axios interceptors and a fetch override, thereby removing reliance on the Glific frontend’s global interceptor and ensuring tokens are centrally managed within FlowEditor.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-auth-header

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cfd4ec6 and 0b36355.

📒 Files selected for processing (3)
  • src/external/index.ts (0 hunks)
  • src/index.js (1 hunks)
  • src/services/axios.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/external/index.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/services/axios.ts (1)
src/__mocks__/axios.ts (1)
  • axios (3-3)
🔇 Additional comments (4)
src/services/axios.ts (3)

17-21: LGTM!

The helper function correctly handles both string and URL types and performs a simple substring check for flow-editor requests.


28-44: LGTM!

The Axios request interceptor correctly:

  • Checks for flow-editor URLs before adding auth headers
  • Merges headers without overwriting existing ones
  • Handles errors appropriately

23-26: Scope and correct the global POST Content-Type header. You’re setting Content-Type: application/javascript for all POSTs, which is highly unusual—most APIs expect application/json. Either change it to application/json or limit application/javascript to only the endpoints that actually require it. Confirm the FlowEditor API’s requirements.

src/index.js (1)

6-6: LGTM!

The side-effect import correctly initializes the Axios configuration and fetch override when the module loads, ensuring authentication headers are applied to all flow-editor requests.

Comment on lines +3 to +15
export const getAuthHeaders = () => {
const glific_session = localStorage.getItem('glific_session');
if (glific_session) {
try {
const token = JSON.parse(glific_session).access_token;
return { Authorization: token };
} catch (error) {
console.error('Failed to parse glific_session:', error);
return {};
}
}
return {};
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add "Bearer " prefix to the Authorization header.

The Authorization header should typically follow the format Bearer <token> for JWT-based authentication. The current implementation returns just the token value without the "Bearer " prefix, which may cause authentication failures.

Apply this diff to add the Bearer prefix:

 export const getAuthHeaders = () => {
   const glific_session = localStorage.getItem('glific_session');
   if (glific_session) {
     try {
       const token = JSON.parse(glific_session).access_token;
-      return { Authorization: token };
+      return { Authorization: `Bearer ${token}` };
     } catch (error) {
       console.error('Failed to parse glific_session:', error);
       return {};
     }
   }
   return {};
 };
🤖 Prompt for AI Agents
In src/services/axios.ts around lines 3 to 15, the getAuthHeaders function
returns the raw token instead of a Bearer token; update the returned
Authorization header to include the "Bearer " prefix (e.g., Authorization:
`Bearer ${token}`) while preserving existing JSON parsing and error handling so
that when a valid glific_session exists the header is returned as {
Authorization: `Bearer ${token}` } and on parse failure or missing session it
still returns {}.

Comment on lines +46 to +69
// Intercept fetch requests globally (for requests that might use fetch)
const originalFetch = window.fetch;
window.fetch = function(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
// Only add auth headers if this is a flow-editor request
if (typeof input == 'string' && isFlowEditorRequest(input)) {
const authHeaders = getAuthHeaders();

// Merge headers
const headers = {
...authHeaders,
...(init?.headers || {})
};

const modifiedInit = {
...init,
headers
};

return originalFetch(input, modifiedInit);
}

// For all other requests, use original fetch without modification
return originalFetch(input, init);
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix fetch override to handle all input types and Headers objects.

The current implementation has several critical issues:

  1. Line 50: Only checks if input is a string, missing URL objects that would also match the flow-editor pattern
  2. Lines 54-57: Header merging assumes init?.headers is a plain object, but it can be a Headers instance or an array of [key, value] pairs
  3. Missing Request handling: The function doesn't handle cases where input is a Request object (which can contain its own headers and URL)

These gaps could result in auth headers not being applied or runtime errors.

Apply this diff to fix the issues:

 // Intercept fetch requests globally (for requests that might use fetch)
 const originalFetch = window.fetch;
 window.fetch = function(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
-  // Only add auth headers if this is a flow-editor request
-  if (typeof input == 'string' && isFlowEditorRequest(input)) {
+  // Determine the URL for checking
+  let url: string;
+  if (typeof input === 'string') {
+    url = input;
+  } else if (input instanceof URL) {
+    url = input.toString();
+  } else if (input instanceof Request) {
+    url = input.url;
+  } else {
+    // Fallback: pass through unmodified
+    return originalFetch(input, init);
+  }
+
+  // Only add auth headers if this is a flow-editor request
+  if (isFlowEditorRequest(url)) {
     const authHeaders = getAuthHeaders();
 
-    // Merge headers
-    const headers = {
-      ...authHeaders,
-      ...(init?.headers || {})
-    };
-
-    const modifiedInit = {
-      ...init,
-      headers
-    };
+    // Merge headers - handle different header types
+    const existingHeaders = init?.headers || {};
+    const mergedHeaders = new Headers(existingHeaders);
+    
+    // Add auth headers if not already present
+    Object.entries(authHeaders).forEach(([key, value]) => {
+      if (!mergedHeaders.has(key)) {
+        mergedHeaders.set(key, value as string);
+      }
+    });
+
+    const modifiedInit = {
+      ...init,
+      headers: mergedHeaders
+    };
 
     return originalFetch(input, modifiedInit);
   }
 
   // For all other requests, use original fetch without modification
   return originalFetch(input, init);
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Intercept fetch requests globally (for requests that might use fetch)
const originalFetch = window.fetch;
window.fetch = function(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
// Only add auth headers if this is a flow-editor request
if (typeof input == 'string' && isFlowEditorRequest(input)) {
const authHeaders = getAuthHeaders();
// Merge headers
const headers = {
...authHeaders,
...(init?.headers || {})
};
const modifiedInit = {
...init,
headers
};
return originalFetch(input, modifiedInit);
}
// For all other requests, use original fetch without modification
return originalFetch(input, init);
};
// Intercept fetch requests globally (for requests that might use fetch)
const originalFetch = window.fetch;
window.fetch = function(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
// Determine the URL for checking
let url: string;
if (typeof input === 'string') {
url = input;
} else if (input instanceof URL) {
url = input.toString();
} else if (input instanceof Request) {
url = input.url;
} else {
// Fallback: pass through unmodified
return originalFetch(input, init);
}
// Only add auth headers if this is a flow-editor request
if (isFlowEditorRequest(url)) {
const authHeaders = getAuthHeaders();
// Merge headers - handle different header types
const existingHeaders = init?.headers || {};
const mergedHeaders = new Headers(existingHeaders);
// Add auth headers if not already present
Object.entries(authHeaders).forEach(([key, value]) => {
if (!mergedHeaders.has(key)) {
mergedHeaders.set(key, value as string);
}
});
const modifiedInit = {
...init,
headers: mergedHeaders
};
return originalFetch(input, modifiedInit);
}
// For all other requests, use original fetch without modification
return originalFetch(input, init);
};

@akanshaaa19 akanshaaa19 requested review from kurund and madclaws October 7, 2025 17:21
Copy link
Member

@mdshamoon mdshamoon left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@github-actions
Copy link

Without activity, this PR will be closed in 14 days.

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.

FlowEditor: Own Authorization header (remove frontend/global interception)

4 participants