mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-07-18 19:36:02 +00:00
feat(mcp): granular OAuth scopes and per-client rate limiting
- Split `media:read` into `geo:read` and `weather:read` scopes - Add dedicated `atlas:read/write` scopes (previously under `places`) - Add dedicated `todos:read/write` scopes (previously under `collab`) - Rate limiting now keyed by userId+clientId instead of userId alone - Bind MCP sessions to the OAuth client that created them - Log MCP tool calls to audit log with clientId - Invalidate all MCP sessions on addon state change - Reduce session sweep interval from 10min to 1min - Update all translations with new scope labels
This commit is contained in:
@@ -29,7 +29,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'common.change': 'Zmień',
|
||||
'common.uploading': 'Przesyłanie...',
|
||||
'common.backToPlanning': 'Powrót do planowania',
|
||||
'common.reset': 'Reset',
|
||||
'common.reset': 'Resetuj',
|
||||
|
||||
// Navbar
|
||||
'nav.trip': 'Podróż',
|
||||
@@ -198,7 +198,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.mcp.endpoint': 'Endpoint MCP',
|
||||
'settings.mcp.clientConfig': 'Konfiguracja klienta',
|
||||
'settings.mcp.clientConfigHint': 'Zastąp <your_token> tokenem API z listy poniżej. Ścieżka do npx może wymagać dostosowania do Twojego systemu (np. C:\\PROGRA~1\\nodejs\\npx.cmd w systemie Windows).',
|
||||
'settings.mcp.clientConfigHintOAuth': 'Replace <your_client_id> and <your_client_secret> with the credentials shown in the OAuth 2.1 client you created above. mcp-remote will open your browser to complete the authorization the first time you connect. The path to npx may need to be adjusted for your system (e.g. C:\PROGRA~1\nodejs\npx.cmd on Windows).',
|
||||
'settings.mcp.clientConfigHintOAuth': 'Zastąp <your_client_id> i <your_client_secret> danymi uwierzytelniającymi z klienta OAuth 2.1 utworzonego powyżej. mcp-remote otworzy przeglądarkę, aby dokończyć autoryzację przy pierwszym połączeniu. Ścieżka do npx może wymagać dostosowania do Twojego systemu (np. C:\\PROGRA~1\\nodejs\\npx.cmd w systemie Windows).',
|
||||
'settings.mcp.copy': 'Kopiuj',
|
||||
'settings.mcp.copied': 'Skopiowano!',
|
||||
'settings.mcp.apiTokens': 'Tokeny API',
|
||||
@@ -220,6 +220,48 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.mcp.toast.createError': 'Nie udało się utworzyć tokenu',
|
||||
'settings.mcp.toast.deleted': 'Token został usunięty',
|
||||
'settings.mcp.toast.deleteError': 'Nie udało się usunąć tokenu',
|
||||
'settings.mcp.apiTokensDeprecated': 'Tokeny API są przestarzałe i zostaną usunięte w przyszłej wersji. Użyj zamiast tego klientów OAuth 2.1.',
|
||||
'settings.oauth.clients': 'Klienci OAuth 2.1',
|
||||
'settings.oauth.clientsHint': 'Zarejestruj klientów OAuth 2.1, aby zewnętrzne aplikacje MCP (Claude Web, Cursor itp.) mogły się łączyć bez statycznych tokenów.',
|
||||
'settings.oauth.createClient': 'Nowy klient',
|
||||
'settings.oauth.noClients': 'Brak zarejestrowanych klientów OAuth.',
|
||||
'settings.oauth.clientId': 'ID klienta',
|
||||
'settings.oauth.clientSecret': 'Sekret klienta',
|
||||
'settings.oauth.deleteClient': 'Usuń klienta',
|
||||
'settings.oauth.deleteClientMessage': 'Ten klient i wszystkie aktywne sesje zostaną trwale usunięte. Każda aplikacja, która go używa, natychmiast utraci dostęp.',
|
||||
'settings.oauth.rotateSecret': 'Odnów sekret',
|
||||
'settings.oauth.rotateSecretMessage': 'Zostanie wygenerowany nowy sekret klienta, a wszystkie istniejące sesje zostaną natychmiast unieważnione. Zaktualizuj aplikację przed zamknięciem tego okna.',
|
||||
'settings.oauth.rotateSecretConfirm': 'Odnów',
|
||||
'settings.oauth.rotateSecretConfirming': 'Odnawianie…',
|
||||
'settings.oauth.rotateSecretDoneTitle': 'Wygenerowano nowy sekret',
|
||||
'settings.oauth.rotateSecretDoneWarning': 'Ten sekret jest wyświetlany tylko raz. Skopiuj go teraz i zaktualizuj aplikację — wszystkie poprzednie sesje zostały unieważnione.',
|
||||
'settings.oauth.activeSessions': 'Aktywne sesje OAuth',
|
||||
'settings.oauth.sessionScopes': 'Uprawnienia',
|
||||
'settings.oauth.sessionExpires': 'Wygasa',
|
||||
'settings.oauth.revoke': 'Unieważnij',
|
||||
'settings.oauth.revokeSession': 'Unieważnij sesję',
|
||||
'settings.oauth.revokeSessionMessage': 'Spowoduje to natychmiastowe unieważnienie dostępu dla tej sesji OAuth.',
|
||||
'settings.oauth.modal.createTitle': 'Zarejestruj klienta OAuth',
|
||||
'settings.oauth.modal.presets': 'Szybkie ustawienia',
|
||||
'settings.oauth.modal.clientName': 'Nazwa aplikacji',
|
||||
'settings.oauth.modal.clientNamePlaceholder': 'np. Claude Web, Moja aplikacja MCP',
|
||||
'settings.oauth.modal.redirectUris': 'URI przekierowania',
|
||||
'settings.oauth.modal.redirectUrisPlaceholder': 'https://your-app.com/callback\nhttps://your-app.com/auth',
|
||||
'settings.oauth.modal.redirectUrisHint': 'Jeden URI na linię. Wymagane HTTPS (localhost zwolniony). Wymagana dokładna zgodność.',
|
||||
'settings.oauth.modal.scopes': 'Dozwolone uprawnienia',
|
||||
'settings.oauth.modal.scopesHint': 'list_trips i get_trip_summary są zawsze dostępne — bez wymaganych uprawnień. Umożliwiają AI odkrycie potrzebnych ID podróży.',
|
||||
'settings.oauth.modal.selectAll': 'Zaznacz wszystko',
|
||||
'settings.oauth.modal.deselectAll': 'Odznacz wszystko',
|
||||
'settings.oauth.modal.creating': 'Rejestrowanie…',
|
||||
'settings.oauth.modal.create': 'Zarejestruj klienta',
|
||||
'settings.oauth.modal.createdTitle': 'Klient zarejestrowany',
|
||||
'settings.oauth.modal.createdWarning': 'Sekret klienta jest wyświetlany tylko raz. Skopiuj go teraz — nie można go odzyskać.',
|
||||
'settings.oauth.toast.createError': 'Nie udało się zarejestrować klienta OAuth',
|
||||
'settings.oauth.toast.deleted': 'Klient OAuth usunięty',
|
||||
'settings.oauth.toast.deleteError': 'Nie udało się usunąć klienta OAuth',
|
||||
'settings.oauth.toast.revoked': 'Sesja unieważniona',
|
||||
'settings.oauth.toast.revokeError': 'Nie udało się unieważnić sesji',
|
||||
'settings.oauth.toast.rotateError': 'Nie udało się odnowić sekretu klienta',
|
||||
'settings.account': 'Konto',
|
||||
'settings.about': 'O aplikacji',
|
||||
'settings.about.reportBug': 'Zgłoś błąd',
|
||||
@@ -429,7 +471,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'admin.recommended': 'Polecane',
|
||||
'admin.weatherKey': 'Klucz OpenWeatherMap API',
|
||||
'admin.weatherKeyHint': 'Do danych pogodowych. Uzyskaj go bezpłatnie na openweathermap.org',
|
||||
'admin.validateKey': 'Test',
|
||||
'admin.validateKey': 'Testuj',
|
||||
'admin.keyValid': 'Połączono',
|
||||
'admin.keyInvalid': 'Niepoprawny',
|
||||
'admin.keySaved': 'Klucze API zostały zapisane',
|
||||
@@ -485,7 +527,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'admin.addons.catalog.vacay.description': 'Osobisty planer urlopu z widokiem kalendarza',
|
||||
'admin.addons.catalog.atlas.name': 'Atlas',
|
||||
'admin.addons.catalog.atlas.description': 'Mapa świata z odwiedzonymi krajami i statystykami podróży',
|
||||
'admin.addons.catalog.collab.name': 'Collab',
|
||||
'admin.addons.catalog.collab.name': 'Współpraca',
|
||||
'admin.addons.catalog.collab.description': 'Notatki w czasie rzeczywistym, ankiety i czat do planowania podróży',
|
||||
'admin.addons.catalog.memories.name': 'Zdjęcia (Immich)',
|
||||
'admin.addons.catalog.memories.description': 'Udostępniaj zdjęcia z podróży za pośrednictwem swojej instancji Immich',
|
||||
@@ -610,7 +652,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'vacay.legend': 'Legenda',
|
||||
'vacay.publicHoliday': 'Święto państwowe',
|
||||
'vacay.companyHoliday': 'Urlop firmowy',
|
||||
'vacay.weekend': 'Weekend',
|
||||
'vacay.weekend': 'Weekendowy',
|
||||
'vacay.modeVacation': 'Urlop',
|
||||
'vacay.modeCompany': 'Urlop firmowy',
|
||||
'vacay.entitlement': 'Wymiar',
|
||||
@@ -708,7 +750,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.lastTrip': 'Ostatnia podróż',
|
||||
'atlas.nextTrip': 'Następna podróż',
|
||||
'atlas.daysLeft': 'dni do wyjazdu',
|
||||
'atlas.streak': 'Streak',
|
||||
'atlas.streak': 'Seria',
|
||||
'atlas.years': 'lata',
|
||||
'atlas.yearInRow': 'rok z rzędu',
|
||||
'atlas.yearsInRow': 'lat z rzędu',
|
||||
@@ -974,6 +1016,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'budget.totalBudget': 'Całkowity budżet',
|
||||
'budget.byCategory': 'Według kategorii',
|
||||
'budget.editTooltip': 'Kliknij, aby edytować',
|
||||
'budget.linkedToReservation': 'Powiązano z rezerwacją — edytuj nazwę tam',
|
||||
'budget.confirm.deleteCategory': 'Czy na pewno chcesz usunąć kategorię "{name}" z {count} wpisami?',
|
||||
'budget.deleteCategory': 'Usuń kategorię',
|
||||
'budget.perPerson': 'Za osobę',
|
||||
@@ -1074,6 +1117,9 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'packing.template': 'Szablon',
|
||||
'packing.templateApplied': '{count} przedmiotów dodanych z szablonu',
|
||||
'packing.templateError': 'Nie udało się zastosować szablonu',
|
||||
'packing.saveAsTemplate': 'Zapisz jako szablon',
|
||||
'packing.templateName': 'Nazwa szablonu',
|
||||
'packing.templateSaved': 'Lista pakowania zapisana jako szablon',
|
||||
'packing.bags': 'Torby',
|
||||
'packing.noBag': 'Nieprzypisane',
|
||||
'packing.totalWeight': 'Waga całkowita',
|
||||
@@ -1357,8 +1403,6 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'memories.reviewTitle': 'Przejrzyj swoje zdjęcia',
|
||||
'memories.reviewHint': 'Kliknij w zdjęcia, aby wykluczyć je z udostępnienia.',
|
||||
'memories.shareCount': 'Udostępnij {count} zdjęć',
|
||||
'memories.immichUrl': 'URL serwera Immich',
|
||||
'memories.immichApiKey': 'Klucz API',
|
||||
'memories.testConnection': 'Test',
|
||||
'memories.connected': 'Połączono',
|
||||
'memories.disconnected': 'Nie połączono',
|
||||
@@ -1467,11 +1511,8 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'admin.notifications.title': 'Powiadomienia',
|
||||
'admin.notifications.hint': 'Wybierz jeden kanał powiadomień.',
|
||||
'admin.notifications.none': 'Wyłączone',
|
||||
'admin.notifications.email': 'Email (SMTP)',
|
||||
'admin.notifications.email': 'E-mail (SMTP)',
|
||||
'admin.notifications.webhook': 'Webhook',
|
||||
'admin.notifications.events': 'Zdarzenia powiadomień',
|
||||
'admin.notifications.eventsHint': 'Wybierz zdarzenia wyzwalające powiadomienia.',
|
||||
'admin.notifications.configureFirst': 'Najpierw skonfiguruj ustawienia SMTP lub webhook.',
|
||||
'admin.notifications.save': 'Zapisz ustawienia powiadomień',
|
||||
'admin.notifications.saved': 'Ustawienia powiadomień zapisane',
|
||||
'admin.notifications.testWebhook': 'Wyślij testowy webhook',
|
||||
@@ -1496,7 +1537,7 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.webhookUrl.hint': 'Wprowadź adres URL webhooka Discord, Slack lub własnego, aby otrzymywać powiadomienia.',
|
||||
'settings.webhookUrl.save': 'Zapisz',
|
||||
'settings.webhookUrl.saved': 'URL webhooka zapisany',
|
||||
'settings.webhookUrl.test': 'Test',
|
||||
'settings.webhookUrl.test': 'Testuj',
|
||||
'settings.webhookUrl.testSuccess': 'Testowy webhook wysłany pomyślnie',
|
||||
'settings.webhookUrl.testFailed': 'Wysyłanie testowego webhooka nie powiodło się',
|
||||
'settings.notificationPreferences.inapp': 'In-App',
|
||||
@@ -1692,6 +1733,70 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'notif.generic.text': 'Masz nowe powiadomienie',
|
||||
'notif.dev.unknown_event.title': '[DEV] Nieznane zdarzenie',
|
||||
'notif.dev.unknown_event.text': 'Typ zdarzenia "{event}" nie jest zarejestrowany w EVENT_NOTIFICATION_CONFIG',
|
||||
|
||||
// OAuth scope groups
|
||||
'oauth.scope.group.trips': 'Podróże',
|
||||
'oauth.scope.group.places': 'Miejsca',
|
||||
'oauth.scope.group.atlas': 'Atlas',
|
||||
'oauth.scope.group.packing': 'Pakowanie',
|
||||
'oauth.scope.group.todos': 'Zadania',
|
||||
'oauth.scope.group.budget': 'Budżet',
|
||||
'oauth.scope.group.reservations': 'Rezerwacje',
|
||||
'oauth.scope.group.collab': 'Współpraca',
|
||||
'oauth.scope.group.notifications': 'Powiadomienia',
|
||||
'oauth.scope.group.vacay': 'Urlop',
|
||||
'oauth.scope.group.geo': 'Geo',
|
||||
'oauth.scope.group.weather': 'Pogoda',
|
||||
|
||||
// OAuth scope labels & descriptions
|
||||
'oauth.scope.trips:read.label': 'Przeglądaj podróże i itineraria',
|
||||
'oauth.scope.trips:read.description': 'Odczytuj podróże, dni, notatki i członków',
|
||||
'oauth.scope.trips:write.label': 'Edytuj podróże i itineraria',
|
||||
'oauth.scope.trips:write.description': 'Twórz i aktualizuj podróże, dni, notatki oraz zarządzaj członkami',
|
||||
'oauth.scope.trips:delete.label': 'Usuń podróże',
|
||||
'oauth.scope.trips:delete.description': 'Trwale usuń całe podróże — ta akcja jest nieodwracalna',
|
||||
'oauth.scope.trips:share.label': 'Zarządzaj linkami udostępniania',
|
||||
'oauth.scope.trips:share.description': 'Twórz, aktualizuj i unieważniaj publiczne linki udostępniania',
|
||||
'oauth.scope.places:read.label': 'Przeglądaj miejsca i dane mapy',
|
||||
'oauth.scope.places:read.description': 'Odczytuj miejsca, przypisania dni, tagi i kategorie',
|
||||
'oauth.scope.places:write.label': 'Zarządzaj miejscami',
|
||||
'oauth.scope.places:write.description': 'Twórz, aktualizuj i usuń miejsca, przypisania i tagi',
|
||||
'oauth.scope.atlas:read.label': 'Przeglądaj Atlas',
|
||||
'oauth.scope.atlas:read.description': 'Odczytuj odwiedzone kraje, regiony i listę marzeń',
|
||||
'oauth.scope.atlas:write.label': 'Zarządzaj Atlasem',
|
||||
'oauth.scope.atlas:write.description': 'Oznaczaj kraje i regiony jako odwiedzone, zarządzaj listą marzeń',
|
||||
'oauth.scope.packing:read.label': 'Przeglądaj listy pakowania',
|
||||
'oauth.scope.packing:read.description': 'Odczytuj przedmioty, torby i przypisania kategorii',
|
||||
'oauth.scope.packing:write.label': 'Zarządzaj listami pakowania',
|
||||
'oauth.scope.packing:write.description': 'Dodawaj, aktualizuj, usuwaj, zaznaczaj i porządkuj przedmioty i torby',
|
||||
'oauth.scope.todos:read.label': 'Przeglądaj listy zadań',
|
||||
'oauth.scope.todos:read.description': 'Odczytuj zadania podróży i przypisania kategorii',
|
||||
'oauth.scope.todos:write.label': 'Zarządzaj listami zadań',
|
||||
'oauth.scope.todos:write.description': 'Twórz, aktualizuj, zaznaczaj, usuwaj i porządkuj zadania',
|
||||
'oauth.scope.budget:read.label': 'Przeglądaj budżet',
|
||||
'oauth.scope.budget:read.description': 'Odczytuj pozycje budżetu i zestawienie wydatków',
|
||||
'oauth.scope.budget:write.label': 'Zarządzaj budżetem',
|
||||
'oauth.scope.budget:write.description': 'Twórz, aktualizuj i usuń pozycje budżetu',
|
||||
'oauth.scope.reservations:read.label': 'Przeglądaj rezerwacje',
|
||||
'oauth.scope.reservations:read.description': 'Odczytuj rezerwacje i szczegóły zakwaterowania',
|
||||
'oauth.scope.reservations:write.label': 'Zarządzaj rezerwacjami',
|
||||
'oauth.scope.reservations:write.description': 'Twórz, aktualizuj, usuwaj i porządkuj rezerwacje',
|
||||
'oauth.scope.collab:read.label': 'Przeglądaj współpracę',
|
||||
'oauth.scope.collab:read.description': 'Odczytuj notatki, ankiety i wiadomości',
|
||||
'oauth.scope.collab:write.label': 'Zarządzaj współpracą',
|
||||
'oauth.scope.collab:write.description': 'Twórz, aktualizuj i usuń notatki, ankiety i wiadomości',
|
||||
'oauth.scope.notifications:read.label': 'Przeglądaj powiadomienia',
|
||||
'oauth.scope.notifications:read.description': 'Odczytuj powiadomienia i liczby nieprzeczytanych',
|
||||
'oauth.scope.notifications:write.label': 'Zarządzaj powiadomieniami',
|
||||
'oauth.scope.notifications:write.description': 'Oznaczaj powiadomienia jako przeczytane i odpowiadaj na nie',
|
||||
'oauth.scope.vacay:read.label': 'Przeglądaj plany urlopowe',
|
||||
'oauth.scope.vacay:read.description': 'Odczytuj dane planowania urlopu, wpisy i statystyki',
|
||||
'oauth.scope.vacay:write.label': 'Zarządzaj planami urlopowymi',
|
||||
'oauth.scope.vacay:write.description': 'Twórz i zarządzaj wpisami urlopowymi, świętami i planami zespołu',
|
||||
'oauth.scope.geo:read.label': 'Mapy i geokodowanie',
|
||||
'oauth.scope.geo:read.description': 'Wyszukuj miejsca, rozwiązuj adresy URL map i odwrotnie geokoduj współrzędne',
|
||||
'oauth.scope.weather:read.label': 'Prognozy pogody',
|
||||
'oauth.scope.weather:read.description': 'Pobieraj prognozy pogody dla miejsc i dat podróży',
|
||||
}
|
||||
|
||||
export default pl
|
||||
|
||||
Reference in New Issue
Block a user