feat: add OAuth 2.0 login UI (Google, Yandex, Discord, VK)

- Add OAuthProvider type and extend User.auth_type union
- Add OAuth API methods (providers, authorize, callback)
- Add loginWithOAuth to auth store
- Create OAuthCallback page with state validation
- Create OAuthProviderIcon component with brand SVGs
- Add OAuth buttons to Login page between Telegram and Email
- Add OAuth callback route to App.tsx
- Add translations for ru, en, zh, fa
This commit is contained in:
Fringg
2026-02-07 01:59:05 +03:00
parent af25e6a1b8
commit 83aeae81b8
12 changed files with 329 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
import apiClient from './client';
import type { AuthResponse, RegisterResponse, TokenResponse, User } from '../types';
import type { AuthResponse, OAuthProvider, RegisterResponse, TokenResponse, User } from '../types';
export const authApi = {
// Telegram WebApp authentication
@@ -124,4 +124,31 @@ export const authApi = {
});
return response.data;
},
// OAuth: get enabled providers
getOAuthProviders: async (): Promise<{ providers: OAuthProvider[] }> => {
const response = await apiClient.get<{ providers: OAuthProvider[] }>(
'/cabinet/auth/oauth/providers',
);
return response.data;
},
// OAuth: get authorization URL
getOAuthAuthorizeUrl: async (
provider: string,
): Promise<{ authorize_url: string; state: string }> => {
const response = await apiClient.get<{ authorize_url: string; state: string }>(
`/cabinet/auth/oauth/${provider}/authorize`,
);
return response.data;
},
// OAuth: callback (exchange code for tokens)
oauthCallback: async (provider: string, code: string, state: string): Promise<AuthResponse> => {
const response = await apiClient.post<AuthResponse>(
`/cabinet/auth/oauth/${provider}/callback`,
{ code, state },
);
return response.data;
},
};

View File

@@ -74,6 +74,7 @@ const AUTH_ENDPOINTS = [
'/cabinet/auth/refresh',
'/cabinet/auth/password/forgot',
'/cabinet/auth/password/reset',
'/cabinet/auth/oauth/',
];
function isAuthEndpoint(url: string | undefined): boolean {