* Add workspace MCP settings and token access controls. Ship MCP settings UI, OAuth revoke/list helpers, Passport deploy wiring, and workspace.token:mcp gating so assistants can connect without pulling in welcome/onboarding from the parent epic. Co-authored-by: Cursor <cursoragent@cursor.com> * Type MCP client config shapes instead of string checks. Encode http/config-root on each advanced client and tighten primary client ids so snippet generation does not branch on magic strings. Co-authored-by: Cursor <cursoragent@cursor.com> * Polish MCP settings follow-ups from review. Translate Ukrainian MCP copy, deep-link ChatGPT into connector creation, drop an unused asset and revoke arg, and assert PATs are rejected on the MCP endpoint. Co-authored-by: Cursor <cursoragent@cursor.com> * Harden MCP connected clients, revoke scope, and OAuth consent. List recoverable sessions with live refresh tokens, revoke only PATs, throttle registration alone, and block viewers from authorizing MCP. Co-authored-by: Cursor <cursoragent@cursor.com> * Simplify MCP OAuth route throttling to a single middleware group. Co-authored-by: Cursor <cursoragent@cursor.com> * Allow workspace viewers read-only MCP access with web policy writes. Mirror the web app: MCP connects on view + OAuth mcp:use, write tools enforce createPost/update/delete/manageAccounts/manageTeam, and demotion to Viewer keeps grants. Cover role denials, consent, and disconnect. Co-authored-by: Cursor <cursoragent@cursor.com> * Harden MCP tool authz with shared workspace helpers. Route ApiKey tools through AuthorizesMcpTool, fail closed on null user or policy argument, and resolve the current workspace before mutating. Co-authored-by: Cursor <cursoragent@cursor.com> * Drop redundant string casts on validated request data. Enum::from and validated() fields are already strings, so the casts add noise without changing behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * Show only the current user's MCP connections in settings. Match API keys privacy: list and disconnect your own OAuth clients, not teammates' across the account. Co-authored-by: Cursor <cursoragent@cursor.com> * Cover LoadWorkspaceFromToken gaps and harden AuthorizesMcpTool tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Drop redundant is_string guard before UpdatePostTool find. Co-authored-by: Cursor <cursoragent@cursor.com> * Refactor AppSidebar to always show MCP link and simplify route middleware definition in ai.php. The MCP link is now consistently displayed regardless of the current workspace state, and the route middleware syntax has been streamlined. * Refresh MCP connected clients with Inertia usePoll. Co-authored-by: Cursor <cursoragent@cursor.com> * Bump laravel/mcp to 0.9.1 and add the TryPost server icon. Requires laravel/boost 2.5 for the Icon attribute; expose images/trypost/icon.png on TryPostServer. Co-authored-by: Cursor <cursoragent@cursor.com> * Drop no-op ReflectionClass import in TryPostServerTest. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
385 lines
19 KiB
PHP
385 lines
19 KiB
PHP
<?php
|
||
|
||
return [
|
||
'title' => 'Paramètres',
|
||
'description' => 'Gérez votre profil et les paramètres de votre compte',
|
||
|
||
'hub' => [
|
||
'title' => 'Paramètres',
|
||
'description' => 'Choisissez ce que vous souhaitez gérer.',
|
||
'profile' => [
|
||
'title' => 'Profil',
|
||
'description' => 'Mettez à jour vos informations personnelles, votre mot de passe et vos préférences de notification.',
|
||
],
|
||
'workspace' => [
|
||
'title' => 'Espace de travail',
|
||
'description' => 'Configurez votre espace de travail, votre marque, vos membres et vos clés API.',
|
||
],
|
||
'account' => [
|
||
'title' => 'Compte',
|
||
'description' => 'Gérez les informations, l\'utilisation et la facturation de votre compte.',
|
||
],
|
||
],
|
||
|
||
'nav' => [
|
||
'profile' => 'Profil',
|
||
'authentication' => 'Authentification',
|
||
'workspace' => 'Espace de travail',
|
||
'members' => 'Membres',
|
||
'notifications' => 'Notifications',
|
||
'billing' => 'Facturation',
|
||
],
|
||
|
||
'notifications' => [
|
||
'title' => 'Préférences de notification',
|
||
'heading' => 'Notifications par e-mail',
|
||
'description' => 'Choisissez les notifications par e-mail que vous souhaitez recevoir',
|
||
'post_published' => 'Publication publiée',
|
||
'post_published_description' => 'Recevez un e-mail lorsque votre publication est publiée avec succès',
|
||
'post_failed' => 'Échec de la publication',
|
||
'post_failed_description' => 'Recevez un e-mail lorsque la publication de votre contenu échoue',
|
||
'account_disconnected' => 'Compte déconnecté',
|
||
'account_disconnected_description' => 'Recevez un e-mail lorsqu\'un compte social est déconnecté',
|
||
'save' => 'Enregistrer les préférences',
|
||
],
|
||
|
||
'profile' => [
|
||
'title' => 'Paramètres du profil',
|
||
'photo_heading' => 'Photo de profil',
|
||
'photo_description' => 'Importez une photo de profil',
|
||
'heading' => 'Informations du profil',
|
||
'description' => 'Mettez à jour votre nom et votre adresse e-mail',
|
||
'avatar' => 'Avatar',
|
||
'name' => 'Nom',
|
||
'name_placeholder' => 'Nom complet',
|
||
'email' => 'Adresse e-mail',
|
||
'email_placeholder' => 'Adresse e-mail',
|
||
'email_unverified' => 'Votre adresse e-mail n\'est pas vérifiée.',
|
||
'resend_verification' => 'Cliquez ici pour renvoyer l\'e-mail de vérification.',
|
||
'verification_sent' => 'Un nouveau lien de vérification a été envoyé à votre adresse e-mail.',
|
||
'save' => 'Enregistrer',
|
||
],
|
||
|
||
'authentication' => [
|
||
'title' => 'Authentification',
|
||
'page_title' => 'Paramètres d\'authentification',
|
||
'sessions' => [
|
||
'title' => 'Sessions actives',
|
||
'description' => 'Si vous remarquez quelque chose de suspect, déconnectez les autres appareils.',
|
||
'unknown_browser' => 'Navigateur inconnu',
|
||
'unknown_ip' => 'IP inconnue',
|
||
'on' => 'le',
|
||
'active_now' => 'Actif maintenant',
|
||
'log_out_others' => 'Déconnecter les autres appareils',
|
||
'modal_title' => 'Déconnecter les autres appareils',
|
||
'modal_description_password' => 'Saisissez votre mot de passe actuel pour confirmer que vous souhaitez déconnecter les autres sessions de navigateur.',
|
||
'modal_description_email' => 'Saisissez votre adresse e-mail pour confirmer que vous souhaitez déconnecter les autres sessions de navigateur.',
|
||
'password_placeholder' => 'Mot de passe actuel',
|
||
'email_placeholder' => 'L\'e-mail de votre compte',
|
||
'cancel' => 'Annuler',
|
||
'submit' => 'Déconnecter les autres appareils',
|
||
'email_mismatch' => 'L\'adresse e-mail ne correspond pas à votre compte.',
|
||
'flash_logged_out' => 'Vous avez été déconnecté des autres appareils.',
|
||
],
|
||
'password' => [
|
||
'update_title' => 'Modifier le mot de passe',
|
||
'set_title' => 'Définir un mot de passe',
|
||
'update_description' => 'Assurez-vous que votre compte utilise un mot de passe long et aléatoire pour rester sécurisé.',
|
||
'set_description' => 'Ajoutez un mot de passe pour pouvoir vous connecter sans fournisseur associé.',
|
||
'current_password' => 'Mot de passe actuel',
|
||
'new_password' => 'Nouveau mot de passe',
|
||
'confirm_password' => 'Confirmer le mot de passe',
|
||
'save' => 'Enregistrer le mot de passe',
|
||
'set' => 'Définir le mot de passe',
|
||
],
|
||
'providers' => [
|
||
'title' => 'Comptes connectés',
|
||
'description' => 'Connectez-vous plus rapidement grâce à ces fournisseurs associés.',
|
||
'connected' => 'Connecté',
|
||
'not_connected' => 'Non connecté',
|
||
'connect' => 'Connecter',
|
||
'disconnect' => 'Déconnecter',
|
||
'flash_disconnected' => ':provider déconnecté avec succès.',
|
||
'flash_connected' => ':provider connecté avec succès.',
|
||
'flash_already_linked' => 'Ce compte :provider est déjà associé à un autre utilisateur.',
|
||
'flash_cannot_disconnect' => 'Vous ne pouvez pas déconnecter votre seule méthode de connexion. Définissez d\'abord un mot de passe ou connectez un autre fournisseur.',
|
||
],
|
||
],
|
||
|
||
'delete_account' => [
|
||
'heading' => 'Supprimer le compte',
|
||
'description' => 'Supprimez votre compte et toutes ses ressources',
|
||
'warning' => 'Avertissement',
|
||
'warning_message' => 'Procédez avec prudence : cette action est irréversible. Si vous êtes propriétaire de ce compte, les membres invités seront aussi définitivement supprimés.',
|
||
'button' => 'Supprimer le compte',
|
||
'modal_title' => 'Voulez-vous vraiment supprimer votre compte ?',
|
||
'modal_description_password' => 'Une fois votre compte supprimé, toutes ses ressources et données seront également supprimées définitivement. Si vous êtes propriétaire du compte, les membres invités seront aussi définitivement supprimés. Veuillez saisir votre mot de passe pour confirmer.',
|
||
'modal_description_email' => 'Une fois votre compte supprimé, toutes ses ressources et données seront également supprimées définitivement. Si vous êtes propriétaire du compte, les membres invités seront aussi définitivement supprimés. Veuillez saisir votre adresse e-mail :email pour confirmer.',
|
||
'password' => 'Mot de passe',
|
||
'password_placeholder' => 'Mot de passe',
|
||
'email_placeholder' => 'L\'e-mail de votre compte',
|
||
'email_mismatch' => 'L\'adresse e-mail ne correspond pas à votre compte.',
|
||
'cancel' => 'Annuler',
|
||
'confirm' => 'Supprimer le compte',
|
||
],
|
||
|
||
'workspace' => [
|
||
'tabs' => [
|
||
'workspace' => 'Espace de travail',
|
||
'brand' => 'Marque',
|
||
'users' => 'Membres',
|
||
'api_keys' => 'Clés API',
|
||
'mcp' => 'MCP',
|
||
],
|
||
'title' => 'Paramètres de l\'espace de travail',
|
||
'logo_heading' => 'Logo de l\'espace de travail',
|
||
'logo_description' => 'Importez un logo pour votre espace de travail',
|
||
'heading' => 'Nom de l\'espace de travail',
|
||
'description' => 'Mettez à jour le nom de votre espace de travail',
|
||
'members_heading' => 'Membres',
|
||
'members_description' => 'Gérez les membres et les invitations de l\'espace de travail',
|
||
'name' => 'Nom',
|
||
'name_placeholder' => 'Mon espace de travail',
|
||
'save' => 'Enregistrer',
|
||
'danger_description' => 'Actions irréversibles.',
|
||
'delete_warning' => 'Avertissement',
|
||
'delete_title' => 'Supprimer cet espace de travail',
|
||
'delete_description' => 'Supprime définitivement cet espace de travail et tout son contenu — publications, comptes connectés et médias. Vous serez facturé pour un espace de travail de moins.',
|
||
'delete_description_self_hosted' => 'Supprime définitivement cet espace de travail, ses publications, comptes connectés et médias.',
|
||
'delete_only_description' => 'Vous ne pouvez pas supprimer votre seul espace de travail. Annulez l’abonnement dans la facturation pour arrêter de payer, ou supprimez votre compte dans Authentification pour annuler la facturation et tout supprimer définitivement.',
|
||
'delete_go_to_billing' => 'Aller à la facturation',
|
||
'delete_go_to_delete_account' => 'Supprimer le compte',
|
||
'delete_members_warning' => '{1}:count autre membre perdra l’accès. Les membres sans autre workspace TryPost seront définitivement supprimés.|[2,*]:count autres membres perdront l’accès. Les membres sans autre workspace TryPost seront définitivement supprimés.',
|
||
'delete_action' => 'Supprimer l’espace de travail',
|
||
'delete_cancel' => 'Annuler',
|
||
'delete_confirm_title' => 'Supprimer l’espace de travail ?',
|
||
'delete_confirm_description' => 'Cela supprime définitivement l’espace de travail et toutes ses données. Votre facturation sera mise à jour pour refléter un espace de travail en moins.',
|
||
'delete_confirm_description_self_hosted' => 'Cela supprime définitivement l’espace de travail et toutes ses données.',
|
||
],
|
||
|
||
'brand' => [
|
||
'title' => 'Marque',
|
||
'description' => 'Configurez l\'identité de votre marque pour le contenu généré par l\'IA.',
|
||
'name' => 'Nom de l\'espace de travail',
|
||
'name_placeholder' => 'Ma marque',
|
||
'website' => 'Site web',
|
||
'website_placeholder' => 'https://yourbrand.com',
|
||
'brand_description' => 'Description',
|
||
'brand_description_placeholder' => 'Parlez-nous de votre marque, de ce que vous faites et de votre audience...',
|
||
'voice' => 'Voix de la marque',
|
||
'voice_description' => 'Choisissez les traits qui définissent le ton de votre contenu.',
|
||
'voice_group' => [
|
||
'pov' => 'Point de vue',
|
||
'formality' => 'Formalité',
|
||
'energy' => 'Énergie',
|
||
'humor' => 'Humour',
|
||
'attitude' => 'Attitude',
|
||
'warmth' => 'Chaleur',
|
||
'confidence' => 'Assurance',
|
||
'style' => 'Style',
|
||
],
|
||
'voice_trait' => [
|
||
'first_person' => 'Première personne',
|
||
'second_person' => 'Deuxième personne (vous)',
|
||
'third_person' => 'Troisième personne',
|
||
'formal' => 'Formel',
|
||
'balanced' => 'Équilibré',
|
||
'casual' => 'Décontracté',
|
||
'calm' => 'Calme',
|
||
'moderate' => 'Modéré',
|
||
'enthusiastic' => 'Enthousiaste',
|
||
'vibrant' => 'Vibrant',
|
||
'serious' => 'Sérieux',
|
||
'dry' => 'Pince-sans-rire',
|
||
'witty' => 'Spirituel',
|
||
'playful' => 'Enjoué',
|
||
'respectful' => 'Respectueux',
|
||
'even_handed' => 'Impartial',
|
||
'bold' => 'Audacieux',
|
||
'provocative' => 'Provocateur',
|
||
'neutral' => 'Neutre',
|
||
'friendly' => 'Amical',
|
||
'empathetic' => 'Empathique',
|
||
'humble' => 'Humble',
|
||
'confident' => 'Assuré',
|
||
'assertive' => 'Affirmé',
|
||
'direct' => 'Direct',
|
||
'concise' => 'Concis',
|
||
'transparent' => 'Transparent',
|
||
'no_hype' => 'Sans esbroufe',
|
||
'practical' => 'Pratique',
|
||
'data_driven' => 'Axé sur les données',
|
||
'storytelling' => 'Narratif',
|
||
'inspirational' => 'Inspirant',
|
||
'educational' => 'Éducatif',
|
||
'technical' => 'Technique',
|
||
'minimalist' => 'Peu d\'émojis',
|
||
],
|
||
'brand_color' => 'Couleur de la marque',
|
||
'background_color' => 'Couleur de fond',
|
||
'text_color' => 'Couleur du texte',
|
||
'font' => 'Police',
|
||
'image_style' => 'Style d\'image',
|
||
'image_style_description' => 'Style visuel appliqué lors de la génération des images de diapositives et de couverture des publications IA.',
|
||
'image_style_cinematic' => 'Cinématographique',
|
||
'image_style_illustration' => 'Illustration',
|
||
'image_style_isometric_3d' => 'Isométrique',
|
||
'image_style_cartoon' => 'Dessin animé',
|
||
'image_style_typographic' => 'Typographique',
|
||
'image_style_infographic' => 'Infographie',
|
||
'image_style_minimalist' => 'Minimaliste',
|
||
'image_style_mockup' => 'Maquette',
|
||
'content_language' => 'Langue du contenu',
|
||
'content_language_description' => 'Langue utilisée pour les légendes, les hashtags générés par l\'IA et tout texte à l\'intérieur des images ou vidéos générées.',
|
||
'font_placeholder' => 'Sélectionner une police…',
|
||
'font_search' => 'Rechercher une police…',
|
||
'font_empty' => 'Aucune police trouvée.',
|
||
'language_placeholder' => 'Sélectionner une langue…',
|
||
'language_search' => 'Rechercher une langue…',
|
||
'language_empty' => 'Aucune langue trouvée.',
|
||
|
||
],
|
||
|
||
'members' => [
|
||
'title' => 'Membres',
|
||
'heading' => 'Membres de l\'équipe',
|
||
'description' => 'Gérez les membres et les invitations de cet espace de travail',
|
||
|
||
'cancel' => 'Annuler',
|
||
'remove' => 'Retirer',
|
||
'make_role' => 'Nommer :role',
|
||
|
||
'invite' => [
|
||
'title' => 'Inviter un membre',
|
||
'description' => 'Envoyez une invitation par e-mail pour ajouter des collaborateurs',
|
||
'email' => 'E-mail',
|
||
'email_placeholder' => 'collaborateur@email.com',
|
||
'role' => 'Rôle',
|
||
'role_placeholder' => 'Sélectionner un rôle',
|
||
'submit' => 'Envoyer l\'invitation',
|
||
],
|
||
|
||
'pending' => [
|
||
'title' => 'Invitations en attente',
|
||
'description' => 'Invitations en attente d\'acceptation',
|
||
'empty' => 'Aucune invitation en attente',
|
||
],
|
||
|
||
'list' => [
|
||
'title' => 'Membres',
|
||
'description' => 'Personnes ayant accès à cet espace de travail',
|
||
'empty' => 'Aucun membre en dehors du propriétaire',
|
||
],
|
||
|
||
'remove_modal' => [
|
||
'title' => 'Retirer le membre',
|
||
'description' => 'Voulez-vous vraiment retirer ce membre de l\'espace de travail ? Il perdra l\'accès à toutes les ressources de l\'espace de travail.',
|
||
'action' => 'Retirer le membre',
|
||
],
|
||
|
||
'cancel_invite_modal' => [
|
||
'title' => 'Annuler l\'invitation',
|
||
'description' => 'Voulez-vous vraiment annuler cette invitation ?',
|
||
'action' => 'Annuler l\'invitation',
|
||
],
|
||
|
||
'roles' => [
|
||
'owner' => 'Propriétaire',
|
||
'admin' => 'Administrateur',
|
||
'member' => 'Membre',
|
||
'viewer' => 'Lecteur',
|
||
],
|
||
|
||
'errors' => [
|
||
'invite_exists' => 'Une invitation existe déjà pour cet e-mail.',
|
||
'email_belongs_to_account' => 'Cet e-mail appartient déjà à un autre compte TryPost. Demandez un e-mail professionnel dédié.',
|
||
],
|
||
|
||
'flash' => [
|
||
'invite_sent' => 'Invitation envoyée avec succès !',
|
||
'invite_deleted' => 'Invitation supprimée.',
|
||
'member_removed' => 'Membre retiré avec succès.',
|
||
'role_updated' => 'Rôle du membre mis à jour.',
|
||
'wrong_email' => 'Cette invitation concerne une autre adresse e-mail.',
|
||
'already_member' => 'Vous êtes déjà membre de cet espace de travail.',
|
||
'invite_accepted' => 'Bienvenue ! Vous êtes maintenant membre de l\'espace de travail.',
|
||
'invite_workspace_gone' => 'Cette invitation n’est plus valide car l’espace de travail a été supprimé.',
|
||
'invite_declined' => 'Invitation refusée.',
|
||
],
|
||
],
|
||
|
||
'account' => [
|
||
'tabs' => [
|
||
'account' => 'Compte',
|
||
'usage' => 'Utilisation',
|
||
'billing' => 'Facturation',
|
||
],
|
||
'title' => 'Paramètres du compte',
|
||
'description' => 'Gérez le nom de votre compte et l\'e-mail de facturation',
|
||
'name' => 'Nom du compte',
|
||
'name_placeholder' => 'Mon entreprise',
|
||
'billing_email' => 'E-mail de facturation',
|
||
'billing_email_placeholder' => 'facturation@entreprise.com',
|
||
'billing_email_hint' => 'Cet e-mail sera utilisé pour les factures et les communications de facturation de Stripe.',
|
||
'submit' => 'Enregistrer',
|
||
],
|
||
|
||
'flash' => [
|
||
'account_updated' => 'Compte mis à jour avec succès !',
|
||
'profile_updated' => 'Profil mis à jour avec succès !',
|
||
'password_updated' => 'Mot de passe mis à jour avec succès !',
|
||
'workspace_updated' => 'Paramètres mis à jour avec succès !',
|
||
'photo_updated' => 'Photo mise à jour avec succès !',
|
||
'photo_deleted' => 'Photo supprimée avec succès !',
|
||
'delete_failed_billing' => 'Nous n’avons pas pu annuler votre abonnement auprès du prestataire de facturation. Rien n’a été supprimé. Réessayez ou contactez le support.',
|
||
'logo_updated' => 'Logo importé avec succès !',
|
||
'logo_deleted' => 'Logo supprimé avec succès !',
|
||
'notifications_updated' => 'Préférences de notification mises à jour !',
|
||
],
|
||
|
||
'api_keys' => [
|
||
'title' => 'Clés API',
|
||
'page_title' => 'Clés API',
|
||
'heading' => 'Clés API',
|
||
'description' => 'Gérez les clés API pour l\'accès programmatique à votre espace de travail.',
|
||
'create' => 'Créer une clé API',
|
||
'copy' => 'Copier',
|
||
'new_token_message' => 'Votre nouvelle clé API a été créée. Copiez-la maintenant — vous ne pourrez plus la voir par la suite.',
|
||
'table' => [
|
||
'name' => 'Nom',
|
||
'key' => 'Clé',
|
||
'status' => 'Statut',
|
||
'expires' => 'Expire le',
|
||
'last_used' => 'Dernière utilisation',
|
||
'never' => 'Jamais',
|
||
],
|
||
'actions' => [
|
||
'copy_id' => 'Copier l\'ID de la clé API',
|
||
'copy_id_success' => 'ID de la clé API copié dans le presse-papiers',
|
||
'delete' => 'Supprimer',
|
||
],
|
||
'empty' => [
|
||
'title' => 'Aucune clé API pour le moment',
|
||
'description' => 'Créez une clé API pour accéder à votre espace de travail de manière programmatique.',
|
||
],
|
||
'delete_modal' => [
|
||
'title' => 'Supprimer la clé API',
|
||
'description' => 'Voulez-vous vraiment supprimer cette clé API ? Toutes les applications utilisant cette clé perdront immédiatement l\'accès.',
|
||
'action' => 'Supprimer la clé API',
|
||
],
|
||
'create_dialog' => [
|
||
'title' => 'Créer une clé API',
|
||
'description' => 'Créez une nouvelle clé API pour l\'accès programmatique à votre espace de travail.',
|
||
'name' => 'Nom',
|
||
'name_placeholder' => 'par ex. Clé API de production',
|
||
'expires' => 'Date d\'expiration (facultatif)',
|
||
'expires_placeholder' => 'Aucune expiration',
|
||
'submit' => 'Créer',
|
||
'cancel' => 'Annuler',
|
||
],
|
||
'flash' => [
|
||
'created' => 'Clé API créée avec succès !',
|
||
'deleted' => 'Clé API supprimée avec succès !',
|
||
],
|
||
],
|
||
];
|