register, login, create and manage sites and pages
This commit is contained in:
233
README.md
Normal file
233
README.md
Normal file
@@ -0,0 +1,233 @@
|
||||
# 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:**
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
2. **Start the backend:**
|
||||
|
||||
```bash
|
||||
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):**
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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 ✅
|
||||
- [x] User registration (email/password)
|
||||
- [x] User login (email/password + JWT)
|
||||
- [x] OAuth2 login (Google, GitHub) with JWT redirect
|
||||
- [x] Token refresh with 7-day refresh token
|
||||
- [x] Site CRUD (create, list, get, update, delete)
|
||||
- [x] Page CRUD within a site
|
||||
- [x] Frontend: Login, Register, OAuth callback pages
|
||||
- [x] Frontend: Dashboard with site cards, create/delete dialogs
|
||||
- [x] Frontend: JWT interceptor, auth guard, lazy routes
|
||||
Reference in New Issue
Block a user