refactor: убрать вход через внешние провайдеры (OAuth) полностью
Решение владельца 27.09.2026 (D-084): сервис ставится на сервер конкретного человека, и ему всё равно нужен свой OAuth у провайдера — поддержка общего входа только создаёт трение (регистрация приложений, redirect URI, модерация, чужие ключи в конфиге). Способы входа остаются: пароль + 2FA и ключи доступа (WebAuthn). Удалено: - сервер: internal/auth/oauth.go, internal/server/oauth.go, internal/store/oauth.go и их тесты; поля и методы конфига OAuth*; oauthLimiter и регистрация ручек; отображение ошибок oauth.*; features.oauth_enabled/oauth_providers в /meta; - клиент: web/src/api/oauth.ts, раздел «Вход через внешние сервисы», кнопки провайдеров на странице входа, ключи i18n (ru/en), тесты и фикстуры; - установщик: переменные OAUTH_* из .env, .env.example и шаблона (хелпер чтения существующих значений переименован в existing_value — он остался нужен для VAPID_SUBJECT); - зависимость golang.org/x/oauth2 (go mod tidy). Схема: миграция 00027 удаляет таблицу oauth_accounts (00019 не переписываем — она применена на стендах). Откат миграции возвращает структуру; тест TestOAuthRemovalMigration проверяет накат, откат и повторный накат. AGENT.md (локальный) помечает пункты про OAuth как отменённые.
This commit is contained in:
@@ -81,25 +81,6 @@ func newAPIError(err error) apiError {
|
||||
case errors.Is(err, auth.ErrPasskeyLimit):
|
||||
candidate.Status, candidate.Code = http.StatusConflict, "auth.passkey_limit"
|
||||
candidate.Message = "passkey limit reached for this account"
|
||||
// OAuth-провайдеры (Фаза 7).
|
||||
case errors.Is(err, auth.ErrOAuthNotConfigured):
|
||||
candidate.Status, candidate.Code = http.StatusNotFound, "oauth.provider_not_configured"
|
||||
candidate.Message = "oauth provider is not configured on this instance"
|
||||
case errors.Is(err, auth.ErrOAuthUnknownProvider):
|
||||
candidate.Status, candidate.Code = http.StatusNotFound, "oauth.provider_unknown"
|
||||
candidate.Message = "unknown oauth provider"
|
||||
case errors.Is(err, auth.ErrOAuthState):
|
||||
candidate.Status, candidate.Code = http.StatusBadRequest, "oauth.state_invalid"
|
||||
candidate.Message = "oauth state is invalid or expired"
|
||||
case errors.Is(err, auth.ErrOAuthEmailUnverified):
|
||||
candidate.Status, candidate.Code = http.StatusForbidden, "oauth.email_unverified"
|
||||
candidate.Message = "provider did not confirm the email address"
|
||||
case errors.Is(err, auth.ErrOAuthEmailMissing):
|
||||
candidate.Status, candidate.Code = http.StatusForbidden, "oauth.email_missing"
|
||||
candidate.Message = "provider did not return an email address"
|
||||
case errors.Is(err, auth.ErrOAuthExchange):
|
||||
candidate.Status, candidate.Code = http.StatusBadGateway, "oauth.exchange_failed"
|
||||
candidate.Message = "oauth provider rejected the request"
|
||||
case errors.Is(err, store.ErrNotFound):
|
||||
candidate.Status, candidate.Code, candidate.Message = http.StatusNotFound, "not_found", "resource not found"
|
||||
case errors.Is(err, store.ErrConflict):
|
||||
|
||||
Reference in New Issue
Block a user