first commit

This commit is contained in:
Дмитрий Мамедов
2026-06-10 16:23:41 +03:00
commit f37733a5c9
70 changed files with 16338 additions and 0 deletions

264
README.md Normal file
View File

@@ -0,0 +1,264 @@
# SSO Service
Self-hosted SSO / OIDC-сервис — аналог Keycloak / Яндекс ID. Node.js (NestJS).
## Технологии
- **Runtime:** Node.js 22, NestJS 11
- **Database:** PostgreSQL 16 + Prisma ORM
- **Cache:** Redis 7
- **Message Broker:** RabbitMQ 4
- **Logging:** Pino (JSON, nestjs-pino)
- **Metrics:** Prometheus
- **Security:** Argon2, JWT (Access + Refresh), Helmet, OIDC (authorization_code, PKCE)
- **Templates:** EJS + Bootstrap 5
## Возможности
### Аутентификация
- Логин/пароль (Argon2)
- Вход по коду на email
- Вход по коду на телефон
- QR-авторизация (для мобильного приложения)
- Refresh + rotate токенов
### Веб-панель
- `/login` — страница входа (пароль, код на email, QR)
- `/register` — регистрация
- `/profile` — личный кабинет (редактирование профиля)
- `/admin` — админ-панель:
- Статистика (пользователи, клиенты, сессии)
- CRUD пользователей
- CRUD OAuth-клиентов (как oauth.yandex.ru)
### Роли
- **USER** — только свой профиль
- **ADMIN** — управление пользователями и OAuth-клиентами
### OIDC / OAuth2
- `/authorize` (authorization_code)
- `/token` (authorization_code, refresh_token, client_credentials)
- `/userinfo`
- `/revoke`
- PKCE support
## Быстрый старт
### 1. Инфраструктура
```bash
docker compose up -d
```
### 2. База данных
```bash
npx prisma db push
```
### 3. Тестовые данные
```bash
npx ts-node prisma/seed.ts
```
Создаёт:
- **Admin:** `admin@sso.local` / `admin123!`
- **OAuth Client:** `test-client` (секрет в консоли)
### 4. Запуск
```bash
npm run start:dev
```
Сервис: `http://localhost:3000`
## API Endpoints
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | /api/auth/register | No | Регистрация |
| POST | /api/auth/login | No | Логин (пароль) |
| POST | /api/auth/login/email-code | No | Логин (код на email) |
| POST | /api/auth/login/phone-code | No | Логин (код на телефон) |
| POST | /api/auth/send-email-code | No | Отправить код на email |
| POST | /api/auth/send-phone-code | No | Отправить код на телефон |
| POST | /api/auth/qr/init | No | Создать QR-сессию |
| POST | /api/auth/qr/poll | No | Проверить QR-сессию |
| POST | /api/auth/refresh | No | Обновить токен |
| POST | /api/auth/logout | No | Выйти |
| GET | /api/auth/profile | JWT | Профиль |
| POST | /api/auth/profile/update | JWT | Обновить профиль |
| GET | /api/authorize | No | OAuth2 authorize |
| POST | /api/token | No | OAuth2 token |
| GET | /api/userinfo | Bearer | OIDC userinfo |
| POST | /api/revoke | No | Отозвать токен |
| GET | /api/admin/stats | JWT+ADMIN | Статистика |
| GET | /api/admin/users | JWT+ADMIN | Список пользователей |
| POST | /api/admin/users | JWT+ADMIN | Создать пользователя |
| PUT | /api/admin/users/:id | JWT+ADMIN | Обновить пользователя |
| DELETE | /api/admin/users/:id | JWT+ADMIN | Удалить пользователя |
| GET | /api/admin/clients | JWT+ADMIN | Список OAuth-клиентов |
| POST | /api/admin/clients | JWT+ADMIN | Создать OAuth-клиент |
| PUT | /api/admin/clients/:id | JWT+ADMIN | Обновить OAuth-клиент |
| DELETE | /api/admin/clients/:id | JWT+ADMIN | Удалить OAuth-клиент |
| GET | /metrics | No | Prometheus метрики |
## Веб-панель
| Страница | URL | Доступ |
|----------|-----|--------|
| Логин | /login | Все |
| Регистрация | /register | Все |
| Профиль | /profile | Авторизованные |
| Админка (пользователи) | /admin | ADMIN |
| Админка (клиенты) | /admin/clients | ADMIN |
## Примеры cURL
### Регистрация
```bash
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"secret1234","displayName":"Test"}'
```
### Логин по паролю
```bash
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"secret1234"}'
```
### Логин по коду на email
```bash
# Шаг 1: запросить код
curl -X POST http://localhost:3000/api/auth/send-email-code \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com"}'
# Шаг 2: войти с кодом
curl -X POST http://localhost:3000/api/auth/login/email-code \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","code":"123456"}'
```
### QR-авторизация
```bash
# Инициализация
curl -X POST http://localhost:3000/api/auth/qr/init
# Проверка статуса
curl -X POST http://localhost:3000/api/auth/qr/poll \
-H "Content-Type: application/json" \
-d '{"sessionId":"<sessionId>"}'
```
### Админка (список пользователей)
```bash
curl http://localhost:3000/api/admin/users \
-H "Authorization: Bearer <admin_token>"
```
### Метрики
```bash
curl http://localhost:3000/metrics
```
### RabbitMQ Management
```
http://localhost:15672
Login: sso / sso_secret
```
## Переменные окружения
Скопируйте `.env.example` в `.env`:
```bash
cp .env.example .env
```
Все переменные строго валидируются (Zod). Fast Fail.
## Быстрая установка одной командой
```bash
curl -fsSL https://github.com/ssomvk/sso-service/raw/main/install.sh | bash
```
Скрипт автоматически:
1. Проверяет Node.js, Docker, Docker Compose
2. Скачивает проект в `~/sso-service`
3. Создаёт `.env` со случайными JWT-секретами
4. Запускает PostgreSQL, Redis, RabbitMQ через Docker
5. Устанавливает зависимости, применяет миграции, сидирует БД
6. Собирает и запускает сервис
После установки:
- **Веб-панель:** http://localhost:3000
- **Админ:** `admin@sso.local` / `admin123!`
- **Метрики:** http://localhost:3000/metrics
- **RabbitMQ UI:** http://localhost:15672 (`sso` / `sso_secret`)
### Переменные окружения (опционально)
```bash
INSTALL_DIR=/opt/sso curl -fsSL https://github.com/ssomvk/sso-service/raw/main/install.sh | bash
```
## Ручная установка
```bash
# 1. Клонировать
git clone https://github.com/ssomvk/sso-service.git
cd sso-service
# 2. Настроить окружение
cp .env.example .env
# Отредактировать .env под себя
# 3. Запустить инфраструктуру
docker compose up -d
# 4. Установить зависимости и применить миграции
npm ci
npx prisma generate
npx prisma db push
npx ts-node prisma/seed.ts
# 5. Собрать и запустить
npm run build
node dist/main
```
## Production-деплой
```bash
npm run build
node dist/main
```
Корректно обрабатывает X-Forwarded-For (TRUST_PROXY).
## Публикация на GitHub
```bash
# 1. Создать репозиторий на github.com → New repository
# Название: sso-service (или любое другое)
# Visibility: Public
# 2. Инициализировать git и запушить
cd sso-service
git init
git add -A
git commit -m "Initial commit: SSO service (NestJS, Prisma 7, PostgreSQL)"
git branch -M main
git remote add origin https://github.com/ВАШ_ЛОГИН/sso-service.git
git push -u origin main
# 3. Установка с любого сервера:
curl -fsSL https://github.com/ВАШ_ЛОГИН/sso-service/raw/main/install.sh | bash
```
**Важно:** Перед пушем отредактируйте `install.sh` — замените `REPO="ssomvk/sso-service"` на ваш репозиторий (строка 4).