Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions apps/mobile/app.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const path = require("node:path");
require("dotenv").config({
path: path.resolve(__dirname, "../../.env"),
override: true,
});

module.exports = {
expo: {
name: "Superset",
slug: "superset",
version: "1.0.0",
orientation: "portrait",
icon: "./assets/icon.png",
userInterfaceStyle: "light",
newArchEnabled: true,
scheme: "superset",
splash: {
image: "./assets/splash-icon.png",
resizeMode: "contain",
backgroundColor: "#ffffff",
},
ios: {
supportsTablet: true,
bundleIdentifier: "sh.superset.mobile",
infoPlist: {
ITSAppUsesNonExemptEncryption: false,
},
},
android: {
adaptiveIcon: {
foregroundImage: "./assets/adaptive-icon.png",
backgroundColor: "#ffffff",
},
package: "sh.superset.mobile",
edgeToEdgeEnabled: true,
predictiveBackGestureEnabled: false,
},
web: {
favicon: "./assets/favicon.png",
bundler: "metro",
},
plugins: ["expo-router"],
extra: {
router: {},
eas: {
projectId: "fa9332a8-896a-4d2a-be5b-d82469b46e5d",
},
},
owner: "supserset-sh",
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.

⚠️ Potential issue | 🟠 Major

Typo in owner field.

The owner is set to "supserset-sh" but based on the repository organization (superset-sh/superset), this should likely be "superset-sh". This typo would cause EAS builds and updates to fail or target the wrong project.

🐛 Proposed fix
-		owner: "supserset-sh",
+		owner: "superset-sh",
📝 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
owner: "supserset-sh",
owner: "superset-sh",
🤖 Prompt for AI Agents
In `@apps/mobile/app.config.js` at line 49, Fix the typo in the app config's owner
field by changing the value of the owner property in the exported config object
from "supserset-sh" to "superset-sh" so EAS builds and updates target the
correct project; locate the owner key in apps/mobile/app.config.js (the owner
property in the config/exported object) and update its string value accordingly.

},
};
45 changes: 0 additions & 45 deletions apps/mobile/app.json

This file was deleted.

54 changes: 54 additions & 0 deletions apps/mobile/apps/mobile/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import path from "node:path";
import { config } from "dotenv";
import type { ConfigContext, ExpoConfig } from "expo/config";

// Load .env file
config({
path: path.resolve(__dirname, "../../.env"),
override: true,
});

export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
name: "Superset",
slug: "superset",
version: "1.0.0",
orientation: "portrait",
icon: "./assets/icon.png",
userInterfaceStyle: "light",
newArchEnabled: true,
scheme: "superset",
splash: {
image: "./assets/splash-icon.png",
resizeMode: "contain",
backgroundColor: "#ffffff",
},
ios: {
supportsTablet: true,
bundleIdentifier: "sh.superset.mobile",
infoPlist: {
ITSAppUsesNonExemptEncryption: false,
},
},
android: {
adaptiveIcon: {
foregroundImage: "./assets/adaptive-icon.png",
backgroundColor: "#ffffff",
},
package: "sh.superset.mobile",
edgeToEdgeEnabled: true,
predictiveBackGestureEnabled: false,
},
web: {
favicon: "./assets/favicon.png",
bundler: "metro",
},
plugins: ["expo-router"],
extra: {
router: {},
eas: {
projectId: "fa9332a8-896a-4d2a-be5b-d82469b46e5d",
},
},
owner: "supserset-sh",
});
1 change: 1 addition & 0 deletions apps/mobile/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ module.exports = (api) => {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["react-native-worklets/plugin"],
};
};
7 changes: 2 additions & 5 deletions apps/mobile/lib/auth/client.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { expoClient } from "@better-auth/expo/client";
import { createAuthClient } from "better-auth/react";
import * as SecureStore from "expo-secure-store";

import { getBaseUrl } from "../base-url";

const BASE_URL = getBaseUrl();
import { env } from "../env";

export const authClient = createAuthClient({
baseURL: BASE_URL,
baseURL: env.EXPO_PUBLIC_API_URL,
Comment on lines +4 to +7
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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find env.ts in apps/mobile
find apps/mobile -name "env.ts" -o -name "env.js" -o -name "env.tsx"

Repository: superset-sh/superset

Length of output: 86


🏁 Script executed:

# Check the current content of apps/mobile/lib/auth/client.ts
cat apps/mobile/lib/auth/client.ts

Repository: superset-sh/superset

Length of output: 520


🏁 Script executed:

# Look for base-url.ts to understand the old implementation
find . -name "base-url.ts" -o -name "base-url.js"

Repository: superset-sh/superset

Length of output: 46


🏁 Script executed:

# Check git history to see what was removed (focusing on base-url)
git log --all --full-history -p -- "**/base-url.ts" | head -100

Repository: superset-sh/superset

Length of output: 2066


🏁 Script executed:

# View the env.ts file to see z.url() implementation
cat apps/mobile/lib/env.ts

Repository: superset-sh/superset

Length of output: 791


🏁 Script executed:

# Check if base-url.ts currently exists
ls -la apps/mobile/lib/base-url.ts 2>&1

Repository: superset-sh/superset

Length of output: 138


🏁 Script executed:

# More comprehensive git history for base-url.ts (show all changes)
git log --all --oneline -- "apps/mobile/lib/base-url.ts" | head -20

Repository: superset-sh/superset

Length of output: 124


🏁 Script executed:

# Check git status and recent removals in this directory
git log --all --oneline -- "apps/mobile/lib/" | head -30

Repository: superset-sh/superset

Length of output: 136


🏁 Script executed:

# Check the most recent state - see if base-url.ts was removed in a later commit
git log --all -p -- "apps/mobile/lib/base-url.ts" | head -200

Repository: superset-sh/superset

Length of output: 2066


🏁 Script executed:

# Look for recent commits that might have removed it
git log --all --oneline -20

Repository: superset-sh/superset

Length of output: 136


🏁 Script executed:

# Check what files are in apps/mobile/lib/
ls -la apps/mobile/lib/

Repository: superset-sh/superset

Length of output: 401


🏁 Script executed:

# Check what commit e699cc7 did - specifically what it removed
git show e699cc7 --stat

Repository: superset-sh/superset

Length of output: 50376


🏁 Script executed:

# Get the full diff for e699cc7 to see if it removed base-url.ts
git show e699cc7

Repository: superset-sh/superset

Length of output: 50380


🏁 Script executed:

# Search the entire codebase for trailing slash normalization patterns
rg 'replace.*/$' apps/mobile/ --type ts --type tsx

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

# Also check for slash normalization in different ways
rg 'trailing|slash.*replace|normalize.*url' apps/mobile/ --type ts --type tsx -i

Repository: superset-sh/superset

Length of output: 91


🌐 Web query:

better-auth baseURL trailing slash handling double slash

💡 Result:

Short answer — better-auth expects a normalized baseURL (no trailing path slash) and can be confused by double-slashes coming from baseURL + basePath or from un-normalized incoming requests; set BETTER_AUTH_URL / baseURL without a trailing slash, set basePath starting with a single leading slash, and ensure your proxy/host normalizes or forwards correct host/proto headers. Also upgrade to a fixed release (1.4.2+ and 1.4.5+ for later rou3 fixes) because older versions had baseURL/double-slash-related issues. [1][2][3]

Practical checklist

  • Explicitly set baseURL (or BETTER_AUTH_URL) — use e.g. https://example.com (no trailing slash). [4]
  • Use basePath with a single leading slash: e.g. basePath: "/api/auth". Avoid concatenating strings that produce "//".
  • If you must build URLs, join paths safely (remove trailing slash from baseURL or use URL/path join helpers) to avoid double-slash.
  • Ensure your proxy (NGINX/Vercel/Cloudflare, etc.) collapses multiple slashes and forwards correct X-Forwarded-Host / X-Forwarded-Proto, or configure better-auth to read a trusted baseURL so it cannot be poisoned by the first incoming request. (Older versions allowed an external request to set baseURL when it was unset.) [2][3]
  • Upgrade better-auth to a version that includes fixes: vulnerability/fixes referenced in advisories (upgrade to >=1.4.2 for baseURL poisoning fix and >=1.4.5 for rou3 double-slash normalization fix). [2][5]

Sources

  • better-auth docs — options/baseURL and BETTER_AUTH_URL. [4]
  • Security advisories describing baseURL-poisoning and rou3 double-slash issues and fixed versions. [2][3][5]

Ensure baseURL doesn't have trailing slash to avoid better-auth issues.

The z.url() validator in env.ts does not normalize trailing slashes. If EXPO_PUBLIC_API_URL is set with a trailing slash (e.g., https://api.example.com/), it will be passed directly to createAuthClient, which expects a normalized URL without trailing slashes. This can result in double slashes in auth request paths (e.g., https://api.example.com//auth), causing request failures. better-auth's own documentation and security advisories explicitly warn against this pattern.

Either:

  1. Add trailing slash normalization to env.ts (e.g., z.url().transform(url => url.replace(/\/$/, ''))), or
  2. Document that EXPO_PUBLIC_API_URL must not include a trailing slash.
🤖 Prompt for AI Agents
In `@apps/mobile/lib/auth/client.ts` around lines 4 - 7, The baseURL passed into
createAuthClient via env.EXPO_PUBLIC_API_URL can contain a trailing slash which
leads to double-slash auth paths; fix by normalizing the env value (in env.ts)
using z.url().transform to strip a trailing slash (e.g., replace(/\/$/, '')) so
authClient is always initialized with a URL without a trailing slash; update the
z.url() schema for EXPO_PUBLIC_API_URL rather than changing auth/client.ts.

plugins: [
expoClient({
scheme: "superset",
Expand Down
48 changes: 0 additions & 48 deletions apps/mobile/lib/base-url.ts

This file was deleted.

7 changes: 2 additions & 5 deletions apps/mobile/lib/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ const envSchema = z.object({
NODE_ENV: z
.enum(["development", "production", "test"])
.default("development"),
EXPO_PUBLIC_API_URL: z
.string()
.url()
.transform((url) => url.replace(/\/$/, "")),
EXPO_PUBLIC_WEB_URL: z.string().url().optional(),
EXPO_PUBLIC_API_URL: z.url(),
EXPO_PUBLIC_WEB_URL: z.url().optional(),
EXPO_PUBLIC_DEEP_LINK_SCHEME: z.string().default("superset"),
EXPO_PUBLIC_DEEP_LINK_DOMAIN: z.string().optional(),
});
Expand Down
4 changes: 3 additions & 1 deletion apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"better-auth": "1.4.16",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dotenv": "^17.2.3",
"expo": "~54.0.31",
"expo-constants": "^18.0.13",
"expo-dev-client": "~6.0.20",
Expand All @@ -29,12 +30,13 @@
"expo-router": "^6.0.21",
"expo-secure-store": "~15.0.8",
"expo-status-bar": "^3.0.9",
"expo-system-ui": "~6.0.9",
"expo-web-browser": "~15.0.10",
"lucide-react-native": "^0.562.0",
"react": "19.1.0",
"react-native": "0.81.5",
"react-native-reanimated": "~4.1.1",
"react-native-safe-area-context": "^5.6.2",
"react-native-safe-area-context": "~5.6.0",
"react-native-screens": "^4.16.0",
"react-native-svg": "^15.12.1",
"react-native-worklets": "~0.5.0",
Expand Down
10 changes: 5 additions & 5 deletions apps/mobile/uniwind-types.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// NOTE: This file is generated by uniwind and it should not be edited manually.
/// <reference types="uniwind/types" />

declare module "uniwind" {
export interface UniwindConfig {
themes: readonly ["light", "dark"];
}
declare module 'uniwind' {
export interface UniwindConfig {
themes: readonly ['light', 'dark']
}
}

export {};
export {}
8 changes: 7 additions & 1 deletion biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
"useIgnoreFile": true
},
"files": {
"includes": ["**", "!**/drizzle", "!**/*.template.js", "!**/*.template.sh"]
"includes": [
"**",
"!**/drizzle",
"!**/*.template.js",
"!**/*.template.sh",
"!apps/mobile/uniwind-types.d.ts"
]
},
"formatter": {
"formatWithErrors": true
Expand Down
6 changes: 5 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.