squarefi-bff-api-module 1.32.1 → 1.32.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/api/auth.d.ts +29 -0
  2. package/dist/api/auth.js +59 -0
  3. package/dist/api/bank-data.d.ts +4 -0
  4. package/dist/api/bank-data.js +6 -0
  5. package/dist/api/counterparties.d.ts +14 -0
  6. package/dist/api/counterparties.js +16 -0
  7. package/dist/api/developer.d.ts +12 -0
  8. package/dist/api/developer.js +12 -0
  9. package/dist/api/exchange.d.ts +14 -0
  10. package/dist/api/exchange.js +20 -0
  11. package/dist/api/frontend.d.ts +11 -0
  12. package/dist/api/frontend.js +11 -0
  13. package/dist/api/index.d.ts +38 -0
  14. package/dist/api/index.js +36 -0
  15. package/dist/api/issuing.d.ts +64 -0
  16. package/dist/api/issuing.js +140 -0
  17. package/dist/api/kyc.d.ts +21 -0
  18. package/dist/api/kyc.js +21 -0
  19. package/dist/api/list.d.ts +16 -0
  20. package/dist/api/list.js +16 -0
  21. package/dist/api/orders.d.ts +49 -0
  22. package/dist/api/orders.js +84 -0
  23. package/dist/api/persona.d.ts +7 -0
  24. package/dist/api/persona.js +7 -0
  25. package/dist/api/storage.d.ts +8 -0
  26. package/dist/api/storage.js +16 -0
  27. package/dist/api/tenants.d.ts +6 -0
  28. package/dist/api/tenants.js +6 -0
  29. package/dist/api/totp.d.ts +17 -0
  30. package/dist/api/totp.js +45 -0
  31. package/{src/api/types/autogen/apiV2.types.ts → dist/api/types/autogen/apiV2.types.d.ts} +0 -1
  32. package/dist/api/types/autogen/apiV2.types.js +5 -0
  33. package/dist/api/types/types.d.ts +2258 -0
  34. package/dist/api/types/types.js +1 -0
  35. package/dist/api/user.d.ts +18 -0
  36. package/dist/api/user.js +18 -0
  37. package/dist/api/virtual-accounts.d.ts +9 -0
  38. package/dist/api/virtual-accounts.js +9 -0
  39. package/dist/api/wallets.d.ts +24 -0
  40. package/dist/api/wallets.js +30 -0
  41. package/dist/constants.d.ts +303 -0
  42. package/dist/constants.js +332 -0
  43. package/dist/hooks/index.js +3 -0
  44. package/dist/hooks/useCalc.d.ts +25 -0
  45. package/dist/hooks/useCalc.js +115 -0
  46. package/dist/hooks/useFileUpload.d.ts +49 -0
  47. package/dist/hooks/useFileUpload.js +100 -0
  48. package/dist/hooks/useSupabaseSubscription/config.d.ts +2 -0
  49. package/dist/hooks/useSupabaseSubscription/config.js +5 -0
  50. package/dist/hooks/useSupabaseSubscription/index.js +2 -0
  51. package/dist/hooks/useSupabaseSubscription/specialized.d.ts +5 -0
  52. package/{src/hooks/useSupabaseSubscription/specialized.ts → dist/hooks/useSupabaseSubscription/specialized.js} +2 -5
  53. package/dist/hooks/useSupabaseSubscription/types.d.ts +16 -0
  54. package/dist/hooks/useSupabaseSubscription/types.js +1 -0
  55. package/dist/hooks/useSupabaseSubscription/useSupabaseSubscription.d.ts +5 -0
  56. package/dist/hooks/useSupabaseSubscription/useSupabaseSubscription.js +37 -0
  57. package/dist/index.d.ts +7 -0
  58. package/dist/utils/apiClientFactory.d.ts +31 -0
  59. package/dist/utils/apiClientFactory.js +138 -0
  60. package/dist/utils/converters.d.ts +1 -0
  61. package/dist/utils/converters.js +1 -0
  62. package/dist/utils/encrypt.d.ts +10 -0
  63. package/dist/utils/encrypt.js +77 -0
  64. package/dist/utils/fileStorage.d.ts +120 -0
  65. package/dist/utils/fileStorage.js +292 -0
  66. package/dist/utils/storage.d.ts +3 -0
  67. package/dist/utils/storage.js +24 -0
  68. package/dist/utils/supabase.d.ts +1 -0
  69. package/dist/utils/supabase.js +12 -0
  70. package/dist/utils/tokensFactory.d.ts +12 -0
  71. package/dist/utils/tokensFactory.js +42 -0
  72. package/package.json +4 -1
  73. package/.env.example +0 -1
  74. package/.husky/pre-commit +0 -2
  75. package/.prettierignore +0 -6
  76. package/.prettierrc +0 -7
  77. package/CHANGELOG.md +0 -1415
  78. package/FIXED_RLS_ERROR.md +0 -146
  79. package/QUICK_TEST.md +0 -127
  80. package/STORAGE_MODULE_SUMMARY.md +0 -228
  81. package/TEST_INSTRUCTIONS.md +0 -122
  82. package/docs/AUTH_TOKEN_USAGE.md +0 -290
  83. package/docs/BACKEND_SERVICE_URL.md +0 -334
  84. package/docs/FRONTEND_STORAGE_GUIDE.md +0 -529
  85. package/docs/STORAGE_MODULE.md +0 -490
  86. package/docs/STORAGE_QUICK_START.md +0 -76
  87. package/scripts/generate-openapi-types.ts +0 -41
  88. package/scripts/supabase-storage-setup.sql +0 -223
  89. package/src/api/auth.ts +0 -78
  90. package/src/api/bank-data.ts +0 -11
  91. package/src/api/counterparties.ts +0 -73
  92. package/src/api/developer.ts +0 -20
  93. package/src/api/exchange.ts +0 -44
  94. package/src/api/frontend.ts +0 -20
  95. package/src/api/index.ts +0 -57
  96. package/src/api/issuing.ts +0 -214
  97. package/src/api/kyc.ts +0 -41
  98. package/src/api/list.ts +0 -26
  99. package/src/api/orders.ts +0 -255
  100. package/src/api/persona.ts +0 -16
  101. package/src/api/storage.ts +0 -24
  102. package/src/api/tenants.ts +0 -8
  103. package/src/api/totp.ts +0 -51
  104. package/src/api/types/types.ts +0 -2820
  105. package/src/api/user.ts +0 -27
  106. package/src/api/virtual-accounts.ts +0 -15
  107. package/src/api/wallets.ts +0 -65
  108. package/src/constants.ts +0 -343
  109. package/src/hooks/useCalc.ts +0 -181
  110. package/src/hooks/useFileUpload.ts +0 -129
  111. package/src/hooks/useSupabaseSubscription/config.ts +0 -7
  112. package/src/hooks/useSupabaseSubscription/types.ts +0 -18
  113. package/src/hooks/useSupabaseSubscription/useSupabaseSubscription.ts +0 -53
  114. package/src/utils/apiClientFactory.ts +0 -194
  115. package/src/utils/converters.ts +0 -1
  116. package/src/utils/encrypt.ts +0 -96
  117. package/src/utils/fileStorage.ts +0 -353
  118. package/src/utils/storage.ts +0 -29
  119. package/src/utils/supabase.ts +0 -16
  120. package/src/utils/tokensFactory.ts +0 -59
  121. package/tsconfig.json +0 -15
  122. package/types.d.ts +0 -11
  123. /package/{src/hooks/index.ts → dist/hooks/index.d.ts} +0 -0
  124. /package/{src/hooks/useSupabaseSubscription/index.ts → dist/hooks/useSupabaseSubscription/index.d.ts} +0 -0
  125. /package/{src/index.ts → dist/index.js} +0 -0
@@ -1,129 +0,0 @@
1
- import { useState, useCallback } from 'react';
2
- import { uploadFile, UploadFileOptions, UploadFileResult } from '../utils/fileStorage';
3
-
4
- interface UseFileUploadOptions {
5
- bucket: string;
6
- folder?: string; // Папка внутри бакета (например, 'documents', 'images/avatars'). Создается автоматически, если не существует
7
- authToken?: string; // JWT token для авторизации
8
- onSuccess?: (result: UploadFileResult) => void;
9
- onError?: (error: string) => void;
10
- }
11
-
12
- interface UseFileUploadReturn {
13
- upload: (file: File, fileName?: string) => Promise<UploadFileResult>;
14
- uploading: boolean;
15
- progress: number;
16
- error: string | null;
17
- result: UploadFileResult | null;
18
- reset: () => void;
19
- }
20
-
21
- /**
22
- * React хук для загрузки файлов в Supabase Storage
23
- *
24
- * Папки создаются автоматически при загрузке файла, если их не существует.
25
- *
26
- * @example
27
- * ```tsx
28
- * // Загрузка в корень бакета
29
- * const { upload, uploading, error, result } = useFileUpload({
30
- * bucket: 'user-files',
31
- * onSuccess: (result) => console.log('Загружено:', result.path),
32
- * });
33
- *
34
- * // Загрузка в конкретную папку (папка создастся автоматически)
35
- * const { upload } = useFileUpload({
36
- * bucket: 'documents',
37
- * folder: 'invoices', // файл будет загружен в invoices/
38
- * });
39
- *
40
- * // Загрузка во вложенную папку (все папки создадутся автоматически)
41
- * const { upload } = useFileUpload({
42
- * bucket: 'images',
43
- * folder: 'avatars/2024', // файл будет загружен в avatars/2024/
44
- * });
45
- *
46
- * const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
47
- * const file = e.target.files?.[0];
48
- * if (file) await upload(file);
49
- * };
50
- * ```
51
- */
52
- export const useFileUpload = (options: UseFileUploadOptions): UseFileUploadReturn => {
53
- const { bucket, folder, authToken, onSuccess, onError } = options;
54
-
55
- const [uploading, setUploading] = useState(false);
56
- const [progress, setProgress] = useState(0);
57
- const [error, setError] = useState<string | null>(null);
58
- const [result, setResult] = useState<UploadFileResult | null>(null);
59
-
60
- const upload = useCallback(
61
- async (file: File, customFileName?: string): Promise<UploadFileResult> => {
62
- setUploading(true);
63
- setProgress(0);
64
- setError(null);
65
- setResult(null);
66
-
67
- try {
68
- // Симулируем прогресс (Supabase не предоставляет реальный progress)
69
- const progressInterval = setInterval(() => {
70
- setProgress((prev) => Math.min(prev + 10, 90));
71
- }, 100);
72
-
73
- const uploadOptions: UploadFileOptions = {
74
- file,
75
- fileName: customFileName || `${Date.now()}-${file.name}`,
76
- bucket,
77
- folder,
78
- contentType: file.type,
79
- authToken,
80
- };
81
-
82
- const uploadResult = await uploadFile(uploadOptions);
83
-
84
- clearInterval(progressInterval);
85
- setProgress(100);
86
- setResult(uploadResult);
87
-
88
- if (uploadResult.success) {
89
- onSuccess?.(uploadResult);
90
- } else {
91
- const errorMsg = uploadResult.error || 'Ошибка загрузки файла';
92
- setError(errorMsg);
93
- onError?.(errorMsg);
94
- }
95
-
96
- return uploadResult;
97
- } catch (err) {
98
- const errorMsg = err instanceof Error ? err.message : 'Непредвиденная ошибка';
99
- setError(errorMsg);
100
- onError?.(errorMsg);
101
- setProgress(0);
102
-
103
- return {
104
- success: false,
105
- error: errorMsg,
106
- };
107
- } finally {
108
- setUploading(false);
109
- }
110
- },
111
- [bucket, folder, authToken, onSuccess, onError],
112
- );
113
-
114
- const reset = useCallback(() => {
115
- setUploading(false);
116
- setProgress(0);
117
- setError(null);
118
- setResult(null);
119
- }, []);
120
-
121
- return {
122
- upload,
123
- uploading,
124
- progress,
125
- error,
126
- result,
127
- reset,
128
- };
129
- };
@@ -1,7 +0,0 @@
1
- import { SubscriptionConfig } from './types';
2
-
3
- export const createWalletTransactionsConfig = (walletId: string): SubscriptionConfig => ({
4
- channelName: `wallet-transactions-${walletId}`,
5
- table: 'transactions',
6
- filter: `wallet_id=eq.${walletId}`,
7
- });
@@ -1,18 +0,0 @@
1
- export interface SubscriptionConfig {
2
- channelName: string;
3
- table: string;
4
- schema?: string;
5
- event?: 'INSERT' | 'UPDATE' | 'DELETE' | '*';
6
- filter?: string;
7
- }
8
-
9
- export interface UseSupabaseSubscriptionProps {
10
- config: SubscriptionConfig;
11
- callback: (payload?: unknown) => void;
12
- enabled?: boolean;
13
- key?: string;
14
- }
15
-
16
- export interface UseWalletTransactionsSubscriptionProps extends Omit<UseSupabaseSubscriptionProps, 'config'> {
17
- walletId: string | undefined;
18
- }
@@ -1,53 +0,0 @@
1
- 'use client';
2
-
3
- import { useEffect, useRef } from 'react';
4
-
5
- import { UseSupabaseSubscriptionProps } from './types';
6
-
7
- import { supabaseClient } from '../../utils/supabase';
8
-
9
- export const useSupabaseSubscription = ({ config, callback, enabled = true, key }: UseSupabaseSubscriptionProps) => {
10
- const subscriptionRef = useRef<any>(null);
11
- const callbackRef = useRef(callback);
12
-
13
- callbackRef.current = callback;
14
-
15
- useEffect(() => {
16
- if (!enabled || !supabaseClient) {
17
- return;
18
- }
19
-
20
- if (subscriptionRef.current) {
21
- supabaseClient.removeChannel(subscriptionRef.current);
22
- subscriptionRef.current = null;
23
- }
24
-
25
- const subscription = supabaseClient
26
- .channel(key || config.channelName)
27
- .on(
28
- 'postgres_changes' as any,
29
- {
30
- event: config.event || '*',
31
- schema: config.schema || 'public',
32
- table: config.table,
33
- ...(config.filter && { filter: config.filter }),
34
- },
35
- (payload) => callbackRef.current(payload),
36
- )
37
- .subscribe();
38
-
39
- subscriptionRef.current = subscription;
40
-
41
- return () => {
42
- if (subscriptionRef.current && supabaseClient) {
43
- supabaseClient.removeChannel(subscriptionRef.current);
44
- subscriptionRef.current = null;
45
- }
46
- };
47
- }, [enabled, config.channelName, config.table, config.schema, config.event, config.filter, supabaseClient, key]);
48
-
49
- return {
50
- isConnected: !!subscriptionRef.current,
51
- isClientAvailable: !!supabaseClient,
52
- };
53
- };
@@ -1,194 +0,0 @@
1
- /* eslint-disable no-console */
2
- import { isTMA } from '@telegram-apps/sdk-react';
3
- import axios, { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
4
-
5
- import { telegramSignUpPath, telegramSignInPath, refreshTokenPath } from '../api/auth';
6
-
7
- import { AppEnviroment, ResponseStatus } from '../constants';
8
-
9
- import { deleteTokens, getTokens, refreshTokens } from './tokensFactory';
10
-
11
- // eslint-disable-next-line no-constant-condition
12
-
13
- const apiV1BaseURL = process.env.API_URL ?? 'ENV variable API_URL is not defined';
14
- const apiV2BaseURL = process.env.API_V2_URL ?? 'ENV variable API_V2_URL is not defined';
15
- const apiTOTPBaseURL = process.env.API_TOTP_URL ?? 'ENV variable API_TOTP_URL is not defined';
16
- const envTenantId = process.env.TENANT_ID ?? 'ENV variable TENANT_ID is not defined';
17
- const envLogoutURL = process.env.LOGOUT_URL ?? '/auth/logout';
18
-
19
- type AxiosError = {
20
- response: AxiosResponse;
21
- config: InternalAxiosRequestConfig;
22
- };
23
-
24
- type CreateApiClientOptions = {
25
- baseURL: string;
26
- tenantId: string;
27
- isBearerToken?: boolean;
28
- };
29
-
30
- type RequestQueueItem = {
31
- resolve: Function;
32
- reject: Function;
33
- };
34
-
35
- let isTokenRefreshing = false;
36
- let requestQueue: RequestQueueItem[] = [];
37
-
38
- export const createApiClient = ({ baseURL, isBearerToken, tenantId }: CreateApiClientOptions) => {
39
- const instance = axios.create({
40
- baseURL,
41
- timeout: 60000,
42
- });
43
-
44
- instance.interceptors.request.use((config) => {
45
- const { access_token } = getTokens();
46
-
47
- const modifiedHeaders = {
48
- ...config.headers,
49
- 'x-tenant-id': tenantId,
50
- };
51
-
52
- if (access_token) {
53
- const authHeader = isBearerToken ? `Bearer ${access_token}` : access_token;
54
- modifiedHeaders.Authorization = authHeader;
55
- }
56
-
57
- config.context = {
58
- ...config.context,
59
- appEnvironment: isTMA() ? AppEnviroment.TELEGRAM : AppEnviroment.WEB,
60
- };
61
-
62
- return {
63
- ...config,
64
- headers: modifiedHeaders,
65
- } as unknown as InternalAxiosRequestConfig;
66
- });
67
-
68
- instance.interceptors.response.use(
69
- (response) => response,
70
- (error: AxiosError) => {
71
- if (typeof window === 'undefined') {
72
- return Promise.reject(error);
73
- }
74
- if (
75
- error?.response?.status === ResponseStatus.UNAUTHORIZED &&
76
- !error?.response?.config.context?.bypassUnauthorizedHandler
77
- ) {
78
- const { response, config: failedRequestConfig } = error;
79
- const { refresh_token } = getTokens();
80
- const isRetryRequest = failedRequestConfig.context?.isRetryRequest;
81
-
82
- const isRefreshTokenRequest = failedRequestConfig.url?.includes(refreshTokenPath);
83
- const isTelegramSignInRequest = failedRequestConfig.url?.includes(telegramSignInPath);
84
- const isTelegramSignUpRequest = failedRequestConfig.url?.includes(telegramSignUpPath);
85
- const isRefreshNotRequired = !refresh_token && !isTMA();
86
- const isLogoutNeccesary =
87
- isRefreshNotRequired ||
88
- isTelegramSignInRequest ||
89
- isTelegramSignUpRequest ||
90
- isRefreshTokenRequest ||
91
- isRetryRequest;
92
-
93
- const isRefreshAvailable = !isTokenRefreshing && !isRefreshNotRequired;
94
-
95
- if (isLogoutNeccesary) {
96
- if (typeof window !== 'undefined') {
97
- window.location.href = envLogoutURL;
98
- deleteTokens();
99
- }
100
- requestQueue = [];
101
- return Promise.reject(response);
102
- }
103
- if (isRefreshAvailable) {
104
- isTokenRefreshing = true;
105
- refreshTokens()
106
- .then((data) => {
107
- if (data?.access_token) {
108
- requestQueue.forEach((request) => request.resolve());
109
- requestQueue = [];
110
- }
111
- })
112
- .catch((tokenRefreshError) => {
113
- if (typeof window !== 'undefined') {
114
- window.location.href = envLogoutURL;
115
- deleteTokens();
116
- }
117
- requestQueue = [];
118
- return Promise.reject(tokenRefreshError);
119
- })
120
- .finally(() => {
121
- isTokenRefreshing = false;
122
- });
123
- }
124
- return new Promise((res, rej) => {
125
- requestQueue.push({
126
- resolve: () => {
127
- failedRequestConfig.context = {
128
- ...failedRequestConfig.context,
129
- isRetryRequest: true,
130
- };
131
- return res(instance(failedRequestConfig));
132
- },
133
- reject: () => rej(instance(failedRequestConfig)),
134
- });
135
- });
136
- }
137
-
138
- console.error('Axios error', error);
139
-
140
- return Promise.reject(error);
141
- },
142
- );
143
-
144
- const patchRequest = async <T>(url: string, config?: AxiosRequestConfig): Promise<T> => {
145
- const { data = {}, ...restConfig } = config ?? {};
146
-
147
- const res = await instance.patch(url, data, restConfig);
148
-
149
- return res.data;
150
- };
151
-
152
- const postRequest = async <T>(url: string, config?: AxiosRequestConfig): Promise<T> => {
153
- const { data = {}, ...restConfig } = config ?? {};
154
-
155
- const res = await instance.post(url, data, restConfig);
156
-
157
- return res.data;
158
- };
159
-
160
- const deleteRequest = async (url: string, config?: AxiosRequestConfig) => {
161
- const { data = {}, ...restConfig } = config ?? {};
162
-
163
- const res = await instance.delete(url, { data, ...restConfig });
164
-
165
- return res.data;
166
- };
167
-
168
- const getRequest = async <T>(url: string, config?: AxiosRequestConfig): Promise<T> => {
169
- const { params = {}, ...restConfig } = config ?? {};
170
-
171
- const res = await instance.get(url, { params, ...restConfig });
172
-
173
- return res.data;
174
- };
175
-
176
- return { patchRequest, postRequest, deleteRequest, getRequest };
177
- };
178
-
179
- export const apiClientV1 = createApiClient({
180
- baseURL: apiV1BaseURL,
181
- tenantId: envTenantId,
182
- });
183
-
184
- export const apiClientV2 = createApiClient({
185
- baseURL: apiV2BaseURL,
186
- isBearerToken: true,
187
- tenantId: envTenantId,
188
- });
189
-
190
- export const apiClientTOTP = createApiClient({
191
- baseURL: apiTOTPBaseURL,
192
- isBearerToken: true,
193
- tenantId: envTenantId,
194
- });
@@ -1 +0,0 @@
1
- export const convertPhoneToSupabaseFormat = (phone: string) => phone.replace(/\D/g, '');
@@ -1,96 +0,0 @@
1
- import crypto, { CipherKey } from 'crypto';
2
- import NodeRSA from 'node-rsa';
3
-
4
- import { API } from '../api/types/types';
5
-
6
- type MakeSecureRequestParams = {
7
- callback: (props: API.Common.Encrypted.Request) => Promise<API.Common.Encrypted.Response>;
8
- publicKey: string;
9
- };
10
-
11
- export const generateSecretKey = () => {
12
- const secretKey = crypto.randomBytes(32);
13
- return secretKey;
14
- };
15
-
16
- export const decryptAESData = async (encryptedData: string, iv: string, secretKey: CipherKey) => {
17
- const decipher = crypto.createDecipheriv('aes-256-cbc', secretKey, Buffer.from(iv, 'base64'));
18
- let decrypted = decipher.update(encryptedData, 'base64', 'utf8');
19
- decrypted += decipher.final('utf8');
20
- return JSON.parse(decrypted);
21
- };
22
-
23
- /**
24
- * Очищает и валидирует публичный RSA ключ
25
- * Исправляет ошибку InvalidAsn1Error: encoding too long
26
- * путем удаления лишних символов и нормализации переносов строк
27
- */
28
- const cleanAndValidatePublicKey = (publicKey: string): string => {
29
- try {
30
- // Декодируем base64 ключ
31
- const publicKeyBase64 = Buffer.from(publicKey, 'base64').toString('utf8');
32
-
33
- // Удаляем лишние символы (переносы строк, пробелы в начале и конце)
34
- // Нормализуем переносы строк для корректной обработки ASN.1
35
- const cleanedKey = publicKeyBase64.trim().replace(/\r?\n|\r/g, '\n');
36
-
37
- // Проверяем, что ключ содержит необходимые маркеры
38
- if (!cleanedKey.includes('BEGIN') || !cleanedKey.includes('END')) {
39
- throw new Error('Invalid public key format: missing BEGIN/END markers');
40
- }
41
-
42
- return cleanedKey;
43
- } catch (error) {
44
- throw new Error(`Invalid public key format: ${error instanceof Error ? error.message : 'Unknown error'}`);
45
- }
46
- };
47
-
48
- /**
49
- * Автоматически определяет формат RSA ключа по заголовку
50
- * Помогает избежать ошибок импорта при неправильном указании формата
51
- */
52
- const detectKeyFormat = (key: string): 'pkcs1' | 'pkcs8' => {
53
- if (key.includes('BEGIN RSA PUBLIC KEY')) {
54
- return 'pkcs1';
55
- } else if (key.includes('BEGIN PUBLIC KEY')) {
56
- return 'pkcs8';
57
- }
58
- // По умолчанию возвращаем pkcs8, как было ранее
59
- return 'pkcs8';
60
- };
61
-
62
- export const makeSecureRequest = async <T>({ callback, publicKey }: MakeSecureRequestParams): Promise<T> => {
63
- const clientRsa = new NodeRSA();
64
-
65
- try {
66
- // Очищаем и валидируем публичный ключ
67
- const cleanedPublicKey = cleanAndValidatePublicKey(publicKey);
68
-
69
- // Определяем формат ключа автоматически
70
- const keyFormat = detectKeyFormat(cleanedPublicKey);
71
-
72
- // Импортируем ключ с правильным форматом
73
- clientRsa.importKey(cleanedPublicKey, `${keyFormat}-public-pem`);
74
- } catch (error) {
75
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
76
- throw new Error(`Failed to import RSA public key: ${errorMessage}`);
77
- }
78
-
79
- const clientSecretKey = generateSecretKey();
80
- const clientPayload = {
81
- key: clientSecretKey.toString('base64'),
82
- timestamp: Date.now(),
83
- };
84
-
85
- const encrypted_key = clientRsa.encrypt(JSON.stringify(clientPayload), 'base64');
86
-
87
- const { success, encrypted, data, iv } = await callback({ encrypted_key });
88
-
89
- if (success && encrypted && data && iv) {
90
- const decryptedData = await decryptAESData(data, iv, clientSecretKey);
91
-
92
- return decryptedData.data;
93
- } else {
94
- throw new Error('Failed to get encrypted secret key');
95
- }
96
- };