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:
@@ -22,7 +22,6 @@ const meta: InstanceMeta = {
|
||||
web_push_enabled: false,
|
||||
unfurl_enabled: false,
|
||||
passkeys_enabled: false,
|
||||
oauth_enabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -310,13 +310,11 @@ const metaWithPasskeys = {
|
||||
voice_enabled: false,
|
||||
web_push_enabled: false,
|
||||
unfurl_enabled: false,
|
||||
oauth_enabled: true,
|
||||
passkeys_enabled: true,
|
||||
oauth_providers: ['github'],
|
||||
},
|
||||
};
|
||||
|
||||
describe('страница входа: ключи и внешние провайдеры', () => {
|
||||
describe('страница входа: ключи доступа', () => {
|
||||
it('входит по ключу и переводит в приложение', async () => {
|
||||
const assertion = {
|
||||
id: 'credential-id',
|
||||
@@ -359,11 +357,6 @@ describe('страница входа: ключи и внешние провай
|
||||
method: 'POST',
|
||||
response: () => json({ user }),
|
||||
},
|
||||
{
|
||||
match: '/api/v1/auth/oauth/providers',
|
||||
response: () =>
|
||||
json({ providers: [{ id: 'github', name: 'GitHub' }], redirect_url: 'https://x' }),
|
||||
},
|
||||
{ match: '/api/v1/users/@me', response: () => json({ user }) },
|
||||
{ match: '/api/v1/users/@me/guilds', response: () => json({ guilds: [] }) },
|
||||
]);
|
||||
@@ -371,8 +364,6 @@ describe('страница входа: ключи и внешние провай
|
||||
const { router } = renderApp('/login');
|
||||
const visitor = userEvent.setup();
|
||||
|
||||
// Кнопка внешнего провайдера нарисована по списку с сервера.
|
||||
expect(await screen.findByTestId('oauth-github')).toBeVisible();
|
||||
await visitor.click(await screen.findByTestId('passkey-login'));
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -382,39 +373,11 @@ describe('страница входа: ключи и внешние провай
|
||||
expect((finish?.body as { ceremony: string }).ceremony).toBe('ceremony-login');
|
||||
});
|
||||
|
||||
it('ошибка возврата от провайдера показывается на странице входа', async () => {
|
||||
installFetch([
|
||||
{
|
||||
match: '/api/v1/meta',
|
||||
response: () =>
|
||||
json({
|
||||
...metaWithPasskeys,
|
||||
features: { ...metaWithPasskeys.features, passkeys_enabled: false },
|
||||
}),
|
||||
},
|
||||
{ match: '/api/v1/instance', response: () => json({ instance: instanceOpen }) },
|
||||
{
|
||||
match: '/api/v1/auth/oauth/providers',
|
||||
response: () => json({ providers: [], redirect_url: 'https://x' }),
|
||||
},
|
||||
]);
|
||||
|
||||
renderApp('/login?oauth_error=provider_not_configured');
|
||||
|
||||
expect(await screen.findByTestId('oauth-error')).toHaveTextContent(
|
||||
'Этот способ входа выключен на инстансе',
|
||||
);
|
||||
});
|
||||
|
||||
it('без поддержки браузера кнопка входа по ключу не показывается', async () => {
|
||||
vi.stubGlobal('PublicKeyCredential', undefined);
|
||||
installFetch([
|
||||
{ match: '/api/v1/meta', response: () => json(metaWithPasskeys) },
|
||||
{ match: '/api/v1/instance', response: () => json({ instance: instanceOpen }) },
|
||||
{
|
||||
match: '/api/v1/auth/oauth/providers',
|
||||
response: () => json({ providers: [], redirect_url: 'https://x' }),
|
||||
},
|
||||
]);
|
||||
|
||||
renderApp('/login');
|
||||
|
||||
@@ -78,7 +78,6 @@ const enabledMeta: InstanceMeta = {
|
||||
web_push_enabled: false,
|
||||
unfurl_enabled: false,
|
||||
passkeys_enabled: false,
|
||||
oauth_enabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user