Files
indie/README.md
2026-06-30 11:13:55 +05:45

9.2 KiB

Indie — Independent Website Platform

A platform that lets anyone create, own, and publish their own static website without social media gatekeeping. Built with a drag-and-drop builder and LLM prompt-to-site generation. Every site is backed by a git repository. Users self-host or use free subdomain hosting.


Quick Start

Prerequisites

  • Java 17+
  • Node.js 18+ and npm
  • Docker & Docker Compose (for PostgreSQL, MongoDB, MinIO)
  • Angular CLI 17 (npm install -g @angular/cli@17)
  • Gradle wrapper (included)

Setup

  1. Start infrastructure:

    docker compose up -d
    
  2. Start the backend:

    cd backend
    ./gradlew bootRun
    

    The API will be available at http://localhost:8080. Swagger UI at http://localhost:8080/swagger-ui.html.

  3. Start the frontend (separate terminal):

    cd frontend
    npm install
    ng serve
    

    The app will be available at http://localhost:4200. API calls are proxied to http://localhost:8080.

Environment Variables

Variable Description Default
SPRING_DATASOURCE_URL PostgreSQL JDBC URL jdbc:postgresql://localhost:5432/indie
SPRING_DATASOURCE_USERNAME DB username indie
SPRING_DATASOURCE_PASSWORD DB password indie_dev
SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_ID Google OAuth 2.0 client ID (omit to disable Google login)
SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_SECRET Google OAuth 2.0 client secret
SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENT_ID GitHub OAuth App client ID (omit to disable GitHub login)
SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GITHUB_CLIENT_SECRET GitHub OAuth App client secret
INDIE_JWT_ACCESS_EXPIRATION Access token TTL (ms) 900000 (15 min)
INDIE_JWT_REFRESH_EXPIRATION Refresh token TTL (ms) 604800000 (7 days)
INDIE_GIT_REPOS_PATH Git repositories root /var/git/sites/
INDIE_GIT_AUTHOR_NAME Default git author name Indie Platform
INDIE_GIT_AUTHOR_EMAIL Default git author email git@indie.local

Project Structure

backend/
├── build.gradle                          # Dependencies and build config
├── settings.gradle                       # Project name
├── gradlew / gradlew.bat                 # Gradle wrapper
├── gradle/wrapper/                       # Wrapper JAR + properties
└── src/main/
    ├── java/com/indie/
    │   ├── IndieApplication.java         # Spring Boot main class
    │   ├── config/
    │   │   ├── SecurityConfig.java       # HTTP security, JWT filter, OAuth2 login, CORS
    │   │   ├── JwtConfig.java            # RS256 token generation and validation
    │   │   └── GitConfig.java            # Git repository settings
    │   ├── model/
    │   │   ├── User.java                 # User entity with local + OAuth support
    │   │   ├── Site.java                 # Site entity per user
    │   │   ├── Page.java                 # Page within a site
    │   │   ├── Component.java            # Component on a page (heading, text, image, etc.)
    │   │   ├── JsonbConverter.java       # JPA converter for JSONB columns
    │   │   └── *.java                    # Enums (AuthProvider, SiteStatus, ComponentType)
    │   ├── repository/
    │   │   ├── UserRepository.java
    │   │   ├── SiteRepository.java
    │   │   ├── PageRepository.java
    │   │   └── ComponentRepository.java
    │   ├── dto/
    │   │   ├── RegisterRequest.java
    │   │   ├── LoginRequest.java
    │   │   ├── RefreshTokenRequest.java
    │   │   ├── AuthResponse.java         # JWT tokens + user info
    │   │   ├── SiteRequest.java
    │   │   ├── SiteResponse.java
    │   │   ├── PageRequest.java
    │   │   └── PageResponse.java
    │   ├── service/
    │   │   ├── AuthService.java          # Register, login, token refresh
    │   │   ├── OAuth2UserService.java    # Maps Google/GitHub user info to User entity
    │   │   └── OAuth2SuccessHandler.java # Redirects with JWT after OAuth login
    │   └── controller/
    │       ├── AuthController.java       # POST /api/auth/register, /login, /refresh, /logout
    │       ├── SiteController.java       # CRUD /api/sites
    │       └── PageController.java       # CRUD /api/sites/{siteId}/pages
    └── resources/
        └── application.yml              # All configuration

frontend/
├── proxy.conf.json                      # Dev proxy to backend
├── angular.json                         # Angular CLI configuration
├── tailwind.config.js                   # Tailwind CSS configuration
├── package.json
└── src/
    ├── index.html
    ├── styles.css                       # Global styles + Tailwind imports
    └── app/
        ├── app.component.ts             # Root component
        ├── app.config.ts                # App providers
        ├── app.routes.ts                # Lazy-loaded routes
        ├── core/
        │   ├── models/
        │   │   ├── auth-response.ts     # AuthResponse & UserInfo interfaces
        │   │   ├── site.ts              # SiteResponse interface
        │   │   └── page.ts              # PageResponse interface
        │   ├── services/
        │   │   ├── auth.service.ts      # Auth HTTP + token storage
        │   │   ├── site.service.ts      # Site CRUD HTTP
        │   │   └── page.service.ts      # Page CRUD HTTP
        │   ├── guards/
        │   │   └── auth.guard.ts        # Route guard (redirects to /login)
        │   └── interceptors/
        │       └── jwt.interceptor.ts   # Attaches Bearer token
        ├── auth/
        │   ├── login/
        │   │   └── login.component.ts   # Email/password login form
        │   ├── register/
        │   │   └── register.component.ts # Name/email/password register form
        │   └── oauth-callback/
        │       └── oauth-callback.component.ts # Reads tokens from OAuth redirect
        └── dashboard/
            ├── dashboard.component.ts   # Site cards grid + toolbar
            ├── create-site-dialog/
            │   └── create-site-dialog.ts # Create site dialog
            └── delete-site-dialog/
                └── delete-site-dialog.ts # Confirm delete dialog

API Overview

Authentication (/api/auth)

Method Path Description
POST /api/auth/register Register with email + password
POST /api/auth/login Login with email + password
POST /api/auth/refresh Refresh access token
POST /api/auth/logout Logout
GET /oauth2/authorization/google Login with Google
GET /oauth2/authorization/github Login with GitHub

Sites (/api/sites)

Method Path Description
GET /api/sites List user's sites
POST /api/sites Create a new site
GET /api/sites/{id} Get site details
PUT /api/sites/{id} Update site
DELETE /api/sites/{id} Delete site

Pages (/api/sites/{siteId}/pages)

Method Path Description
GET /api/sites/{siteId}/pages List pages for a site
POST /api/sites/{siteId}/pages Create a new page
GET /api/sites/{siteId}/pages/{pageId} Get page details
PUT /api/sites/{siteId}/pages/{pageId} Update page
DELETE /api/sites/{siteId}/pages/{pageId} Delete page

Tech Stack

Layer Technology
Backend Java 17, Spring Boot 3.2, Gradle
Frontend Angular 17, Angular Material, Tailwind CSS
Relational DB PostgreSQL 16
Document DB MongoDB 7
Object Storage MinIO (dev) / Cloudflare R2 (prod)
Auth Spring Security + OAuth2 Client + JWT (RS256)
Git JGit
API Docs Springdoc OpenAPI (Swagger UI)

Development

# Backend
cd backend
./gradlew build         # Build
./gradlew test          # Run tests
./gradlew bootRun       # Run locally (requires docker compose up -d first)

# Frontend
cd frontend
npm install             # Install dependencies
ng serve                # Dev server at localhost:4200
ng build                # Production build

Build Status

v0.1 — Auth & Foundation

  • User registration (email/password)
  • User login (email/password + JWT)
  • OAuth2 login (Google, GitHub) with JWT redirect
  • Token refresh with 7-day refresh token
  • Site CRUD (create, list, get, update, delete)
  • Page CRUD within a site
  • Frontend: Login, Register, OAuth callback pages
  • Frontend: Dashboard with site cards, create/delete dialogs
  • Frontend: JWT interceptor, auth guard, lazy routes