mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
feat: account linking and merge UI for cabinet
Add Connected Accounts page (link/unlink OAuth providers), Link OAuth Callback handler, and Merge Accounts page with subscription comparison and user choice. Includes API methods, TypeScript types, routes in App.tsx, navigation from Profile, and i18n for all 4 locales (ru, en, zh, fa). Merge page works without JWT auth (validated by merge token).
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
import apiClient from './client';
|
||||
import type { AuthResponse, OAuthProvider, RegisterResponse, TokenResponse, User } from '../types';
|
||||
import type {
|
||||
AuthResponse,
|
||||
LinkCallbackResponse,
|
||||
LinkedProvidersResponse,
|
||||
MergePreviewResponse,
|
||||
MergeResponse,
|
||||
OAuthProvider,
|
||||
RegisterResponse,
|
||||
TokenResponse,
|
||||
User,
|
||||
} from '../types';
|
||||
|
||||
export const authApi = {
|
||||
// Telegram WebApp authentication
|
||||
@@ -190,4 +200,64 @@ export const authApi = {
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Account linking
|
||||
getLinkedProviders: async (): Promise<LinkedProvidersResponse> => {
|
||||
const response = await apiClient.get<LinkedProvidersResponse>(
|
||||
'/cabinet/auth/account/linked-providers',
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
linkProviderInit: async (provider: string): Promise<{ authorize_url: string; state: string }> => {
|
||||
const response = await apiClient.get<{ authorize_url: string; state: string }>(
|
||||
`/cabinet/auth/account/link/${encodeURIComponent(provider)}/init`,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
linkProviderCallback: async (
|
||||
provider: string,
|
||||
code: string,
|
||||
state: string,
|
||||
deviceId?: string,
|
||||
): Promise<LinkCallbackResponse> => {
|
||||
const response = await apiClient.post<LinkCallbackResponse>(
|
||||
`/cabinet/auth/account/link/${encodeURIComponent(provider)}/callback`,
|
||||
{
|
||||
code,
|
||||
state,
|
||||
device_id: deviceId,
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
unlinkProvider: async (provider: string): Promise<{ success: boolean }> => {
|
||||
const response = await apiClient.post<{ success: boolean }>(
|
||||
`/cabinet/auth/account/unlink/${encodeURIComponent(provider)}`,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Account merge (no JWT required)
|
||||
getMergePreview: async (mergeToken: string): Promise<MergePreviewResponse> => {
|
||||
const response = await apiClient.get<MergePreviewResponse>(
|
||||
`/cabinet/auth/merge/${encodeURIComponent(mergeToken)}`,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
executeMerge: async (
|
||||
mergeToken: string,
|
||||
keepSubscriptionFrom: number,
|
||||
): Promise<MergeResponse> => {
|
||||
const response = await apiClient.post<MergeResponse>(
|
||||
`/cabinet/auth/merge/${encodeURIComponent(mergeToken)}`,
|
||||
{
|
||||
keep_subscription_from: keepSubscriptionFrom,
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -75,6 +75,7 @@ const AUTH_ENDPOINTS = [
|
||||
'/cabinet/auth/password/forgot',
|
||||
'/cabinet/auth/password/reset',
|
||||
'/cabinet/auth/oauth/',
|
||||
'/cabinet/auth/merge/',
|
||||
];
|
||||
|
||||
function isAuthEndpoint(url: string | undefined): boolean {
|
||||
|
||||
Reference in New Issue
Block a user