Skip to content

koompi/koompi-oauth-monorepo-example

Repository files navigation

Example Koompi OAuth Starter

Expo + Express monorepo that showcases a full OAuth 2.0 flow against Koompi for both web and mobile.


Why this starter?

  • Single source of truth – the backend owns every credential, redirect, and session decision.
  • Expo-first DX – share UI, navigation, and auth logic across native apps while still shipping to the web.
  • Monorepo ergonomics – pnpm + Turborepo wire together the backend, mobile, and shared packages with zero manual linking.
  • Real OAuth plumbing – deep-link capable mobile login, web callback page, and token exchange flows that mirror production deployments.

What you get

  • Backend (apps/backend) – Node.js + Express + TypeScript API with OAuth endpoints, MongoDB wiring, and JWT session issuance.
  • Mobile (apps/mobile) – Expo Router app with native deep linking (example://oauth/callback), secure token storage, and starter wallet UI.
  • Web (apps/web) – React web client that mirrors the same login flow via Koompi and shares UI primitives.
  • Shared packages – eslint config, UI kit, feature modules, and an axios-based HTTP client so every surface behaves consistently.

Repository map

apps/
  backend/   # Express API, OAuth controller/service, Mongo config
  mobile/    # Expo Router app, auth hook, wallet views, deep linking config
  web/       # React SPA consuming the OAuth session
packages/
  eslint-config/  # Shared lint rules
  feature-home/   # Example shared feature for mobile/web
  http-client/    # Axios helpers with token attachment
  ui/             # Reusable RN components

OAuth 2.0 authorization-code flow

  1. Client bootstraps – mobile/web calls GET /api/oauth/login for provider metadata (scopes, authorize URL, PKCE code verifier if used).
  2. User authorization – client opens the returned Koompi authorize URL.
  3. Callback ingress – Koompi redirects to the shared backend callback (/api/oauth/callback) with code + state and optional platform query.
  4. Token exchange – backend swaps the code for access token + user profile via Koompi OAuth endpoints.
  5. Session minting – backend normalizes the Koompi profile, persists/updates a Mongo user, and signs an app JWT.
  6. Callback egress
    • Web → redirects to config.frontend.url + /oauth/callback?token=....
    • Mobile → deep links to example://oauth/callback?token=....
  7. Client storage – mobile uses useAuth + secure store, web stores the JWT via its auth context.

The entire flow (diagrams & troubleshooting) lives in docs/KOOMPI_OAUTH_INTEGRATION.md.

Environment & configuration

All secrets live in apps/backend/.env:

MONGODB_URI=mongodb://localhost:27017/example
JWT_SECRET=super-secret
SESSION_EXPIRY_HOURS=12

# Koompi OAuth credentials (from dashboard)
KOOMPI_CLIENT_ID=pk_local_...
KOOMPI_CLIENT_SECRET=sk_local_...
KOOMPI_REDIRECT_URI=http://localhost:4000/api/oauth/callback
KOOMPI_MOBILE_REDIRECT_URI=https://YOUR-NGROK-ID.ngrok-free.app/api/oauth/callback?platform=mobile

Clients only need to know how to reach the backend:

  • Mobile – uses process.env.EXPO_PUBLIC_BACKEND_URL (defaults to http://localhost:4000).
  • Web – configure VITE_API_BASE_URL in apps/web/.env.local.

🔁 Use Ngrok (or Cloudflare Tunnel) to expose the backend whenever you test the mobile flow on a physical device. Update KOOMPI_MOBILE_REDIRECT_URI to match the tunnel URL every time it changes.

Quick start

pnpm install
pnpm dev            # runs backend, mobile, and web watchers via Turborepo

Run surfaces individually

pnpm dev:mobile     # Expo + Metro for the mobile app
pnpm dev --filter @example/backend  # backend only
pnpm dev --filter @example/web      # Vite dev server

Mobile deep link testing

  1. Update apps/mobile/app.json if you change the scheme (example).
  2. Launch Expo Go or a dev client: pnpm --filter @example/mobile start.
  3. Authenticate: backend redirects through Ngrok back into the app via example://oauth/callback.

Building & linting

pnpm build          # builds every package/app with caching
pnpm lint           # eslint across backend, mobile, web, shared packages
pnpm test           # run workspace tests (Jest)

Notable files

  • apps/backend/src/routes/oauthRoutes.ts – HTTP surface for /api/oauth/login and /api/oauth/callback.
  • apps/backend/src/services/oauthService.ts – exchanges codes, generates redirect URLs, maps Koompi profile → Example user.
  • apps/mobile/hooks/useAuth.ts – encapsulates login/logout, token parsing, error handling, and deep-link listeners.
  • apps/web/src/context/AuthContext.tsx – web session provider built on the same API responses.
  • packages/http-client/src/index.ts – axios instance + interceptor to inject JWTs from secure storage/local storage.

Troubleshooting cheat sheet

Symptom Likely cause Fix
"Redirect URI not authorized" Ngrok URL or localhost mismatch Re-enter the exact callback in the Koompi dashboard + backend .env
App never re-opens after login Deep-link scheme mismatch Ensure app.json scheme matches REDIRECT_SCHEME in useAuth.ts
Invalid client from Koompi Wrong KOOMPI_CLIENT_ID/SECRET Copy the latest credentials into .env, restart backend
Web callback shows error Missing VITE_API_BASE_URL Create apps/web/.env.local pointing to backend
Mobile stuck on spinner No token in deep link Inspect Ngrok logs, confirm backend is hitting /api/oauth/callback?platform=mobile

Reference docs

  • docs/KOOMPI_OAUTH_INTEGRATION.md – deep dive into the OAuth flow.
  • apps/backend/README.md, apps/mobile/README.md & apps/web/README.md – surface-specific setup notes.

With ❤️ from the KOOMPI team. Happy building!

About

Expo + Express monorepo that showcases a full OAuth 2.0 flow against Koompi for both web and mobile.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors