From bcefe4ec6d564247f022309e543b1864d21e4c5d Mon Sep 17 00:00:00 2001 From: Gilad Resisi Date: Tue, 14 Jul 2026 16:08:12 +0700 Subject: [PATCH] fix(instagram,facebook): prevent broken page-grant channels and guide reconnection The Facebook OAuth page grant is shared across all Meta channels, which caused two failure modes: the page picker offered pages the app was never granted (saving one stored a poisoned "undefined___..." token), and a bad grant could never be repaired because reconnecting silently reused the previous selection. Backend (provider files): - Filter pages without an access_token out of the Facebook and Instagram pickers - they were never granted in the OAuth dialog and cannot be published to - Classify Graph error code 190 as refresh-token instead of bad-body so invalid tokens mark the channel for reconnection - Add auth_type=rerequest to the OAuth URL so previously declined permissions/assets are re-prompted and a bad grant can be repaired - Clear refreshNeeded when a channel is reconnected (re-adding the same account heals in place) Frontend: - Extend the Facebook/Instagram tile toolTip with the shared-grant warning - Add an optional onBack prop to the continue-provider empty state so the full-page OAuth landing is not a dead end ("Back to Postiz") Co-Authored-By: Claude Fable 5 --- .../launches/continue.integration.tsx | 10 ++++ .../src/components/layout/top.tip.tsx | 2 +- .../with-continue-provider.tsx | 12 ++++- .../integrations/integration.repository.ts | 1 + .../integrations/social/facebook.provider.ts | 17 +++++- .../integrations/social/instagram.provider.ts | 53 +++++++++++++------ .../translation/locales/ar/translation.json | 1 + .../translation/locales/bn/translation.json | 1 + .../translation/locales/de/translation.json | 1 + .../translation/locales/en/translation.json | 1 + .../translation/locales/es/translation.json | 1 + .../translation/locales/fr/translation.json | 1 + .../translation/locales/he/translation.json | 1 + .../translation/locales/it/translation.json | 1 + .../translation/locales/ja/translation.json | 1 + .../locales/ka_ge/translation.json | 1 + .../translation/locales/ko/translation.json | 1 + .../translation/locales/pt/translation.json | 1 + .../translation/locales/ru/translation.json | 1 + .../translation/locales/tr/translation.json | 1 + .../translation/locales/vi/translation.json | 1 + .../translation/locales/zh/translation.json | 1 + 22 files changed, 91 insertions(+), 20 deletions(-) diff --git a/apps/frontend/src/components/launches/continue.integration.tsx b/apps/frontend/src/components/launches/continue.integration.tsx index 0240dc2d41..f37732ebf2 100644 --- a/apps/frontend/src/components/launches/continue.integration.tsx +++ b/apps/frontend/src/components/launches/continue.integration.tsx @@ -354,6 +354,16 @@ export const ContinueIntegration: FC<{ existingId={[]} initialData={twoStepState.pages} isSaving={isSaving} + onBack={ + logged || twoStepState.returnURL + ? () => + navigateOrShow( + '/launches', + twoStepState.returnURL, + 'Channel setup cancelled' + ) + : undefined + } /> diff --git a/apps/frontend/src/components/layout/top.tip.tsx b/apps/frontend/src/components/layout/top.tip.tsx index e9679a1576..808ced8ea5 100644 --- a/apps/frontend/src/components/layout/top.tip.tsx +++ b/apps/frontend/src/components/layout/top.tip.tsx @@ -2,5 +2,5 @@ import { Tooltip } from 'react-tooltip'; export const ToolTip = () => { - return ; + return ; }; diff --git a/apps/frontend/src/components/new-launch/providers/continue-provider/with-continue-provider.tsx b/apps/frontend/src/components/new-launch/providers/continue-provider/with-continue-provider.tsx index 50491d64b4..3680011f5c 100644 --- a/apps/frontend/src/components/new-launch/providers/continue-provider/with-continue-provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/continue-provider/with-continue-provider.tsx @@ -22,6 +22,9 @@ export interface ContinueProviderProps { existingId: string[]; initialData?: any[]; isSaving?: boolean; + // Shows a "Back to Postiz" button in the empty state — used by the + // full-page OAuth landing flow, which has no dialog to close + onBack?: () => void; } export interface EmptyStateMessage { @@ -59,7 +62,7 @@ export function withContinueProvider( } = config; return function ContinueProviderComponent(props: ContinueProviderProps) { - const { onSave, existingId, initialData, isSaving } = props; + const { onSave, existingId, initialData, isSaving, onBack } = props; const call = useCustomProviderFunction(); const t = useT(); const [selection, setSelection] = useState(null); @@ -119,6 +122,13 @@ export function withContinueProvider( )} ))} + {!!onBack && ( +
+ +
+ )} ); } diff --git a/libraries/nestjs-libraries/src/database/prisma/integrations/integration.repository.ts b/libraries/nestjs-libraries/src/database/prisma/integrations/integration.repository.ts index 15434d6c83..7cb76a5928 100644 --- a/libraries/nestjs-libraries/src/database/prisma/integrations/integration.repository.ts +++ b/libraries/nestjs-libraries/src/database/prisma/integrations/integration.repository.ts @@ -189,6 +189,7 @@ export class IntegrationRepository { ...params, disabled: false, deletedAt: null, + refreshNeeded: false, }, }); } diff --git a/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts b/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts index 7c287152b9..3baa4aef7f 100644 --- a/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts @@ -27,6 +27,8 @@ import { Rules } from '@gitroom/nestjs-libraries/chat/rules.description.decorato export class FacebookProvider extends SocialAbstract implements SocialProvider { identifier = 'facebook'; name = 'Facebook Page'; + toolTip = + 'Your Facebook page selection is shared across all your Meta channels, check all relevant pages'; isBetweenSteps = true; scopes = [ 'pages_show_list', @@ -79,6 +81,14 @@ export class FacebookProvider extends SocialAbstract implements SocialProvider { }; } + if (/"code":\s*190\b/.test(body)) { + return { + type: 'refresh-token' as const, + value: + 'The Facebook access token is invalid, please reconnect the channel', + }; + } + if (body.indexOf('1366046') > -1) { return { type: 'bad-body' as const, @@ -243,6 +253,9 @@ export class FacebookProvider extends SocialAbstract implements SocialProvider { `${process.env.FRONTEND_URL}/integrations/social/facebook` )}` + `&state=${state}` + + // Re-prompt permissions/assets the user previously declined, so a + // bad page grant can be repaired by reconnecting + `&auth_type=rerequest` + `&scope=${this.scopes.join(',')}`, codeVerifier: makeId(10), state, @@ -383,7 +396,9 @@ export class FacebookProvider extends SocialAbstract implements SocialProvider { // Business Manager API not available for all users } - return allPages; + // Pages without an access_token were never granted to the app in the + // OAuth dialog — publishing through them is impossible + return allPages.filter((p: any) => p.access_token); } async fetchPageInformation(accessToken: string, data: { page: string }) { diff --git a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts index c96234777f..11f33ed51f 100644 --- a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts @@ -28,7 +28,8 @@ export class InstagramProvider identifier = 'instagram'; name = 'Instagram\n(Facebook Business)'; isBetweenSteps = true; - toolTip = 'Instagram must be business and connected to a Facebook page'; + toolTip = + 'Your Facebook page selection is shared across all your Meta channels, check all relevant pages\nInstagram must be business and connected to a Facebook page, check this page too'; scopes = [ 'instagram_basic', 'pages_show_list', @@ -319,11 +320,11 @@ export class InstagramProvider }; } - if (body.indexOf('190,') > -1) { + if (/"code":\s*190\b/.test(body)) { return { - type: 'bad-body' as const, + type: 'refresh-token' as const, value: - 'The account is missing some permissions to perform this action, please re-add the account and allow all permissions', + 'The Instagram access token is invalid, please reconnect the channel', }; } @@ -421,6 +422,9 @@ export class InstagramProvider `${process.env.FRONTEND_URL}/integrations/social/instagram` )}` + `&state=${state}` + + // Re-prompt permissions/assets the user previously declined, so a + // bad page grant can be repaired by reconnecting + `&auth_type=rerequest` + `&scope=${encodeURIComponent(this.scopes.join(','))}`, codeVerifier: makeId(10), state, @@ -544,21 +548,36 @@ export class InstagramProvider // Business Manager API not available for all users } - const onlyConnectedAccounts = await Promise.all( - allFacebookPages - .filter((f: any) => f.instagram_business_account) - .map(async (p: any) => { - return { - pageId: p.id, - ...(await ( + const onlyConnectedAccounts = ( + await Promise.all( + allFacebookPages + .filter((f: any) => f.instagram_business_account) + .map(async (p: any) => { + // Pages without an access_token were never granted to the app + // in the OAuth dialog — selecting them would store a broken + // "undefined___..." token + const { access_token } = await ( await fetch( - `https://graph.facebook.com/v20.0/${p.instagram_business_account.id}?fields=name,profile_picture_url&access_token=${accessToken}` + `https://graph.facebook.com/v20.0/${p.id}?fields=access_token&access_token=${accessToken}` ) - ).json()), - id: p.instagram_business_account.id, - }; - }) - ); + ).json(); + + if (!access_token) { + return null; + } + + return { + pageId: p.id, + ...(await ( + await fetch( + `https://graph.facebook.com/v20.0/${p.instagram_business_account.id}?fields=name,profile_picture_url&access_token=${accessToken}` + ) + ).json()), + id: p.instagram_business_account.id, + }; + }) + ) + ).filter(Boolean); return onlyConnectedAccounts.map((p: any) => ({ pageId: p.pageId, diff --git a/libraries/react-shared-libraries/src/translation/locales/ar/translation.json b/libraries/react-shared-libraries/src/translation/locales/ar/translation.json index 26ee15169b..76436199eb 100644 --- a/libraries/react-shared-libraries/src/translation/locales/ar/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/ar/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "لم نتمكن من العثور على أي نشاط تجاري مرتبط بالصفحات المحددة.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "نوصي بربط جميع الصفحات وجميع الأنشطة التجارية.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "يرجى إغلاق هذه النافذة، حذف التكامل الخاص بك، ثم إضافة قناة جديدة مرة أخرى.", + "back_to_postiz": "العودة إلى Postiz", "select_instagram_account": "اختر حساب إنستغرام:", "select_page": "اختر الصفحة:", "generate_image_with_ai": "توليد صورة بالذكاء الاصطناعي", diff --git a/libraries/react-shared-libraries/src/translation/locales/bn/translation.json b/libraries/react-shared-libraries/src/translation/locales/bn/translation.json index 2ceddb61d4..689fca3016 100644 --- a/libraries/react-shared-libraries/src/translation/locales/bn/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/bn/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "আমরা নির্বাচিত পৃষ্ঠাগুলির সাথে সংযুক্ত কোনো ব্যবসা খুঁজে পাইনি।", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "আমরা আপনাকে সব পৃষ্ঠা এবং সব ব্যবসা সংযুক্ত করার পরামর্শ দিই।", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "অনুগ্রহ করে এই ডায়ালগটি বন্ধ করুন, আপনার ইন্টিগ্রেশন মুছে ফেলুন এবং আবার একটি নতুন চ্যানেল যোগ করুন।", + "back_to_postiz": "Postiz-এ ফিরে যান", "select_instagram_account": "Instagram অ্যাকাউন্ট নির্বাচন করুন:", "select_page": "পৃষ্ঠা নির্বাচন করুন:", "generate_image_with_ai": "AI দিয়ে ছবি তৈরি করুন", diff --git a/libraries/react-shared-libraries/src/translation/locales/de/translation.json b/libraries/react-shared-libraries/src/translation/locales/de/translation.json index 7d1385c07b..a61a2add47 100644 --- a/libraries/react-shared-libraries/src/translation/locales/de/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/de/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "Wir konnten kein Unternehmen finden, das mit den ausgewählten Seiten verbunden ist.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Wir empfehlen Ihnen, alle Seiten und alle Unternehmen zu verbinden.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Bitte schließen Sie diesen Dialog, löschen Sie Ihre Integration und fügen Sie erneut einen neuen Kanal \n hinzu.", + "back_to_postiz": "Zurück zu Postiz", "select_instagram_account": "Instagram-Konto auswählen:", "select_page": "Seite auswählen:", "generate_image_with_ai": "Bild mit KI generieren", diff --git a/libraries/react-shared-libraries/src/translation/locales/en/translation.json b/libraries/react-shared-libraries/src/translation/locales/en/translation.json index 6b0e634d6e..c70a279819 100644 --- a/libraries/react-shared-libraries/src/translation/locales/en/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/en/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "We couldn't find any business connected to the selected pages.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "We recommend you to connect all the pages and all the businesses.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Please close this dialog, delete your integration and add a new channel\n again.", + "back_to_postiz": "Back to Postiz", "select_instagram_account": "Select Instagram Account:", "select_page": "Select Page:", "generate_image_with_ai": "Generate image with AI", diff --git a/libraries/react-shared-libraries/src/translation/locales/es/translation.json b/libraries/react-shared-libraries/src/translation/locales/es/translation.json index 5bd8f1cf93..762115bdf1 100644 --- a/libraries/react-shared-libraries/src/translation/locales/es/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/es/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "No pudimos encontrar ningún negocio conectado a las páginas seleccionadas.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Te recomendamos conectar todas las páginas y todos los negocios.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Por favor, cierra este diálogo, elimina tu integración y agrega un nuevo canal nuevamente.", + "back_to_postiz": "Volver a Postiz", "select_instagram_account": "Selecciona la cuenta de Instagram:", "select_page": "Selecciona la página:", "generate_image_with_ai": "Generar imagen con IA", diff --git a/libraries/react-shared-libraries/src/translation/locales/fr/translation.json b/libraries/react-shared-libraries/src/translation/locales/fr/translation.json index d9831e2473..3d222945c8 100644 --- a/libraries/react-shared-libraries/src/translation/locales/fr/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/fr/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "Nous n'avons trouvé aucune entreprise liée aux pages sélectionnées.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Nous vous recommandons de connecter toutes les pages et toutes les entreprises.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Veuillez fermer cette fenêtre, supprimer votre intégration et ajouter à nouveau un nouveau canal.", + "back_to_postiz": "Retour à Postiz", "select_instagram_account": "Sélectionnez le compte Instagram :", "select_page": "Sélectionnez la page :", "generate_image_with_ai": "Générer une image avec l'IA", diff --git a/libraries/react-shared-libraries/src/translation/locales/he/translation.json b/libraries/react-shared-libraries/src/translation/locales/he/translation.json index 65631b988d..d0ee4b03f1 100644 --- a/libraries/react-shared-libraries/src/translation/locales/he/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/he/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "לא הצלחנו למצוא עסק שמחובר לעמודים שנבחרו.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "אנו ממליצים לחבר את כל העמודים וכל העסקים.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "אנא סגור את החלון הזה, מחק את האינטגרציה שלך והוסף ערוץ חדש שוב.", + "back_to_postiz": "חזרה ל-Postiz", "select_instagram_account": "בחר חשבון אינסטגרם:", "select_page": "בחר עמוד:", "generate_image_with_ai": "צור תמונה עם בינה מלאכותית", diff --git a/libraries/react-shared-libraries/src/translation/locales/it/translation.json b/libraries/react-shared-libraries/src/translation/locales/it/translation.json index b9f6dd3b3c..cc93f7ad3d 100644 --- a/libraries/react-shared-libraries/src/translation/locales/it/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/it/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "Non siamo riusciti a trovare nessuna azienda collegata alle pagine selezionate.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Ti consigliamo di collegare tutte le pagine e tutte le aziende.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Per favore chiudi questa finestra di dialogo, elimina la tua integrazione e aggiungi nuovamente un nuovo canale.", + "back_to_postiz": "Torna a Postiz", "select_instagram_account": "Seleziona account Instagram:", "select_page": "Seleziona pagina:", "generate_image_with_ai": "Genera immagine con IA", diff --git a/libraries/react-shared-libraries/src/translation/locales/ja/translation.json b/libraries/react-shared-libraries/src/translation/locales/ja/translation.json index bb62ce1c98..8c4d1f0552 100644 --- a/libraries/react-shared-libraries/src/translation/locales/ja/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/ja/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "選択したページに接続されているビジネスが見つかりませんでした。", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "すべてのページとすべてのビジネスを接続することをおすすめします。", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "このダイアログを閉じて、連携を削除し、再度新しいチャンネルを追加してください。", + "back_to_postiz": "Postizに戻る", "select_instagram_account": "Instagramアカウントを選択:", "select_page": "ページを選択:", "generate_image_with_ai": "AIで画像を生成", diff --git a/libraries/react-shared-libraries/src/translation/locales/ka_ge/translation.json b/libraries/react-shared-libraries/src/translation/locales/ka_ge/translation.json index 80b95ff03e..5fcf20ad5d 100644 --- a/libraries/react-shared-libraries/src/translation/locales/ka_ge/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/ka_ge/translation.json @@ -229,6 +229,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "არჩეულ გვერდებს მიერთებული ბიზნესი ვერ ვიპოვეთ.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "გირჩევთ დააკავშიროთ ყველა გვერდი და ყველა ბიზნესი.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "დახურეთ ეს ფანჯარა, წაშალეთ ინტეგრაცია და თავიდან დაამატეთ არხი.", + "back_to_postiz": "Postiz-ზე დაბრუნება", "select_instagram_account": "აირჩიეთ Instagram ანგარიში:", "select_page": "გვერდის არჩევა:", "generate_image_with_ai": "სურათის გენერირება AI-ით", diff --git a/libraries/react-shared-libraries/src/translation/locales/ko/translation.json b/libraries/react-shared-libraries/src/translation/locales/ko/translation.json index fba9c26375..2f5a7ac01a 100644 --- a/libraries/react-shared-libraries/src/translation/locales/ko/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/ko/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "선택한 페이지에 연결된 비즈니스를 찾을 수 없습니다.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "모든 페이지와 모든 비즈니스를 연결하는 것을 권장합니다.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "이 대화 상자를 닫고, 통합을 삭제한 후 새 채널을 다시 추가해 주세요.", + "back_to_postiz": "Postiz로 돌아가기", "select_instagram_account": "Instagram 계정 선택:", "select_page": "페이지 선택:", "generate_image_with_ai": "AI로 이미지 생성", diff --git a/libraries/react-shared-libraries/src/translation/locales/pt/translation.json b/libraries/react-shared-libraries/src/translation/locales/pt/translation.json index 8b32e51a85..068b507e2d 100644 --- a/libraries/react-shared-libraries/src/translation/locales/pt/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/pt/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "Não conseguimos encontrar nenhum negócio conectado às páginas selecionadas.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Recomendamos que você conecte todas as páginas e todos os negócios.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Por favor, feche este diálogo, exclua sua integração e adicione um novo canal novamente.", + "back_to_postiz": "Voltar ao Postiz", "select_instagram_account": "Selecione a Conta do Instagram:", "select_page": "Selecione a Página:", "generate_image_with_ai": "Gerar imagem com IA", diff --git a/libraries/react-shared-libraries/src/translation/locales/ru/translation.json b/libraries/react-shared-libraries/src/translation/locales/ru/translation.json index cdb2644cc4..95f27e20c2 100644 --- a/libraries/react-shared-libraries/src/translation/locales/ru/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/ru/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "Мы не смогли найти ни одного бизнеса, связанного с выбранными страницами.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Рекомендуем подключить все страницы и все бизнесы.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Пожалуйста, закройте это окно, удалите интеграцию и снова добавьте новый канал.", + "back_to_postiz": "Вернуться в Postiz", "select_instagram_account": "Выберите аккаунт Instagram:", "select_page": "Выберите страницу:", "generate_image_with_ai": "Сгенерировать изображение с помощью ИИ", diff --git a/libraries/react-shared-libraries/src/translation/locales/tr/translation.json b/libraries/react-shared-libraries/src/translation/locales/tr/translation.json index 5beff003f4..d70786b38c 100644 --- a/libraries/react-shared-libraries/src/translation/locales/tr/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/tr/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "Seçilen sayfalara bağlı herhangi bir işletme bulamadık.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Tüm sayfaları ve tüm işletmeleri bağlamanızı öneririz.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Lütfen bu pencereyi kapatın, entegrasyonunuzu silin ve tekrar yeni bir kanal ekleyin.", + "back_to_postiz": "Postiz'e geri dön", "select_instagram_account": "Instagram Hesabı Seç:", "select_page": "Sayfa Seç:", "generate_image_with_ai": "Yapay Zeka ile görsel oluştur", diff --git a/libraries/react-shared-libraries/src/translation/locales/vi/translation.json b/libraries/react-shared-libraries/src/translation/locales/vi/translation.json index fb66983ce7..1638be0347 100644 --- a/libraries/react-shared-libraries/src/translation/locales/vi/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/vi/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "Chúng tôi không tìm thấy doanh nghiệp nào liên kết với các trang đã chọn.", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "Chúng tôi khuyên bạn nên kết nối tất cả các trang và tất cả các doanh nghiệp.", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "Vui lòng đóng hộp thoại này, xóa tích hợp của bạn và thêm kênh mới lại.", + "back_to_postiz": "Quay lại Postiz", "select_instagram_account": "Chọn tài khoản Instagram:", "select_page": "Chọn Trang:", "generate_image_with_ai": "Tạo hình ảnh bằng AI", diff --git a/libraries/react-shared-libraries/src/translation/locales/zh/translation.json b/libraries/react-shared-libraries/src/translation/locales/zh/translation.json index 8d0208c099..09d39d1061 100644 --- a/libraries/react-shared-libraries/src/translation/locales/zh/translation.json +++ b/libraries/react-shared-libraries/src/translation/locales/zh/translation.json @@ -230,6 +230,7 @@ "we_couldn_t_find_any_business_connected_to_the_selected_pages": "我们未能找到与所选页面关联的任何企业。", "we_recommend_you_to_connect_all_the_pages_and_all_the_businesses": "我们建议您连接所有页面和所有企业。", "please_close_this_dialog_delete_your_integration_and_add_a_new_channel_again": "请关闭此对话框,删除您的集成并再次添加新频道。", + "back_to_postiz": "返回 Postiz", "select_instagram_account": "选择 Instagram 账号:", "select_page": "选择页面:", "generate_image_with_ai": "用 AI 生成图片",