From ed9850c96f4dc7f2c10152bfbba8a24e07644547 Mon Sep 17 00:00:00 2001 From: shop Date: Sun, 17 May 2026 13:41:16 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=B7=D0=B0?= =?UTF-8?q?=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=B0=D0=B4=D0=BC=D0=B8?= =?UTF-8?q?=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=BE=D1=80=20(ADMIN?= =?UTF-8?q?=5FEMAIL)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .env.example | 3 ++- README.md | 12 +++++++++++- src/public/css/style.css | 9 +++++++++ src/seed-admin.js | 13 +++++++++++-- src/views/admin/users.ejs | 5 +++++ wiki/Home.md | 9 +++++++++ 6 files changed, 47 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index ff03510..d362411 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,8 @@ NODE_ENV=production TRUST_PROXY=1 SESSION_SECRET=change-me-to-a-long-random-string -# Первый администратор (создаётся при старте, если email не занят) +# Единственный администратор (зарегистрированный пользователь с этим email) +# При регистрации через сайт все получают роль customer; admin — только этот аккаунт ADMIN_EMAIL=admin@site.com ADMIN_PASSWORD=admin ADMIN_NAME=Администратор diff --git a/README.md b/README.md index 5e8e35e..1cf33cf 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ - Корзина и оформление заказа - Регистрация, вход (пароль или passkey), сброс пароля по email - Личный кабинет: профиль, бронирования -- Роли клиент / администратор, админ-панель +- Роли: клиент (`customer`) и **один** администратор (`admin`) — аккаунт из `ADMIN_EMAIL` в `.env` - Согласие на cookies - Подписка «сообщить о поступлении», если товара нет в наличии @@ -158,6 +158,16 @@ DATABASE_URL=postgresql://shop:shop@127.0.0.1:5432/shop | `DATABASE_URL` | Строка подключения PostgreSQL | | `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE` | Альтернатива `DATABASE_URL` | | `HOST` | `127.0.0.1` в production (доступ через Caddy) | +| `ADMIN_EMAIL` | Email **единственного** администратора (создаётся/обновляется при старте) | +| `ADMIN_PASSWORD` | Пароль администратора (только при первом создании аккаунта) | +| `ADMIN_NAME` | Имя администратора | + +### Роли и администратор + +- Через **регистрацию** на сайте все пользователи получают роль **клиент** (`customer`). +- **Один** зарегистрированный пользователь — **администратор**: аккаунт с email из `ADMIN_EMAIL` (по умолчанию `admin@site.com`). При старте приложения он создаётся, если ещё нет, или ему назначается роль `admin`. +- Админ-панель: `/admin` (кнопка в шапке и в личном кабинете — только у администратора). +- Сменить администратора: укажите другой email в `ADMIN_EMAIL` и перезапустите shop (прежние admin-аккаунты станут клиентами). --- diff --git a/src/public/css/style.css b/src/public/css/style.css index 79c3813..2cc78a6 100644 --- a/src/public/css/style.css +++ b/src/public/css/style.css @@ -685,6 +685,15 @@ a:hover { margin-top: 1.25rem; } +.admin-hint { + margin: 0 0 1rem; + font-size: 0.9rem; +} + +.admin-hint code { + font-size: 0.85em; +} + .admin-header { margin-bottom: 1.5rem; } diff --git a/src/seed-admin.js b/src/seed-admin.js index f2c47ff..7d273ef 100644 --- a/src/seed-admin.js +++ b/src/seed-admin.js @@ -7,6 +7,15 @@ async function seedAdmin() { const password = process.env.ADMIN_PASSWORD || 'admin'; const name = process.env.ADMIN_NAME || 'Администратор'; + // Только один администратор — пользователь с ADMIN_EMAIL (остальные customer) + const { rowCount: demoted } = await query( + `UPDATE users SET role = $1 WHERE role = $2 AND email != $3`, + [ROLES.CUSTOMER, ROLES.ADMIN, email] + ); + if (demoted > 0) { + console.log('Снята роль admin у', demoted, 'пользоват(елей) — админ только:', email); + } + const { rows } = await query('SELECT id, role FROM users WHERE email = $1', [email]); if (!rows[0]) { @@ -16,13 +25,13 @@ async function seedAdmin() { VALUES ($1, $2, $3, $4)`, [email, hash, name, ROLES.ADMIN] ); - console.log('Создан администратор:', email); + console.log('Создан администратор (единственный):', email); return; } if (rows[0].role !== ROLES.ADMIN) { await query('UPDATE users SET role = $1 WHERE id = $2', [ROLES.ADMIN, rows[0].id]); - console.log('Пользователю назначена роль admin:', email); + console.log('Назначен единственный администратор:', email); } } diff --git a/src/views/admin/users.ejs b/src/views/admin/users.ejs index 512e9cf..384ca23 100644 --- a/src/views/admin/users.ejs +++ b/src/views/admin/users.ejs @@ -12,6 +12,11 @@ +

+ Один администратор — зарегистрированный пользователь с email из ADMIN_EMAIL в .env. + Остальные при регистрации получают роль «Клиент». +

+ diff --git a/wiki/Home.md b/wiki/Home.md index 5547bf0..9fde205 100644 --- a/wiki/Home.md +++ b/wiki/Home.md @@ -16,6 +16,15 @@ **Без Docker:** Ubuntu 22.04 / 24.04, Node.js 20, PostgreSQL 17. +## Роли + +| Роль | Кто | +|------|-----| +| **customer** | Все, кто регистрируется через сайт | +| **admin** | **Один** пользователь — email из `ADMIN_EMAIL` в `.env` (по умолчанию `admin@site.com` / пароль `admin`) | + +Админ-панель доступна только этому аккаунту. + ## Быстрый старт ### Docker