diff --git a/apps/api/src/integrations/tahesab/tahesab-http.client.ts b/apps/api/src/integrations/tahesab/tahesab-http.client.ts index b26cab4..470b58c 100644 --- a/apps/api/src/integrations/tahesab/tahesab-http.client.ts +++ b/apps/api/src/integrations/tahesab/tahesab-http.client.ts @@ -132,9 +132,14 @@ export class TahesabHttpClient { req.on('error', (err) => { this.logger.error(`Tahesab call failed: ${path}`, err); + const raw = err.message || String(err); + const tlsHint = + /self-signed|certificate|UNABLE_TO_VERIFY|CERT_/i.test(raw) + ? ' — در تنظیمات اتصال، گزینه «پذیرش گواهی SSL خودامضا» را فعال کنید.' + : ''; reject( new BadGatewayException( - `اتصال به ته‌حساب ناموفق بود: ${err.message}`, + `اتصال به ته‌حساب ناموفق بود: ${raw}${tlsHint}`, ), ); }); diff --git a/apps/web/src/views/TahesabSettingsView.vue b/apps/web/src/views/TahesabSettingsView.vue index 75e0665..e5f0290 100644 --- a/apps/web/src/views/TahesabSettingsView.vue +++ b/apps/web/src/views/TahesabSettingsView.vue @@ -70,6 +70,21 @@ function resetForm() { form.enabled = true; } +function looksLikePrivateHttps(url: string) { + return /^https:\/\/(\d{1,3}\.){3}\d{1,3}(:\d+)?/i.test(url.trim()); +} + +function isTlsError(text: string | null | undefined) { + if (!text) return false; + return /self-signed|certificate|UNABLE_TO_VERIFY|CERT_|گواهی/i.test(text); +} + +function onBaseUrlBlur() { + if (!editingId.value && looksLikePrivateHttps(form.baseUrl)) { + form.allowInsecureTls = true; + } +} + function startEdit(row: TahesabConnectionDto) { editingId.value = row.id; form.label = row.label; @@ -162,12 +177,31 @@ async function testConn(id: string) { `/integrations/tahesab/connections/${id}/test`, ); if (data.ok) ok.value = 'اتصال سالم است.'; - else error.value = data.error ?? 'تست اتصال ناموفق بود.'; + else { + error.value = data.error ?? 'تست اتصال ناموفق بود.'; + if (isTlsError(data.error)) { + error.value += + ' → دکمه «فعال‌سازی SSL خودامضا» را بزنید یا در ویرایش اتصال تیک آن را بگذارید.'; + } + } await load(); } catch (e) { - error.value = axios.isAxiosError(e) - ? String((e.response?.data as { message?: string })?.message ?? 'تست ناموفق') - : 'تست ناموفق'; + error.value = apiErr(e, 'تست ناموفق'); + } +} + +async function enableInsecureTls(id: string) { + error.value = ''; + ok.value = ''; + try { + await api.patch(`/integrations/tahesab/connections/${id}`, { + allowInsecureTls: true, + }); + ok.value = 'پذیرش گواهی خودامضا فعال شد. در حال تست…'; + await load(); + await testConn(id); + } catch (e) { + error.value = apiErr(e, 'فعال‌سازی ناموفق بود'); } } @@ -332,6 +366,14 @@ onMounted(load);

{{ error }}

{{ ok }}

+ +
@@ -341,6 +383,7 @@ onMounted(load); DB: {{ row.dbName }} · توکن: {{ row.tokenMasked }} +
+ @@ -373,6 +424,7 @@ onMounted(load); required dir="ltr" placeholder="https://api-test.tahesab.ir یا https://IP:8081" + @blur="onBaseUrlBlur" />
@@ -401,9 +453,9 @@ onMounted(load); فعال -