Skip to content

Ajit/fix fetch auth config#2068

Open
deadlyjack wants to merge 4 commits intomainfrom
ajit/fix-fetch-auth-config
Open

Ajit/fix fetch auth config#2068
deadlyjack wants to merge 4 commits intomainfrom
ajit/fix-fetch-auth-config

Conversation

@deadlyjack
Copy link
Copy Markdown
Member

No description provided.

Ajit Kumar added 2 commits April 28, 2026 18:31
…ion imports

- Replaced ajax calls with fetch in sponsor, sponsors, and themeSetting pages.
- Updated constants import to config in various files for better configuration management.
- Improved error handling for API responses.
- Adjusted logic for premium theme checks based on new config settings.
- Enhanced cookie management in the Authenticator plugin for better security.
- Fixed minor typos and improved code readability across multiple files.
@github-actions github-actions Bot added the translations Anything related to Translations Whether a Issue or PR label Apr 28, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 28, 2026

Greptile Summary

This PR refactors the auth system from a custom-header XHR flow to a cookie-based scheme: a new Authenticator.java injects the auth token into Android's CookieManager with HttpOnly; Secure; SameSite=None, and a local ajax.js replaces the @deadlyjack/ajax package with withCredentials = true configured globally in main.js for XHR calls. A new config.js consolidates the old constants.js.

  • P1 — Core login fetch lacks credentials: 'include': getLoggedInUser() in auth.js fetches GET /api/login without credentials: \"include\", so the auth cookie is never sent; the server always returns 401 and the user appears permanently logged out.
  • P1 — Server-side logout not invalidated: logout() sends DELETE /login without credentials, leaving the server-side session alive after local logout.
  • P1 — Sponsor purchase fetch unauthenticated: The POST to /api/sponsor in sponsor.js also lacks credentials: \"include\".

Confidence Score: 3/5

Not safe to merge — multiple P1 issues mean the new cookie-based auth flow is broken end-to-end in the Cordova WebView.

Three independent P1 findings across the core login check, logout, and sponsor purchase all using fetch without credentials:include, making the new cookie auth scheme non-functional for critical paths.

src/lib/auth.js (core login/logout fetch calls), src/pages/sponsor/sponsor.js (purchase POST), and previously-flagged plugin purchase/refund fetch calls.

Security Review

  • Stale server-side session on logout (src/lib/auth.js): logout() sends DELETE /login without credentials: \"include\", so the auth cookie is never forwarded to the server. The server-side session is not invalidated; only the local cookie/cache is cleared.
  • Unauthenticated core API calls (src/lib/auth.js, src/pages/sponsor/sponsor.js): getLoggedInUser(), logout(), and the sponsor purchase POST all use fetch without credentials: \"include\", breaking the intended cookie-based auth scheme.

Important Files Changed

Filename Overview
src/lib/auth.js Core auth refactored to cookie-based flow via fetch; both getLoggedInUser() and logout() fetch calls are missing credentials: 'include', breaking login detection and server-side logout.
src/lib/ajax.js New local XHR-based ajax utility replacing @deadlyjack/ajax; withCredentials is wired up via ajax.configure in main.js.
src/lib/config.js New config module consolidating constants.js; includes HAS_PRO getter/setter replacing IS_FREE_VERSION global.
src/lib/adRewards.js getRewardIdentity references undefined user variable (previously flagged); canShowAds/isRewardedSupported correctly migrated to config.HAS_PRO.
src/plugins/auth/src/android/Authenticator.java Refactored to inject auth cookie via CookieManager with HttpOnly; Secure; SameSite=None — addresses previous HttpOnly finding.
src/pages/plugin/plugin.js Migrated from ajax to fetch for order/refund calls; credentials: 'include' still missing (previously flagged).
src/main.js Correctly wires ajax.configure with withCredentials=true for API XHR calls; migrates IS_FREE_VERSION to config.HAS_PRO.
src/pages/sponsor/sponsor.js POST to /api/sponsor is missing credentials: 'include', so the server receives an unauthenticated purchase confirmation.
src/lib/checkPluginsUpdate.js Correctly migrated from ajax to fetch with proper res.ok check and JSON parsing; previous options-object bug is fixed.

Sequence Diagram

sequenceDiagram
    participant App as JS WebView
    participant CM as CookieManager
    participant Server as API Server

    Note over App,CM: Login
    App->>CM: saveToken via cordova.exec
    CM->>CM: setCookie with HttpOnly Secure SameSite=None
    CM-->>App: success

    Note over App,Server: Auth check - getLoggedInUser
    App->>Server: fetch GET /login - no credentials include
    Server-->>App: 401 Unauthorized - cookie not forwarded

    Note over App,Server: XHR path via ajax utility
    App->>Server: XHR with withCredentials true
    Server-->>App: 200 OK - cookie forwarded correctly

    Note over App,Server: Logout
    App->>Server: fetch DELETE /login - no credentials include
    Server-->>App: request without session - session NOT cleared
    App->>CM: clearTokenCookie via cordova.exec
    CM-->>App: local cookie cleared only
Loading

Reviews (2): Last reviewed commit: "fix: update cookie settings to include H..." | Re-trigger Greptile

Comment thread src/lib/checkPluginsUpdate.js Outdated
).readFile("json");

const res = await ajax({
const res = await fetch({
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P0 fetch called with options object instead of URL string

fetch expects a URL string (or Request) as its first argument. Passing { url: '...' } causes fetch to stringify the object to [object Object] and make a request to that invalid URL, so plugin update checks will always fail silently.

Comment thread src/lib/adRewards.js Outdated
device?.uuid ||
"guest";
return String(userId);
const userId = user?.id || "Guest";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 user is undefined and userId is never returned

The refactor removed the auth.getUserInfo() call but kept the reference to user, which is never declared in this scope. This throws a ReferenceError at runtime, so getRewardIdentity always falls into the catch branch and returns device.uuid || "guest". Additionally, even if user were defined, there is no return userId statement, so the function would return undefined.

Comment thread src/plugins/auth/src/android/Authenticator.java
@deadlyjack
Copy link
Copy Markdown
Member Author

@greptile_apps review again with confidence score

Comment thread src/lib/auth.js
Comment on lines 99 to +115
}

async getUserInfo() {
try {
const data = await this._exec("getUserInfo");
return typeof data === "string" ? JSON.parse(data) : data;
} catch (error) {
console.error("Failed to fetch user data.", error);
return null;
}
}
/**
*
* @returns {User}
*/
async getLoggedInUser() {
if (loggedInUser) return loggedInUser;

async getAvatar() {
try {
const userData = await this.getUserInfo();
if (!userData) return null;

if (userData.github) {
return `https://avatars.githubusercontent.com/${userData.github}`;
const res = await fetch(`${config.API_BASE}/login`);

if (res.ok) {
loggedInUser = await res.json();
localStorage.setItem(CACHE_USER_KEY, JSON.stringify(loggedInUser));
clearTimeout(cacheTimeout);
cacheTimeout = setTimeout(() => (loggedInUser = null), 600_000);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Core auth fetch missing credentials: 'include'

getLoggedInUser() calls fetch against acode.app/api without credentials: 'include'. The Cordova WebView loads from a local origin (file:// or localhost), so these are cross-origin requests. Without credentials: 'include' the auth cookie set by CookieManager is not forwarded — the server will always see an unauthenticated request, return 401, and getLoggedInUser() will return null, meaning loginEvents.emit() in main.js is never called and the user always appears logged out. By contrast, every ajax/XHR call explicitly sets withCredentials = true via ajax.configure in main.js, showing this omission is unintentional.

Comment thread src/lib/auth.js
Comment on lines 75 to +82
}

async openLoginUrl() {
const url = "https://acode.app/login?redirect=app";

async logout() {
try {
await new Promise((resolve, reject) => {
CustomTabs.open(url, { showTitle: true }, resolve, reject);
const res = await fetch(`${config.API_BASE}/login`, {
method: "DELETE",
});
if (!res.ok) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 security logout() server-side session not invalidated without credentials

The DELETE /login call also lacks credentials: 'include'. The cookie is not sent to the server so the session is never invalidated server-side — the server-side session remains alive even after the user "logs out" locally. Add credentials: "include" here as well.

Comment on lines 83 to +93
);

try {
const res = await ajax.post(`${constants.API_BASE}/sponsor`, {
data: {
const res = await fetch(`${config.API_BASE}/sponsor`, {
method: "POST",
body: JSON.stringify({
...sponsorDetails,
tier: productId,
packageName: BuildInfo.packageName,
purchaseToken: order.purchaseToken,
},
}),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Sponsor purchase fetch missing credentials: 'include'

The POST to /api/sponsor doesn't include credentials: "include", so the auth cookie won't be forwarded in this cross-origin Cordova WebView context. The server will receive an unauthenticated purchase confirmation request. Every ajax/XHR call sets withCredentials = true via ajax.configure in main.js, so the omission here appears unintentional.

* fix: hooks not working on free version

* Update hooks/post-process.js

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update post-process.js

---------
Copy link
Copy Markdown
Member

@RohitKushvaha01 RohitKushvaha01 left a comment

Choose a reason for hiding this comment

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

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

translations Anything related to Translations Whether a Issue or PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants