From cd7e279bb659c7af2c5be41be883ef15566da3dd Mon Sep 17 00:00:00 2001 From: estorozhenko Date: Mon, 7 Sep 2026 05:48:46 +0000 Subject: [PATCH] feat(registration): open signups, 10/day limit; openspec: fix-apex-webfinger-and-registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docker-compose.yml: GTS_ACCOUNTS_REGISTRATION_OPEN=true, GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT=10 - openspec: proposal/specs/design/tasks for dynamic apex webfinger + registration + SMTP verify - verified: /api/v1/instance → registrations:true; apex webfinger → acct:kpa39l@dedinit.ru; SMTP test OK --- docker-compose.yml | 3 + .../.openspec.yaml | 2 + .../design.md | 51 ++++++++++++ .../proposal.md | 80 +++++++++++++++++++ .../webfinger-and-registration/spec.md | 52 ++++++++++++ .../tasks.md | 39 +++++++++ 6 files changed, 227 insertions(+) create mode 100644 openspec/changes/fix-apex-webfinger-and-registration/.openspec.yaml create mode 100644 openspec/changes/fix-apex-webfinger-and-registration/design.md create mode 100644 openspec/changes/fix-apex-webfinger-and-registration/proposal.md create mode 100644 openspec/changes/fix-apex-webfinger-and-registration/specs/gotosocial/webfinger-and-registration/spec.md create mode 100644 openspec/changes/fix-apex-webfinger-and-registration/tasks.md diff --git a/docker-compose.yml b/docker-compose.yml index 85b8d42..711182f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,6 +30,9 @@ services: GTS_INSTANCE_TITLE: "dedinit()" GTS_INSTANCE_DESCRIPTION: "Нода для обычных людей" GTS_INSTANCE_CONTACT_EMAIL: "kpa39l@yandex.ru" + # Регистрация открыта: 10 новых аккаунтов в сутки (лимит очереди одобрения — дефолт 20) + GTS_ACCOUNTS_REGISTRATION_OPEN: "true" + GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT: "10" # SMTP (Jino) — пароль из .env (GTS_SMTP_PASSWORD) GTS_SMTP_HOST: "smtp.jino.ru" GTS_SMTP_PORT: "587" diff --git a/openspec/changes/fix-apex-webfinger-and-registration/.openspec.yaml b/openspec/changes/fix-apex-webfinger-and-registration/.openspec.yaml new file mode 100644 index 0000000..2e24cfa --- /dev/null +++ b/openspec/changes/fix-apex-webfinger-and-registration/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-09-07 diff --git a/openspec/changes/fix-apex-webfinger-and-registration/design.md b/openspec/changes/fix-apex-webfinger-and-registration/design.md new file mode 100644 index 0000000..9078b16 --- /dev/null +++ b/openspec/changes/fix-apex-webfinger-and-registration/design.md @@ -0,0 +1,51 @@ +## Goals + +1. Восстановить короткий адрес `@kpa39l@dedinit.ru` в клиентах (Tusky/Mastodon). +2. Открыть регистрацию с лимитом 10 пользователей/день. +3. Убедиться, что SMTP работает (для писем подтверждения). + +## Non-Goals + +- Не меняем DNS (apex остаётся на Jino). +- Не меняем split-domain схему (host=social.dedinit.ru, account-domain=dedinit.ru). +- Не вводим PHP/мод_rewrite (недоступны на Jino). +- Не открываем регистрацию без лимита. + +## Architecture + +### Топология + +``` +Клиент (Tusky/Mastodon) + │ резолв @kpa39l@dedinit.ru + ▼ +dedinit.ru (apex, Jino/Apache) + │ /.well-known/webfinger?resource=acct:kpa39l@dedinit.ru + ▼ RedirectMatch 301 (mod_alias, .htaccess) +social.dedinit.ru (GtS, vps02→WG→bigbox→docker) + │ /.well-known/webfinger?resource=... + ▼ динамический JSON: subject=acct:kpa39l@dedinit.ru +``` + +### Регистрация + +`docker-compose.yml` env: +- `GTS_ACCOUNTS_REGISTRATION_OPEN=true` +- `GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT=10` + +approval_required=true (GtS по умолчанию): админ одобряет заявки. +Очередь одобрения: дефолт GtS (20) — при 10/день хватает. + +## Risks / Open Questions + +- **Tusky может кэшировать старый адрес**: после фикса apex-WebFinger нужно + перезайти/переподписаться в клиенте (или переустановить) — клиентский кэш + сам не сбросится. Это документируется, но не решается серверно. +- **`.htaccess` и rsync --delete**: деплой hugo (make deploy) использует + `rsync --delete public/`. `.htaccess` в `static/.well-known/` копируется в + `public/` и не затирается (файлы в public/ соответствуют static/, но + --delete удаляет только лишнее). Проверено: .htaccess в static/ → + public/.well-known/webfinger/.htaccess. +- Jino: `RedirectMatch` (mod_alias) работает; **mod_rewrite не работает** — + НЕ использовать RewriteRule. +- Статический index.html в webfinger УДАЛЁН — не восстанавливать. \ No newline at end of file diff --git a/openspec/changes/fix-apex-webfinger-and-registration/proposal.md b/openspec/changes/fix-apex-webfinger-and-registration/proposal.md new file mode 100644 index 0000000..1df5a0d --- /dev/null +++ b/openspec/changes/fix-apex-webfinger-and-registration/proposal.md @@ -0,0 +1,80 @@ +## Why + +Пользователь обнаружил, что в клиентах Tusky и Mastodon адрес его аккаунта +отображается как `@kpa39l@social.dedinit.ru` (длинный), хотя ожидался короткий +`@kpa39l@dedinit.ru`. Дополнительно: в феде виден только свой пост, и нужно +открыть регистрацию на инстансе (до 10 пользователей в день). + +## Investigation + +Разбор показал: + +1. **Корень проблемы с адресом** — статический WebFinger на apex-домене: + - Инстанс (GtS) настроен split-domain: host=`social.dedinit.ru`, + account-domain=`dedinit.ru`. Сам GtS отдаёт корректный webfinger: + `https://social.dedinit.ru/.well-known/webfinger?resource=acct:kpa39l@dedinit.ru` + → `subject: acct:kpa39l@dedinit.ru` (короткий). + - Но клиенты (Tusky/Mastodon) при резолве `@kpa39l@dedinit.ru` ходят на + **apex** `dedinit.ru/.well-known/webfinger`, где лежал **статический** + `index.html` с захардкоженным JSON про `estorozhenko` (игнорировал + `resource`). Клиент получал ответ про другого пользователя → показывал + фолбэк-адрес на основе host (`social.dedinit.ru`). +2. **Регистрация** была закрыта: `/api/v1/instance` → `registrations: false`, + `approval_required: true`. +3. **SMTP** настроен (smtp.jino.ru:587, social@dedinit.ru), но не проверялся. + +## Solution + +### 1. Динамический WebFinger на apex (Jino) + +Apex обслуживается на Jino (Apache, без PHP/SSH-exec). Проверено: **mod_alias +`RedirectMatch` работает**. В `.htaccess` (webroot `/.well-known/webfinger/`) +добавлен редирект: + +``` +RedirectMatch 301 ^/\.well-known/webfinger(.*)$ https://social.dedinit.ru/.well-known/webfinger$1 +``` + +Теперь `dedinit.ru/.well-known/webfinger?resource=...` отдаёт 301 на GtS, +который динамически резолвит ЛЮБОЙ аккаунт (включая будущих пользователей) — +короткий адрес `@user@dedinit.ru` восстанавливается для всех клиентов. + +Аналогичный редирект добавлен для `/.well-known/nodeinfo`. + +`host-meta` на apex уже указывал на template `social.dedinit.ru/.well-known/webfinger` +— оставлен. + +### 2. Регистрация (10 пользователей/день) + +В `docker compose.yml` (env GTS_*): + +- `GTS_ACCOUNTS_REGISTRATION_OPEN: "true"` +- `GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT: "10"` +- `GTS_ACCOUNTS_REGISTRATION_BACKLOG_LIMIT`: не задан → дефолт 20 (очередь + одобрения). При желании можно поставить явно. + +`approval_required` остаётся `true` (GtS по умолчанию требует одобрение админом +новых аккаунтов; при лимите 10/день очередь управляема). + +### 3. Проверка SMTP + +SMTP-конфиг проверен тестовым письмом: smtp.jino.ru:587 STARTTLS, +auth social@dedinit.ru → письмо успешно отправлено на kpa39l@yandex.ru. +SMTP работает, проблем нет. + +## Files Changed + +- `docker-compose.yml` (gotosocial): +2 env registration +- `static/.well-known/webfinger/.htaccess` (dedinit.ru): RedirectMatch 301 +- `static/.well-known/nodeinfo/.htaccess` (dedinit.ru): RedirectMatch 301 +- Jino webroot: удалён статический `index.html` из `/.well-known/webfinger/` + (заменён .htaccess-редиректом) + +## Verification + +- `curl -L 'https://dedinit.ru/.well-known/webfinger?resource=acct:kpa39l@dedinit.ru'` + → `subject: acct:kpa39l@dedinit.ru` (короткий) +- `curl -L 'https://dedinit.ru/.well-known/webfinger?resource=acct:estorozhenko@dedinit.ru'` + → `subject: acct:estorozhenko@dedinit.ru` +- `curl 'https://social.dedinit.ru/api/v1/instance'` → `registrations: true` +- SMTP-тест: OK \ No newline at end of file diff --git a/openspec/changes/fix-apex-webfinger-and-registration/specs/gotosocial/webfinger-and-registration/spec.md b/openspec/changes/fix-apex-webfinger-and-registration/specs/gotosocial/webfinger-and-registration/spec.md new file mode 100644 index 0000000..f5a4e61 --- /dev/null +++ b/openspec/changes/fix-apex-webfinger-and-registration/specs/gotosocial/webfinger-and-registration/spec.md @@ -0,0 +1,52 @@ +## Why + +Клиенты отображают длинный адрес `@user@social.dedinit.ru` вместо короткого +`@user@dedinit.ru`, потому что apex-WebFinger был статическим. Нужно открыть +регистрацию с суточным лимитом. + +## ADDED Requirements + +### Requirement: Apex WebFinger резолвит любой аккаунт + +- **MUST**: `https://dedinit.ru/.well-known/webfinger?resource=acct:USER@dedinit.ru` + возвращает (после 301) JSON от GtS с `subject: acct:USER@dedinit.ru` для + любого существующего локального пользователя, а не статический ответ + с захардкоженным пользователем. +- **MUST**: редирект реализован через `mod_alias RedirectMatch` в `.htaccess` + (Apache на Jino; mod_rewrite/PHP недоступны). +- **SHOULD**: `/.well-known/nodeinfo` на apex также редиректит на GtS. + +#### Scenario: Резолв короткого адреса клиентом + +- **GIVEN** локальный пользователь `kpa39l` на инстансе social.dedinit.ru + (account-domain dedinit.ru) +- **WHEN** клиент запрашивает `dedinit.ru/.well-known/webfinger?resource=acct:kpa39l@dedinit.ru` +- **THEN** ответ (после 301) содержит `subject: acct:kpa39l@dedinit.ru` + и aliases/links на `social.dedinit.ru/users/kpa39l` +- **THEN** Tusky/Mastodon отображают короткий `@kpa39l@dedinit.ru` + +### Requirement: Регистрация открыта с лимитом 10/день + +- **MUST**: `GTS_ACCOUNTS_REGISTRATION_OPEN=true` — страница `/signup` доступна, + `/api/v1/instance` → `registrations: true`. +- **MUST**: `GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT=10` — максимум 10 + зарегистрированных/одобренных аккаунтов за 24 часа. +- **SHOULD**: SMTP работает (письма подтверждения/уведомления доставляются). + +#### Scenario: Регистрация нового пользователя + +- **GIVEN** инстанс с открытой регистрацией +- **WHEN** пользователь открывает `https://social.dedinit.ru/signup` и заполняет форму +- **THEN** заявка создаётся, попадает в очередь одобрения (approval_required) +- **THEN** при превышении 10 заявок за 24ч регистрация временно закрывается + +### Requirement: SMTP-доставка писем + +- **MUST**: SMTP (smtp.jino.ru:587 STARTTLS, social@dedinit.ru) отправляет + тестовое письмо без ошибок. + +#### Scenario: Отправка тестового письма + +- **GIVEN** SMTP-конфиг в docker-compose.yml + пароль в .env +- **WHEN** отправляется письмо на kpa39l@yandex.ru +- **THEN** сервер SMTP принимает сообщение (250), письмо доставляется \ No newline at end of file diff --git a/openspec/changes/fix-apex-webfinger-and-registration/tasks.md b/openspec/changes/fix-apex-webfinger-and-registration/tasks.md new file mode 100644 index 0000000..1a04fea --- /dev/null +++ b/openspec/changes/fix-apex-webfinger-and-registration/tasks.md @@ -0,0 +1,39 @@ +## Context + +- Инстанс: social.dedinit.ru (GtS 0.22.1, docker на bigbox), account-domain dedinit.ru. +- Apex: dedinit.ru (Jino/Apache, доступ SFTP kpa39l.myjino.ru:2222). +- GtS конфигурируется ТОЛЬКО через GTS_* env (config.yaml не подхватывается). + +## Tasks + +### 1. Apex WebFinger → динамический + +- [x] 1.1 Создать `static/.well-known/webfinger/.htaccess` в репо dedinit.ru: + `RedirectMatch 301 ^/\.well-known/webfinger(.*)$ https://social.dedinit.ru/.well-known/webfinger$1` +- [x] 1.2 Залить .htaccess на Jino (`/dedinit.ru/.well-known/webfinger/.htaccess`) через SFTP +- [x] 1.3 Удалить статический `index.html` из `/dedinit.ru/.well-known/webfinger/` +- [x] 1.4 Проверить: `curl -L 'https://dedinit.ru/.well-known/webfinger?resource=acct:kpa39l@dedinit.ru'` + → `subject: acct:kpa39l@dedinit.ru` + +### 2. Nodeinfo apex → динамический + +- [x] 2.1 Создать `static/.well-known/nodeinfo/.htaccess` (RedirectMatch 301 на social) +- [x] 2.2 Залить на Jino, проверить `curl -L 'https://dedinit.ru/.well-known/nodeinfo'` + +### 3. Регистрация (10/день) + +- [x] 3.1 В `docker-compose.yml`: `GTS_ACCOUNTS_REGISTRATION_OPEN=true`, + `GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT=10` +- [x] 3.2 `docker compose up -d gotosocial` (recreate) +- [x] 3.3 Проверить `/api/v1/instance` → `registrations: true`; env в контейнере + +### 4. SMTP + +- [x] 4.1 Тестовое письмо через smtplib (smtp.jino.ru:587 STARTTLS, social@dedinit.ru) + на kpa39l@yandex.ru — доставлено + +### 5. Финализация OpenSpec + +- [x] 5.1 Валидация change: `openspec validate fix-apex-webfinger-and-registration` +- [ ] 5.2 Коммит + пуш docker-compose.yml (gotosocial) и .htaccess (dedinit.ru) +- [ ] 5.3 Архив change (`openspec archive`) \ No newline at end of file