Skip to content

Pranjal-SB/AcadBridge

Repository files navigation

AcadBridge - Bridge to your academic data

TypeScript Bun License: MIT

AcadBridge is a Bun + TypeScript monorepo for authenticating against Academia and fetching academic data through a clean API.

Note: This repository is backend-only. It provides the API and scraping logic. For the mobile/web wrapper, see the AcadWrap repository (separate).

Features

  • Session-based login and logout
  • Attendance, marks, courses, user, calendar, and timetable scrapers
  • Combined data endpoint for one-shot fetching
  • Shared types and schemas across packages
  • Bun-native testing and runtime support

Quick Start

bun install
bun test
bun run dev

Installation

git clone https://github.com/Pranjal-SB/AcadBridge.git
cd AcadBridge
bun install

Usage

Start the API server:

bun run dev

Build the project:

bun run build

API Endpoints

  • POST /login — Authenticate with Academia credentials
  • DELETE /logout — End the current session
  • GET /hello — Health check
  • GET /attendance — Fetch attendance data
  • GET /marks — Fetch marks and grades
  • GET /courses — Fetch enrolled courses
  • GET /user — Fetch user profile
  • GET /calendar — Fetch academic calendar
  • GET /timetable — Fetch class timetable
  • GET /get — Fetch all data combined

Project Structure

packages/
├── types/    # Shared TypeScript types and Zod schemas
├── scraper/  # Login flow and data scrapers
└── api/      # Hono API server

Infrastructure & Environment Contract


Production Hardening & Operational Contract (Task 5)

Docs-only update (2026-04-09): This section documents the production hardening contract for AcadBridge. No runtime code or test changes are included in this update. These requirements are operational contracts for future implementation.

AcadBridge is designed for secure, multi-user, production hosting. The following operational requirements are enforced in production builds:

1. Startup Environment Validation

  • On startup, the API server validates all required environment variables:
    • REDIS_URL
    • SESSION_ENC_KEY
    • ALLOWED_ORIGINS
    • PORT
  • If any required variable is missing or invalid, the server fails fast and does not start.

2. Rate Limiting

  • /login endpoint:
    • Limited to 5 requests per minute per IP (burst up to 10).
  • Authenticated endpoints (all endpoints requiring a valid sessionToken):
    • Limited to 60 requests per minute per sessionToken (burst up to 120).
  • Exceeding these limits returns HTTP 429 with a clear error message.

3. CORS Strategy (BFF-only, locked down)

  • Only Backend-for-Frontend (BFF) server-to-server integration is supported. Browsers must not call AcadBridge directly.
  • CORS is locked down:
    • Allowed origins are set via the ALLOWED_ORIGINS environment variable (comma-separated).
    • In production, the default is empty (deny all origins).
  • Any browser-originated request from an origin not in the allowlist is denied (no CORS headers).

4. Logging & Observability

  • Every request is assigned a unique request ID, included in all logs and error responses.
  • Logs are structured (JSON or equivalent) and redact sensitive values (no passwords or cookie contents are ever logged).
  • Authentication failures and upstream errors are logged with request ID and minimal context only.

What changed in docs (2026-04-09)

  • Added/clarified explicit documentation for:
    • Startup environment validation (fail fast if required env vars missing)
    • /login rate limiting (5/min/IP, burst 10)
    • Authenticated endpoint rate limiting (60/min/sessionToken, burst 120)
    • BFF-only, locked-down CORS (via ALLOWED_ORIGINS, default deny)
    • Request IDs and structured logs (with sensitive value redaction)
  • No runtime code or test changes were made in this update.

AcadBridge API (Backend)

The following environment variables are required for the AcadBridge API:

  • REDIS_URL: Upstash Redis connection string for session persistence.
  • SESSION_ENC_KEY: A 32+ byte base64-encoded key used for encrypting session data at rest.
  • ALLOWED_ORIGINS: Comma-separated list of allowed origins for CORS. Defaults to empty (deny all) in production.
  • PORT: The port on which the API server listens.
  • DATABASE_URL: (Optional) Supabase Postgres connection string. Provisioned for future accounts, billing, and audit logs.

AcadWrap (Web App)

The following environment variables are mirrored for the future AcadWrap repository:

  • ACADBRIDGE_API_BASE_URL: The internal or production URL of the AcadBridge API. Used server-side only by the AcadWrap BFF.
  • NEXT_PUBLIC_APP_URL: The public URL of the AcadWrap application.
  • ACADWRAP_REFRESH_TTL_SECONDS: (Optional) Cache TTL for academic data in the AcadWrap application.

Commercial Readiness: Supabase Postgres is provisioned now to support future multi-user features (accounts, billing, audit), even if the MVP primarily uses Redis for session state.

Roadmap

See ROADMAP.md for planned improvements including:

  • OpenAPI/Swagger documentation
  • Docker support
  • TypeScript SDK
  • CLI tool

Contributing

  1. Create a branch
  2. Make focused changes
  3. Run bun test
  4. Open a pull request

API Contract: /login and Error Handling (Task 6, docs-only)

/login Response Shapes

  • Success:

    {
      "success": true,
      "sessionToken": "...",
      "cookies": ["JSESSIONID=...", ...]
    }
  • Invalid credentials:

    {
      "success": false,
      "error": "Invalid credentials or unexpected response"
    }
  • CAPTCHA required:

    {
      "success": false,
      "captchaRequired": true,
      "captchaData": {
        "digest": "...",
        "imageBase64": "..."
      },
      "error": "CAPTCHA required"
    }

Error Handling: tokenInvalid

  • Any endpoint that requires a session token (all except /login and /hello) returns errors in the following shape if the token is missing, invalid, or expired:
    {
      "error": "Missing X-CSRF-Token header",
      "tokenInvalid": true
    }
    or
    {
      "error": "Invalid or expired session token",
      "tokenInvalid": true
    }
  • The tokenInvalid: true field is always present for token errors, regardless of endpoint.

What changed in docs (2026-04-09)

  • Added explicit API contract section for /login and error handling, documenting all response shapes (success, invalid credentials, captcha required, tokenInvalid rule).
  • No runtime code or test changes were made; this is a documentation-only update.

License

MIT

About

Bridge to your academic data - SRMIST Academia scraper + API

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors