* 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
18 KiB
PHP
385 lines
18 KiB
PHP
<?php
|
||
|
||
return [
|
||
'title' => 'Impostazioni',
|
||
'description' => 'Gestisci il tuo profilo e le impostazioni dell\'account',
|
||
|
||
'hub' => [
|
||
'title' => 'Impostazioni',
|
||
'description' => 'Scegli cosa vuoi gestire.',
|
||
'profile' => [
|
||
'title' => 'Profilo',
|
||
'description' => 'Aggiorna le tue informazioni personali, la password e le preferenze di notifica.',
|
||
],
|
||
'workspace' => [
|
||
'title' => 'Workspace',
|
||
'description' => 'Configura il tuo workspace, il brand, i membri e le chiavi API.',
|
||
],
|
||
'account' => [
|
||
'title' => 'Account',
|
||
'description' => 'Gestisci le informazioni del tuo account, l\'utilizzo e la fatturazione.',
|
||
],
|
||
],
|
||
|
||
'nav' => [
|
||
'profile' => 'Profilo',
|
||
'authentication' => 'Autenticazione',
|
||
'workspace' => 'Workspace',
|
||
'members' => 'Membri',
|
||
'notifications' => 'Notifiche',
|
||
'billing' => 'Fatturazione',
|
||
],
|
||
|
||
'notifications' => [
|
||
'title' => 'Preferenze di notifica',
|
||
'heading' => 'Notifiche email',
|
||
'description' => 'Scegli quali notifiche email vuoi ricevere',
|
||
'post_published' => 'Post pubblicato',
|
||
'post_published_description' => 'Ricevi un\'email quando il tuo post viene pubblicato con successo',
|
||
'post_failed' => 'Pubblicazione non riuscita',
|
||
'post_failed_description' => 'Ricevi un\'email quando la pubblicazione del tuo post non riesce',
|
||
'account_disconnected' => 'Account scollegato',
|
||
'account_disconnected_description' => 'Ricevi un\'email quando un account social viene scollegato',
|
||
'save' => 'Salva preferenze',
|
||
],
|
||
|
||
'profile' => [
|
||
'title' => 'Impostazioni profilo',
|
||
'photo_heading' => 'Foto del profilo',
|
||
'photo_description' => 'Carica una foto del profilo',
|
||
'heading' => 'Informazioni del profilo',
|
||
'description' => 'Aggiorna il tuo nome e indirizzo email',
|
||
'avatar' => 'Avatar',
|
||
'name' => 'Nome',
|
||
'name_placeholder' => 'Nome completo',
|
||
'email' => 'Indirizzo email',
|
||
'email_placeholder' => 'Indirizzo email',
|
||
'email_unverified' => 'Il tuo indirizzo email non è verificato.',
|
||
'resend_verification' => 'Clicca qui per inviare di nuovo l\'email di verifica.',
|
||
'verification_sent' => 'Un nuovo link di verifica è stato inviato al tuo indirizzo email.',
|
||
'save' => 'Salva',
|
||
],
|
||
|
||
'authentication' => [
|
||
'title' => 'Autenticazione',
|
||
'page_title' => 'Impostazioni di autenticazione',
|
||
'sessions' => [
|
||
'title' => 'Sessioni attive',
|
||
'description' => 'Se noti qualcosa di sospetto, disconnetti gli altri dispositivi.',
|
||
'unknown_browser' => 'Browser sconosciuto',
|
||
'unknown_ip' => 'IP sconosciuto',
|
||
'on' => 'su',
|
||
'active_now' => 'Attivo ora',
|
||
'log_out_others' => 'Disconnetti gli altri dispositivi',
|
||
'modal_title' => 'Disconnetti gli altri dispositivi',
|
||
'modal_description_password' => 'Inserisci la tua password attuale per confermare che vuoi disconnettere le altre sessioni del browser.',
|
||
'modal_description_email' => 'Digita il tuo indirizzo email per confermare che vuoi disconnettere le altre sessioni del browser.',
|
||
'password_placeholder' => 'Password attuale',
|
||
'email_placeholder' => 'L\'email del tuo account',
|
||
'cancel' => 'Annulla',
|
||
'submit' => 'Disconnetti gli altri dispositivi',
|
||
'email_mismatch' => 'L\'indirizzo email non corrisponde al tuo account.',
|
||
'flash_logged_out' => 'Sei stato disconnesso dagli altri dispositivi.',
|
||
],
|
||
'password' => [
|
||
'update_title' => 'Aggiorna password',
|
||
'set_title' => 'Imposta una password',
|
||
'update_description' => 'Assicurati che il tuo account usi una password lunga e casuale per restare al sicuro.',
|
||
'set_description' => 'Aggiungi una password così puoi accedere senza un provider collegato.',
|
||
'current_password' => 'Password attuale',
|
||
'new_password' => 'Nuova password',
|
||
'confirm_password' => 'Conferma password',
|
||
'save' => 'Salva password',
|
||
'set' => 'Imposta password',
|
||
],
|
||
'providers' => [
|
||
'title' => 'Account collegati',
|
||
'description' => 'Accedi più velocemente con questi provider collegati.',
|
||
'connected' => 'Collegato',
|
||
'not_connected' => 'Non collegato',
|
||
'connect' => 'Collega',
|
||
'disconnect' => 'Scollega',
|
||
'flash_disconnected' => ':provider scollegato con successo.',
|
||
'flash_connected' => ':provider collegato con successo.',
|
||
'flash_already_linked' => 'Quell\'account :provider è già collegato a un altro utente.',
|
||
'flash_cannot_disconnect' => 'Non puoi scollegare il tuo unico metodo di accesso. Imposta prima una password o collega un altro provider.',
|
||
],
|
||
],
|
||
|
||
'delete_account' => [
|
||
'heading' => 'Elimina account',
|
||
'description' => 'Elimina il tuo account e tutte le sue risorse',
|
||
'warning' => 'Attenzione',
|
||
'warning_message' => 'Procedi con cautela: questa azione non può essere annullata. Se sei il proprietario di questo account, anche i membri invitati verranno eliminati in modo permanente.',
|
||
'button' => 'Elimina account',
|
||
'modal_title' => 'Vuoi davvero eliminare il tuo account?',
|
||
'modal_description_password' => 'Una volta eliminato il tuo account, tutte le sue risorse e i suoi dati saranno eliminati definitivamente. Se sei il proprietario dell’account, anche i membri invitati verranno eliminati in modo permanente. Inserisci la tua password per confermare.',
|
||
'modal_description_email' => 'Una volta eliminato il tuo account, tutte le sue risorse e i suoi dati saranno eliminati definitivamente. Se sei il proprietario dell’account, anche i membri invitati verranno eliminati in modo permanente. Digita il tuo indirizzo email :email per confermare.',
|
||
'password' => 'Password',
|
||
'password_placeholder' => 'Password',
|
||
'email_placeholder' => 'L\'email del tuo account',
|
||
'email_mismatch' => 'L\'indirizzo email non corrisponde al tuo account.',
|
||
'cancel' => 'Annulla',
|
||
'confirm' => 'Elimina account',
|
||
],
|
||
|
||
'workspace' => [
|
||
'tabs' => [
|
||
'workspace' => 'Workspace',
|
||
'brand' => 'Brand',
|
||
'users' => 'Membri',
|
||
'api_keys' => 'Chiavi API',
|
||
'mcp' => 'MCP',
|
||
],
|
||
'title' => 'Impostazioni del workspace',
|
||
'logo_heading' => 'Logo del workspace',
|
||
'logo_description' => 'Carica un logo per il tuo workspace',
|
||
'heading' => 'Nome del workspace',
|
||
'description' => 'Aggiorna il nome del tuo workspace',
|
||
'members_heading' => 'Membri',
|
||
'members_description' => 'Gestisci i membri e gli inviti del workspace',
|
||
'name' => 'Nome',
|
||
'name_placeholder' => 'Il mio workspace',
|
||
'save' => 'Salva',
|
||
'danger_description' => 'Azioni irreversibili.',
|
||
'delete_warning' => 'Attenzione',
|
||
'delete_title' => 'Elimina questo workspace',
|
||
'delete_description' => 'Elimina definitivamente questo workspace e tutto il suo contenuto — post, account collegati e media. Verrai addebitato per un workspace in meno.',
|
||
'delete_description_self_hosted' => 'Elimina definitivamente questo workspace, i suoi post, gli account collegati e i media.',
|
||
'delete_only_description' => 'Non puoi eliminare il tuo unico workspace. Annulla l’abbonamento nella fatturazione per smettere di pagare, oppure elimina il tuo account in Autenticazione per annullare la fatturazione e rimuovere tutto in modo permanente.',
|
||
'delete_go_to_billing' => 'Vai alla fatturazione',
|
||
'delete_go_to_delete_account' => 'Elimina account',
|
||
'delete_members_warning' => '{1}:count altro membro perderà l’accesso. I membri senza un altro workspace TryPost verranno eliminati in modo permanente.|[2,*]:count altri membri perderanno l’accesso. I membri senza un altro workspace TryPost verranno eliminati in modo permanente.',
|
||
'delete_action' => 'Elimina workspace',
|
||
'delete_cancel' => 'Annulla',
|
||
'delete_confirm_title' => 'Eliminare il workspace?',
|
||
'delete_confirm_description' => 'Questo elimina definitivamente il workspace e tutti i suoi dati. La fatturazione verrà aggiornata per riflettere un workspace in meno.',
|
||
'delete_confirm_description_self_hosted' => 'Questo elimina definitivamente il workspace e tutti i suoi dati.',
|
||
],
|
||
|
||
'brand' => [
|
||
'title' => 'Brand',
|
||
'description' => 'Configura l\'identità del tuo brand per i contenuti generati dall\'IA.',
|
||
'name' => 'Nome del workspace',
|
||
'name_placeholder' => 'Il mio brand',
|
||
'website' => 'Sito web',
|
||
'website_placeholder' => 'https://iltuobrand.com',
|
||
'brand_description' => 'Descrizione',
|
||
'brand_description_placeholder' => 'Raccontaci del tuo brand, cosa fai e chi è il tuo pubblico...',
|
||
'voice' => 'Tono del brand',
|
||
'voice_description' => 'Scegli i tratti che definiscono come suonano i tuoi contenuti.',
|
||
'voice_group' => [
|
||
'pov' => 'Punto di vista',
|
||
'formality' => 'Formalità',
|
||
'energy' => 'Energia',
|
||
'humor' => 'Umorismo',
|
||
'attitude' => 'Atteggiamento',
|
||
'warmth' => 'Calore',
|
||
'confidence' => 'Sicurezza',
|
||
'style' => 'Stile',
|
||
],
|
||
'voice_trait' => [
|
||
'first_person' => 'Prima persona',
|
||
'second_person' => 'Seconda persona (tu)',
|
||
'third_person' => 'Terza persona',
|
||
'formal' => 'Formale',
|
||
'balanced' => 'Equilibrato',
|
||
'casual' => 'Informale',
|
||
'calm' => 'Calmo',
|
||
'moderate' => 'Moderato',
|
||
'enthusiastic' => 'Entusiasta',
|
||
'vibrant' => 'Vivace',
|
||
'serious' => 'Serio',
|
||
'dry' => 'Pacato / sottile',
|
||
'witty' => 'Arguto',
|
||
'playful' => 'Giocoso',
|
||
'respectful' => 'Rispettoso',
|
||
'even_handed' => 'Imparziale',
|
||
'bold' => 'Audace',
|
||
'provocative' => 'Provocatorio',
|
||
'neutral' => 'Neutro',
|
||
'friendly' => 'Amichevole',
|
||
'empathetic' => 'Empatico',
|
||
'humble' => 'Umile',
|
||
'confident' => 'Sicuro',
|
||
'assertive' => 'Assertivo',
|
||
'direct' => 'Diretto',
|
||
'concise' => 'Conciso',
|
||
'transparent' => 'Trasparente',
|
||
'no_hype' => 'Senza esagerazioni',
|
||
'practical' => 'Pratico',
|
||
'data_driven' => 'Basato sui dati',
|
||
'storytelling' => 'Narrativo',
|
||
'inspirational' => 'Ispirazionale',
|
||
'educational' => 'Educativo',
|
||
'technical' => 'Tecnico',
|
||
'minimalist' => 'Poche emoji',
|
||
],
|
||
'brand_color' => 'Colore del brand',
|
||
'background_color' => 'Colore di sfondo',
|
||
'text_color' => 'Colore del testo',
|
||
'font' => 'Font',
|
||
'image_style' => 'Stile immagine',
|
||
'image_style_description' => 'Stile visivo applicato quando si generano le immagini delle slide e di copertina per i post IA.',
|
||
'image_style_cinematic' => 'Cinematografico',
|
||
'image_style_illustration' => 'Illustrazione',
|
||
'image_style_isometric_3d' => 'Isometrico',
|
||
'image_style_cartoon' => 'Cartone animato',
|
||
'image_style_typographic' => 'Tipografico',
|
||
'image_style_infographic' => 'Infografica',
|
||
'image_style_minimalist' => 'Minimalista',
|
||
'image_style_mockup' => 'Mockup',
|
||
'content_language' => 'Lingua dei contenuti',
|
||
'content_language_description' => 'Lingua usata per didascalie, hashtag generati dall\'IA e qualsiasi testo all\'interno di immagini o video generati.',
|
||
'font_placeholder' => 'Seleziona un font…',
|
||
'font_search' => 'Cerca font…',
|
||
'font_empty' => 'Nessun font trovato.',
|
||
'language_placeholder' => 'Seleziona una lingua…',
|
||
'language_search' => 'Cerca lingua…',
|
||
'language_empty' => 'Nessuna lingua trovata.',
|
||
|
||
],
|
||
|
||
'members' => [
|
||
'title' => 'Membri',
|
||
'heading' => 'Membri del team',
|
||
'description' => 'Gestisci membri e inviti per questo workspace',
|
||
|
||
'cancel' => 'Annulla',
|
||
'remove' => 'Rimuovi',
|
||
'make_role' => 'Rendi :role',
|
||
|
||
'invite' => [
|
||
'title' => 'Invita membro',
|
||
'description' => 'Invia un invito via email per aggiungere collaboratori',
|
||
'email' => 'Email',
|
||
'email_placeholder' => 'collaboratore@email.com',
|
||
'role' => 'Ruolo',
|
||
'role_placeholder' => 'Seleziona un ruolo',
|
||
'submit' => 'Invia invito',
|
||
],
|
||
|
||
'pending' => [
|
||
'title' => 'Inviti in sospeso',
|
||
'description' => 'Inviti in attesa di accettazione',
|
||
'empty' => 'Nessun invito in sospeso',
|
||
],
|
||
|
||
'list' => [
|
||
'title' => 'Membri',
|
||
'description' => 'Persone con accesso a questo workspace',
|
||
'empty' => 'Nessun membro oltre al proprietario',
|
||
],
|
||
|
||
'remove_modal' => [
|
||
'title' => 'Rimuovi membro',
|
||
'description' => 'Vuoi davvero rimuovere questo membro dal workspace? Perderà l\'accesso a tutte le risorse del workspace.',
|
||
'action' => 'Rimuovi membro',
|
||
],
|
||
|
||
'cancel_invite_modal' => [
|
||
'title' => 'Annulla invito',
|
||
'description' => 'Vuoi davvero annullare questo invito?',
|
||
'action' => 'Annulla invito',
|
||
],
|
||
|
||
'roles' => [
|
||
'owner' => 'Proprietario',
|
||
'admin' => 'Amministratore',
|
||
'member' => 'Membro',
|
||
'viewer' => 'Visualizzatore',
|
||
],
|
||
|
||
'errors' => [
|
||
'invite_exists' => 'Esiste già un invito per questa email.',
|
||
'email_belongs_to_account' => 'Questa email appartiene già a un altro account TryPost. Chiedi un’email di lavoro dedicata.',
|
||
],
|
||
|
||
'flash' => [
|
||
'invite_sent' => 'Invito inviato con successo!',
|
||
'invite_deleted' => 'Invito eliminato.',
|
||
'member_removed' => 'Membro rimosso con successo.',
|
||
'role_updated' => 'Ruolo del membro aggiornato.',
|
||
'wrong_email' => 'Questo invito è per un indirizzo email diverso.',
|
||
'already_member' => 'Sei già membro di questo workspace.',
|
||
'invite_accepted' => 'Benvenuto! Ora sei membro del workspace.',
|
||
'invite_workspace_gone' => 'Questo invito non è più valido perché il workspace è stato eliminato.',
|
||
'invite_declined' => 'Invito rifiutato.',
|
||
],
|
||
],
|
||
|
||
'account' => [
|
||
'tabs' => [
|
||
'account' => 'Account',
|
||
'usage' => 'Utilizzo',
|
||
'billing' => 'Fatturazione',
|
||
],
|
||
'title' => 'Impostazioni dell\'account',
|
||
'description' => 'Gestisci il nome del tuo account e l\'email di fatturazione',
|
||
'name' => 'Nome dell\'account',
|
||
'name_placeholder' => 'La mia azienda',
|
||
'billing_email' => 'Email di fatturazione',
|
||
'billing_email_placeholder' => 'fatturazione@azienda.com',
|
||
'billing_email_hint' => 'Questa email sarà usata per le fatture e le comunicazioni di fatturazione da Stripe.',
|
||
'submit' => 'Salva',
|
||
],
|
||
|
||
'flash' => [
|
||
'account_updated' => 'Account aggiornato con successo!',
|
||
'profile_updated' => 'Profilo aggiornato con successo!',
|
||
'password_updated' => 'Password aggiornata con successo!',
|
||
'workspace_updated' => 'Impostazioni aggiornate con successo!',
|
||
'photo_updated' => 'Foto aggiornata con successo!',
|
||
'photo_deleted' => 'Foto rimossa con successo!',
|
||
'delete_failed_billing' => 'Non siamo riusciti a cancellare l’abbonamento presso il fornitore di fatturazione. Non è stato eliminato nulla. Riprova o contatta l’assistenza.',
|
||
'logo_updated' => 'Logo caricato con successo!',
|
||
'logo_deleted' => 'Logo rimosso con successo!',
|
||
'notifications_updated' => 'Preferenze di notifica aggiornate!',
|
||
],
|
||
|
||
'api_keys' => [
|
||
'title' => 'Chiavi API',
|
||
'page_title' => 'Chiavi API',
|
||
'heading' => 'Chiavi API',
|
||
'description' => 'Gestisci le chiavi API per l\'accesso programmatico al tuo workspace.',
|
||
'create' => 'Crea chiave API',
|
||
'copy' => 'Copia',
|
||
'new_token_message' => 'La tua nuova chiave API è stata creata. Copiala ora — non potrai vederla di nuovo.',
|
||
'table' => [
|
||
'name' => 'Nome',
|
||
'key' => 'Chiave',
|
||
'status' => 'Stato',
|
||
'expires' => 'Scadenza',
|
||
'last_used' => 'Ultimo utilizzo',
|
||
'never' => 'Mai',
|
||
],
|
||
'actions' => [
|
||
'copy_id' => 'Copia ID chiave API',
|
||
'copy_id_success' => 'ID chiave API copiato negli appunti',
|
||
'delete' => 'Elimina',
|
||
],
|
||
'empty' => [
|
||
'title' => 'Ancora nessuna chiave API',
|
||
'description' => 'Crea una chiave API per accedere al tuo workspace in modo programmatico.',
|
||
],
|
||
'delete_modal' => [
|
||
'title' => 'Elimina chiave API',
|
||
'description' => 'Vuoi davvero eliminare questa chiave API? Tutte le applicazioni che usano questa chiave perderanno immediatamente l\'accesso.',
|
||
'action' => 'Elimina chiave API',
|
||
],
|
||
'create_dialog' => [
|
||
'title' => 'Crea chiave API',
|
||
'description' => 'Crea una nuova chiave API per l\'accesso programmatico al tuo workspace.',
|
||
'name' => 'Nome',
|
||
'name_placeholder' => 'es. Chiave API di produzione',
|
||
'expires' => 'Data di scadenza (facoltativa)',
|
||
'expires_placeholder' => 'Nessuna scadenza',
|
||
'submit' => 'Crea',
|
||
'cancel' => 'Annulla',
|
||
],
|
||
'flash' => [
|
||
'created' => 'Chiave API creata con successo!',
|
||
'deleted' => 'Chiave API eliminata con successo!',
|
||
],
|
||
],
|
||
];
|