feat(auth): вход через OAuth-провайдеры (GitHub, Google, Discord)

Фаза 7, AGENT.md 7.1: провайдеры включаются переменными окружения
OAUTH_<PROVIDER>_CLIENT_ID/SECRET, привязка внешнего аккаунта идёт по
подтверждённому провайдером email через blind index, вход забаненному на
инстансе запрещён, все входы и привязки попадают в события безопасности,
привязка — ещё и в аудит инстанса.

Внешний идентификатор (subject) хранится только индексом HMAC-SHA-256,
токены провайдеров не сохраняются вовсе; state подписывается ключом сессий
и ограничен по времени, редирект после входа — только внутренний путь.
Если провайдер не настроен, ручка отвечает oauth.provider_not_configured,
а клиент показывает человеческий текст вместо кнопки.

Клиент: кнопки входа по списку включённых провайдеров на экране входа и
раздел «Вход через внешние сервисы» в настройках безопасности; адрес
возврата для настроек приложения виден в GET /auth/oauth/providers.

Миграция 00019 добавляет таблицу oauth_accounts. Установщик и .env.example
знают про OAUTH_* и сохраняют значения при --reconfigure.

Тесты: Go — выключенный провайдер, подписанный state (подмена и чужой
провайдер), создание и повторный вход, привязка к существующему аккаунту,
неподтверждённый email, выключенная регистрация, бан инстанса, mocked
провайдер (httptest) для обмена кода; web — кнопки провайдеров и ошибка
возврата; серверная ручка отдаёт понятный отказ без настроек.
This commit is contained in:
2026-09-26 15:13:24 +03:00
parent cd1d662572
commit cebce0ae3b
23 changed files with 1721 additions and 12 deletions
+1
View File
@@ -37,6 +37,7 @@ Copyright (C) 2026 glchat contributors.
| [i18next](https://www.i18next.com) | MIT | Локализация ru/en |
| [age](https://age-encryption.org) (filippo.io/age) | BSD-3-Clause | Шифрование бэкапов |
| [go-webauthn/webauthn](https://github.com/go-webauthn/webauthn) | BSD-3-Clause | Passkeys (WebAuthn): регистрация и вход по ключу (Фаза 7) |
| [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) | BSD-3-Clause | OAuth2-провайдеры входа: GitHub, Google, Discord (Фаза 7) |
| [fxamacker/cbor](https://github.com/fxamacker/cbor) | MIT | CBOR для WebAuthn (транзитивная зависимость go-webauthn) |
Полный список Go-зависимостей с версиями — `go.mod`/`go.sum`; JS-зависимостей —