Compare commits

..

558 Commits

Author SHA1 Message Date
Owen Schwartz edf506953b Merge pull request #2463 from fosrl/dev
1.15.3
2026-02-11 21:42:04 -08:00
Owen Schwartz 5e11746549 New translations en-us.json (Norwegian Bokmal) 2026-02-11 21:40:26 -08:00
Owen Schwartz 1ae315e303 New translations en-us.json (Chinese Simplified) 2026-02-11 21:40:26 -08:00
Owen Schwartz 758b03ab25 New translations en-us.json (Turkish) 2026-02-11 21:40:26 -08:00
Owen Schwartz e756fad573 New translations en-us.json (Russian) 2026-02-11 21:40:26 -08:00
Owen Schwartz 3547450b03 New translations en-us.json (Portuguese) 2026-02-11 21:40:26 -08:00
Owen Schwartz 733f6692c6 New translations en-us.json (Polish) 2026-02-11 21:40:26 -08:00
Owen Schwartz 2d83160b16 New translations en-us.json (Dutch) 2026-02-11 21:40:26 -08:00
Owen Schwartz 256fa880dd New translations en-us.json (Korean) 2026-02-11 21:40:26 -08:00
Owen Schwartz b08c5f5c67 New translations en-us.json (Italian) 2026-02-11 21:40:26 -08:00
Owen Schwartz d0862a2d26 New translations en-us.json (German) 2026-02-11 21:40:26 -08:00
Owen Schwartz e97340ed52 New translations en-us.json (Czech) 2026-02-11 21:40:26 -08:00
Owen Schwartz e27c81eea6 New translations en-us.json (Bulgarian) 2026-02-11 21:40:26 -08:00
Owen Schwartz 7f7f3d43b2 New translations en-us.json (Spanish) 2026-02-11 21:40:26 -08:00
Owen Schwartz 4b1b772098 New translations en-us.json (French) 2026-02-11 21:40:26 -08:00
Owen Schwartz f66b88490f New translations en-us.json (Norwegian Bokmal) 2026-02-11 21:40:26 -08:00
Owen Schwartz 18f9157169 New translations en-us.json (Chinese Simplified) 2026-02-11 21:40:26 -08:00
Owen Schwartz 6eb82a807b New translations en-us.json (Turkish) 2026-02-11 21:40:26 -08:00
Owen Schwartz bf57a97833 New translations en-us.json (Russian) 2026-02-11 21:40:26 -08:00
Owen Schwartz e9e2093220 New translations en-us.json (Portuguese) 2026-02-11 21:40:26 -08:00
Owen Schwartz c3540da2e3 New translations en-us.json (Polish) 2026-02-11 21:40:26 -08:00
Owen Schwartz d228cf56dd New translations en-us.json (Dutch) 2026-02-11 21:40:26 -08:00
Owen Schwartz 8f4cecd963 New translations en-us.json (Korean) 2026-02-11 21:40:26 -08:00
Owen Schwartz 66adff44bb New translations en-us.json (Italian) 2026-02-11 21:40:26 -08:00
Owen Schwartz be41c094dc New translations en-us.json (German) 2026-02-11 21:40:26 -08:00
Owen Schwartz 273848ca18 New translations en-us.json (Czech) 2026-02-11 21:40:26 -08:00
Owen Schwartz 1e9dbead3b New translations en-us.json (Bulgarian) 2026-02-11 21:40:26 -08:00
Owen Schwartz aeaa8ba133 New translations en-us.json (Spanish) 2026-02-11 21:40:26 -08:00
Owen Schwartz 24654af635 New translations en-us.json (French) 2026-02-11 21:40:26 -08:00
Owen Schwartz e88a21d6db New translations en-us.json (Norwegian Bokmal) 2026-02-11 21:40:26 -08:00
Owen Schwartz bcd01badaf New translations en-us.json (Chinese Simplified) 2026-02-11 21:40:26 -08:00
Owen Schwartz 8e063506e0 New translations en-us.json (Turkish) 2026-02-11 21:40:26 -08:00
Owen Schwartz 84f5d6137a New translations en-us.json (Russian) 2026-02-11 21:40:26 -08:00
Owen Schwartz 0a8565f5e8 New translations en-us.json (Portuguese) 2026-02-11 21:40:26 -08:00
Owen Schwartz bd8da25a46 New translations en-us.json (Polish) 2026-02-11 21:40:26 -08:00
Owen Schwartz a841f588dd New translations en-us.json (Dutch) 2026-02-11 21:40:26 -08:00
Owen Schwartz 75a4362ce3 New translations en-us.json (Korean) 2026-02-11 21:40:26 -08:00
Owen Schwartz e763e001e5 New translations en-us.json (Italian) 2026-02-11 21:40:26 -08:00
Owen Schwartz 69475a0ae7 New translations en-us.json (German) 2026-02-11 21:40:26 -08:00
Owen Schwartz 53e14c2ad7 New translations en-us.json (Czech) 2026-02-11 21:40:26 -08:00
Owen Schwartz 1edc33148a New translations en-us.json (Bulgarian) 2026-02-11 21:40:26 -08:00
Owen Schwartz a4cbfc74e4 New translations en-us.json (Spanish) 2026-02-11 21:40:26 -08:00
Owen Schwartz c0d25aeb02 New translations en-us.json (French) 2026-02-11 21:40:26 -08:00
miloschwartz 40f49bf6da add pangolin cloud link 2026-02-11 19:46:19 -08:00
Owen 0bfce87dc6 Ignore migrations 2026-02-11 19:25:00 -08:00
Owen 2a0655e9de Bump version 2026-02-11 19:08:11 -08:00
Owen a86cfa5934 Add missing col in migration 2026-02-11 19:03:23 -08:00
miloschwartz 54b77523c5 remove console.log 2026-02-11 19:02:22 -08:00
Owen ba06c8928d Dont restrict numbers outside of the cloud 2026-02-11 19:01:47 -08:00
miloschwartz c8a4ac1ed4 add global/org idp banner 2026-02-11 19:01:06 -08:00
miloschwartz 143acbae48 add identity provider mode setting 2026-02-11 18:05:06 -08:00
Owen 937f6fdae8 Add better error message 2026-02-11 17:56:58 -08:00
Owen ba7239ac08 Verify everything we can 2026-02-11 17:30:21 -08:00
Owen 2e748274c0 Merge branch 'main' into dev 2026-02-11 17:22:19 -08:00
Owen eab2750953 Add migrations for 1.15.3 2026-02-11 17:21:15 -08:00
miloschwartz 17b6cb0c73 Merge branch 'new-pricing' into dev 2026-02-11 17:11:21 -08:00
Owen 98a4c453c1 Fix anouther subscribed logic issue 2026-02-11 12:41:22 -08:00
Owen 6475dceab9 Rename tiers in features and fix subscribed logic issue 2026-02-11 12:38:18 -08:00
Owen 040a945774 Fix dynamic -> private import violations 2026-02-11 10:30:25 -08:00
Owen 47743a5fa8 Fix private import -> dynamic 2026-02-11 10:26:50 -08:00
Owen Schwartz d47d6de985 New translations en-us.json (Norwegian Bokmal) 2026-02-11 10:23:00 -08:00
Owen Schwartz 37818b8594 New translations en-us.json (Chinese Simplified) 2026-02-11 10:23:00 -08:00
Owen Schwartz 3b184acddd New translations en-us.json (Turkish) 2026-02-11 10:23:00 -08:00
Owen Schwartz 9c80404d17 New translations en-us.json (Russian) 2026-02-11 10:23:00 -08:00
Owen Schwartz aaa7082f9d New translations en-us.json (Portuguese) 2026-02-11 10:23:00 -08:00
Owen Schwartz a45b45b2ce New translations en-us.json (Polish) 2026-02-11 10:23:00 -08:00
Owen Schwartz e4bfbd267e New translations en-us.json (Dutch) 2026-02-11 10:23:00 -08:00
Owen Schwartz 65b4dcc672 New translations en-us.json (Korean) 2026-02-11 10:23:00 -08:00
Owen Schwartz 36fc30b524 New translations en-us.json (Italian) 2026-02-11 10:23:00 -08:00
Owen Schwartz e724ed9137 New translations en-us.json (German) 2026-02-11 10:23:00 -08:00
Owen Schwartz 7ca992af05 New translations en-us.json (Czech) 2026-02-11 10:23:00 -08:00
Owen Schwartz 37f1c714ac New translations en-us.json (Bulgarian) 2026-02-11 10:23:00 -08:00
Owen Schwartz 397a43fb60 New translations en-us.json (Spanish) 2026-02-11 10:23:00 -08:00
Owen Schwartz 45e0a648c6 New translations en-us.json (French) 2026-02-11 10:23:00 -08:00
Owen 7336aa81d9 Update database build in dockerfile 2026-02-11 10:15:07 -08:00
miloschwartz d727c10d98 link to billing page 2026-02-11 10:06:57 -08:00
Owen 321d77a317 Fix setting limits 2026-02-11 10:06:57 -08:00
miloschwartz 19b8a6b737 show required tier in paid features alert 2026-02-11 10:06:56 -08:00
Owen f2e69dfb96 Add override for limits 2026-02-11 10:06:56 -08:00
miloschwartz 8207e49317 use purple banner for all paid features alert 2026-02-11 10:06:56 -08:00
miloschwartz b75600b9ea add subscription violation banner 2026-02-11 10:06:56 -08:00
Owen 7b01f1bef6 Remove s3 bucket 2026-02-11 10:06:56 -08:00
Owen e7bd2c0001 Allow cupons 2026-02-11 10:06:56 -08:00
Owen a26076e9db Add final prices and fix logs 2026-02-11 10:06:56 -08:00
Owen 9711a0fb8e Continue to clean things up 2026-02-11 10:06:56 -08:00
Owen accc670411 Communication improvements 2026-02-11 10:06:56 -08:00
Owen 071c41a54f Show warnings and specifics when downgrading 2026-02-11 10:06:56 -08:00
Owen 35ba6c19c3 Disable features when downgrading 2026-02-11 10:06:56 -08:00
miloschwartz 14c8348166 set default org mapping on create global idp 2026-02-11 10:06:56 -08:00
Owen 7d6ee72025 Finish adding limits checks to all put and post 2026-02-11 10:06:56 -08:00
Owen ea0e770b57 Fix error response 2026-02-11 10:06:56 -08:00
Owen 193b7ff21e Adding limit checks 2026-02-11 10:06:55 -08:00
miloschwartz d814ad9f3e add tier matrix to branding page 2026-02-11 10:06:55 -08:00
miloschwartz da8b620c75 refactor and add tiers 2026-02-11 10:06:55 -08:00
miloschwartz 911b5e6814 refactor front end hooks 2026-02-11 10:06:55 -08:00
Owen f991fd9c71 Fix to use the limits file 2026-02-11 10:06:55 -08:00
Owen 652e4c922d Comment out stripe usage reporting 2026-02-11 10:06:55 -08:00
miloschwartz 4364e3fbc1 fix some errors 2026-02-11 10:06:55 -08:00
Owen a783fdecbc Fix errors 2026-02-11 10:06:55 -08:00
Owen 16f67455a2 Handle auto provisioning 2026-02-11 10:06:55 -08:00
Owen 0850a28d20 Add more tier matrix checks 2026-02-11 10:06:55 -08:00
miloschwartz 5ca598139e use pricing matrix in existing usePaidStatus funcitons 2026-02-11 10:06:55 -08:00
Owen df1bf09163 Add pricing matrix 2026-02-11 10:06:55 -08:00
miloschwartz 50bc8d3e9c add rest of tier types 2026-02-11 10:06:55 -08:00
miloschwartz 86d089024e add tier type 2026-02-11 10:06:55 -08:00
Owen d5c1cf594d Remove site kick 2026-02-11 10:06:54 -08:00
Owen a0b5731e69 Getting swtiching tiers to work 2026-02-11 10:06:54 -08:00
miloschwartz ceb359d614 refactor is licensed and subscribed util functions 2026-02-11 10:06:54 -08:00
miloschwartz a49a9f8e3b dont fingerprint machine clients 2026-02-11 10:06:54 -08:00
miloschwartz 766606b08d use pangolin cli in machine client commands 2026-02-11 10:06:54 -08:00
miloschwartz fed56c1959 show features in ce 2026-02-11 10:06:54 -08:00
miloschwartz ae6ed8ad97 prefill username in login 2026-02-11 10:06:54 -08:00
Owen c1ca0b8e2c Set version when creating sub 2026-02-11 10:06:54 -08:00
Owen 569dc735ce Rename tiers and get working 2026-02-11 10:06:54 -08:00
Owen dd11c2c871 Dont accept invite if over the limits 2026-02-11 10:06:54 -08:00
Owen 8def4a2b68 Dont log to stripe 2026-02-11 10:06:54 -08:00
Owen 13a5f24b07 Dont write stripe to files anymore 2026-02-11 10:06:52 -08:00
Owen 0989d6353e Further billing 2026-02-11 10:06:03 -08:00
Owen 4139a7b73f Basic billing page is working 2026-02-11 10:06:03 -08:00
Owen be60d66ce3 Switch to the new tier system and clean up checks 2026-02-11 10:06:03 -08:00
Owen 0a33043874 Switching to new pricing - remove old feature tracking 2026-02-11 10:06:03 -08:00
Owen 96d1d983e5 Wrap insert in transaction
Ref #2222
2026-02-11 10:06:03 -08:00
Owen 7ffb260d7c Change features, remove site uptime 2026-02-11 10:05:53 -08:00
miloschwartz ce74489df5 link to billing page 2026-02-10 22:07:52 -08:00
Owen 342b188fae Fix setting limits 2026-02-10 21:54:26 -08:00
miloschwartz fa6fee7b55 show required tier in paid features alert 2026-02-10 21:33:05 -08:00
Owen c53d5a4d7d Add override for limits 2026-02-10 21:29:19 -08:00
miloschwartz 521e905724 use purple banner for all paid features alert 2026-02-10 21:21:20 -08:00
miloschwartz 4623090050 add subscription violation banner 2026-02-10 21:19:14 -08:00
Owen dd9e5cc541 Remove s3 bucket 2026-02-10 21:14:14 -08:00
Owen 626be6a347 Allow cupons 2026-02-10 21:08:11 -08:00
Owen 56327ed503 Add final prices and fix logs 2026-02-10 20:42:34 -08:00
Owen 9ff863db5e Continue to clean things up 2026-02-10 18:30:01 -08:00
Owen e2ac6e6d4d Communication improvements 2026-02-10 17:04:22 -08:00
Owen df4101875a Show warnings and specifics when downgrading 2026-02-10 16:35:09 -08:00
Owen 3f5c788d48 Disable features when downgrading 2026-02-10 16:11:19 -08:00
miloschwartz 94ac3ec76e set default org mapping on create global idp 2026-02-10 10:58:01 -08:00
Owen af7263a0b1 Finish adding limits checks to all put and post 2026-02-10 10:53:02 -08:00
Owen 035396f95c Fix error response 2026-02-10 10:53:02 -08:00
Owen f318f6304b Adding limit checks 2026-02-10 10:53:02 -08:00
miloschwartz 9d0ff472e5 add tier matrix to branding page 2026-02-10 10:42:39 -08:00
miloschwartz d27482e812 refactor and add tiers 2026-02-10 10:27:10 -08:00
miloschwartz 69c2212ea0 refactor front end hooks 2026-02-09 20:50:44 -08:00
Owen 10be9bcd56 Fix to use the limits file 2026-02-09 20:39:26 -08:00
Owen f531def0d2 Comment out stripe usage reporting 2026-02-09 20:30:44 -08:00
miloschwartz ed40eae655 fix some errors 2026-02-09 20:23:55 -08:00
Owen ba5ae6ed04 Fix errors 2026-02-09 20:17:14 -08:00
Owen 0a6301697e Handle auto provisioning 2026-02-09 20:11:24 -08:00
Owen 13b4fc6725 Add more tier matrix checks 2026-02-09 19:52:44 -08:00
miloschwartz a095dddd01 use pricing matrix in existing usePaidStatus funcitons 2026-02-09 18:17:18 -08:00
Owen 1b5cfaa49b Add pricing matrix 2026-02-09 18:04:37 -08:00
miloschwartz 66f3fabbae add rest of tier types 2026-02-09 17:52:28 -08:00
miloschwartz 0be8fb7931 add tier type 2026-02-09 17:42:45 -08:00
Owen 431e6ffaae Remove site kick 2026-02-09 17:23:48 -08:00
Owen 7d8185e0ee Getting swtiching tiers to work 2026-02-09 17:05:14 -08:00
miloschwartz dff45748bd refactor is licensed and subscribed util functions 2026-02-09 16:57:41 -08:00
miloschwartz e6464929ff Merge branch 'dev' into new-pricing 2026-02-09 15:05:13 -08:00
miloschwartz 122053939d dont fingerprint machine clients 2026-02-09 14:41:40 -08:00
Owen 300b4a3706 Set version when creating sub 2026-02-08 17:56:50 -08:00
Owen 81ef2db7f8 Rename tiers and get working 2026-02-08 17:56:36 -08:00
Owen c41e8be3e8 Dont accept invite if over the limits 2026-02-08 11:55:24 -08:00
Owen 41bab0ce0b Dont log to stripe 2026-02-08 11:13:09 -08:00
Owen 5f26b9eeea Merge branch 'k8s' into new-pricing 2026-02-08 11:08:51 -08:00
Owen 1cca69ad23 Further billing 2026-02-08 11:08:23 -08:00
miloschwartz 410ed3949b use pangolin cli in machine client commands 2026-02-07 17:13:55 -08:00
miloschwartz efc6ef3075 show features in ce 2026-02-07 17:00:44 -08:00
Owen e101ac341b Basic billing page is working 2026-02-06 17:41:20 -08:00
Owen 6cfc7b7c69 Switch to the new tier system and clean up checks 2026-02-06 16:27:31 -08:00
Owen 313acabc86 Wrap insert in transaction
Ref #2222
2026-02-06 10:48:18 -08:00
Owen 34cced872f Switching to new pricing - remove old feature tracking 2026-02-06 10:47:43 -08:00
Owen ac09e3aaf9 Wrap insert in transaction
Ref #2222
2026-02-06 10:47:19 -08:00
miloschwartz a8f6b6c1da prefill username in login 2026-02-05 16:55:00 -08:00
Owen f899326189 Change features, remove site uptime 2026-02-05 14:56:07 -08:00
Owen b4c01349d1 Merge branch 'dev' 2026-02-04 21:44:07 -08:00
Owen 165bbd3584 Merge branch 'self-serve' into dev 2026-02-04 21:42:32 -08:00
Lokowitz ffb253e0e9 fix dockerfile 2026-02-04 21:42:10 -08:00
Owen e5e9fe456f Add note about the self serve 2026-02-04 21:37:16 -08:00
miloschwartz c63589b204 auto open checkout modal 2026-02-04 21:31:46 -08:00
miloschwartz 11408c2656 add internal redirect 2026-02-04 21:16:59 -08:00
Owen 7d4aed8819 Add prod price ids 2026-02-04 20:37:25 -08:00
miloschwartz 508369a59d adjust language in form 2026-02-04 20:25:20 -08:00
Owen 26a91cd5e1 Add link 2026-02-04 18:29:35 -08:00
Owen 48dd4d5913 Billing licenses working 2026-02-04 18:15:46 -08:00
Owen 72d46b7352 Moving to supporting more than one sub 2026-02-04 17:54:29 -08:00
Owen 4613aae47d Handle license lifecycle 2026-02-04 17:37:31 -08:00
Owen 1bc4480d84 Working on complete auth flow 2026-02-04 16:32:53 -08:00
miloschwartz b5d76f73e8 add new tier select form 2026-02-04 16:08:47 -08:00
Owen a5c7913e77 Checkout flow works 2026-02-04 15:49:49 -08:00
miloschwartz 34b914f509 add license email 2026-02-04 15:38:02 -08:00
miloschwartz 5a3d75ca12 add quantity check 2026-02-04 15:19:58 -08:00
Owen 158d7b23d8 Add test button to launch stripe 2026-02-04 14:13:25 -08:00
Owen bf5dd3b0a1 Pull secrets from env vars 2026-02-02 21:39:18 -08:00
Owen e4d4c62833 Dont create newt sites with exit node or subnet 2026-02-02 18:19:13 -08:00
Owen 20ae903d7f Subscribed limits for domains is higher 2026-02-02 16:46:48 -08:00
Owen f5f757e4bd Subscribed limits for domains is higher 2026-02-02 16:45:54 -08:00
Owen 5ad564d21b Use rand 2026-02-02 10:25:14 -08:00
miloschwartz 8f8775cb93 override device name with computed device name on register 2026-02-01 17:37:18 -08:00
miloschwartz 37695827aa show user display name on device page 2026-02-01 17:30:05 -08:00
miloschwartz 7a72d209ea add --network host to newt install command for docker run 2026-02-01 17:24:16 -08:00
Owen f2ba4b270f Dont write stripe to files anymore 2026-01-29 20:56:46 -08:00
MoweME b0566d3c6f fix(i18n): correct German site terminology
Updates the German translation to use "Standort" (site) instead of "Seite" (page) for consistency with the site context.
2026-01-29 10:01:30 -08:00
MoweME 5dda8c384f fix(i18n): correct German translation strings
Corrects mistranslation of device timestamp labels and fixes product name reference in site tunnel settings.
2026-01-29 10:01:30 -08:00
Lokowitz 873408270e removed unused gomod code 2026-01-28 15:06:23 -08:00
Lokowitz 8fec8f35bc removed unused code 2026-01-28 15:06:23 -08:00
Owen 141c846fe2 Properly insert PANGOLIN_SETUP_TOKEN into db
Fixes #2361
2026-01-28 15:04:17 -08:00
Owen cb569ff14d Properly insert PANGOLIN_SETUP_TOKEN into db
Fixes #2361
2026-01-28 15:03:31 -08:00
Lokowitz 1497469016 revert format:write 2026-01-28 14:50:42 -08:00
Lokowitz e356a6d33b fix lable error and make dockerfile readable 2026-01-28 14:50:42 -08:00
miloschwartz 12aea2901d fix depreated zod warning 2026-01-26 14:11:03 -08:00
miloschwartz 5ff56467ea error response improvements to logo url 2026-01-26 14:00:22 -08:00
miloschwartz 3a8718a4b0 remove archive confirmtion on account devices dialog 2026-01-26 13:36:25 -08:00
Owen 37c4a7b690 Retry verify 2026-01-24 11:55:32 -08:00
Owen b735e7c34d Fix #2314 2026-01-24 11:47:17 -08:00
Owen 5f85c3b3b8 Remove extra rebuild command 2026-01-24 11:35:45 -08:00
miloschwartz 5d9cb9fa21 fix clear olmId from client on archive 2026-01-24 11:11:25 -08:00
miloschwartz 643d56958d fix saas private import 2026-01-23 10:07:05 -08:00
miloschwartz f378d6f040 fix input border 2026-01-22 21:24:28 -08:00
Milo Schwartz bb57794388 Merge pull request #2306 from Fredkiss3/fix/tab-from-host-port
fix: tab between host & port in resource target address column
2026-01-22 21:14:20 -08:00
miloschwartz a9ca49b8a2 Merge branch 'main' into dev 2026-01-22 21:10:40 -08:00
Fred KISSIE c1b473294e 🔥 remove useless useEffect 2026-01-23 04:54:24 +01:00
Fred KISSIE e3e4bdfe09 🚸 fix target item tabbing by memoizing the getColumns (and its dependencies) 2026-01-23 04:40:19 +01:00
miloschwartz bfbeace2e2 fix import in list approvals 2026-01-22 17:54:53 -08:00
miloschwartz efcf46ce8a fix policy check on olm register 2026-01-22 16:28:15 -08:00
miloschwartz 2085715965 fix wrong redirect url when idp login with custom auth domain 2026-01-22 15:46:48 -08:00
Owen d227db7b7b Show the source in the UI 2026-01-22 15:18:27 -08:00
Owen 2af67ad355 Fix the source of the cli blueprint 2026-01-22 15:18:27 -08:00
miloschwartz f100854423 add ios and android to readme 2026-01-22 15:18:27 -08:00
miloschwartz 92331d7a33 clean up paid features check 2026-01-22 15:18:27 -08:00
Owen 9a5bcb9099 Hiring 2026-01-22 15:18:27 -08:00
miloschwartz 8eb6bb2a95 dont include posture in repsonse if not licensed or subscribed 2026-01-22 15:18:27 -08:00
miloschwartz 2aa65ccab3 add mobile links to download banner 2026-01-22 15:18:27 -08:00
miloschwartz be1577a3e7 remove biometric support from ios 2026-01-22 15:18:27 -08:00
miloschwartz c8e1b3bf29 rename windowsDefenderEnabled 2026-01-22 15:18:27 -08:00
Owen e17b986628 Dont show bio info on android 2026-01-22 15:18:27 -08:00
Owen 5f19918ca0 Show the source in the UI 2026-01-22 15:16:41 -08:00
Owen 2959ad0e70 Fix the source of the cli blueprint 2026-01-22 15:03:04 -08:00
miloschwartz a76eec7bb7 add ios and android to readme 2026-01-22 11:27:24 -08:00
miloschwartz 068b2a0dcd clean up paid features check 2026-01-22 11:16:27 -08:00
Owen 316b7e5653 Hiring 2026-01-22 10:38:32 -08:00
miloschwartz 00fc1da33c dont include posture in repsonse if not licensed or subscribed 2026-01-22 10:36:52 -08:00
miloschwartz 9ef93df54f add mobile links to download banner 2026-01-21 18:16:16 -08:00
miloschwartz fd9fdf6399 remove biometric support from ios 2026-01-21 18:13:12 -08:00
miloschwartz 8fa1701e06 rename windowsDefenderEnabled 2026-01-21 17:57:20 -08:00
Owen 4abe83f8a9 Dont show bio info on android 2026-01-21 16:36:35 -08:00
Owen 0a7564acb6 Fix not detecting rc release in sign and package 2026-01-21 16:14:00 -08:00
miloschwartz db0f7cfbae add autoupdates to macos 2026-01-21 14:43:48 -08:00
Owen Schwartz 1724885371 New translations en-us.json (Norwegian Bokmal) 2026-01-21 14:41:55 -08:00
Owen Schwartz a97e9ea8b1 New translations en-us.json (Chinese Simplified) 2026-01-21 14:41:55 -08:00
Owen Schwartz 9d30e97526 New translations en-us.json (Turkish) 2026-01-21 14:41:55 -08:00
Owen Schwartz b91330a27a New translations en-us.json (Russian) 2026-01-21 14:41:55 -08:00
Owen Schwartz 744bc9ebe9 New translations en-us.json (Portuguese) 2026-01-21 14:41:55 -08:00
Owen Schwartz 89ed9e6d7f New translations en-us.json (Polish) 2026-01-21 14:41:55 -08:00
Owen Schwartz b007e7f54a New translations en-us.json (Dutch) 2026-01-21 14:41:55 -08:00
Owen Schwartz 6651a6df42 New translations en-us.json (Korean) 2026-01-21 14:41:55 -08:00
Owen Schwartz 3f29b165aa New translations en-us.json (Italian) 2026-01-21 14:41:55 -08:00
Owen Schwartz b13b91face New translations en-us.json (German) 2026-01-21 14:41:55 -08:00
Owen Schwartz 63c14fe2d5 New translations en-us.json (Czech) 2026-01-21 14:41:55 -08:00
Owen Schwartz 14e74ed02d New translations en-us.json (Bulgarian) 2026-01-21 14:41:55 -08:00
Owen Schwartz 7e30750618 New translations en-us.json (Spanish) 2026-01-21 14:41:55 -08:00
Owen Schwartz 4d1dd16be5 New translations en-us.json (French) 2026-01-21 14:41:55 -08:00
Owen Schwartz fa49cf5eba New translations en-us.json (Norwegian Bokmal) 2026-01-21 14:41:55 -08:00
Owen Schwartz 26b39fc1c6 New translations en-us.json (Chinese Simplified) 2026-01-21 14:41:55 -08:00
Owen Schwartz 0d36e368ea New translations en-us.json (Turkish) 2026-01-21 14:41:55 -08:00
Owen Schwartz 859f265c68 New translations en-us.json (Russian) 2026-01-21 14:41:55 -08:00
Owen Schwartz 3219f520ba New translations en-us.json (Portuguese) 2026-01-21 14:41:55 -08:00
Owen Schwartz 97e27b6caf New translations en-us.json (Polish) 2026-01-21 14:41:55 -08:00
Owen Schwartz 09da83a72b New translations en-us.json (Dutch) 2026-01-21 14:41:55 -08:00
Owen Schwartz d13b210e2f New translations en-us.json (Korean) 2026-01-21 14:41:55 -08:00
Owen Schwartz 09fb672718 New translations en-us.json (Italian) 2026-01-21 14:41:55 -08:00
Owen Schwartz 9797ad0e17 New translations en-us.json (German) 2026-01-21 14:41:55 -08:00
Owen Schwartz 8b3d61ac36 New translations en-us.json (Czech) 2026-01-21 14:41:55 -08:00
Owen Schwartz 7161c9547a New translations en-us.json (Bulgarian) 2026-01-21 14:41:55 -08:00
Owen Schwartz 60d4362a87 New translations en-us.json (Spanish) 2026-01-21 14:41:55 -08:00
Owen Schwartz 1836e0c8fc New translations en-us.json (French) 2026-01-21 14:41:55 -08:00
Owen Schwartz d3344aeb34 New translations en-us.json (Norwegian Bokmal) 2026-01-21 14:41:55 -08:00
Owen Schwartz cfeb093fa6 New translations en-us.json (Chinese Simplified) 2026-01-21 14:41:55 -08:00
Owen Schwartz a469b3ffcc New translations en-us.json (Turkish) 2026-01-21 14:41:55 -08:00
Owen Schwartz 14b3a3fdd8 New translations en-us.json (Russian) 2026-01-21 14:41:55 -08:00
Owen Schwartz 94367ce387 New translations en-us.json (Portuguese) 2026-01-21 14:41:55 -08:00
Owen Schwartz 5be518aa50 New translations en-us.json (Polish) 2026-01-21 14:41:55 -08:00
Owen Schwartz d059a8da9e New translations en-us.json (Dutch) 2026-01-21 14:41:55 -08:00
Owen Schwartz 1dcacbef7a New translations en-us.json (Korean) 2026-01-21 14:41:55 -08:00
Owen Schwartz a25edeccf7 New translations en-us.json (Italian) 2026-01-21 14:41:55 -08:00
Owen Schwartz 315f73c77d New translations en-us.json (German) 2026-01-21 14:41:55 -08:00
Owen Schwartz 666288fccc New translations en-us.json (Czech) 2026-01-21 14:41:55 -08:00
Owen Schwartz 0ccf61c2a9 New translations en-us.json (Bulgarian) 2026-01-21 14:41:55 -08:00
Owen Schwartz c16b1b27a3 New translations en-us.json (Spanish) 2026-01-21 14:41:55 -08:00
Owen Schwartz ed9ba60be6 New translations en-us.json (French) 2026-01-21 14:41:55 -08:00
Owen 24d047e3d8 Merge branch 'main' into dev 2026-01-21 14:39:15 -08:00
miloschwartz 9671079ffb show alias address in private resources table 2026-01-21 14:30:42 -08:00
Owen 688892523c Bump version 2026-01-21 14:24:29 -08:00
miloschwartz b02c341f62 add delete client/device cli command 2026-01-21 12:47:04 -08:00
miloschwartz 3e9bcada1e dont show pending/deny approvals in oss 2026-01-21 12:33:33 -08:00
Milo Schwartz 93d4bd6438 Merge pull request #2280 from Fredkiss3/feat/show-newt-install-command
feat: show install commands in sites & clients details page
2026-01-21 12:27:03 -08:00
miloschwartz 5146498b33 remove extra logs 2026-01-21 12:11:29 -08:00
miloschwartz 72da4f39a8 show disk encryption for mac 2026-01-21 11:49:25 -08:00
miloschwartz a2b2fb804b show device model for ios and android 2026-01-21 11:49:25 -08:00
Owen 3eac80e666 We dont care if its archived when recovering the olm 2026-01-20 20:47:35 -08:00
Fred KISSIE 718d2122a4 ♻️ move olm install command to its own component 2026-01-21 05:22:49 +01:00
Fred KISSIE 310c6c90a3 Merge branch 'dev' into feat/show-newt-install-command 2026-01-21 03:26:52 +01:00
Fred KISSIE 9d80f62d58 ♻️ move newt install commands to its own component for reusing in details 2026-01-21 03:21:35 +01:00
Owen 77032fc989 Remove extranious file 2026-01-20 18:07:28 -08:00
miloschwartz 64e6086f0c set docs link for approvals 2026-01-20 17:50:07 -08:00
miloschwartz 3aa58fdc8f add display info for device posture 2026-01-20 17:47:01 -08:00
Owen Schwartz 93bc6ba615 New translations en-us.json (Norwegian Bokmal) 2026-01-20 16:46:05 -08:00
Owen Schwartz 36690d63cb New translations en-us.json (Chinese Simplified) 2026-01-20 16:46:05 -08:00
Owen Schwartz 9896e9799a New translations en-us.json (Turkish) 2026-01-20 16:46:05 -08:00
Owen Schwartz 27afc82b79 New translations en-us.json (Russian) 2026-01-20 16:46:05 -08:00
Owen Schwartz 1c8f01ce7b New translations en-us.json (Portuguese) 2026-01-20 16:46:05 -08:00
Owen Schwartz 4038ccff0d New translations en-us.json (Polish) 2026-01-20 16:46:05 -08:00
Owen Schwartz 5b41bc2f59 New translations en-us.json (Dutch) 2026-01-20 16:46:05 -08:00
Owen Schwartz 014ba760b5 New translations en-us.json (Korean) 2026-01-20 16:46:05 -08:00
Owen Schwartz 96a91ccf09 New translations en-us.json (Italian) 2026-01-20 16:46:05 -08:00
Owen Schwartz 347fbd2a48 New translations en-us.json (German) 2026-01-20 16:46:05 -08:00
Owen Schwartz 29723052ab New translations en-us.json (Czech) 2026-01-20 16:46:05 -08:00
Owen Schwartz 86415d675b New translations en-us.json (Bulgarian) 2026-01-20 16:46:05 -08:00
Owen Schwartz 8fc4a0dc48 New translations en-us.json (Spanish) 2026-01-20 16:46:05 -08:00
Owen Schwartz e14670cdda New translations en-us.json (French) 2026-01-20 16:46:05 -08:00
Jan-Filip Grosse 4d73488f0c updated the sync and creation of new rules objects to include priorities passed by blueprints. 2026-01-20 15:22:12 -08:00
Jan-Filip Grosse 46e62b24cf Updated RuleSchema to include priority as optional int() value. Included validiation to make sure that no priorities are duplicated (including those which get auto-assigned). 2026-01-20 15:22:12 -08:00
Owen 17c3041fe9 Add migrations 2026-01-20 15:20:19 -08:00
Varun Narravula d5ae381528 feat(fingerprint): clean up stale snapshots older than 1 year 2026-01-20 12:13:43 -08:00
Varun Narravula e2e09527ec fix(fingerprint): set fingerprintId reference to null 2026-01-20 12:13:43 -08:00
Varun Narravula 3ce1afbcc9 feat(fingerprint): consolidate posture checks into fingerprint table 2026-01-20 12:13:43 -08:00
Varun Narravula 1f077d7ec2 refactor(fingerprint): start taking fingerprint snapshots in new table 2026-01-20 12:13:43 -08:00
miloschwartz adf3d0347b remove icon 2026-01-20 11:02:06 -08:00
miloschwartz 7ed8b16a53 fix credenza dialog spacing on mobile 2026-01-20 10:18:17 -08:00
miloschwartz 9f7c162107 make approvals placeholder more mobile friendly 2026-01-19 22:02:02 -08:00
miloschwartz fb15f8cde6 add placeholder approvals ui 2026-01-19 21:57:28 -08:00
miloschwartz 45ecfcc6bb add approve and deny actions to devices table 2026-01-19 21:41:12 -08:00
miloschwartz c6f947e470 fix connected col translations 2026-01-19 21:34:14 -08:00
miloschwartz adf5caf18a add product banner to approvals page 2026-01-19 21:30:29 -08:00
miloschwartz 0b8068e13d add pending approvals count to sidebar 2026-01-19 21:25:28 -08:00
miloschwartz f143d2e214 make default filter in approvals be pending 2026-01-19 21:14:33 -08:00
miloschwartz 2e802301ae make client link work approval feed 2026-01-19 21:07:15 -08:00
miloschwartz 7305c721a6 format device approval message 2026-01-19 21:00:48 -08:00
miloschwartz b299f3d6aa use display name function 2026-01-19 21:00:48 -08:00
Fred KISSIE e09cd6c16c ♻️ reset firn 2026-01-19 20:39:24 -08:00
Fred KISSIE b7df8b7319 ♻️ make logo URL optional 2026-01-19 20:39:24 -08:00
Fred KISSIE c92b5942fc 💄 fix analytics refresh button align 2026-01-19 20:39:24 -08:00
Fred KISSIE fe729ec762 🚧wip: command component 2026-01-20 05:21:18 +01:00
miloschwartz 915673798e update updateRole endpoint 2026-01-19 20:20:31 -08:00
miloschwartz 9527fe4f26 add update role openapi registry 2026-01-19 20:12:35 -08:00
miloschwartz e8a8b3f664 remove beta tag for clients 2026-01-19 20:10:30 -08:00
Fred KISSIE d6a829abc2 Merge branch 'dev' into feat/show-newt-install-command 2026-01-20 03:36:38 +01:00
Owen 1a36cd0317 Fix linting errors 2026-01-19 17:57:55 -08:00
Kolin 75005ccf81 Fix WireGuard QR code layout on mobile in site creation page 2026-01-19 17:52:21 -08:00
Kolin fd6c600531 Fix WireGuard QR code layout on mobile in site credentials page 2026-01-19 17:52:21 -08:00
ThanatosDi 6996c2501e feat: zh-TW for v1.14.1 2026-01-19 17:51:30 -08:00
Owen efbd9bdb56 Remove faker 2026-01-19 17:50:46 -08:00
dependabot[bot] 0d34213647 Bump the prod-minor-updates group across 1 directory with 12 updates
Bumps the prod-minor-updates group with 12 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@asteasolutions/zod-to-openapi](https://github.com/asteasolutions/zod-to-openapi) | `8.2.0` | `8.4.0` |
| [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) | `3.955.0` | `3.971.0` |
| [@faker-js/faker](https://github.com/faker-js/faker) | `10.1.0` | `10.2.0` |
| [ioredis](https://github.com/luin/ioredis) | `5.8.2` | `5.9.2` |
| [next-intl](https://github.com/amannn/next-intl) | `4.6.1` | `4.7.0` |
| [pg](https://github.com/brianc/node-postgres/tree/HEAD/packages/pg) | `8.16.3` | `8.17.1` |
| [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.17.4` | `5.21.1` |
| [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.68.0` | `7.71.1` |
| [resend](https://github.com/resend/resend-node) | `6.6.0` | `6.7.0` |
| [stripe](https://github.com/stripe/stripe-node) | `20.1.0` | `20.2.0` |
| [ws](https://github.com/websockets/ws) | `8.18.3` | `8.19.0` |
| [zod](https://github.com/colinhacks/zod) | `4.2.1` | `4.3.5` |



Updates `@asteasolutions/zod-to-openapi` from 8.2.0 to 8.4.0
- [Release notes](https://github.com/asteasolutions/zod-to-openapi/releases)
- [Commits](https://github.com/asteasolutions/zod-to-openapi/compare/v8.2.0...v8.4.0)

Updates `@aws-sdk/client-s3` from 3.955.0 to 3.971.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.971.0/clients/client-s3)

Updates `@faker-js/faker` from 10.1.0 to 10.2.0
- [Release notes](https://github.com/faker-js/faker/releases)
- [Changelog](https://github.com/faker-js/faker/blob/next/CHANGELOG.md)
- [Commits](https://github.com/faker-js/faker/compare/v10.1.0...v10.2.0)

Updates `ioredis` from 5.8.2 to 5.9.2
- [Release notes](https://github.com/luin/ioredis/releases)
- [Changelog](https://github.com/redis/ioredis/blob/main/CHANGELOG.md)
- [Commits](https://github.com/luin/ioredis/compare/v5.8.2...v5.9.2)

Updates `next-intl` from 4.6.1 to 4.7.0
- [Release notes](https://github.com/amannn/next-intl/releases)
- [Changelog](https://github.com/amannn/next-intl/blob/main/CHANGELOG.md)
- [Commits](https://github.com/amannn/next-intl/compare/v4.6.1...v4.7.0)

Updates `pg` from 8.16.3 to 8.17.1
- [Changelog](https://github.com/brianc/node-postgres/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianc/node-postgres/commits/pg@8.17.1/packages/pg)

Updates `posthog-node` from 5.17.4 to 5.21.1
- [Release notes](https://github.com/PostHog/posthog-js/releases)
- [Changelog](https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md)
- [Commits](https://github.com/PostHog/posthog-js/commits/posthog-node@5.21.1/packages/node)

Updates `react-hook-form` from 7.68.0 to 7.71.1
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.68.0...v7.71.1)

Updates `resend` from 6.6.0 to 6.7.0
- [Release notes](https://github.com/resend/resend-node/releases)
- [Commits](https://github.com/resend/resend-node/compare/v6.6.0...v6.7.0)

Updates `stripe` from 20.1.0 to 20.2.0
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v20.1.0...v20.2.0)

Updates `ws` from 8.18.3 to 8.19.0
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.18.3...8.19.0)

Updates `zod` from 4.2.1 to 4.3.5
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.2.1...v4.3.5)

---
updated-dependencies:
- dependency-name: "@asteasolutions/zod-to-openapi"
  dependency-version: 8.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: "@aws-sdk/client-s3"
  dependency-version: 3.971.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: "@faker-js/faker"
  dependency-version: 10.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: ioredis
  dependency-version: 5.9.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: next-intl
  dependency-version: 4.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: pg
  dependency-version: 8.17.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: posthog-node
  dependency-version: 5.21.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: react-hook-form
  dependency-version: 7.71.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: resend
  dependency-version: 6.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: stripe
  dependency-version: 20.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: ws
  dependency-version: 8.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: zod
  dependency-version: 4.3.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 17:50:46 -08:00
dependabot[bot] 870b85d71b Bump the dev-minor-updates group across 1 directory with 3 updates
Bumps the dev-minor-updates group with 3 updates in the / directory: [prettier](https://github.com/prettier/prettier), [react-email](https://github.com/resend/react-email/tree/HEAD/packages/react-email) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `prettier` from 3.7.4 to 3.8.0
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.7.4...3.8.0)

Updates `react-email` from 5.0.7 to 5.2.5
- [Release notes](https://github.com/resend/react-email/releases)
- [Changelog](https://github.com/resend/react-email/blob/canary/packages/react-email/CHANGELOG.md)
- [Commits](https://github.com/resend/react-email/commits/react-email@5.2.5/packages/react-email)

Updates `typescript-eslint` from 8.49.0 to 8.53.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.53.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
- dependency-name: react-email
  dependency-version: 5.2.5
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
- dependency-name: typescript-eslint
  dependency-version: 8.53.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 17:42:02 -08:00
dependabot[bot] 86ba6b6f86 Bump golang.org/x/term in /install in the prod-minor-updates group
Bumps the prod-minor-updates group in /install with 1 update: [golang.org/x/term](https://github.com/golang/term).


Updates `golang.org/x/term` from 0.38.0 to 0.39.0
- [Commits](https://github.com/golang/term/compare/v0.38.0...v0.39.0)

---
updated-dependencies:
- dependency-name: golang.org/x/term
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 17:39:29 -08:00
dependabot[bot] 02be3cd0c4 Bump qs from 6.14.0 to 6.14.1
Bumps [qs](https://github.com/ljharb/qs) from 6.14.0 to 6.14.1.
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.0...v6.14.1)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 17:39:00 -08:00
dependabot[bot] 1b756ef9a0 Bump aws-actions/configure-aws-credentials from 2 to 5
Bumps [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) from 2 to 5.
- [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases)
- [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/v2...v5)

---
updated-dependencies:
- dependency-name: aws-actions/configure-aws-credentials
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 17:38:03 -08:00
dependabot[bot] ceda06f9ae Bump actions/setup-go from 6.1.0 to 6.2.0
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/4dc6199c7b1a012772edbd06daecab0f50c9053c...7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 17:37:55 -08:00
dependabot[bot] 068eba015b Bump actions/setup-node from 6.1.0 to 6.2.0
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/395ad3262231945c25e8478fd5baf05154b1d79f...6044e13b5dc448c55e2357c09f80417699197238)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 17:37:46 -08:00
Owen 7ae6b2df05 Fix email parsing validation error? 2026-01-19 16:45:15 -08:00
Owen 6765d5ad26 Reorder setting the olm agent and version 2026-01-19 16:30:34 -08:00
Owen 35cfd6bec9 Move up figerprint so it happens before block 2026-01-19 14:59:00 -08:00
Owen 90f66baf85 Update config dir values to match install 2026-01-19 13:55:22 -08:00
miloschwartz 5edfed78f2 fix only show advanced toggle on newt sites 2026-01-19 11:50:56 -08:00
miloschwartz fd6a3e5a17 fix default logo size 2026-01-19 11:47:14 -08:00
miloschwartz 14a4b1b4b4 add clear license key command to pangctl 2026-01-19 11:39:58 -08:00
Kolin 5743c0bb72 chore: add ru-RU, bg-BG and cs-CZ locales 2026-01-19 10:11:50 -08:00
miloschwartz acca1b6a91 improve red alert colors 2026-01-18 22:10:34 -08:00
miloschwartz 355265cd1e show paid user alert on approvals 2026-01-18 21:49:15 -08:00
miloschwartz 6ec8d143fa hide pending approval filter in oss 2026-01-18 21:47:00 -08:00
miloschwartz 8ae327e8f5 fix org policy check 2026-01-18 21:24:17 -08:00
Owen c03a61f613 Delete each of the site resources and rebuild 2026-01-18 15:00:08 -08:00
miloschwartz 89928c753c add server info endpoint 2026-01-18 12:19:07 -08:00
miloschwartz a56fcc0fba add olm container install commands 2026-01-18 12:11:58 -08:00
miloschwartz 43c60bcdbc spacing and phrase improvement 2026-01-18 12:08:29 -08:00
miloschwartz a3fa12f0e4 split org security settings to new tab 2026-01-18 12:03:01 -08:00
Owen d696556097 Handle disconnecting message when stoppng 2026-01-18 11:55:41 -08:00
miloschwartz 6a45151741 show fingerprint popup and fix policy check errors 2026-01-18 11:55:24 -08:00
miloschwartz 34e2fbefb9 add view user device page with fingerprint and actions 2026-01-17 20:59:20 -08:00
Owen f7cede4713 Use /etc/sysctl.d/99-podman.conf
Fixes #2253
2026-01-17 12:22:43 -08:00
Owen 610b20c1ff Use the right driver
Fixes #2254
2026-01-17 12:21:47 -08:00
miloschwartz fb19e10cdc Merge branch 'dev' into bubble-errors-up 2026-01-17 12:00:55 -08:00
miloschwartz 2f1756ccf2 add more error messages for org access policy 2026-01-17 12:00:27 -08:00
Owen ce632a25cf Consolidate the messages into the same enum 2026-01-17 11:41:10 -08:00
Fred KISSIE ec10c37468 🚧wip 2026-01-17 02:09:59 +01:00
Fred KISSIE 5ee3e140ed 🔇 fix logs 2026-01-17 02:07:43 +01:00
Owen 888f5f8bb6 Dont terminate on archive 2026-01-16 17:06:16 -08:00
Owen 9114dd5992 Send terminate error messages 2026-01-16 14:57:54 -08:00
Owen a126494c12 Add pending 2026-01-16 14:37:06 -08:00
Milo Schwartz 79ba804c88 Merge pull request #2252 from Fredkiss3/fix/request-analytics-loading-state
Fix: better loading state for analytics
2026-01-16 14:35:55 -08:00
Owen e2cbe11a5f Send error codes down to olm 2026-01-16 14:19:36 -08:00
Owen 05748bf8ff Merge branch 'dev' into msg-delivery 2026-01-16 12:22:23 -08:00
Owen f8c98bf6bf Fix log messages 2026-01-16 12:19:52 -08:00
Fred KISSIE f4496bb23a ♻️ show all country list 2026-01-16 17:36:48 +01:00
Fred KISSIE c93766bb48 💄fix countries list grid items 2026-01-16 17:35:17 +01:00
Owen a1ea3f74b3 Move the query into the sync 2026-01-15 22:00:13 -08:00
Milo Schwartz 06aaa7c680 Merge pull request #2121 from Fredkiss3/feat/device-approvals
feat: device approvals
2026-01-15 21:33:31 -08:00
Owen 65e8bfc93e Message syncing works 2026-01-15 21:26:13 -08:00
miloschwartz ff5e12655f add pretty apple device names 2026-01-15 17:59:45 -08:00
Fred KISSIE 1065004fa3 🚸 show a better loading state for analytics 2026-01-16 02:07:08 +01:00
Fred KISSIE 6d90d734f4 🏷️ fix types 2026-01-15 23:25:05 +01:00
Varun Narravula 6c8757f230 feat(olm): reset/send new olm secret if a matching fingerprint is detected 2026-01-15 12:33:26 -08:00
Milo Schwartz 40e37b1798 Merge pull request #2244 from water-sucks/add-fingerprint-and-posture-check-info
feat(fingerprint): store posture checks and fingerprint info
2026-01-15 12:05:41 -08:00
miloschwartz 8e1fd4474f fix whitelist hyrdration closes #2190 2026-01-14 22:09:56 -08:00
miloschwartz bd87585396 fix whitelist hyrdration closes #2190 2026-01-14 22:08:16 -08:00
Varun Narravula e9e935d6c4 feat(fingerprint): add platform fingerprint hash 2026-01-14 20:21:22 -08:00
miloschwartz 2f2c2b4222 improved org idp login flow 2026-01-14 19:15:19 -08:00
Fred KISSIE 9749a272ec 🏷️fix types 2026-01-15 03:46:25 +01:00
Fred KISSIE b76a50238e 🏷️ fix types 2026-01-15 03:40:30 +01:00
Fred KISSIE a4f3963a5a ♻️update approval filter & set approval to denied when blocked 2026-01-15 03:34:42 +01:00
Owen d52bd65d21 Fix build 2026-01-14 17:54:34 -08:00
Fred KISSIE fb51f42f35 ♻️ set approval & blocked work in tandem 2026-01-15 01:33:52 +01:00
Fred KISSIE c910a715bd ♻️ set blocked to true if approvalState is set to denied 2026-01-15 01:12:38 +01:00
Fred KISSIE 9040f9b82a ♻️ set approval state nullable 2026-01-15 01:03:02 +01:00
Fred KISSIE fc0ec0d754 🐛 remove unused approval state 2026-01-15 00:28:30 +01:00
Fred KISSIE b3569174b6 🐛 fix sqlite type 2026-01-15 00:20:45 +01:00
Fred KISSIE 0cae624995 🏷️ fix types 2026-01-14 23:57:16 +01:00
Fred KISSIE cbf184342b Merge branch 'dev' into feat/device-approvals 2026-01-14 23:08:40 +01:00
Fred KISSIE ce123a7f1a 💬 make the message more descriptive 2026-01-14 03:37:47 +01:00
Fred KISSIE 0c5daa7173 process approvals on the frontend 2026-01-14 03:31:49 +01:00
Fred KISSIE bc20a34a49 process approval endpoint 2026-01-14 03:00:40 +01:00
Fred KISSIE d5b6a426a9 💄 filter by approval state 2026-01-14 02:24:11 +01:00
Fred KISSIE 4c78e93143 💄 show approval state in the user device uI 2026-01-14 01:59:51 +01:00
miloschwartz 5f184e9e5e support background image on org auth pages 2026-01-13 16:35:27 -08:00
miloschwartz 2201b0395d add optional tags field to idp 2026-01-13 16:21:40 -08:00
miloschwartz 51818044b1 fix broken redirect url on custom auth url login 2026-01-13 15:48:07 -08:00
Fred KISSIE 30943010e6 ♻️ sort by pending first 2026-01-14 00:37:48 +01:00
Fred KISSIE dd5ca10226 ♻️ empty data 2026-01-14 00:35:35 +01:00
miloschwartz a56b058858 fix role name missing in forward headers 2026-01-13 15:28:02 -08:00
miloschwartz eade72e2c6 set text-destructive color 2026-01-13 09:36:53 -08:00
miloschwartz e9bc9747b8 check if olm is blocked in get user olm 2026-01-12 22:08:58 -08:00
Owen eb0cdda0f9 Merge branch 'dev' into msg-delivery 2026-01-12 21:17:38 -08:00
Owen 552adf3200 Properly handle blocked devices 2026-01-12 21:14:18 -08:00
Owen eba25fcc4d Add increment options and slight cleanup 2026-01-12 20:48:18 -08:00
miloschwartz 673cd0fcd1 add block client 2026-01-12 20:37:53 -08:00
miloschwartz b941b5571f add archive to org clients and add unarchive 2026-01-12 15:52:27 -08:00
Owen ca026b41c0 Merge branch 'main' into dev 2026-01-11 14:19:59 -08:00
Owen 29a683a815 Copy all tags to github reg 2026-01-11 14:19:38 -08:00
Owen 69dbd20ea5 Use same regex for blueprint aliases
Closes #2218
Fixes #2216
2026-01-11 13:39:46 -08:00
miloschwartz 427ee026ac Merge branch 'org-only-idp' into dev 2026-01-11 10:47:57 -08:00
miloschwartz 0a537c6830 add org only idp to integration api 2026-01-11 10:47:19 -08:00
Owen 89682a2ee4 Try to intent:// into android app from tab 2026-01-11 10:39:39 -08:00
Owen 78b00a18cc Add retry to aquire 2026-01-11 10:39:28 -08:00
Owen 192702daf9 Quiet log 2026-01-11 10:39:18 -08:00
Varun Narravula fcee735578 feat(fingerprints): receive fingerprints/postures from olm and add to db 2026-01-10 21:15:54 -08:00
miloschwartz 2ba49e84bb add archive device instead of delete 2026-01-09 18:00:00 -08:00
Fred KISSIE 262376aa75 approval list UI 2026-01-10 02:37:50 +01:00
miloschwartz 4c8d2266ec clean up login page 2026-01-09 14:41:22 -08:00
miloschwartz bb98bf03aa Merge branch 'org-only-idp' into dev 2026-01-09 13:34:52 -08:00
Fred KISSIE 19c3efc9e9 🚧 working on the approval feed 2026-01-09 02:20:08 +01:00
Fred KISSIE 7164721ee0 🐛 insert timestamp correctly 2026-01-09 01:50:56 +01:00
Fred KISSIE 74b16809ec ♻️ update endpoint to only return relevant data 2026-01-09 01:40:15 +01:00
Fred KISSIE 220723d25f ♻️ component refactor 2026-01-09 01:33:52 +01:00
Fred KISSIE fdb03c9626 ♻️ list approvals with client & user data 2026-01-09 01:33:40 +01:00
Fred KISSIE a81bbb9192 create approval request and mark client approval as pending if the user's role requires it 2026-01-09 01:18:15 +01:00
Fred KISSIE 7a4aff8e4b 🗃️ use clientId and fix bad column name for decision and add userId 2026-01-09 01:17:05 +01:00
miloschwartz 2810632f4a add flag to enable org only idp in ee 2026-01-07 20:40:59 -08:00
Fred KISSIE 2d0dd067b8 ♻️ refactor 2026-01-08 03:41:09 +01:00
Fred KISSIE 3ab25f5ff1 ♻️ refactor 2026-01-08 03:38:55 +01:00
Fred KISSIE 39bebea5f7 create & update role with device approval 2026-01-08 03:33:03 +01:00
miloschwartz 57681dcd3d remove artificial delay 2026-01-07 12:06:50 -08:00
miloschwartz 168ce549f7 remove guards form list idp for integration api 2026-01-06 13:20:18 -05:00
Owen 9ec94441f3 Try to open apps 2026-01-05 21:46:38 -05:00
Owen 53e7b99605 Quiet up logs 2026-01-05 21:25:15 -05:00
Fred KISSIE abfe476cb9 🚧 wip 2026-01-06 02:02:09 +01:00
Fred KISSIE bbca200ceb 🙈 do not include claude.md in gitignore 2026-01-06 01:51:54 +01:00
Fred KISSIE cb21cab117 🚧 add device approval in the roles page 2026-01-06 01:51:33 +01:00
Fred KISSIE 1f80845a7a 🗃️ move approval state to client directly where it makes more sense 2026-01-05 22:49:42 +01:00
Owen 20088ef82b Log in to ecr 2026-01-05 11:31:29 -05:00
Owen 1e0b1a3607 Add missing \ 2026-01-05 11:23:10 -05:00
Owen 24e8455c73 Remove aws cli call 2026-01-05 11:20:25 -05:00
Owen e42a732e93 Add saas workflow 2026-01-05 11:16:30 -05:00
Fred KISSIE 0f2b94307f Merge branch 'dev' into feat/device-approvals 2026-01-05 16:54:18 +01:00
Owen d333cb5199 Add encoded chars to default traefik config
Closes #2176
2026-01-05 10:37:18 -05:00
Owen a6db4f20ad Expand where org id is pulled for subscription 2026-01-05 10:34:11 -05:00
Jack Myers 9ed9472c01 Fix spelling mistake in installer version prompt 2026-01-02 10:18:21 -05:00
Owen f7fcde8312 Add max recursion depth to matchSegments 2025-12-31 10:40:16 -05:00
Owen 6660c850f3 Try to bound logs
Ref #2120
2025-12-31 10:31:40 -05:00
Owen 8a08bdf9f0 Add OCI labels
Fixes #2170
2025-12-29 12:29:27 -05:00
Owen 87807e22e0 Add encoded chars to default traefik config
Closes #2176
2025-12-29 10:49:32 -05:00
Owen 0eb39abdb4 Set hc to unknown when changing to local site
Fixes #2181
2025-12-29 10:22:06 -05:00
miloschwartz a499ebc158 add badger to dyn config example 2025-12-29 10:17:26 -05:00
ruxenburg 9467e6c032 improve delete confirmation logic 2025-12-27 22:20:50 -05:00
ruxenburg 9d849a0ced Fix confirm delete button to require confirmation text before enabling it. 2025-12-27 22:20:50 -05:00
Owen Schwartz 2ca400ab16 New translations en-us.json (French) 2025-12-24 16:14:26 -05:00
Owen Schwartz 4183067c77 New translations en-us.json (Norwegian Bokmal) 2025-12-24 16:14:26 -05:00
Owen Schwartz 5eb4691973 New translations en-us.json (Chinese Simplified) 2025-12-24 16:14:26 -05:00
Owen Schwartz d14dfbf360 New translations en-us.json (Turkish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 493a5ad02a New translations en-us.json (Russian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 481beff028 New translations en-us.json (Portuguese) 2025-12-24 16:14:26 -05:00
Owen Schwartz f1f7e438b4 New translations en-us.json (Polish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 00f84c9d8e New translations en-us.json (Dutch) 2025-12-24 16:14:26 -05:00
Owen Schwartz f75b9c6c86 New translations en-us.json (Korean) 2025-12-24 16:14:26 -05:00
Owen Schwartz 31bc6d5773 New translations en-us.json (Italian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 51dc1450d3 New translations en-us.json (German) 2025-12-24 16:14:26 -05:00
Owen Schwartz fcbea08c87 New translations en-us.json (Czech) 2025-12-24 16:14:26 -05:00
Owen Schwartz 8d60a87aa1 New translations en-us.json (Bulgarian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 956aa64519 New translations en-us.json (Spanish) 2025-12-24 16:14:26 -05:00
Owen Schwartz fd1cb6ca23 New translations en-us.json (French) 2025-12-24 16:14:26 -05:00
Owen Schwartz 37082ae436 New translations en-us.json (Norwegian Bokmal) 2025-12-24 16:14:26 -05:00
Owen Schwartz bb47ca3d2e New translations en-us.json (Chinese Simplified) 2025-12-24 16:14:26 -05:00
Owen Schwartz 0dd3c84b24 New translations en-us.json (Turkish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 848fca7e1b New translations en-us.json (Russian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 2500f99722 New translations en-us.json (Portuguese) 2025-12-24 16:14:26 -05:00
Owen Schwartz c7737c444f New translations en-us.json (Polish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 4d1a7ed69b New translations en-us.json (Dutch) 2025-12-24 16:14:26 -05:00
Owen Schwartz 626d5df67e New translations en-us.json (Korean) 2025-12-24 16:14:26 -05:00
Owen Schwartz e4c369deec New translations en-us.json (Italian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 307209e73f New translations en-us.json (German) 2025-12-24 16:14:26 -05:00
Owen Schwartz dc84935ee6 New translations en-us.json (Czech) 2025-12-24 16:14:26 -05:00
Owen Schwartz 998c1f52ca New translations en-us.json (Bulgarian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 2766758c66 New translations en-us.json (Spanish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 258d1d82f3 New translations en-us.json (French) 2025-12-24 16:14:26 -05:00
Owen Schwartz 46aaadb76a New translations en-us.json (Norwegian Bokmal) 2025-12-24 16:14:26 -05:00
Owen Schwartz ea7a618810 New translations en-us.json (Chinese Simplified) 2025-12-24 16:14:26 -05:00
Owen Schwartz c0e503b31f New translations en-us.json (Turkish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 55f5a41752 New translations en-us.json (Russian) 2025-12-24 16:14:26 -05:00
Owen Schwartz b0be82be86 New translations en-us.json (Portuguese) 2025-12-24 16:14:26 -05:00
Owen Schwartz 96a9bdb700 New translations en-us.json (Polish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 74e6d39c24 New translations en-us.json (Dutch) 2025-12-24 16:14:26 -05:00
Owen Schwartz 61dfa00222 New translations en-us.json (Korean) 2025-12-24 16:14:26 -05:00
Owen Schwartz 476281db2b New translations en-us.json (Italian) 2025-12-24 16:14:26 -05:00
Owen Schwartz f32e31c73d New translations en-us.json (Czech) 2025-12-24 16:14:26 -05:00
Owen Schwartz ea72279080 New translations en-us.json (Bulgarian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 16ba56af84 New translations en-us.json (Spanish) 2025-12-24 16:14:26 -05:00
Owen Schwartz f13ddde988 New translations en-us.json (Norwegian Bokmal) 2025-12-24 16:14:26 -05:00
Owen Schwartz 67dc10dfe9 New translations en-us.json (Chinese Simplified) 2025-12-24 16:14:26 -05:00
Owen Schwartz 5fd216adc2 New translations en-us.json (Turkish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 6f0268f6c0 New translations en-us.json (Russian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 2996dfb33a New translations en-us.json (Portuguese) 2025-12-24 16:14:26 -05:00
Owen Schwartz c92f2cd4ba New translations en-us.json (Polish) 2025-12-24 16:14:26 -05:00
Owen Schwartz 8164d5c1ad New translations en-us.json (Dutch) 2025-12-24 16:14:26 -05:00
Owen Schwartz d9d8d85f6e New translations en-us.json (Korean) 2025-12-24 16:14:26 -05:00
Owen Schwartz d49720703f New translations en-us.json (Italian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 2362a9b4dd New translations en-us.json (German) 2025-12-24 16:14:26 -05:00
Owen Schwartz a8265a5286 New translations en-us.json (Czech) 2025-12-24 16:14:26 -05:00
Owen Schwartz 9ea7431b73 New translations en-us.json (Bulgarian) 2025-12-24 16:14:26 -05:00
Owen Schwartz 37e6f320fe New translations en-us.json (Spanish) 2025-12-24 16:14:26 -05:00
miloschwartz c0c0d48edf ui enhancements 2025-12-24 16:14:26 -05:00
Owen 284cccbe17 Attempt to fix loginPageOrg undefined error 2025-12-24 16:14:26 -05:00
Owen 81a9a94264 Try to remove deadlocks on client updates 2025-12-24 16:14:26 -05:00
Owen dccf101554 Allow all in country in blueprints
Fixes #2163
2025-12-24 16:14:26 -05:00
Owen a01c06bbc7 Respect http status for url & maintenance mode
Fixes #2164
2025-12-24 16:14:26 -05:00
miloschwartz db43cf1b30 add sticky actions col to org idp table 2025-12-24 16:14:26 -05:00
miloschwartz 2f561b5604 adjustments to mobile header css closes #1930 2025-12-24 16:14:26 -05:00
miloschwartz 5a30f036ff fade mobile footer 2025-12-24 16:14:26 -05:00
miloschwartz 768b9ffd09 fix server admin spacing on mobile sidebar 2025-12-24 16:14:26 -05:00
miloschwartz 8732e50047 add flag to disable product help banners 2025-12-24 16:14:26 -05:00
miloschwartz d6e0024c96 improved button loading animation 2025-12-24 16:14:26 -05:00
miloschwartz 9759e86921 add stripPortFromHost and reuse everywhere 2025-12-24 16:14:26 -05:00
Owen 0ccd5714f9 Seperating out functions 2025-12-24 11:50:27 -05:00
Owen e2dfc3eb20 Merge branch 'dev' into msg-delivery 2025-12-24 11:33:41 -05:00
Owen 446eba8bc9 Orging how we are going to make the sync 2025-12-24 10:38:44 -05:00
Owen 18579c0647 Merge branch 'dev' into msg-delivery 2025-12-23 16:57:17 -05:00
Owen 0d37e08638 Merge branch 'dev' into msg-delivery 2025-12-23 16:56:50 -05:00
Owen 75b9703793 Seperate config gen into functions 2025-12-20 11:41:23 -05:00
Fred KISSIE e983e1166a 🚧 wip: approval tables in DB 2025-12-20 00:05:33 +01:00
Owen 322f3bfb1d Add version and send it down 2025-12-19 16:44:57 -05:00
Fred KISSIE 009b86c33b Merge branch 'dev' into feat/device-approvals 2025-12-19 20:03:05 +01:00
Fred KISSIE a5775a0f4f 🗃️ create approvals table 2025-12-19 00:00:10 +01:00
365 changed files with 26470 additions and 14435 deletions
+2 -1
View File
@@ -31,4 +31,5 @@ dist
migrations/ migrations/
config/ config/
build.ts build.ts
tsconfig.json tsconfig.json
migrations/
+2 -12
View File
@@ -44,19 +44,9 @@ updates:
schedule: schedule:
interval: "daily" interval: "daily"
groups: groups:
dev-patch-updates: patch-updates:
dependency-type: "development"
update-types: update-types:
- "patch" - "patch"
dev-minor-updates: minor-updates:
dependency-type: "development"
update-types: update-types:
- "minor" - "minor"
prod-patch-updates:
dependency-type: "production"
update-types:
- "patch"
prod-minor-updates:
dependency-type: "production"
update-types:
- "minor"
+226 -27
View File
@@ -1,4 +1,4 @@
name: CI/CD Pipeline name: Public Pipeline
# CI/CD workflow for building, publishing, mirroring, signing container images and building release binaries. # CI/CD workflow for building, publishing, mirroring, signing container images and building release binaries.
# Actions are pinned to specific SHAs to reduce supply-chain risk. This workflow triggers on tag push events. # Actions are pinned to specific SHAs to reduce supply-chain risk. This workflow triggers on tag push events.
@@ -29,7 +29,7 @@ jobs:
permissions: write-all permissions: write-all
steps: steps:
- name: Configure AWS credentials - name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2 uses: aws-actions/configure-aws-credentials@v5
with: with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }} role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600 role-duration-seconds: 3600
@@ -264,7 +264,7 @@ jobs:
shell: bash shell: bash
- name: Install Go - name: Install Go
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with: with:
go-version: 1.24 go-version: 1.24
@@ -329,20 +329,89 @@ jobs:
skopeo login ghcr.io -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}" skopeo login ghcr.io -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}"
shell: bash shell: bash
- name: Copy tag from Docker Hub to GHCR - name: Copy tags from Docker Hub to GHCR
# Mirror the already-built image (all architectures) to GHCR so we can sign it # Mirror the already-built images (all architectures) to GHCR so we can sign them
# Wait a bit for both architectures to be available in Docker Hub manifest # Wait a bit for both architectures to be available in Docker Hub manifest
env: env:
REGISTRY_AUTH_FILE: ${{ runner.temp }}/containers/auth.json REGISTRY_AUTH_FILE: ${{ runner.temp }}/containers/auth.json
run: | run: |
set -euo pipefail set -euo pipefail
TAG=${{ env.TAG }} TAG=${{ env.TAG }}
echo "Waiting for multi-arch manifest to be ready..." MAJOR_TAG=$(echo $TAG | cut -d. -f1)
MINOR_TAG=$(echo $TAG | cut -d. -f1,2)
echo "Waiting for multi-arch manifests to be ready..."
sleep 30 sleep 30
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:${TAG} -> ${{ env.GHCR_IMAGE }}:${TAG}"
skopeo copy --all --retry-times 3 \ # Determine if this is an RC release
docker://$DOCKERHUB_IMAGE:$TAG \ IS_RC="false"
docker://$GHCR_IMAGE:$TAG if [[ "$TAG" == *"-rc."* ]]; then
IS_RC="true"
fi
if [ "$IS_RC" = "true" ]; then
echo "RC release detected - copying version-specific tags only"
# SQLite OSS
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:${TAG} -> ${{ env.GHCR_IMAGE }}:${TAG}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:$TAG \
docker://$GHCR_IMAGE:$TAG
# PostgreSQL OSS
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:postgresql-${TAG} -> ${{ env.GHCR_IMAGE }}:postgresql-${TAG}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:postgresql-$TAG \
docker://$GHCR_IMAGE:postgresql-$TAG
# SQLite Enterprise
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:ee-${TAG} -> ${{ env.GHCR_IMAGE }}:ee-${TAG}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:ee-$TAG \
docker://$GHCR_IMAGE:ee-$TAG
# PostgreSQL Enterprise
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:ee-postgresql-${TAG} -> ${{ env.GHCR_IMAGE }}:ee-postgresql-${TAG}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:ee-postgresql-$TAG \
docker://$GHCR_IMAGE:ee-postgresql-$TAG
else
echo "Regular release detected - copying all tags (latest, major, minor, full version)"
# SQLite OSS - all tags
for TAG_SUFFIX in "latest" "$MAJOR_TAG" "$MINOR_TAG" "$TAG"; do
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:${TAG_SUFFIX} -> ${{ env.GHCR_IMAGE }}:${TAG_SUFFIX}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:$TAG_SUFFIX \
docker://$GHCR_IMAGE:$TAG_SUFFIX
done
# PostgreSQL OSS - all tags
for TAG_SUFFIX in "latest" "$MAJOR_TAG" "$MINOR_TAG" "$TAG"; do
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:postgresql-${TAG_SUFFIX} -> ${{ env.GHCR_IMAGE }}:postgresql-${TAG_SUFFIX}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:postgresql-$TAG_SUFFIX \
docker://$GHCR_IMAGE:postgresql-$TAG_SUFFIX
done
# SQLite Enterprise - all tags
for TAG_SUFFIX in "latest" "$MAJOR_TAG" "$MINOR_TAG" "$TAG"; do
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:ee-${TAG_SUFFIX} -> ${{ env.GHCR_IMAGE }}:ee-${TAG_SUFFIX}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:ee-$TAG_SUFFIX \
docker://$GHCR_IMAGE:ee-$TAG_SUFFIX
done
# PostgreSQL Enterprise - all tags
for TAG_SUFFIX in "latest" "$MAJOR_TAG" "$MINOR_TAG" "$TAG"; do
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:ee-postgresql-${TAG_SUFFIX} -> ${{ env.GHCR_IMAGE }}:ee-postgresql-${TAG_SUFFIX}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:ee-postgresql-$TAG_SUFFIX \
docker://$GHCR_IMAGE:ee-postgresql-$TAG_SUFFIX
done
fi
echo "All images copied successfully to GHCR!"
shell: bash shell: bash
- name: Login to GitHub Container Registry (for cosign) - name: Login to GitHub Container Registry (for cosign)
@@ -371,28 +440,158 @@ jobs:
issuer="https://token.actions.githubusercontent.com" issuer="https://token.actions.githubusercontent.com"
id_regex="^https://github.com/${{ github.repository }}/.+" # accept this repo (all workflows/refs) id_regex="^https://github.com/${{ github.repository }}/.+" # accept this repo (all workflows/refs)
for IMAGE in "${GHCR_IMAGE}" "${DOCKERHUB_IMAGE}"; do # Track failures
echo "Processing ${IMAGE}:${TAG}" FAILED_TAGS=()
SUCCESSFUL_TAGS=()
DIGEST="$(skopeo inspect --retry-times 3 docker://${IMAGE}:${TAG} | jq -r '.Digest')" # Determine if this is an RC release
REF="${IMAGE}@${DIGEST}" IS_RC="false"
echo "Resolved digest: ${REF}" if [[ "$TAG" == *"-rc."* ]]; then
IS_RC="true"
fi
echo "==> cosign sign (keyless) --recursive ${REF}" # Define image variants to sign
cosign sign --recursive "${REF}" if [ "$IS_RC" = "true" ]; then
echo "RC release - signing version-specific tags only"
IMAGE_TAGS=(
"${TAG}"
"postgresql-${TAG}"
"ee-${TAG}"
"ee-postgresql-${TAG}"
)
else
echo "Regular release - signing all tags"
MAJOR_TAG=$(echo $TAG | cut -d. -f1)
MINOR_TAG=$(echo $TAG | cut -d. -f1,2)
IMAGE_TAGS=(
"latest" "$MAJOR_TAG" "$MINOR_TAG" "$TAG"
"postgresql-latest" "postgresql-$MAJOR_TAG" "postgresql-$MINOR_TAG" "postgresql-$TAG"
"ee-latest" "ee-$MAJOR_TAG" "ee-$MINOR_TAG" "ee-$TAG"
"ee-postgresql-latest" "ee-postgresql-$MAJOR_TAG" "ee-postgresql-$MINOR_TAG" "ee-postgresql-$TAG"
)
fi
echo "==> cosign sign (key) --recursive ${REF}" # Sign each image variant for both registries
cosign sign --key env://COSIGN_PRIVATE_KEY --recursive "${REF}" for BASE_IMAGE in "${GHCR_IMAGE}" "${DOCKERHUB_IMAGE}"; do
for IMAGE_TAG in "${IMAGE_TAGS[@]}"; do
echo "Processing ${BASE_IMAGE}:${IMAGE_TAG}"
TAG_FAILED=false
echo "==> cosign verify (public key) ${REF}" # Wrap the entire tag processing in error handling
cosign verify --key env://COSIGN_PUBLIC_KEY "${REF}" -o text (
set -e
DIGEST="$(skopeo inspect --retry-times 3 docker://${BASE_IMAGE}:${IMAGE_TAG} | jq -r '.Digest')"
REF="${BASE_IMAGE}@${DIGEST}"
echo "Resolved digest: ${REF}"
echo "==> cosign verify (keyless policy) ${REF}" echo "==> cosign sign (keyless) --recursive ${REF}"
cosign verify \ cosign sign --recursive "${REF}"
--certificate-oidc-issuer "${issuer}" \
--certificate-identity-regexp "${id_regex}" \ echo "==> cosign sign (key) --recursive ${REF}"
"${REF}" -o text cosign sign --key env://COSIGN_PRIVATE_KEY --recursive "${REF}"
# Retry wrapper for verification to handle registry propagation delays
retry_verify() {
local cmd="$1"
local attempts=6
local delay=5
local i=1
until eval "$cmd"; do
if [ $i -ge $attempts ]; then
echo "Verification failed after $attempts attempts"
return 1
fi
echo "Verification not yet available. Retry $i/$attempts after ${delay}s..."
sleep $delay
i=$((i+1))
delay=$((delay*2))
# Cap the delay to avoid very long waits
if [ $delay -gt 60 ]; then delay=60; fi
done
return 0
}
echo "==> cosign verify (public key) ${REF}"
if retry_verify "cosign verify --key env://COSIGN_PUBLIC_KEY '${REF}' -o text"; then
VERIFIED_INDEX=true
else
VERIFIED_INDEX=false
fi
echo "==> cosign verify (keyless policy) ${REF}"
if retry_verify "cosign verify --certificate-oidc-issuer '${issuer}' --certificate-identity-regexp '${id_regex}' '${REF}' -o text"; then
VERIFIED_INDEX_KEYLESS=true
else
VERIFIED_INDEX_KEYLESS=false
fi
# If index verification fails, attempt to verify child platform manifests
if [ "${VERIFIED_INDEX}" != "true" ] || [ "${VERIFIED_INDEX_KEYLESS}" != "true" ]; then
echo "Index verification not available; attempting child manifest verification for ${BASE_IMAGE}:${IMAGE_TAG}"
CHILD_VERIFIED=false
for ARCH in arm64 amd64; do
CHILD_TAG="${IMAGE_TAG}-${ARCH}"
echo "Resolving child digest for ${BASE_IMAGE}:${CHILD_TAG}"
CHILD_DIGEST="$(skopeo inspect --retry-times 3 docker://${BASE_IMAGE}:${CHILD_TAG} | jq -r '.Digest' || true)"
if [ -n "${CHILD_DIGEST}" ] && [ "${CHILD_DIGEST}" != "null" ]; then
CHILD_REF="${BASE_IMAGE}@${CHILD_DIGEST}"
echo "==> cosign verify (public key) child ${CHILD_REF}"
if retry_verify "cosign verify --key env://COSIGN_PUBLIC_KEY '${CHILD_REF}' -o text"; then
CHILD_VERIFIED=true
echo "Public key verification succeeded for child ${CHILD_REF}"
else
echo "Public key verification failed for child ${CHILD_REF}"
fi
echo "==> cosign verify (keyless policy) child ${CHILD_REF}"
if retry_verify "cosign verify --certificate-oidc-issuer '${issuer}' --certificate-identity-regexp '${id_regex}' '${CHILD_REF}' -o text"; then
CHILD_VERIFIED=true
echo "Keyless verification succeeded for child ${CHILD_REF}"
else
echo "Keyless verification failed for child ${CHILD_REF}"
fi
else
echo "No child digest found for ${BASE_IMAGE}:${CHILD_TAG}; skipping"
fi
done
if [ "${CHILD_VERIFIED}" != "true" ]; then
echo "Failed to verify index and no child manifests verified for ${BASE_IMAGE}:${IMAGE_TAG}"
exit 1
fi
fi
) || TAG_FAILED=true
if [ "$TAG_FAILED" = "true" ]; then
echo "⚠️ WARNING: Failed to sign/verify ${BASE_IMAGE}:${IMAGE_TAG}"
FAILED_TAGS+=("${BASE_IMAGE}:${IMAGE_TAG}")
else
echo "✓ Successfully signed and verified ${BASE_IMAGE}:${IMAGE_TAG}"
SUCCESSFUL_TAGS+=("${BASE_IMAGE}:${IMAGE_TAG}")
fi
done
done done
# Report summary
echo ""
echo "=========================================="
echo "Sign and Verify Summary"
echo "=========================================="
echo "Successful: ${#SUCCESSFUL_TAGS[@]}"
echo "Failed: ${#FAILED_TAGS[@]}"
echo ""
if [ ${#FAILED_TAGS[@]} -gt 0 ]; then
echo "Failed tags:"
for tag in "${FAILED_TAGS[@]}"; do
echo " - $tag"
done
echo ""
echo "⚠️ WARNING: Some tags failed to sign/verify, but continuing anyway"
else
echo "✓ All images signed and verified successfully!"
fi
shell: bash shell: bash
post-run: post-run:
@@ -410,7 +609,7 @@ jobs:
permissions: write-all permissions: write-all
steps: steps:
- name: Configure AWS credentials - name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2 uses: aws-actions/configure-aws-credentials@v5
with: with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }} role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600 role-duration-seconds: 3600
+2 -2
View File
@@ -24,9 +24,9 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with: with:
node-version: '22' node-version: '24'
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
+125
View File
@@ -0,0 +1,125 @@
name: SAAS Pipeline
# CI/CD workflow for building, publishing, mirroring, signing container images and building release binaries.
# Actions are pinned to specific SHAs to reduce supply-chain risk. This workflow triggers on tag push events.
permissions:
contents: read
packages: write # for GHCR push
id-token: write # for Cosign Keyless (OIDC) Signing
on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+-s.[0-9]+"
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
jobs:
pre-run:
runs-on: ubuntu-latest
permissions: write-all
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600
aws-region: ${{ secrets.AWS_REGION }}
- name: Verify AWS identity
run: aws sts get-caller-identity
- name: Start EC2 instances
run: |
aws ec2 start-instances --instance-ids ${{ secrets.EC2_INSTANCE_ID_ARM_RUNNER }}
echo "EC2 instances started"
release-arm:
name: Build and Release (ARM64)
runs-on: [self-hosted, linux, arm64, us-east-1]
needs: [pre-run]
if: >-
${{
needs.pre-run.result == 'success'
}}
# Job-level timeout to avoid runaway or stuck runs
timeout-minutes: 120
env:
# Target images
AWS_IMAGE: ${{ secrets.aws_account_id }}.dkr.ecr.us-east-1.amazonaws.com/${{ github.event.repository.name }}
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Monitor storage space
run: |
THRESHOLD=75
USED_SPACE=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')
echo "Used space: $USED_SPACE%"
if [ "$USED_SPACE" -ge "$THRESHOLD" ]; then
echo "Used space is below the threshold of 75% free. Running Docker system prune."
echo y | docker system prune -a
else
echo "Storage space is above the threshold. No action needed."
fi
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.aws_account_id }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600
aws-region: ${{ secrets.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Extract tag name
id: get-tag
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
shell: bash
- name: Update version in package.json
run: |
TAG=${{ env.TAG }}
sed -i "s/export const APP_VERSION = \".*\";/export const APP_VERSION = \"$TAG\";/" server/lib/consts.ts
cat server/lib/consts.ts
shell: bash
- name: Build and push Docker images (Docker Hub - ARM64)
run: |
TAG=${{ env.TAG }}
make build-saas tag=$TAG
echo "Built & pushed ARM64 images to: ${{ env.AWS_IMAGE }}:${TAG}"
shell: bash
post-run:
needs: [pre-run, release-arm]
if: >-
${{
always() &&
needs.pre-run.result == 'success' &&
(needs.release-arm.result == 'success' || needs.release-arm.result == 'skipped' || needs.release-arm.result == 'failure')
}}
runs-on: ubuntu-latest
permissions: write-all
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
role-duration-seconds: 3600
aws-region: ${{ secrets.AWS_REGION }}
- name: Verify AWS identity
run: aws sts get-caller-identity
- name: Stop EC2 instances
run: |
aws ec2 stop-instances --instance-ids ${{ secrets.EC2_INSTANCE_ID_ARM_RUNNER }}
echo "EC2 instances stopped"
+3 -9
View File
@@ -17,9 +17,9 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install Node - name: Install Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with: with:
node-version: '22' node-version: '24'
- name: Copy config file - name: Copy config file
run: cp config/config.example.yml config/config.yml run: cp config/config.example.yml config/config.yml
@@ -34,7 +34,7 @@ jobs:
run: npm run set:oss run: npm run set:oss
- name: Generate database migrations - name: Generate database migrations
run: npm run db:sqlite:generate run: npm run db:generate
- name: Apply database migrations - name: Apply database migrations
run: npm run db:sqlite:push run: npm run db:sqlite:push
@@ -64,9 +64,6 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Copy config file
run: cp config/config.example.yml config/config.yml
- name: Build Docker image sqlite - name: Build Docker image sqlite
run: make dev-build-sqlite run: make dev-build-sqlite
@@ -76,8 +73,5 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Copy config file
run: cp config/config.example.yml config/config.yml
- name: Build Docker image pg - name: Build Docker image pg
run: make dev-build-pg run: make dev-build-pg
+2 -1
View File
@@ -50,4 +50,5 @@ dynamic/
*.mmdb *.mmdb
scratch/ scratch/
tsconfig.json tsconfig.json
hydrateSaas.ts hydrateSaas.ts
CLAUDE.md
+3 -3
View File
@@ -4,13 +4,13 @@
}, },
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"[jsonc]": { "[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "vscode.json-language-features"
}, },
"[javascript]": { "[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"[typescript]": { "[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "vscode.typescript-language-features"
}, },
"[typescriptreact]": { "[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
@@ -19,4 +19,4 @@
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"editor.formatOnSave": true "editor.formatOnSave": true
} }
+33 -29
View File
@@ -5,7 +5,7 @@ WORKDIR /app
ARG BUILD=oss ARG BUILD=oss
ARG DATABASE=sqlite ARG DATABASE=sqlite
RUN apk add --no-cache curl tzdata python3 make g++ RUN apk add --no-cache python3 make g++
# COPY package.json package-lock.json ./ # COPY package.json package-lock.json ./
COPY package*.json ./ COPY package*.json ./
@@ -13,41 +13,31 @@ RUN npm ci
COPY . . COPY . .
RUN echo "export * from \"./$DATABASE\";" > server/db/index.ts RUN if [ "$BUILD" = "oss" ]; then rm -rf server/private; fi && \
RUN echo "export const driver: \"pg\" | \"sqlite\" = \"$DATABASE\";" >> server/db/index.ts npm run set:$DATABASE && \
npm run set:$BUILD && \
RUN echo "export const build = \"$BUILD\" as \"saas\" | \"enterprise\" | \"oss\";" > server/build.ts npm run db:$DATABASE:generate && \
npm run build && \
# Copy the appropriate TypeScript configuration based on build type npm run build:cli
RUN if [ "$BUILD" = "oss" ]; then cp tsconfig.oss.json tsconfig.json; \
elif [ "$BUILD" = "saas" ]; then cp tsconfig.saas.json tsconfig.json; \
elif [ "$BUILD" = "enterprise" ]; then cp tsconfig.enterprise.json tsconfig.json; \
fi
# if the build is oss then remove the server/private directory
RUN if [ "$BUILD" = "oss" ]; then rm -rf server/private; fi
RUN if [ "$DATABASE" = "pg" ]; then npx drizzle-kit generate --dialect postgresql --schema ./server/db/pg/schema --out init; else npx drizzle-kit generate --dialect $DATABASE --schema ./server/db/$DATABASE/schema --out init; fi
RUN mkdir -p dist
RUN npm run next:build
RUN node esbuild.mjs -e server/index.ts -o dist/server.mjs -b $BUILD
RUN if [ "$DATABASE" = "pg" ]; then \
node esbuild.mjs -e server/setup/migrationsPg.ts -o dist/migrations.mjs; \
else \
node esbuild.mjs -e server/setup/migrationsSqlite.ts -o dist/migrations.mjs; \
fi
# test to make sure the build output is there and error if not # test to make sure the build output is there and error if not
RUN test -f dist/server.mjs RUN test -f dist/server.mjs
RUN npm run build:cli
# Prune dev dependencies and clean up to prepare for copy to runner # Prune dev dependencies and clean up to prepare for copy to runner
RUN npm prune --omit=dev && npm cache clean --force RUN npm prune --omit=dev && npm cache clean --force
FROM node:24-alpine AS runner FROM node:24-alpine AS runner
# OCI Image Labels - Build Args for dynamic values
ARG VERSION="dev"
ARG REVISION=""
ARG CREATED=""
ARG LICENSE="AGPL-3.0"
# Derive title and description based on BUILD type
ARG IMAGE_TITLE="Pangolin"
ARG IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere"
WORKDIR /app WORKDIR /app
# Only curl and tzdata needed at runtime - no build tools! # Only curl and tzdata needed at runtime - no build tools!
@@ -56,17 +46,31 @@ RUN apk add --no-cache curl tzdata
# Copy pre-built node_modules from builder (already pruned to production only) # Copy pre-built node_modules from builder (already pruned to production only)
# This includes the compiled native modules like better-sqlite3 # This includes the compiled native modules like better-sqlite3
COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/dist ./dist COPY --from=builder /app/dist ./dist
COPY --from=builder /app/init ./dist/init COPY --from=builder /app/server/migrations ./dist/init
COPY --from=builder /app/package.json ./package.json COPY --from=builder /app/package.json ./package.json
COPY ./cli/wrapper.sh /usr/local/bin/pangctl COPY ./cli/wrapper.sh /usr/local/bin/pangctl
RUN chmod +x /usr/local/bin/pangctl ./dist/cli.mjs RUN chmod +x /usr/local/bin/pangctl ./dist/cli.mjs
COPY server/db/names.json ./dist/names.json COPY server/db/names.json ./dist/names.json
COPY server/db/ios_models.json ./dist/ios_models.json
COPY server/db/mac_models.json ./dist/mac_models.json
COPY public ./public COPY public ./public
# OCI Image Labels
# https://github.com/opencontainers/image-spec/blob/main/annotations.md
LABEL org.opencontainers.image.source="https://github.com/fosrl/pangolin" \
org.opencontainers.image.url="https://github.com/fosrl/pangolin" \
org.opencontainers.image.documentation="https://docs.pangolin.net" \
org.opencontainers.image.vendor="Fossorial" \
org.opencontainers.image.licenses="${LICENSE}" \
org.opencontainers.image.title="${IMAGE_TITLE}" \
org.opencontainers.image.description="${IMAGE_DESCRIPTION}" \
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.revision="${REVISION}" \
org.opencontainers.image.created="${CREATED}"
CMD ["npm", "run", "start"] CMD ["npm", "run", "start"]
+198 -7
View File
@@ -3,6 +3,25 @@
major_tag := $(shell echo $(tag) | cut -d. -f1) major_tag := $(shell echo $(tag) | cut -d. -f1)
minor_tag := $(shell echo $(tag) | cut -d. -f1,2) minor_tag := $(shell echo $(tag) | cut -d. -f1,2)
# OCI label variables
CREATED := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
REVISION := $(shell git rev-parse HEAD 2>/dev/null || echo "unknown")
# Common OCI build args for OSS builds
OCI_ARGS_OSS = --build-arg VERSION=$(tag) \
--build-arg REVISION=$(REVISION) \
--build-arg CREATED=$(CREATED) \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere"
# Common OCI build args for Enterprise builds
OCI_ARGS_EE = --build-arg VERSION=$(tag) \
--build-arg REVISION=$(REVISION) \
--build-arg CREATED=$(CREATED) \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere"
.PHONY: build-release build-sqlite build-postgresql build-ee-sqlite build-ee-postgresql .PHONY: build-release build-sqlite build-postgresql build-ee-sqlite build-ee-postgresql
build-release: build-sqlite build-postgresql build-ee-sqlite build-ee-postgresql build-release: build-sqlite build-postgresql build-ee-sqlite build-ee-postgresql
@@ -15,6 +34,7 @@ build-sqlite:
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
$(OCI_ARGS_OSS) \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:latest \ --tag fosrl/pangolin:latest \
--tag fosrl/pangolin:$(major_tag) \ --tag fosrl/pangolin:$(major_tag) \
@@ -30,6 +50,7 @@ build-postgresql:
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
$(OCI_ARGS_OSS) \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:postgresql-latest \ --tag fosrl/pangolin:postgresql-latest \
--tag fosrl/pangolin:postgresql-$(major_tag) \ --tag fosrl/pangolin:postgresql-$(major_tag) \
@@ -45,6 +66,7 @@ build-ee-sqlite:
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
$(OCI_ARGS_EE) \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:ee-latest \ --tag fosrl/pangolin:ee-latest \
--tag fosrl/pangolin:ee-$(major_tag) \ --tag fosrl/pangolin:ee-$(major_tag) \
@@ -60,6 +82,7 @@ build-ee-postgresql:
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
$(OCI_ARGS_EE) \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:ee-postgresql-latest \ --tag fosrl/pangolin:ee-postgresql-latest \
--tag fosrl/pangolin:ee-postgresql-$(major_tag) \ --tag fosrl/pangolin:ee-postgresql-$(major_tag) \
@@ -67,6 +90,18 @@ build-ee-postgresql:
--tag fosrl/pangolin:ee-postgresql-$(tag) \ --tag fosrl/pangolin:ee-postgresql-$(tag) \
--push . --push .
build-saas:
@if [ -z "$(tag)" ]; then \
echo "Error: tag is required. Usage: make build-release tag=<tag>"; \
exit 1; \
fi
docker buildx build \
--build-arg BUILD=saas \
--build-arg DATABASE=pg \
--platform linux/arm64 \
--tag $(AWS_IMAGE):$(tag) \
--push .
build-release-arm: build-release-arm:
@if [ -z "$(tag)" ]; then \ @if [ -z "$(tag)" ]; then \
echo "Error: tag is required. Usage: make build-release-arm tag=<tag>"; \ echo "Error: tag is required. Usage: make build-release-arm tag=<tag>"; \
@@ -74,9 +109,16 @@ build-release-arm:
fi fi
@MAJOR_TAG=$$(echo $(tag) | cut -d. -f1); \ @MAJOR_TAG=$$(echo $(tag) | cut -d. -f1); \
MINOR_TAG=$$(echo $(tag) | cut -d. -f1,2); \ MINOR_TAG=$$(echo $(tag) | cut -d. -f1,2); \
CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:latest-arm64 \ --tag fosrl/pangolin:latest-arm64 \
--tag fosrl/pangolin:$$MAJOR_TAG-arm64 \ --tag fosrl/pangolin:$$MAJOR_TAG-arm64 \
@@ -86,6 +128,11 @@ build-release-arm:
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:postgresql-latest-arm64 \ --tag fosrl/pangolin:postgresql-latest-arm64 \
--tag fosrl/pangolin:postgresql-$$MAJOR_TAG-arm64 \ --tag fosrl/pangolin:postgresql-$$MAJOR_TAG-arm64 \
@@ -95,6 +142,12 @@ build-release-arm:
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:ee-latest-arm64 \ --tag fosrl/pangolin:ee-latest-arm64 \
--tag fosrl/pangolin:ee-$$MAJOR_TAG-arm64 \ --tag fosrl/pangolin:ee-$$MAJOR_TAG-arm64 \
@@ -104,6 +157,12 @@ build-release-arm:
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:ee-postgresql-latest-arm64 \ --tag fosrl/pangolin:ee-postgresql-latest-arm64 \
--tag fosrl/pangolin:ee-postgresql-$$MAJOR_TAG-arm64 \ --tag fosrl/pangolin:ee-postgresql-$$MAJOR_TAG-arm64 \
@@ -118,9 +177,16 @@ build-release-amd:
fi fi
@MAJOR_TAG=$$(echo $(tag) | cut -d. -f1); \ @MAJOR_TAG=$$(echo $(tag) | cut -d. -f1); \
MINOR_TAG=$$(echo $(tag) | cut -d. -f1,2); \ MINOR_TAG=$$(echo $(tag) | cut -d. -f1,2); \
CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:latest-amd64 \ --tag fosrl/pangolin:latest-amd64 \
--tag fosrl/pangolin:$$MAJOR_TAG-amd64 \ --tag fosrl/pangolin:$$MAJOR_TAG-amd64 \
@@ -130,6 +196,11 @@ build-release-amd:
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:postgresql-latest-amd64 \ --tag fosrl/pangolin:postgresql-latest-amd64 \
--tag fosrl/pangolin:postgresql-$$MAJOR_TAG-amd64 \ --tag fosrl/pangolin:postgresql-$$MAJOR_TAG-amd64 \
@@ -139,6 +210,12 @@ build-release-amd:
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:ee-latest-amd64 \ --tag fosrl/pangolin:ee-latest-amd64 \
--tag fosrl/pangolin:ee-$$MAJOR_TAG-amd64 \ --tag fosrl/pangolin:ee-$$MAJOR_TAG-amd64 \
@@ -148,6 +225,12 @@ build-release-amd:
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:ee-postgresql-latest-amd64 \ --tag fosrl/pangolin:ee-postgresql-latest-amd64 \
--tag fosrl/pangolin:ee-postgresql-$$MAJOR_TAG-amd64 \ --tag fosrl/pangolin:ee-postgresql-$$MAJOR_TAG-amd64 \
@@ -201,27 +284,51 @@ build-rc:
echo "Error: tag is required. Usage: make build-release tag=<tag>"; \ echo "Error: tag is required. Usage: make build-release tag=<tag>"; \
exit 1; \ exit 1; \
fi fi
@CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:$(tag) \ --tag fosrl/pangolin:$(tag) \
--push . --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:postgresql-$(tag) \ --tag fosrl/pangolin:postgresql-$(tag) \
--push . --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:ee-$(tag) \ --tag fosrl/pangolin:ee-$(tag) \
--push . --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:ee-postgresql-$(tag) \ --tag fosrl/pangolin:ee-postgresql-$(tag) \
--push . --push .
@@ -231,27 +338,51 @@ build-rc-arm:
echo "Error: tag is required. Usage: make build-rc-arm tag=<tag>"; \ echo "Error: tag is required. Usage: make build-rc-arm tag=<tag>"; \
exit 1; \ exit 1; \
fi fi
@CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:$(tag)-arm64 \ --tag fosrl/pangolin:$(tag)-arm64 \
--push . && \ --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:postgresql-$(tag)-arm64 \ --tag fosrl/pangolin:postgresql-$(tag)-arm64 \
--push . && \ --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:ee-$(tag)-arm64 \ --tag fosrl/pangolin:ee-$(tag)-arm64 \
--push . && \ --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \ --platform linux/arm64 \
--tag fosrl/pangolin:ee-postgresql-$(tag)-arm64 \ --tag fosrl/pangolin:ee-postgresql-$(tag)-arm64 \
--push . --push .
@@ -261,27 +392,51 @@ build-rc-amd:
echo "Error: tag is required. Usage: make build-rc-amd tag=<tag>"; \ echo "Error: tag is required. Usage: make build-rc-amd tag=<tag>"; \
exit 1; \ exit 1; \
fi fi
@CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:$(tag)-amd64 \ --tag fosrl/pangolin:$(tag)-amd64 \
--push . && \ --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=oss \ --build-arg BUILD=oss \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:postgresql-$(tag)-amd64 \ --tag fosrl/pangolin:postgresql-$(tag)-amd64 \
--push . && \ --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=sqlite \ --build-arg DATABASE=sqlite \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:ee-$(tag)-amd64 \ --tag fosrl/pangolin:ee-$(tag)-amd64 \
--push . && \ --push . && \
docker buildx build \ docker buildx build \
--build-arg BUILD=enterprise \ --build-arg BUILD=enterprise \
--build-arg DATABASE=pg \ --build-arg DATABASE=pg \
--build-arg VERSION=$(tag) \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg LICENSE="Fossorial Commercial" \
--build-arg IMAGE_TITLE="Pangolin EE" \
--build-arg IMAGE_DESCRIPTION="Pangolin Enterprise Edition - Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \ --platform linux/amd64 \
--tag fosrl/pangolin:ee-postgresql-$(tag)-amd64 \ --tag fosrl/pangolin:ee-postgresql-$(tag)-amd64 \
--push . --push .
@@ -314,16 +469,52 @@ create-manifests-rc:
echo "All RC multi-arch manifests created successfully!" echo "All RC multi-arch manifests created successfully!"
build-arm: build-arm:
docker buildx build --platform linux/arm64 -t fosrl/pangolin:latest . @CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker buildx build \
--build-arg VERSION=dev \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/arm64 \
-t fosrl/pangolin:latest .
build-x86: build-x86:
docker buildx build --platform linux/amd64 -t fosrl/pangolin:latest . @CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker buildx build \
--build-arg VERSION=dev \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
--platform linux/amd64 \
-t fosrl/pangolin:latest .
dev-build-sqlite: dev-build-sqlite:
docker build --build-arg DATABASE=sqlite -t fosrl/pangolin:latest . @CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker build \
--build-arg DATABASE=sqlite \
--build-arg VERSION=dev \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
-t fosrl/pangolin:latest .
dev-build-pg: dev-build-pg:
docker build --build-arg DATABASE=pg -t fosrl/pangolin:postgresql-latest . @CREATED=$$(date -u +"%Y-%m-%dT%H:%M:%SZ"); \
REVISION=$$(git rev-parse HEAD 2>/dev/null || echo "unknown"); \
docker build \
--build-arg DATABASE=pg \
--build-arg VERSION=dev \
--build-arg REVISION=$$REVISION \
--build-arg CREATED=$$CREATED \
--build-arg IMAGE_TITLE="Pangolin" \
--build-arg IMAGE_DESCRIPTION="Identity-aware VPN and proxy for remote access to anything, anywhere" \
-t fosrl/pangolin:postgresql-latest .
test: test:
docker run -it -p 3000:3000 -p 3001:3001 -p 3002:3002 -v ./config:/app/config fosrl/pangolin:latest docker run -it -p 3000:3000 -p 3001:3001 -p 3002:3002 -v ./config:/app/config fosrl/pangolin:latest
+8
View File
@@ -35,6 +35,12 @@
</div> </div>
<p align="center">
<a href="https://docs.pangolin.net/careers/join-us">
<img src="https://img.shields.io/badge/🚀_We're_Hiring!-Join_Our_Team-brightgreen?style=for-the-badge" alt="We're Hiring!" />
</a>
</p>
<p align="center"> <p align="center">
<strong> <strong>
Start testing Pangolin at <a href="https://app.pangolin.net/auth/signup">app.pangolin.net</a> Start testing Pangolin at <a href="https://app.pangolin.net/auth/signup">app.pangolin.net</a>
@@ -74,6 +80,8 @@ Download the Pangolin client for your platform:
- [Mac](https://pangolin.net/downloads/mac) - [Mac](https://pangolin.net/downloads/mac)
- [Windows](https://pangolin.net/downloads/windows) - [Windows](https://pangolin.net/downloads/windows)
- [Linux](https://pangolin.net/downloads/linux) - [Linux](https://pangolin.net/downloads/linux)
- [iOS](https://pangolin.net/downloads/ios)
- [Android](https://pangolin.net/downloads/android)
## Get Started ## Get Started
-72
View File
@@ -1,72 +0,0 @@
import requests
import yaml
import json
import base64
# The file path for the YAML file to be read
# You can change this to the path of your YAML file
YAML_FILE_PATH = 'blueprint.yaml'
# The API endpoint and headers from the curl request
API_URL = 'http://api.pangolin.net/v1/org/test/blueprint'
HEADERS = {
'accept': '*/*',
'Authorization': 'Bearer <your_token_here>',
'Content-Type': 'application/json'
}
def convert_and_send(file_path, url, headers):
"""
Reads a YAML file, converts its content to a JSON payload,
and sends it via a PUT request to a specified URL.
"""
try:
# Read the YAML file content
with open(file_path, 'r') as file:
yaml_content = file.read()
# Parse the YAML string to a Python dictionary
# This will be used to ensure the YAML is valid before sending
parsed_yaml = yaml.safe_load(yaml_content)
# convert the parsed YAML to a JSON string
json_payload = json.dumps(parsed_yaml)
print("Converted JSON payload:")
print(json_payload)
# Encode the JSON string to Base64
encoded_json = base64.b64encode(json_payload.encode('utf-8')).decode('utf-8')
# Create the final payload with the base64 encoded data
final_payload = {
"blueprint": encoded_json
}
print("Sending the following Base64 encoded JSON payload:")
print(final_payload)
print("-" * 20)
# Make the PUT request with the base64 encoded payload
response = requests.put(url, headers=headers, json=final_payload)
# Print the API response for debugging
print(f"API Response Status Code: {response.status_code}")
print("API Response Content:")
print(response.text)
# Raise an exception for bad status codes (4xx or 5xx)
response.raise_for_status()
except FileNotFoundError:
print(f"Error: The file '{file_path}' was not found.")
except yaml.YAMLError as e:
print(f"Error parsing YAML file: {e}")
except requests.exceptions.RequestException as e:
print(f"An error occurred during the API request: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# Run the function
if __name__ == "__main__":
convert_and_send(YAML_FILE_PATH, API_URL, HEADERS)
-70
View File
@@ -1,70 +0,0 @@
client-resources:
client-resource-nice-id-uno:
name: this is my resource
protocol: tcp
proxy-port: 3001
hostname: localhost
internal-port: 3000
site: lively-yosemite-toad
client-resource-nice-id-duce:
name: this is my resource
protocol: udp
proxy-port: 3000
hostname: localhost
internal-port: 3000
site: lively-yosemite-toad
proxy-resources:
resource-nice-id-uno:
name: this is my resource
protocol: http
full-domain: duce.test.example.com
host-header: example.com
tls-server-name: example.com
# auth:
# pincode: 123456
# password: sadfasdfadsf
# sso-enabled: true
# sso-roles:
# - Member
# sso-users:
# - owen@pangolin.net
# whitelist-users:
# - owen@pangolin.net
# auto-login-idp: 1
headers:
- name: X-Example-Header
value: example-value
- name: X-Another-Header
value: another-value
rules:
- action: allow
match: ip
value: 1.1.1.1
- action: deny
match: cidr
value: 2.2.2.2/32
- action: pass
match: path
value: /admin
targets:
- site: lively-yosemite-toad
path: /path
pathMatchType: prefix
hostname: localhost
method: http
port: 8000
- site: slim-alpine-chipmunk
hostname: localhost
path: /yoman
pathMatchType: exact
method: http
port: 8001
resource-nice-id-duce:
name: this is other resource
protocol: tcp
proxy-port: 3000
targets:
- site: lively-yosemite-toad
hostname: localhost
port: 3000
+36
View File
@@ -0,0 +1,36 @@
import { CommandModule } from "yargs";
import { db, licenseKey } from "@server/db";
import { eq } from "drizzle-orm";
type ClearLicenseKeysArgs = { };
export const clearLicenseKeys: CommandModule<
{},
ClearLicenseKeysArgs
> = {
command: "clear-license-keys",
describe:
"Clear all license keys from the database",
// no args
builder: (yargs) => {
return yargs;
},
handler: async (argv: {}) => {
try {
console.log(`Clearing all license keys from the database`);
// Delete all license keys
const deletedCount = await db
.delete(licenseKey)
.where(eq(licenseKey.licenseKeyId, licenseKey.licenseKeyId)) .returning();; // delete all
console.log(`Deleted ${deletedCount.length} license key(s) from the database`);
process.exit(0);
} catch (error) {
console.error("Error:", error);
process.exit(1);
}
}
};
+123
View File
@@ -0,0 +1,123 @@
import { CommandModule } from "yargs";
import { db, clients, olms, currentFingerprint, userClients, approvals } from "@server/db";
import { eq, and, inArray } from "drizzle-orm";
type DeleteClientArgs = {
orgId: string;
niceId: string;
};
export const deleteClient: CommandModule<{}, DeleteClientArgs> = {
command: "delete-client",
describe:
"Delete a client and all associated data (OLMs, current fingerprint, userClients, approvals). Snapshots are preserved.",
builder: (yargs) => {
return yargs
.option("orgId", {
type: "string",
demandOption: true,
describe: "The organization ID"
})
.option("niceId", {
type: "string",
demandOption: true,
describe: "The client niceId (identifier)"
});
},
handler: async (argv: { orgId: string; niceId: string }) => {
try {
const { orgId, niceId } = argv;
console.log(
`Deleting client with orgId: ${orgId}, niceId: ${niceId}...`
);
// Find the client
const [client] = await db
.select()
.from(clients)
.where(and(eq(clients.orgId, orgId), eq(clients.niceId, niceId)))
.limit(1);
if (!client) {
console.error(
`Error: Client with orgId "${orgId}" and niceId "${niceId}" not found.`
);
process.exit(1);
}
const clientId = client.clientId;
console.log(`Found client with clientId: ${clientId}`);
// Find all OLMs associated with this client
const associatedOlms = await db
.select()
.from(olms)
.where(eq(olms.clientId, clientId));
console.log(`Found ${associatedOlms.length} OLM(s) associated with this client`);
// Delete in a transaction to ensure atomicity
await db.transaction(async (trx) => {
// Delete currentFingerprint entries for the associated OLMs
// Note: We delete these explicitly before deleting OLMs to ensure
// we have control, even though cascade would handle it
let fingerprintCount = 0;
if (associatedOlms.length > 0) {
const olmIds = associatedOlms.map((olm) => olm.olmId);
const deletedFingerprints = await trx
.delete(currentFingerprint)
.where(inArray(currentFingerprint.olmId, olmIds))
.returning();
fingerprintCount = deletedFingerprints.length;
}
console.log(`Deleted ${fingerprintCount} current fingerprint(s)`);
// Delete OLMs
// Note: OLMs have onDelete: "set null" for clientId, so we need to delete them explicitly
const deletedOlms = await trx
.delete(olms)
.where(eq(olms.clientId, clientId))
.returning();
console.log(`Deleted ${deletedOlms.length} OLM(s)`);
// Delete approvals
// Note: Approvals have onDelete: "cascade" but we delete explicitly for clarity
const deletedApprovals = await trx
.delete(approvals)
.where(eq(approvals.clientId, clientId))
.returning();
console.log(`Deleted ${deletedApprovals.length} approval(s)`);
// Delete userClients
// Note: userClients have onDelete: "cascade" but we delete explicitly for clarity
const deletedUserClients = await trx
.delete(userClients)
.where(eq(userClients.clientId, clientId))
.returning();
console.log(`Deleted ${deletedUserClients.length} userClient association(s)`);
// Finally, delete the client itself
const deletedClients = await trx
.delete(clients)
.where(eq(clients.clientId, clientId))
.returning();
console.log(`Deleted client: ${deletedClients[0]?.name || niceId}`);
});
console.log("\nClient deletion completed successfully!");
console.log("\nSummary:");
console.log(` - Client: ${niceId} (clientId: ${clientId})`);
console.log(` - Olm(s): ${associatedOlms.length}`);
console.log(` - Current fingerprints: deleted`);
console.log(` - Approvals: deleted`);
console.log(` - UserClients: deleted`);
console.log(` - Snapshots: preserved (not deleted)`);
process.exit(0);
} catch (error) {
console.error("Error deleting client:", error);
process.exit(1);
}
}
};
+4
View File
@@ -6,6 +6,8 @@ import { setAdminCredentials } from "@cli/commands/setAdminCredentials";
import { resetUserSecurityKeys } from "@cli/commands/resetUserSecurityKeys"; import { resetUserSecurityKeys } from "@cli/commands/resetUserSecurityKeys";
import { clearExitNodes } from "./commands/clearExitNodes"; import { clearExitNodes } from "./commands/clearExitNodes";
import { rotateServerSecret } from "./commands/rotateServerSecret"; import { rotateServerSecret } from "./commands/rotateServerSecret";
import { clearLicenseKeys } from "./commands/clearLicenseKeys";
import { deleteClient } from "./commands/deleteClient";
yargs(hideBin(process.argv)) yargs(hideBin(process.argv))
.scriptName("pangctl") .scriptName("pangctl")
@@ -13,5 +15,7 @@ yargs(hideBin(process.argv))
.command(resetUserSecurityKeys) .command(resetUserSecurityKeys)
.command(clearExitNodes) .command(clearExitNodes)
.command(rotateServerSecret) .command(rotateServerSecret)
.command(clearLicenseKeys)
.command(deleteClient)
.demandCommand() .demandCommand()
.help().argv; .help().argv;
+24 -21
View File
@@ -1,27 +1,30 @@
# To see all available options, please visit the docs: # To see all available options, please visit the docs:
# https://docs.pangolin.net/self-host/advanced/config-file # https://docs.pangolin.net/
app:
dashboard_url: http://localhost:3002
log_level: debug
domains:
domain1:
base_domain: example.com
server:
secret: my_secret_key
gerbil: gerbil:
base_endpoint: example.com start_port: 51820
base_endpoint: "{{.DashboardDomain}}"
orgs: app:
block_size: 24 dashboard_url: "https://{{.DashboardDomain}}"
subnet_group: 100.90.137.0/20 log_level: "info"
telemetry:
anonymous_usage: true
domains:
domain1:
base_domain: "{{.BaseDomain}}"
server:
secret: "{{.Secret}}"
cors:
origins: ["https://{{.DashboardDomain}}"]
methods: ["GET", "POST", "PUT", "DELETE", "PATCH"]
allowed_headers: ["X-CSRF-Token", "Content-Type"]
credentials: false
flags: flags:
require_email_verification: false require_email_verification: false
disable_signup_without_invite: true disable_signup_without_invite: true
disable_user_create_org: true disable_user_create_org: false
allow_raw_resources: true allow_raw_resources: true
enable_integration_api: true
+19 -3
View File
@@ -1,5 +1,9 @@
http: http:
middlewares: middlewares:
badger:
plugin:
badger:
disableForwardAuth: true
redirect-to-https: redirect-to-https:
redirectScheme: redirectScheme:
scheme: https scheme: https
@@ -13,14 +17,16 @@ http:
- web - web
middlewares: middlewares:
- redirect-to-https - redirect-to-https
- badger
# Next.js router (handles everything except API and WebSocket paths) # Next.js router (handles everything except API and WebSocket paths)
next-router: next-router:
rule: "Host(`{{.DashboardDomain}}`)" rule: "Host(`{{.DashboardDomain}}`) && !PathPrefix(`/api/v1`)"
service: next-service service: next-service
priority: 10
entryPoints: entryPoints:
- websecure - websecure
middlewares:
- badger
tls: tls:
certResolver: letsencrypt certResolver: letsencrypt
@@ -28,9 +34,10 @@ http:
api-router: api-router:
rule: "Host(`{{.DashboardDomain}}`) && PathPrefix(`/api/v1`)" rule: "Host(`{{.DashboardDomain}}`) && PathPrefix(`/api/v1`)"
service: api-service service: api-service
priority: 100
entryPoints: entryPoints:
- websecure - websecure
middlewares:
- badger
tls: tls:
certResolver: letsencrypt certResolver: letsencrypt
@@ -44,3 +51,12 @@ http:
loadBalancer: loadBalancer:
servers: servers:
- url: "http://pangolin:3000" # API/WebSocket server - url: "http://pangolin:3000" # API/WebSocket server
tcp:
serversTransports:
pp-transport-v1:
proxyProtocol:
version: 1
pp-transport-v2:
proxyProtocol:
version: 2
+25 -5
View File
@@ -3,32 +3,52 @@ api:
dashboard: true dashboard: true
providers: providers:
http:
endpoint: "http://pangolin:3001/api/v1/traefik-config"
pollInterval: "5s"
file: file:
directory: "/var/dynamic" filename: "/etc/traefik/dynamic_config.yml"
watch: true
experimental: experimental:
plugins: plugins:
badger: badger:
moduleName: "github.com/fosrl/badger" moduleName: "github.com/fosrl/badger"
version: "v1.3.0" version: "{{.BadgerVersion}}"
log: log:
level: "DEBUG" level: "INFO"
format: "common" format: "common"
maxSize: 100 maxSize: 100
maxBackups: 3 maxBackups: 3
maxAge: 3 maxAge: 3
compress: true compress: true
certificatesResolvers:
letsencrypt:
acme:
httpChallenge:
entryPoint: web
email: "{{.LetsEncryptEmail}}"
storage: "/letsencrypt/acme.json"
caServer: "https://acme-v02.api.letsencrypt.org/directory"
entryPoints: entryPoints:
web: web:
address: ":80" address: ":80"
websecure: websecure:
address: ":9443" address: ":443"
transport: transport:
respondingTimeouts: respondingTimeouts:
readTimeout: "30m" readTimeout: "30m"
http:
tls:
certResolver: "letsencrypt"
encodedCharacters:
allowEncodedSlash: true
allowEncodedQuestionMark: true
serversTransport: serversTransport:
insecureSkipVerify: true insecureSkipVerify: true
ping:
entryPoint: "web"
+2 -2
View File
@@ -7,8 +7,8 @@ services:
POSTGRES_DB: postgres # Default database name POSTGRES_DB: postgres # Default database name
POSTGRES_USER: postgres # Default user POSTGRES_USER: postgres # Default user
POSTGRES_PASSWORD: password # Default password (change for production!) POSTGRES_PASSWORD: password # Default password (change for production!)
volumes: # volumes:
- ./config/postgres:/var/lib/postgresql/data # - ./config/postgres:/var/lib/postgresql/data
ports: ports:
- "5432:5432" # Map host port 5432 to container port 5432 - "5432:5432" # Map host port 5432 to container port 5432
restart: no restart: no
+14
View File
@@ -0,0 +1,14 @@
import { defineConfig } from "drizzle-kit";
import path from "path";
const schema = [path.join("server", "db", "pg", "schema")];
export default defineConfig({
dialect: "postgresql",
schema: schema,
out: path.join("server", "migrations"),
verbose: true,
dbCredentials: {
url: process.env.DATABASE_URL as string
}
});
+7 -1
View File
@@ -6,6 +6,12 @@ import path from "path";
import fs from "fs"; import fs from "fs";
// import { glob } from "glob"; // import { glob } from "glob";
// Read default build type from server/build.ts
let build = "oss";
const buildFile = fs.readFileSync(path.resolve("server/build.ts"), "utf8");
const m = buildFile.match(/export\s+const\s+build\s*=\s*["'](oss|saas|enterprise)["']/);
if (m) build = m[1];
const banner = ` const banner = `
// patch __dirname // patch __dirname
// import { fileURLToPath } from "url"; // import { fileURLToPath } from "url";
@@ -37,7 +43,7 @@ const argv = yargs(hideBin(process.argv))
describe: "Build type (oss, saas, enterprise)", describe: "Build type (oss, saas, enterprise)",
type: "string", type: "string",
choices: ["oss", "saas", "enterprise"], choices: ["oss", "saas", "enterprise"],
default: "oss" default: build
}) })
.help() .help()
.alias("help", "h").argv; .alias("help", "h").argv;
+4 -1
View File
@@ -43,9 +43,12 @@ entryPoints:
http: http:
tls: tls:
certResolver: "letsencrypt" certResolver: "letsencrypt"
encodedCharacters:
allowEncodedSlash: true
allowEncodedQuestionMark: true
serversTransport: serversTransport:
insecureSkipVerify: true insecureSkipVerify: true
ping: ping:
entryPoint: "web" entryPoint: "web"
+41
View File
@@ -210,6 +210,47 @@ func isDockerRunning() bool {
return true return true
} }
func isPodmanRunning() bool {
cmd := exec.Command("podman", "info")
if err := cmd.Run(); err != nil {
return false
}
return true
}
// detectContainerType detects whether the system is currently using Docker or Podman
// by checking which container runtime is running and has containers
func detectContainerType() SupportedContainer {
// Check if we have running containers with podman
if isPodmanRunning() {
cmd := exec.Command("podman", "ps", "-q")
output, err := cmd.Output()
if err == nil && len(strings.TrimSpace(string(output))) > 0 {
return Podman
}
}
// Check if we have running containers with docker
if isDockerRunning() {
cmd := exec.Command("docker", "ps", "-q")
output, err := cmd.Output()
if err == nil && len(strings.TrimSpace(string(output))) > 0 {
return Docker
}
}
// If no containers are running, check which one is installed and running
if isPodmanRunning() && isPodmanInstalled() {
return Podman
}
if isDockerRunning() && isDockerInstalled() {
return Docker
}
return Undefined
}
// executeDockerComposeCommandWithArgs executes the appropriate docker command with arguments supplied // executeDockerComposeCommandWithArgs executes the appropriate docker command with arguments supplied
func executeDockerComposeCommandWithArgs(args ...string) error { func executeDockerComposeCommandWithArgs(args ...string) error {
var cmd *exec.Cmd var cmd *exec.Cmd
+2 -2
View File
@@ -93,7 +93,7 @@ func installCrowdsec(config Config) error {
if checkIfTextInFile("config/traefik/dynamic_config.yml", "PUT_YOUR_BOUNCER_KEY_HERE_OR_IT_WILL_NOT_WORK") { if checkIfTextInFile("config/traefik/dynamic_config.yml", "PUT_YOUR_BOUNCER_KEY_HERE_OR_IT_WILL_NOT_WORK") {
fmt.Println("Failed to replace bouncer key! Please retrieve the key and replace it in the config/traefik/dynamic_config.yml file using the following command:") fmt.Println("Failed to replace bouncer key! Please retrieve the key and replace it in the config/traefik/dynamic_config.yml file using the following command:")
fmt.Println(" docker exec crowdsec cscli bouncers add traefik-bouncer") fmt.Printf(" %s exec crowdsec cscli bouncers add traefik-bouncer\n", config.InstallationContainerType)
} }
return nil return nil
@@ -117,7 +117,7 @@ func GetCrowdSecAPIKey(containerType SupportedContainer) (string, error) {
} }
// Execute the command to get the API key // Execute the command to get the API key
cmd := exec.Command("docker", "exec", "crowdsec", "cscli", "bouncers", "add", "traefik-bouncer", "-o", "raw") cmd := exec.Command(string(containerType), "exec", "crowdsec", "cscli", "bouncers", "add", "traefik-bouncer", "-o", "raw")
var out bytes.Buffer var out bytes.Buffer
cmd.Stdout = &out cmd.Stdout = &out
+2 -2
View File
@@ -3,8 +3,8 @@ module installer
go 1.24.0 go 1.24.0
require ( require (
golang.org/x/term v0.38.0 golang.org/x/term v0.39.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
require golang.org/x/sys v0.39.0 // indirect require golang.org/x/sys v0.40.0 // indirect
+4 -4
View File
@@ -1,7 +1,7 @@
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+21 -16
View File
@@ -6,7 +6,8 @@ import (
"fmt" "fmt"
"io" "io"
"io/fs" "io/fs"
"math/rand" "crypto/rand"
"encoding/base64"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
@@ -229,7 +230,16 @@ func main() {
} }
} }
config.InstallationContainerType = podmanOrDocker(reader) // Try to detect container type from existing installation
detectedType := detectContainerType()
if detectedType == Undefined {
// If detection fails, prompt the user
fmt.Println("Unable to detect container type from existing installation.")
config.InstallationContainerType = podmanOrDocker(reader)
} else {
config.InstallationContainerType = detectedType
fmt.Printf("Detected container type: %s\n", config.InstallationContainerType)
}
config.DoCrowdsecInstall = true config.DoCrowdsecInstall = true
err := installCrowdsec(config) err := installCrowdsec(config)
@@ -286,10 +296,10 @@ func podmanOrDocker(reader *bufio.Reader) SupportedContainer {
os.Exit(1) os.Exit(1)
} }
if err := exec.Command("bash", "-c", "cat /etc/sysctl.conf | grep 'net.ipv4.ip_unprivileged_port_start='").Run(); err != nil { if err := exec.Command("bash", "-c", "cat /etc/sysctl.d/99-podman.conf 2>/dev/null | grep 'net.ipv4.ip_unprivileged_port_start=' || cat /etc/sysctl.conf 2>/dev/null | grep 'net.ipv4.ip_unprivileged_port_start='").Run(); err != nil {
fmt.Println("Would you like to configure ports >= 80 as unprivileged ports? This enables podman containers to listen on low-range ports.") fmt.Println("Would you like to configure ports >= 80 as unprivileged ports? This enables podman containers to listen on low-range ports.")
fmt.Println("Pangolin will experience startup issues if this is not configured, because it needs to listen on port 80/443 by default.") fmt.Println("Pangolin will experience startup issues if this is not configured, because it needs to listen on port 80/443 by default.")
approved := readBool(reader, "The installer is about to execute \"echo 'net.ipv4.ip_unprivileged_port_start=80' >> /etc/sysctl.conf && sysctl -p\". Approve?", true) approved := readBool(reader, "The installer is about to execute \"echo 'net.ipv4.ip_unprivileged_port_start=80' > /etc/sysctl.d/99-podman.conf && sysctl --system\". Approve?", true)
if approved { if approved {
if os.Geteuid() != 0 { if os.Geteuid() != 0 {
fmt.Println("You need to run the installer as root for such a configuration.") fmt.Println("You need to run the installer as root for such a configuration.")
@@ -300,7 +310,7 @@ func podmanOrDocker(reader *bufio.Reader) SupportedContainer {
// container low-range ports as unprivileged ports. // container low-range ports as unprivileged ports.
// Linux only. // Linux only.
if err := run("bash", "-c", "echo 'net.ipv4.ip_unprivileged_port_start=80' >> /etc/sysctl.conf && sysctl -p"); err != nil { if err := run("bash", "-c", "echo 'net.ipv4.ip_unprivileged_port_start=80' > /etc/sysctl.d/99-podman.conf && sysctl --system"); err != nil {
fmt.Printf("Error configuring unprivileged ports: %v\n", err) fmt.Printf("Error configuring unprivileged ports: %v\n", err)
os.Exit(1) os.Exit(1)
} }
@@ -340,7 +350,7 @@ func collectUserInput(reader *bufio.Reader) Config {
// Basic configuration // Basic configuration
fmt.Println("\n=== Basic Configuration ===") fmt.Println("\n=== Basic Configuration ===")
config.IsEnterprise = readBoolNoDefault(reader, "Do you want to install the Enterprise version of Pangolin? The EE is free for persoal use or for businesses making less than 100k USD annually.") config.IsEnterprise = readBoolNoDefault(reader, "Do you want to install the Enterprise version of Pangolin? The EE is free for personal use or for businesses making less than 100k USD annually.")
config.BaseDomain = readString(reader, "Enter your base domain (no subdomain e.g. example.com)", "") config.BaseDomain = readString(reader, "Enter your base domain (no subdomain e.g. example.com)", "")
@@ -583,17 +593,12 @@ func showSetupTokenInstructions(containerType SupportedContainer, dashboardDomai
} }
func generateRandomSecretKey() string { func generateRandomSecretKey() string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" secret := make([]byte, 32)
const length = 32 _, err := rand.Read(secret)
if err != nil {
var seededRand *rand.Rand = rand.New( panic(fmt.Sprintf("Failed to generate random secret key: %v", err))
rand.NewSource(time.Now().UnixNano()))
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
} }
return string(b) return base64.StdEncoding.EncodeToString(secret)
} }
func getPublicIP() string { func getPublicIP() string {
+236 -135
View File
@@ -18,6 +18,8 @@
"componentsMember": "Вие сте част от {count, plural, =0 {нула организации} one {една организация} other {# организации}}.", "componentsMember": "Вие сте част от {count, plural, =0 {нула организации} one {една организация} other {# организации}}.",
"componentsInvalidKey": "Засечен е невалиден или изтекъл лиценз. Проверете лицензионните условия, за да се възползвате от всички функционалности.", "componentsInvalidKey": "Засечен е невалиден или изтекъл лиценз. Проверете лицензионните условия, за да се възползвате от всички функционалности.",
"dismiss": "Отхвърляне", "dismiss": "Отхвърляне",
"subscriptionViolationMessage": "Превишихте ограничението на текущия си план. Коригирайте проблема, като премахнете сайтове, потребители или други ресурси, за да оставате в рамките на плана си.",
"subscriptionViolationViewBilling": "Преглед на фактурирането",
"componentsLicenseViolation": "Нарушение на лиценза: Сървърът използва {usedSites} сайта, което надвишава лицензионния лимит от {maxSites} сайта. Проверете лицензионните условия, за да се възползвате от всички функционалности.", "componentsLicenseViolation": "Нарушение на лиценза: Сървърът използва {usedSites} сайта, което надвишава лицензионния лимит от {maxSites} сайта. Проверете лицензионните условия, за да се възползвате от всички функционалности.",
"componentsSupporterMessage": "Благодарим ви, че подкрепяте Pangolin като {tier}!", "componentsSupporterMessage": "Благодарим ви, че подкрепяте Pangolin като {tier}!",
"inviteErrorNotValid": "Съжаляваме, но изглежда, че поканата, до която се опитвате да получите достъп, не е приета или вече не е валидна.", "inviteErrorNotValid": "Съжаляваме, но изглежда, че поканата, до която се опитвате да получите достъп, не е приета или вече не е валидна.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Свържете се с мрежа.", "sitesBannerTitle": "Свържете се с мрежа.",
"sitesBannerDescription": "Сайтът е връзка с отдалечена мрежа, която позволява на Pangolin да предоставя достъп до ресурси, било то публични или частни, на потребители навсякъде. Инсталирайте мрежовия конектор на сайта (Newt) навсякъде, където можете да стартирате бинарен или контейнер, за да създадете връзката.", "sitesBannerDescription": "Сайтът е връзка с отдалечена мрежа, която позволява на Pangolin да предоставя достъп до ресурси, било то публични или частни, на потребители навсякъде. Инсталирайте мрежовия конектор на сайта (Newt) навсякъде, където можете да стартирате бинарен или контейнер, за да създадете връзката.",
"sitesBannerButtonText": "Инсталиране на сайт.", "sitesBannerButtonText": "Инсталиране на сайт.",
"approvalsBannerTitle": "Одобрете или откажете достъп до устройство",
"approvalsBannerDescription": "Прегледайте и одобрите или откажете искания за достъп до устройства от потребители. Когато се изисква одобрение на устройства, потребителите трябва да получат администраторско одобрение, преди техните устройства да могат да се свържат с ресурсите на вашата организация.",
"approvalsBannerButtonText": "Научете повече",
"siteCreate": "Създайте сайт", "siteCreate": "Създайте сайт",
"siteCreateDescription2": "Следвайте стъпките по-долу, за да създадете и свържете нов сайт", "siteCreateDescription2": "Следвайте стъпките по-долу, за да създадете и свържете нов сайт",
"siteCreateDescription": "Създайте нов сайт, за да започнете да свързвате ресурси", "siteCreateDescription": "Създайте нов сайт, за да започнете да свързвате ресурси",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Търсене на роли...", "accessRolesSearch": "Търсене на роли...",
"accessRolesAdd": "Добавете роля", "accessRolesAdd": "Добавете роля",
"accessRoleDelete": "Изтриване на роля", "accessRoleDelete": "Изтриване на роля",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Управление на одобрения",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Прегледайте и управлявайте чакащи одобрения за достъп до тази организация",
"description": "Описание", "description": "Описание",
"inviteTitle": "Отворени покани", "inviteTitle": "Отворени покани",
"inviteDescription": "Управлявайте покани за други потребители да се присъединят към организацията", "inviteDescription": "Управлявайте покани за други потребители да се присъединят към организацията",
@@ -452,18 +457,18 @@
"selectDuration": "Изберете продължителност", "selectDuration": "Изберете продължителност",
"selectResource": "Изберете Ресурс", "selectResource": "Изберете Ресурс",
"filterByResource": "Филтрирай По Ресурс", "filterByResource": "Филтрирай По Ресурс",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Изберете състояние на одобрение",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Филтрирайте по състояние на одобрение",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Няма одобрения",
"approvalState": "Approval State", "approvalState": "Състояние на одобрение",
"approve": "Approve", "approve": "Одобряване",
"approved": "Approved", "approved": "Одобрен",
"denied": "Denied", "denied": "Отказан",
"deniedApproval": "Denied Approval", "deniedApproval": "Одобрение е отказано",
"all": "All", "all": "Всички",
"deny": "Deny", "deny": "Откажете",
"viewDetails": "View Details", "viewDetails": "Разгледай подробности",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "поискана нова устройство",
"resetFilters": "Нулиране на Филтрите", "resetFilters": "Нулиране на Филтрите",
"totalBlocked": "Заявки Блокирани От Pangolin", "totalBlocked": "Заявки Блокирани От Pangolin",
"totalRequests": "Общо Заявки", "totalRequests": "Общо Заявки",
@@ -743,28 +748,28 @@
"countries": "Държави", "countries": "Държави",
"accessRoleCreate": "Създайте роля", "accessRoleCreate": "Създайте роля",
"accessRoleCreateDescription": "Създайте нова роля за групиране на потребители и управление на техните разрешения.", "accessRoleCreateDescription": "Създайте нова роля за групиране на потребители и управление на техните разрешения.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Редактиране на роля",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Редактирайте информацията за ролята.",
"accessRoleCreateSubmit": "Създайте роля", "accessRoleCreateSubmit": "Създайте роля",
"accessRoleCreated": "Ролята е създадена", "accessRoleCreated": "Ролята е създадена",
"accessRoleCreatedDescription": "Ролята беше успешно създадена.", "accessRoleCreatedDescription": "Ролята беше успешно създадена.",
"accessRoleErrorCreate": "Неуспешно създаване на роля", "accessRoleErrorCreate": "Неуспешно създаване на роля",
"accessRoleErrorCreateDescription": "Възникна грешка при създаването на ролята.", "accessRoleErrorCreateDescription": "Възникна грешка при създаването на ролята.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Обновете роля",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Ролята е актуализирана",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Ролята беше успешно актуализирана.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Одобрението е обработено",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Задайте решение на заявка за одобрение да бъде одобрено.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Задайте решение на заявка за одобрение да бъде отказано.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Неуспешно актуализиране на ролята",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Възникна грешка при актуализиране на ролята.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Неуспешно обработване на одобрение",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Възникна грешка при обработване на одобрението.",
"accessRoleErrorNewRequired": "Нова роля е необходима", "accessRoleErrorNewRequired": "Нова роля е необходима",
"accessRoleErrorRemove": "Неуспешно премахване на роля", "accessRoleErrorRemove": "Неуспешно премахване на роля",
"accessRoleErrorRemoveDescription": "Възникна грешка при премахването на роля.", "accessRoleErrorRemoveDescription": "Възникна грешка при премахването на роля.",
"accessRoleName": "Име на роля", "accessRoleName": "Име на роля",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Ще изтриете ролята `{name}`. Не можете да отмените това действие.",
"accessRoleRemove": "Премахни роля", "accessRoleRemove": "Премахни роля",
"accessRoleRemoveDescription": "Премахни роля от организацията", "accessRoleRemoveDescription": "Премахни роля от организацията",
"accessRoleRemoveSubmit": "Премахни роля", "accessRoleRemoveSubmit": "Премахни роля",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Увеличаване на броя на сайтовете", "sitestCountIncrease": "Увеличаване на броя на сайтовете",
"idpManage": "Управление на доставчици на идентичност", "idpManage": "Управление на доставчици на идентичност",
"idpManageDescription": "Прегледайте и управлявайте доставчици на идентичност в системата", "idpManageDescription": "Прегледайте и управлявайте доставчици на идентичност в системата",
"idpGlobalModeBanner": "Доставчиците на идентичност (IdPs) за всяка организация са деактивирани на този сървър. Използват се глобални IdPs (споделени между всички организации). Управлявайте глобалните IdPs в <adminPanelLink>администраторския панел</adminPanelLink>. За да активирате IdPs за всяка организация, редактирайте конфигурацията на сървъра и задайте режима на IdP към org. <configDocsLink>Вижте документацията</configDocsLink>. Ако желаете да продължите да използвате глобалните IdPs и да премахнете това от настройките на организацията, изрично задайте режима на global в конфигурацията.",
"idpGlobalModeBannerUpgradeRequired": "Доставчиците на идентичност (IdPs) за всяка организация са деактивирани на този сървър. Използват се глобални IdPs (споделени между всички организации). Управлявайте глобалните IdPs в <adminPanelLink>администраторския панел</adminPanelLink>. За да използвате доставчици на идентичност за всяка организация, трябва да надстроите до изданието Enterprise.",
"idpGlobalModeBannerLicenseRequired": "Доставчиците на идентичност (IdPs) за всяка организация са деактивирани на този сървър. Използват се глобални IdPs (споделени между всички организации). Управлявайте глобалните IdPs в <adminPanelLink>администраторския панел</adminPanelLink>. За да използвате доставчици на идентичност за всяка организация, е необходим лиценз за изданието Enterprise.",
"idpDeletedDescription": "Доставчик на идентичност успешно изтрит", "idpDeletedDescription": "Доставчик на идентичност успешно изтрит",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Сигурни ли сте, че искате да изтриете доставчика за идентичност?", "idpQuestionRemove": "Сигурни ли сте, че искате да изтриете доставчика за идентичност?",
@@ -900,7 +908,7 @@
"inviteAlready": "Изглежда, че сте били поканени!", "inviteAlready": "Изглежда, че сте били поканени!",
"inviteAlreadyDescription": "За да приемете поканата, трябва да влезете или да създадете акаунт.", "inviteAlreadyDescription": "За да приемете поканата, трябва да влезете или да създадете акаунт.",
"signupQuestion": "Вече имате акаунт?", "signupQuestion": "Вече имате акаунт?",
"login": "Log In", "login": "Вход",
"resourceNotFound": "Ресурсът не е намерен", "resourceNotFound": "Ресурсът не е намерен",
"resourceNotFoundDescription": "Ресурсът, който се опитвате да достъпите, не съществува.", "resourceNotFoundDescription": "Ресурсът, който се опитвате да достъпите, не съществува.",
"pincodeRequirementsLength": "ПИН трябва да бъде точно 6 цифри", "pincodeRequirementsLength": "ПИН трябва да бъде точно 6 цифри",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Тази организация изисква да сменяте паролата си на всеки {maxDays} дни.", "passwordExpiryDescription": "Тази организация изисква да сменяте паролата си на всеки {maxDays} дни.",
"changePasswordNow": "Сменете паролата сега", "changePasswordNow": "Сменете паролата сега",
"pincodeAuth": "Код на удостоверителя", "pincodeAuth": "Код на удостоверителя",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Изпратете кода",
"passwordResetSubmit": "Заявка за нулиране", "passwordResetSubmit": "Заявка за нулиране",
"passwordResetAlreadyHaveCode": "Въведете код.", "passwordResetAlreadyHaveCode": "Въведете код.",
"passwordResetSmtpRequired": "Моля, свържете се с вашия администратор", "passwordResetSmtpRequired": "Моля, свържете се с вашия администратор",
"passwordResetSmtpRequiredDescription": "Кодът за нулиране на парола е задължителен за нулиране на паролата ви. Моля, свържете се с вашия администратор за помощ.", "passwordResetSmtpRequiredDescription": "Кодът за нулиране на парола е задължителен за нулиране на паролата ви. Моля, свържете се с вашия администратор за помощ.",
"passwordBack": "Назад към Парола", "passwordBack": "Назад към Парола",
"loginBack": "Go back to main login page", "loginBack": "Върнете се на главната страница за вход",
"signup": "Регистрация", "signup": "Регистрация",
"loginStart": "Влезте, за да започнете", "loginStart": "Влезте, за да започнете",
"idpOidcTokenValidating": "Валидиране на OIDC токен", "idpOidcTokenValidating": "Валидиране на OIDC токен",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Актуализиране на IdP организация", "actionUpdateIdpOrg": "Актуализиране на IdP организация",
"actionCreateClient": "Създаване на клиент", "actionCreateClient": "Създаване на клиент",
"actionDeleteClient": "Изтриване на клиент", "actionDeleteClient": "Изтриване на клиент",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Архивиране на клиента",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Разархивиране на клиента",
"actionBlockClient": "Block Client", "actionBlockClient": "Блокиране на клиента",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Деблокиране на клиента",
"actionUpdateClient": "Актуализиране на клиент", "actionUpdateClient": "Актуализиране на клиент",
"actionListClients": "Списък с клиенти", "actionListClients": "Списък с клиенти",
"actionGetClient": "Получаване на клиент", "actionGetClient": "Получаване на клиент",
@@ -1164,14 +1172,14 @@
"searchProgress": "Търсене...", "searchProgress": "Търсене...",
"create": "Създаване", "create": "Създаване",
"orgs": "Организации", "orgs": "Организации",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Възникна неочаквана грешка. Моля, опитайте отново.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Необходим е вход за вашето устройство.",
"passwordForgot": "Забравена парола?", "passwordForgot": "Забравена парола?",
"otpAuth": "Двуфакторно удостоверяване", "otpAuth": "Двуфакторно удостоверяване",
"otpAuthDescription": "Въведете кода от приложението за удостоверяване или един от вашите резервни кодове за еднократна употреба.", "otpAuthDescription": "Въведете кода от приложението за удостоверяване или един от вашите резервни кодове за еднократна употреба.",
"otpAuthSubmit": "Изпрати код", "otpAuthSubmit": "Изпрати код",
"idpContinue": "Или продължете със", "idpContinue": "Или продължете със",
"otpAuthBack": "Back to Password", "otpAuthBack": "Назад към парола",
"navbar": "Навигационно меню", "navbar": "Навигационно меню",
"navbarDescription": "Главно навигационно меню за приложението", "navbarDescription": "Главно навигационно меню за приложението",
"navbarDocsLink": "Документация", "navbarDocsLink": "Документация",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Общ преглед", "sidebarOverview": "Общ преглед",
"sidebarHome": "Начало", "sidebarHome": "Начало",
"sidebarSites": "Сайтове", "sidebarSites": "Сайтове",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Заявки за одобрение",
"sidebarResources": "Ресурси", "sidebarResources": "Ресурси",
"sidebarProxyResources": "Публично", "sidebarProxyResources": "Публично",
"sidebarClientResources": "Частно", "sidebarClientResources": "Частно",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Идентификационни доставчици", "sidebarIdentityProviders": "Идентификационни доставчици",
"sidebarLicense": "Лиценз", "sidebarLicense": "Лиценз",
"sidebarClients": "Клиенти", "sidebarClients": "Клиенти",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Устройства на потребителя",
"sidebarMachineClients": "Машини", "sidebarMachineClients": "Машини",
"sidebarDomains": "Домейни", "sidebarDomains": "Домейни",
"sidebarGeneral": "Управление.", "sidebarGeneral": "Управление.",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Възникна грешка при създаване на админ акаунт.", "setupErrorCreateAdmin": "Възникна грешка при създаване на админ акаунт.",
"certificateStatus": "Статус на сертификата", "certificateStatus": "Статус на сертификата",
"loading": "Зареждане", "loading": "Зареждане",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Зареждане на анализи",
"restart": "Рестарт", "restart": "Рестарт",
"domains": "Домейни", "domains": "Домейни",
"domainsDescription": "Създайте и управлявайте наличните домейни в организацията", "domainsDescription": "Създайте и управлявайте наличните домейни в организацията",
@@ -1336,7 +1344,7 @@
"refreshError": "Неуспешно обновяване на данни", "refreshError": "Неуспешно обновяване на данни",
"verified": "Потвърдено", "verified": "Потвърдено",
"pending": "Чакащо", "pending": "Чакащо",
"pendingApproval": "Pending Approval", "pendingApproval": "Очаква одобрение",
"sidebarBilling": "Фактуриране", "sidebarBilling": "Фактуриране",
"billing": "Фактуриране", "billing": "Фактуриране",
"orgBillingDescription": "Управлявайте информацията за плащане и абонаментите", "orgBillingDescription": "Управлявайте информацията за плащане и абонаментите",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Преглед на лимитите за използване", "billingUsageLimitsOverview": "Преглед на лимитите за използване",
"billingMonitorUsage": "Следете своята употреба спрямо конфигурираните лимити. Ако имате нужда от увеличаване на лимитите, моля свържете се с нас support@pangolin.net.", "billingMonitorUsage": "Следете своята употреба спрямо конфигурираните лимити. Ако имате нужда от увеличаване на лимитите, моля свържете се с нас support@pangolin.net.",
"billingDataUsage": "Използване на данни", "billingDataUsage": "Използване на данни",
"billingOnlineTime": "Време на работа на сайта", "billingSites": "Сайтове",
"billingUsers": "Активни потребители", "billingUsers": "Потребители",
"billingDomains": "Активни домейни", "billingDomains": "Домейни",
"billingRemoteExitNodes": "Активни самостоятелно хоствани възли", "billingRemoteExitNodes": "Дистанционни възли",
"billingNoLimitConfigured": "Няма конфигуриран лимит", "billingNoLimitConfigured": "Няма конфигуриран лимит",
"billingEstimatedPeriod": "Очакван период на фактуриране", "billingEstimatedPeriod": "Очакван период на фактуриране",
"billingIncludedUsage": "Включено използване", "billingIncludedUsage": "Включено използване",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Неуспех при получаване на URL на портала", "billingFailedToGetPortalUrl": "Неуспех при получаване на URL на портала",
"billingPortalError": "Грешка в портала", "billingPortalError": "Грешка в портала",
"billingDataUsageInfo": "Таксува се за всички данни, прехвърляни през вашите защитени тунели, когато сте свързани към облака. Това включва както входящия, така и изходящия трафик за всички ваши сайтове. Когато достигнете лимита си, вашите сайтове ще бъдат прекъснати, докато не надстроите плана или не намалите използването. Данните не се таксуват при използване на възли.", "billingDataUsageInfo": "Таксува се за всички данни, прехвърляни през вашите защитени тунели, когато сте свързани към облака. Това включва както входящия, така и изходящия трафик за всички ваши сайтове. Когато достигнете лимита си, вашите сайтове ще бъдат прекъснати, докато не надстроите плана или не намалите използването. Данните не се таксуват при използване на възли.",
"billingOnlineTimeInfo": "Таксува се на база колко време вашите сайтове остават свързани с облака. Пример: 44,640 минути се равняват на един сайт работещ 24/7 за цял месец. Когато достигнете лимита си, вашите сайтове ще бъдат прекъснати, докато не надстроите плана или не намалите използването. Времето не се таксува при използване на възли.", "billingSInfo": "Колко сайта можете да използвате",
"billingUsersInfo": "Таксува се всеки потребител в организацията. Таксуването се изчислява ежедневно въз основа на броя на активните потребителски акаунти във вашата организация.", "billingUsersInfo": "Колко потребители можете да използвате",
"billingDomainInfo": "Таксува се всеки домейн в организацията. Таксуването се изчислява ежедневно въз основа на броя на активните домейн акаунти във вашата организация.", "billingDomainInfo": "Колко домейни можете да използвате",
"billingRemoteExitNodesInfo": "Таксува се всеки управляван възел в организацията. Таксуването се изчислява ежедневно въз основа на броя на активните управлявани възли във вашата организация.", "billingRemoteExitNodesInfo": "Колко дистанционни възли можете да използвате",
"billingLicenseKeys": "Лицензионни ключове",
"billingLicenseKeysDescription": "Управлявайте вашите абонаменти за лицензионни ключове",
"billingLicenseSubscription": "Абонамент за лиценз",
"billingInactive": "Неактивен",
"billingLicenseItem": "Лицензионен елемент",
"billingQuantity": "Количество",
"billingTotal": "общо",
"billingModifyLicenses": "Промяна на абонамента за лиценз",
"domainNotFound": "Домейнът не е намерен", "domainNotFound": "Домейнът не е намерен",
"domainNotFoundDescription": "Този ресурс е деактивиран, защото домейнът вече не съществува в нашата система. Моля, задайте нов домейн за този ресурс.", "domainNotFoundDescription": "Този ресурс е деактивиран, защото домейнът вече не съществува в нашата система. Моля, задайте нов домейн за този ресурс.",
"failed": "Неуспешно", "failed": "Неуспешно",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Ключът за защита е премахнат успешно", "securityKeyRemoveSuccess": "Ключът за защита е премахнат успешно",
"securityKeyRemoveError": "Неуспешно премахване на ключ за защита", "securityKeyRemoveError": "Неуспешно премахване на ключ за защита",
"securityKeyLoadError": "Неуспешно зареждане на ключове за защита", "securityKeyLoadError": "Неуспешно зареждане на ключове за защита",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Използвайте ключ за защита",
"securityKeyAuthError": "Неуспешно удостоверяване с ключ за сигурност", "securityKeyAuthError": "Неуспешно удостоверяване с ключ за сигурност",
"securityKeyRecommendation": "Регистрирайте резервен ключ за безопасност на друго устройство, за да сте сигурни, че винаги ще имате достъп до профила си", "securityKeyRecommendation": "Регистрирайте резервен ключ за безопасност на друго устройство, за да сте сигурни, че винаги ще имате достъп до профила си",
"registering": "Регистрация...", "registering": "Регистрация...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Номерът на порта е задължителен за не-HTTP ресурси", "resourcePortRequired": "Номерът на порта е задължителен за не-HTTP ресурси",
"resourcePortNotAllowed": "Номерът на порта не трябва да бъде задаван за HTTP ресурси", "resourcePortNotAllowed": "Номерът на порта не трябва да бъде задаван за HTTP ресурси",
"billingPricingCalculatorLink": "Калкулатор на цените", "billingPricingCalculatorLink": "Калкулатор на цените",
"billingYourPlan": "Вашият план",
"billingViewOrModifyPlan": "Преглед или промяна на текущия ви план",
"billingViewPlanDetails": "Преглед на подробности за плана",
"billingUsageAndLimits": "Използване и граници",
"billingViewUsageAndLimits": "Преглед на ограниченията на плана и текущото използване",
"billingCurrentUsage": "Текущо използване",
"billingMaximumLimits": "Максимални граници",
"billingRemoteNodes": "Дистанционни възли",
"billingUnlimited": "Неограничено",
"billingPaidLicenseKeys": "Платени лицензионни ключове",
"billingManageLicenseSubscription": "Управлявайте абонамента си за платени самостоятелно хоствани лицензионни ключове",
"billingCurrentKeys": "Текущи ключове",
"billingModifyCurrentPlan": "Промяна на текущия план",
"billingConfirmUpgrade": "Потвърдете повишаването",
"billingConfirmDowngrade": "Потвърдете понижението",
"billingConfirmUpgradeDescription": "Предстои ви да повишите плана си. Прегледайте новите ограничения и цени по-долу.",
"billingConfirmDowngradeDescription": "Предстои ви да понижите плана си. Прегледайте новите ограничения и цени по-долу.",
"billingPlanIncludes": "Планът включва",
"billingProcessing": "Процесиране...",
"billingConfirmUpgradeButton": "Потвърдете повишаването",
"billingConfirmDowngradeButton": "Потвърдете понижението",
"billingLimitViolationWarning": "Използването надвишава новите планови ограничения",
"billingLimitViolationDescription": "Текущото ви използване надвишава ограниченията на този план. След понижаване, всички действия ще бъдат деактивирани, докато не намалите използването в рамките на новите ограничения. Моля, прегледайте по-долу функциите, които в момента са извън ограниченията. Ограничения в нарушение:",
"billingFeatureLossWarning": "Уведомление за наличност на функциите",
"billingFeatureLossDescription": "Чрез понижението на плана, функциите, недостъпни в новия план, ще бъдат автоматично деактивирани. Някои настройки и конфигурации може да бъдат загубени. Моля, прегледайте ценовата матрица, за да разберете кои функции вече няма да са на разположение.",
"billingUsageExceedsLimit": "Текущото използване ({current}) надвишава ограничението ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Съгласен съм с", "IAgreeToThe": "Съгласен съм с",
"termsOfService": "условията за ползване", "termsOfService": "условията за ползване",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Интервал за здраве", "IntervalSeconds": "Интервал за здраве",
"timeoutSeconds": "Време за изчакване (сек)", "timeoutSeconds": "Време за изчакване (сек)",
"timeIsInSeconds": "Времето е в секунди", "timeIsInSeconds": "Времето е в секунди",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Изискват одобрение на устройства",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Потребители с тази роля трябва да имат нови устройства одобрени от администратор преди да могат да се свържат и да имат достъп до ресурси.",
"retryAttempts": "Опити за повторно", "retryAttempts": "Опити за повторно",
"expectedResponseCodes": "Очаквани кодове за отговор", "expectedResponseCodes": "Очаквани кодове за отговор",
"expectedResponseCodesDescription": "HTTP статус код, указващ здравословно състояние. Ако бъде оставено празно, между 200-300 се счита за здравословно.", "expectedResponseCodesDescription": "HTTP статус код, указващ здравословно състояние. Ако бъде оставено празно, между 200-300 се счита за здравословно.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Не са намерени вътрешни ресурси.", "resourcesTableNoInternalResourcesFound": "Не са намерени вътрешни ресурси.",
"resourcesTableDestination": "Дестинация", "resourcesTableDestination": "Дестинация",
"resourcesTableAlias": "Псевдоним", "resourcesTableAlias": "Псевдоним",
"resourcesTableAliasAddress": "Адрес на псевдоним.",
"resourcesTableAliasAddressInfo": "Този адрес е част от подсистемата на организацията. Използва се за разрешаване на псевдонимни записи чрез вътрешно DNS разрешаване.",
"resourcesTableClients": "Клиенти", "resourcesTableClients": "Клиенти",
"resourcesTableAndOnlyAccessibleInternally": "и са достъпни само вътрешно при свързване с клиент.", "resourcesTableAndOnlyAccessibleInternally": "и са достъпни само вътрешно при свързване с клиент.",
"resourcesTableNoTargets": "Без цели", "resourcesTableNoTargets": "Без цели",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Изберете своя доставчик на идентичност, за да продължите", "orgAuthChooseIdpDescription": "Изберете своя доставчик на идентичност, за да продължите",
"orgAuthNoIdpConfigured": "Тази организация няма конфигурирани доставчици на идентичност. Можете да влезете с вашата Pangolin идентичност.", "orgAuthNoIdpConfigured": "Тази организация няма конфигурирани доставчици на идентичност. Можете да влезете с вашата Pangolin идентичност.",
"orgAuthSignInWithPangolin": "Впишете се с Pangolin", "orgAuthSignInWithPangolin": "Впишете се с Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Влезте в организация",
"orgAuthSelectOrgTitle": "Вход в организация.", "orgAuthSelectOrgTitle": "Вход в организация.",
"orgAuthSelectOrgDescription": "Въведете идентификатора на вашата организация, за да продължите.", "orgAuthSelectOrgDescription": "Въведете идентификатора на вашата организация, за да продължите.",
"orgAuthOrgIdPlaceholder": "вашата-организация", "orgAuthOrgIdPlaceholder": "вашата-организация",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Назад към стандартния вход.", "orgAuthBackToSignIn": "Назад към стандартния вход.",
"orgAuthNoAccount": "Нямате профил?", "orgAuthNoAccount": "Нямате профил?",
"subscriptionRequiredToUse": "Необходим е абонамент, за да използвате тази функция.", "subscriptionRequiredToUse": "Необходим е абонамент, за да използвате тази функция.",
"mustUpgradeToUse": "Трябва да повишите своя абонамент, за да използвате тази функция.",
"subscriptionRequiredTierToUse": "Тази функция изисква <tierLink>{tier}</tierLink> или по-висок план.",
"upgradeToTierToUse": "Повишете до <tierLink>{tier}</tierLink> или по-висок план, за да използвате тази функция.",
"subscriptionTierTier1": "Домашен",
"subscriptionTierTier2": "Екип",
"subscriptionTierTier3": "Бизнес",
"subscriptionTierEnterprise": "Предприятие",
"idpDisabled": "Доставчиците на идентичност са деактивирани.", "idpDisabled": "Доставчиците на идентичност са деактивирани.",
"orgAuthPageDisabled": "Страницата за удостоверяване на организацията е деактивирана.", "orgAuthPageDisabled": "Страницата за удостоверяване на организацията е деактивирана.",
"domainRestartedDescription": "Проверка на домейна е рестартирана успешно", "domainRestartedDescription": "Проверка на домейна е рестартирана успешно",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Получаване на лиценз",
"description": "Изберете план и ни кажете как планирате да използвате Pangolin.",
"chooseTier": "Изберете вашия план",
"viewPricingLink": "Вижте цените, функциите и ограниченията",
"tiers": {
"starter": {
"title": "Стартов",
"description": "Предприятие, 25 потребители, 25 сайта и общностна поддръжка."
},
"scale": {
"title": "Скала",
"description": "Предприятие, 50 потребители, 50 сайта и приоритетна поддръжка."
}
},
"personalUseOnly": "Само за лична употреба (безплатен лиценз — без плащане)",
"buttons": {
"continueToCheckout": "Продължете към плащане"
},
"toasts": {
"checkoutError": {
"title": "Грешка при плащането",
"description": "Не можа да се започне плащането. Моля, опитайте отново."
}
}
},
"priority": "Приоритет", "priority": "Приоритет",
"priorityDescription": "По-високите приоритетни маршрути се оценяват първи. Приоритет = 100 означава автоматично подреждане (системата решава). Използвайте друго число, за да наложите ръчен приоритет.", "priorityDescription": "По-високите приоритетни маршрути се оценяват първи. Приоритет = 100 означава автоматично подреждане (системата решава). Използвайте друго число, за да наложите ръчен приоритет.",
"instanceName": "Име на инстанция", "instanceName": "Име на инстанция",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Край на следващата година", "logRetentionEndOfFollowingYear": "Край на следващата година",
"actionLogsDescription": "Прегледайте историята на действията, извършени в тази организация", "actionLogsDescription": "Прегледайте историята на действията, извършени в тази организация",
"accessLogsDescription": "Прегледайте заявките за удостоверяване на достъпа до ресурсите в тази организация", "accessLogsDescription": "Прегледайте заявките за удостоверяване на достъпа до ресурсите в тази организация",
"licenseRequiredToUse": "Необходим е лиценз Enterprise, за да се използва тази функция.", "licenseRequiredToUse": "Изисква се лиценз за <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink>, за да използвате тази функция. Тази функция е също достъпна в <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "Необходимо е <enterpriseEditionLink>изданието Enterprise</enterpriseEditionLink>, за да използвате тази функция. Тази функция е също достъпна в <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Решавач на сертификати", "certResolver": "Решавач на сертификати",
"certResolverDescription": "Изберете решавач на сертификати за използване за този ресурс.", "certResolverDescription": "Изберете решавач на сертификати за използване за този ресурс.",
"selectCertResolver": "Изберете решавач на сертификати", "selectCertResolver": "Изберете решавач на сертификати",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Кодът трябва да бъде 9 символа (напр. A1AJ-N5JD)", "deviceCodeInvalidFormat": "Кодът трябва да бъде 9 символа (напр. A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Невалиден или изтекъл код", "deviceCodeInvalidOrExpired": "Невалиден или изтекъл код",
"deviceCodeVerifyFailed": "Неуспешна проверка на кода на устройството", "deviceCodeVerifyFailed": "Неуспешна проверка на кода на устройството",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Валидиране на кода на устройството...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Проверка на оторизацията на устройството...",
"signedInAs": "Вписан като", "signedInAs": "Вписан като",
"deviceCodeEnterPrompt": "Въведете кода, показан на устройството", "deviceCodeEnterPrompt": "Въведете кода, показан на устройството",
"continue": "Продължете", "continue": "Продължете",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Достъп до всички организации, до които има достъп акаунтът ви", "deviceOrganizationsAccess": "Достъп до всички организации, до които има достъп акаунтът ви",
"deviceAuthorize": "Разрешете {applicationName}", "deviceAuthorize": "Разрешете {applicationName}",
"deviceConnected": "Устройството е свързано!", "deviceConnected": "Устройството е свързано!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Устройството е оторизирано да има достъп до акаунта ви. Моля, върнете се към клиентското приложение.",
"pangolinCloud": "Pangolin Cloud", "pangolinCloud": "Pangolin Cloud",
"viewDevices": "Преглед на устройствата", "viewDevices": "Преглед на устройствата",
"viewDevicesDescription": "Управлявайте свързаните си устройства", "viewDevicesDescription": "Управлявайте свързаните си устройства",
@@ -2343,7 +2421,7 @@
"identifier": "Идентификатор", "identifier": "Идентификатор",
"deviceLoginUseDifferentAccount": "Не сте вие? Използвайте друг акаунт.", "deviceLoginUseDifferentAccount": "Не сте вие? Използвайте друг акаунт.",
"deviceLoginDeviceRequestingAccessToAccount": "Устройство запитващо достъп до този акаунт.", "deviceLoginDeviceRequestingAccessToAccount": "Устройство запитващо достъп до този акаунт.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Изберете метод на удостоверяване, за да продължите.",
"noData": "Няма Данни", "noData": "Няма Данни",
"machineClients": "Машинни клиенти", "machineClients": "Машинни клиенти",
"install": "Инсталирай", "install": "Инсталирай",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "В момента срещаме технически затруднения. Моля, проверете отново скоро.", "maintenanceScreenMessage": "В момента срещаме технически затруднения. Моля, проверете отново скоро.",
"maintenanceScreenEstimatedCompletion": "Прогнозно завършване:", "maintenanceScreenEstimatedCompletion": "Прогнозно завършване:",
"createInternalResourceDialogDestinationRequired": "Дестинацията е задължителна.", "createInternalResourceDialogDestinationRequired": "Дестинацията е задължителна.",
"available": "Available", "available": "Налично",
"archived": "Archived", "archived": "Архивирано",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Не са намерени архивирани устройства.",
"deviceArchived": "Device archived", "deviceArchived": "Устройството е архивирано.",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Устройството беше успешно архивирано.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Грешка при архивиране на устройството.",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Неуспех при архивиране на устройството.",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Сигурни ли сте, че искате да архивирате това устройство?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Устройството ще бъде архивирано и премахнато от вашия списък с активни устройства.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Архивиране на устройството",
"archiveDevice": "Archive Device", "archiveDevice": "Архивиране на устройство",
"archive": "Archive", "archive": "Архив",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Устройството е разархивирано.",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Устройството беше успешно разархивирано.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Грешка при разархивиране на устройството.",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Неуспешно разархивиране на устройството.",
"unarchive": "Unarchive", "unarchive": "Разархивиране",
"archiveClient": "Archive Client", "archiveClient": "Архивиране на клиента",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Сигурни ли сте, че искате да архивирате този клиент?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Клиентът ще бъде архивиран и премахнат от вашия списък с активни клиенти.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Архивиране на клиента",
"blockClient": "Block Client", "blockClient": "Блокиране на клиента",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Сигурни ли сте, че искате да блокирате този клиент?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Устройството ще бъде принудено да прекъсне, ако е в момента свързано. Можете да го отблокирате по-късно.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Блокиране на клиента",
"active": "Active", "active": "Активно",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Потребителско име или имейл",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Изберете вашата организация",
"signInTo": "Log in in to", "signInTo": "Влезте в",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Продължете с парола",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Няма налични методи за удостоверяване за тази организация.",
"enterPassword": "Enter your password", "enterPassword": "Въведете вашата парола",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Въведете кода от вашето приложение за удостоверяване",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Моля, използвайте ключа за сигурност, за да влезете.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Трябва ли да използвате различен акаунт?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "С натискането на бутоните по-долу, потвърждавате, че сте прочели, разбирате и се съгласявате с <termsOfService>Условията за ползване</termsOfService> и <privacyPolicy>Политиката за поверителност</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Условия за ползване",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Политика за поверителност",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Не е намерен потребител с това потребителско име.",
"verify": "Verify", "verify": "Потвърждение",
"signIn": "Sign In", "signIn": "Вход",
"forgotPassword": "Forgot password?", "forgotPassword": "Забравена парола?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Ако сте влизали преди, можете да въведете вашето потребителско име или имейл по-горе, за да се удостовери с идентификатора на вашата организация. Лесно е!",
"continueAnyway": "Continue anyway", "continueAnyway": "Продължете въпреки това",
"dontShowAgain": "Don't show again", "dontShowAgain": "Не показвайте повече",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Знаете ли?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Опитвате се да влезете?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Опитвате ли се да влезете чрез идентификационния доставчик на вашата организация?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Влезте или се регистрирайте с вашата организация вместо това.",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Използвайте различен акаунт",
"logIn": "Log In", "logIn": "Вход",
"deviceInformation": "Device Information", "deviceInformation": "Информация за устройството",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Информация за устройството и агента",
"platform": "Platform", "deviceSecurity": "Защита на устройството.",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Информация за състоянието на защитата на устройството.",
"windowsVersion": "Windows Version", "platform": "Платформа",
"iosVersion": "iOS Version", "macosVersion": "Версия на macOS",
"androidVersion": "Android Version", "windowsVersion": "Версия на Windows",
"osVersion": "OS Version", "iosVersion": "Версия на iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Версия на Android",
"deviceModel": "Device Model", "osVersion": "Версия на ОС",
"serialNumber": "Serial Number", "kernelVersion": "Версия на ядрото",
"hostname": "Hostname", "deviceModel": "Модел на устройството",
"firstSeen": "First Seen", "serialNumber": "Сериен номер",
"lastSeen": "Last Seen", "hostname": "Име на хост",
"deviceSettingsDescription": "View device information and settings", "firstSeen": "Видян за първи път",
"devicePendingApprovalDescription": "This device is waiting for approval", "lastSeen": "Последно видян",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "biometricsEnabled": "Активирани биометрични данни.",
"unblockClient": "Unblock Client", "diskEncrypted": "Криптиран диск.",
"unblockClientDescription": "The device has been unblocked", "firewallEnabled": "Активирана защитна стена.",
"unarchiveClient": "Unarchive Client", "autoUpdatesEnabled": "Активирани автоматични актуализации.",
"unarchiveClientDescription": "The device has been unarchived", "tpmAvailable": "TPM е на разположение.",
"block": "Block", "windowsAntivirusEnabled": "Активирана антивирусна програма",
"unblock": "Unblock", "macosSipEnabled": "Protection на системната цялост (SIP).",
"deviceActions": "Device Actions", "macosGatekeeperEnabled": "Gatekeeper.",
"deviceActionsDescription": "Manage device status and access", "macosFirewallStealthMode": "Скрит режим на защитната стена.",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "linuxAppArmorEnabled": "AppArmor.",
"linuxSELinuxEnabled": "SELinux.",
"deviceSettingsDescription": "Разгледайте информация и настройки на устройството",
"devicePendingApprovalDescription": "Това устройство чака одобрение",
"deviceBlockedDescription": "Това устройство е в момента блокирано. Няма да може да се свърже с никакви ресурси, освен ако не бъде деблокирано.",
"unblockClient": "Деблокирайте клиента",
"unblockClientDescription": "Устройството е деблокирано",
"unarchiveClient": "Разархивиране на клиента",
"unarchiveClientDescription": "Устройството е разархивирано",
"block": "Блокирането",
"unblock": "Деблокиране",
"deviceActions": "Действия с устройствата",
"deviceActionsDescription": "Управлявайте състоянието и достъпа на устройството",
"devicePendingApprovalBannerDescription": "Това устройство чака одобрение. Няма да може да се свърже с ресурси, докато не бъде одобрено.",
"connected": "Свързан",
"disconnected": "Прекъснат",
"approvalsEmptyStateTitle": "Одобрения на устройство не са активирани",
"approvalsEmptyStateDescription": "Активирайте одобрения на устройства за роли, така че да изискват администраторско одобрение, преди потребителите да могат да свързват нови устройства.",
"approvalsEmptyStateStep1Title": "Отидете на роли",
"approvalsEmptyStateStep1Description": "Навигирайте до настройките на ролите на вашата организация, за да конфигурирате одобренията на устройства.",
"approvalsEmptyStateStep2Title": "Активирайте одобрения на устройства",
"approvalsEmptyStateStep2Description": "Редактирайте ролята и активирайте опцията 'Изискване на одобрения за устройства'. Потребители с тази роля ще трябва администраторско одобрение за нови устройства.",
"approvalsEmptyStatePreviewDescription": "Преглед: Когато е активирано, чакащите заявки за устройства ще се появят тук за преглед",
"approvalsEmptyStateButtonText": "Управлявайте роли"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "Jste členem {count, plural, =0 {0 organizací} one {1 organizace} other {# organizací}}.", "componentsMember": "Jste členem {count, plural, =0 {0 organizací} one {1 organizace} other {# organizací}}.",
"componentsInvalidKey": "Byly nalezeny neplatné nebo propadlé licenční klíče. Pokud chcete nadále používat všechny funkce, postupujte podle licenčních podmínek.", "componentsInvalidKey": "Byly nalezeny neplatné nebo propadlé licenční klíče. Pokud chcete nadále používat všechny funkce, postupujte podle licenčních podmínek.",
"dismiss": "Zavřít", "dismiss": "Zavřít",
"subscriptionViolationMessage": "Jste za hranicemi vašeho aktuálního plánu. Opravte problém odstraněním webů, uživatelů nebo jiných zdrojů, abyste zůstali ve vašem tarifu.",
"subscriptionViolationViewBilling": "Zobrazit fakturaci",
"componentsLicenseViolation": "Porušení licenčních podmínek: Tento server používá {usedSites} stránek, což překračuje limit {maxSites} licencovaných stránek. Pokud chcete nadále používat všechny funkce, postupujte podle licenčních podmínek.", "componentsLicenseViolation": "Porušení licenčních podmínek: Tento server používá {usedSites} stránek, což překračuje limit {maxSites} licencovaných stránek. Pokud chcete nadále používat všechny funkce, postupujte podle licenčních podmínek.",
"componentsSupporterMessage": "Děkujeme, že podporujete Pangolin jako {tier}!", "componentsSupporterMessage": "Děkujeme, že podporujete Pangolin jako {tier}!",
"inviteErrorNotValid": "Je nám líto, ale vypadá to, že pozvánka, ke které se snažíte získat přístup, nebyla přijata nebo již není platná.", "inviteErrorNotValid": "Je nám líto, ale vypadá to, že pozvánka, ke které se snažíte získat přístup, nebyla přijata nebo již není platná.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Připojit jakoukoli síť", "sitesBannerTitle": "Připojit jakoukoli síť",
"sitesBannerDescription": "Lokalita je připojení k vzdálené síti, která umožňuje Pangolinu poskytovat přístup k prostředkům, ať už veřejným nebo soukromým, uživatelům kdekoli. Nainstalujte síťový konektor (Newt) kamkoli, kam můžete spustit binární soubor nebo kontejner, aby bylo možné připojení navázat.", "sitesBannerDescription": "Lokalita je připojení k vzdálené síti, která umožňuje Pangolinu poskytovat přístup k prostředkům, ať už veřejným nebo soukromým, uživatelům kdekoli. Nainstalujte síťový konektor (Newt) kamkoli, kam můžete spustit binární soubor nebo kontejner, aby bylo možné připojení navázat.",
"sitesBannerButtonText": "Nainstalovat lokalitu", "sitesBannerButtonText": "Nainstalovat lokalitu",
"approvalsBannerTitle": "Schválit nebo zakázat přístup k zařízení",
"approvalsBannerDescription": "Zkontrolovat a schválit nebo zakázat žádosti uživatelů o přístup k zařízení. Pokud jsou vyžadována schválení zařízení, musí být uživatelé oprávněni před tím, než se jejich zařízení mohou připojit k zdrojům vaší organizace.",
"approvalsBannerButtonText": "Zjistit více",
"siteCreate": "Vytvořit lokalitu", "siteCreate": "Vytvořit lokalitu",
"siteCreateDescription2": "Postupujte podle níže uvedených kroků, abyste vytvořili a připojili novou lokalitu", "siteCreateDescription2": "Postupujte podle níže uvedených kroků, abyste vytvořili a připojili novou lokalitu",
"siteCreateDescription": "Vytvořit nový web pro zahájení připojování zdrojů", "siteCreateDescription": "Vytvořit nový web pro zahájení připojování zdrojů",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Hledat role...", "accessRolesSearch": "Hledat role...",
"accessRolesAdd": "Přidat roli", "accessRolesAdd": "Přidat roli",
"accessRoleDelete": "Odstranit roli", "accessRoleDelete": "Odstranit roli",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Spravovat schválení",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Zobrazit a spravovat čekající oprávnění pro přístup k této organizaci",
"description": "L 343, 22.12.2009, s. 1).", "description": "L 343, 22.12.2009, s. 1).",
"inviteTitle": "Otevřít pozvánky", "inviteTitle": "Otevřít pozvánky",
"inviteDescription": "Spravovat pozvánky pro ostatní uživatele do organizace", "inviteDescription": "Spravovat pozvánky pro ostatní uživatele do organizace",
@@ -452,18 +457,18 @@
"selectDuration": "Vyberte dobu trvání", "selectDuration": "Vyberte dobu trvání",
"selectResource": "Vybrat dokument", "selectResource": "Vybrat dokument",
"filterByResource": "Filtrovat podle zdroje", "filterByResource": "Filtrovat podle zdroje",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Vyberte stát schválení",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtrovat podle státu schválení",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Žádná schválení",
"approvalState": "Approval State", "approvalState": "Země schválení",
"approve": "Approve", "approve": "Schválit",
"approved": "Approved", "approved": "Schváleno",
"denied": "Denied", "denied": "Zamítnuto",
"deniedApproval": "Denied Approval", "deniedApproval": "Odmítnuto schválení",
"all": "All", "all": "Vše",
"deny": "Deny", "deny": "Zamítnout",
"viewDetails": "View Details", "viewDetails": "Zobrazit detaily",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "vyžádal si nové zařízení",
"resetFilters": "Resetovat filtry", "resetFilters": "Resetovat filtry",
"totalBlocked": "Požadavky blokovány Pangolinem", "totalBlocked": "Požadavky blokovány Pangolinem",
"totalRequests": "Celkem požadavků", "totalRequests": "Celkem požadavků",
@@ -743,28 +748,28 @@
"countries": "Země", "countries": "Země",
"accessRoleCreate": "Vytvořit roli", "accessRoleCreate": "Vytvořit roli",
"accessRoleCreateDescription": "Vytvořte novou roli pro seskupení uživatelů a spravujte jejich oprávnění.", "accessRoleCreateDescription": "Vytvořte novou roli pro seskupení uživatelů a spravujte jejich oprávnění.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Upravit roli",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Upravit informace o roli.",
"accessRoleCreateSubmit": "Vytvořit roli", "accessRoleCreateSubmit": "Vytvořit roli",
"accessRoleCreated": "Role vytvořena", "accessRoleCreated": "Role vytvořena",
"accessRoleCreatedDescription": "Role byla úspěšně vytvořena.", "accessRoleCreatedDescription": "Role byla úspěšně vytvořena.",
"accessRoleErrorCreate": "Nepodařilo se vytvořit roli", "accessRoleErrorCreate": "Nepodařilo se vytvořit roli",
"accessRoleErrorCreateDescription": "Došlo k chybě při vytváření role.", "accessRoleErrorCreateDescription": "Došlo k chybě při vytváření role.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Aktualizovat roli",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Role aktualizována",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Role byla úspěšně aktualizována.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Zpracovaná schválení",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Nastavit rozhodnutí o schválení žádosti o schválení.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Nastavit žádost o schválení rozhodnutí o zamítnutí.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Nepodařilo se aktualizovat roli",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Došlo k chybě při aktualizaci role.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Zpracování schválení se nezdařilo",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Při zpracování schválení došlo k chybě.",
"accessRoleErrorNewRequired": "Je vyžadována nová role", "accessRoleErrorNewRequired": "Je vyžadována nová role",
"accessRoleErrorRemove": "Nepodařilo se odstranit roli", "accessRoleErrorRemove": "Nepodařilo se odstranit roli",
"accessRoleErrorRemoveDescription": "Došlo k chybě při odstraňování role.", "accessRoleErrorRemoveDescription": "Došlo k chybě při odstraňování role.",
"accessRoleName": "Název role", "accessRoleName": "Název role",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Chystáte se odstranit roli `{name}`. Tuto akci nelze vrátit zpět.",
"accessRoleRemove": "Odstranit roli", "accessRoleRemove": "Odstranit roli",
"accessRoleRemoveDescription": "Odebrat roli z organizace", "accessRoleRemoveDescription": "Odebrat roli z organizace",
"accessRoleRemoveSubmit": "Odstranit roli", "accessRoleRemoveSubmit": "Odstranit roli",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Zvýšit počet stránek", "sitestCountIncrease": "Zvýšit počet stránek",
"idpManage": "Spravovat poskytovatele identity", "idpManage": "Spravovat poskytovatele identity",
"idpManageDescription": "Zobrazit a spravovat poskytovatele identity v systému", "idpManageDescription": "Zobrazit a spravovat poskytovatele identity v systému",
"idpGlobalModeBanner": "Poskytovatelé identity (IdP) pro každou organizaci jsou na tomto serveru zakázáni. Používá globální IdP (sdílené napříč všemi organizacemi). Správa globálních IdP v <adminPanelLink>admin panelu</adminPanelLink>. Chcete-li povolit IdP pro každou organizaci, upravte konfiguraci serveru a nastavte IdP režim na org. <configDocsLink>Viz dokumentace</configDocsLink>. Pokud chcete pokračovat v používání globálních IdP a zmizet z nastavení organizace, explicitně nastavte režim na globální v konfiguraci.",
"idpGlobalModeBannerUpgradeRequired": "Poskytovatelé identity (IdP) pro každou organizaci jsou na tomto serveru zakázáni. Používá globální IdP (sdílené napříč všemi organizacemi). Spravujte globální IdP v <adminPanelLink>admin panelu</adminPanelLink>. Chcete-li použít poskytovatele identity pro každou organizaci, musíte přejít na Enterprise vydání.",
"idpGlobalModeBannerLicenseRequired": "Poskytovatelé identity (IdP) pro každou organizaci jsou na tomto serveru zakázáni. Používá globální IdP (sdílené napříč všemi organizacemi). Správa globálních IdP v <adminPanelLink>admin panelu</adminPanelLink>. Chcete-li použít poskytovatele identity pro každou organizaci, je vyžadována Enterprise licence.",
"idpDeletedDescription": "Poskytovatel identity byl úspěšně odstraněn", "idpDeletedDescription": "Poskytovatel identity byl úspěšně odstraněn",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Jste si jisti, že chcete trvale odstranit poskytovatele identity?", "idpQuestionRemove": "Jste si jisti, že chcete trvale odstranit poskytovatele identity?",
@@ -900,7 +908,7 @@
"inviteAlready": "Vypadá to, že jste byli pozváni!", "inviteAlready": "Vypadá to, že jste byli pozváni!",
"inviteAlreadyDescription": "Chcete-li přijmout pozvánku, musíte se přihlásit nebo vytvořit účet.", "inviteAlreadyDescription": "Chcete-li přijmout pozvánku, musíte se přihlásit nebo vytvořit účet.",
"signupQuestion": "Již máte účet?", "signupQuestion": "Již máte účet?",
"login": "Log In", "login": "Přihlásit se",
"resourceNotFound": "Zdroj nebyl nalezen", "resourceNotFound": "Zdroj nebyl nalezen",
"resourceNotFoundDescription": "Dokument, ke kterému se snažíte přistupovat, neexistuje.", "resourceNotFoundDescription": "Dokument, ke kterému se snažíte přistupovat, neexistuje.",
"pincodeRequirementsLength": "PIN musí být přesně 6 číslic", "pincodeRequirementsLength": "PIN musí být přesně 6 číslic",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Tato organizace vyžaduje změnu hesla každých {maxDays} dní.", "passwordExpiryDescription": "Tato organizace vyžaduje změnu hesla každých {maxDays} dní.",
"changePasswordNow": "Změnit heslo", "changePasswordNow": "Změnit heslo",
"pincodeAuth": "Ověřovací kód", "pincodeAuth": "Ověřovací kód",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Odeslat kód",
"passwordResetSubmit": "Žádost o obnovení", "passwordResetSubmit": "Žádost o obnovení",
"passwordResetAlreadyHaveCode": "Zadejte kód", "passwordResetAlreadyHaveCode": "Zadejte kód",
"passwordResetSmtpRequired": "Obraťte se na správce", "passwordResetSmtpRequired": "Obraťte se na správce",
"passwordResetSmtpRequiredDescription": "Pro obnovení hesla je vyžadován kód pro obnovení hesla. Kontaktujte prosím svého administrátora.", "passwordResetSmtpRequiredDescription": "Pro obnovení hesla je vyžadován kód pro obnovení hesla. Kontaktujte prosím svého administrátora.",
"passwordBack": "Zpět na heslo", "passwordBack": "Zpět na heslo",
"loginBack": "Go back to main login page", "loginBack": "Přejít zpět na hlavní přihlašovací stránku",
"signup": "Zaregistrovat se", "signup": "Zaregistrovat se",
"loginStart": "Přihlaste se a začněte", "loginStart": "Přihlaste se a začněte",
"idpOidcTokenValidating": "Ověřování OIDC tokenu", "idpOidcTokenValidating": "Ověřování OIDC tokenu",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Aktualizovat IDP Org", "actionUpdateIdpOrg": "Aktualizovat IDP Org",
"actionCreateClient": "Vytvořit klienta", "actionCreateClient": "Vytvořit klienta",
"actionDeleteClient": "Odstranit klienta", "actionDeleteClient": "Odstranit klienta",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Archivovat klienta",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Zrušit archiv klienta",
"actionBlockClient": "Block Client", "actionBlockClient": "Blokovat klienta",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Odblokovat klienta",
"actionUpdateClient": "Aktualizovat klienta", "actionUpdateClient": "Aktualizovat klienta",
"actionListClients": "Seznam klientů", "actionListClients": "Seznam klientů",
"actionGetClient": "Získat klienta", "actionGetClient": "Získat klienta",
@@ -1164,14 +1172,14 @@
"searchProgress": "Hledat...", "searchProgress": "Hledat...",
"create": "Vytvořit", "create": "Vytvořit",
"orgs": "Organizace", "orgs": "Organizace",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Došlo k neočekávané chybě. Zkuste to prosím znovu.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Přihlášení je vyžadováno pro vaše zařízení.",
"passwordForgot": "Zapomněli jste heslo?", "passwordForgot": "Zapomněli jste heslo?",
"otpAuth": "Dvoufaktorové ověření", "otpAuth": "Dvoufaktorové ověření",
"otpAuthDescription": "Zadejte kód z vaší autentizační aplikace nebo jeden z vlastních záložních kódů.", "otpAuthDescription": "Zadejte kód z vaší autentizační aplikace nebo jeden z vlastních záložních kódů.",
"otpAuthSubmit": "Odeslat kód", "otpAuthSubmit": "Odeslat kód",
"idpContinue": "Nebo pokračovat s", "idpContinue": "Nebo pokračovat s",
"otpAuthBack": "Back to Password", "otpAuthBack": "Zpět na heslo",
"navbar": "Navigation Menu", "navbar": "Navigation Menu",
"navbarDescription": "Hlavní navigační menu aplikace", "navbarDescription": "Hlavní navigační menu aplikace",
"navbarDocsLink": "Dokumentace", "navbarDocsLink": "Dokumentace",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Přehled", "sidebarOverview": "Přehled",
"sidebarHome": "Domů", "sidebarHome": "Domů",
"sidebarSites": "Stránky", "sidebarSites": "Stránky",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Žádosti o schválení",
"sidebarResources": "Zdroje", "sidebarResources": "Zdroje",
"sidebarProxyResources": "Veřejnost", "sidebarProxyResources": "Veřejnost",
"sidebarClientResources": "Soukromé", "sidebarClientResources": "Soukromé",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Poskytovatelé identity", "sidebarIdentityProviders": "Poskytovatelé identity",
"sidebarLicense": "Licence", "sidebarLicense": "Licence",
"sidebarClients": "Klienti", "sidebarClients": "Klienti",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Uživatelská zařízení",
"sidebarMachineClients": "Stroje a přístroje", "sidebarMachineClients": "Stroje a přístroje",
"sidebarDomains": "Domény", "sidebarDomains": "Domény",
"sidebarGeneral": "Spravovat", "sidebarGeneral": "Spravovat",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Došlo k chybě při vytváření účtu správce serveru.", "setupErrorCreateAdmin": "Došlo k chybě při vytváření účtu správce serveru.",
"certificateStatus": "Stav certifikátu", "certificateStatus": "Stav certifikátu",
"loading": "Načítání", "loading": "Načítání",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Načítání analytiky",
"restart": "Restartovat", "restart": "Restartovat",
"domains": "Domény", "domains": "Domény",
"domainsDescription": "Vytvořit a spravovat domény dostupné v organizaci", "domainsDescription": "Vytvořit a spravovat domény dostupné v organizaci",
@@ -1336,7 +1344,7 @@
"refreshError": "Obnovení dat se nezdařilo", "refreshError": "Obnovení dat se nezdařilo",
"verified": "Ověřeno", "verified": "Ověřeno",
"pending": "Nevyřízeno", "pending": "Nevyřízeno",
"pendingApproval": "Pending Approval", "pendingApproval": "Čeká na schválení",
"sidebarBilling": "Fakturace", "sidebarBilling": "Fakturace",
"billing": "Fakturace", "billing": "Fakturace",
"orgBillingDescription": "Spravovat fakturační informace a předplatné", "orgBillingDescription": "Spravovat fakturační informace a předplatné",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Přehled omezení použití", "billingUsageLimitsOverview": "Přehled omezení použití",
"billingMonitorUsage": "Sledujte vaše využití pomocí nastavených limitů. Pokud potřebujete zvýšit limity, kontaktujte nás prosím support@pangolin.net.", "billingMonitorUsage": "Sledujte vaše využití pomocí nastavených limitů. Pokud potřebujete zvýšit limity, kontaktujte nás prosím support@pangolin.net.",
"billingDataUsage": "Využití dat", "billingDataUsage": "Využití dat",
"billingOnlineTime": "Stránka online čas", "billingSites": "Stránky",
"billingUsers": "Aktivní uživatelé", "billingUsers": "Uživatelé",
"billingDomains": "Aktivní domény", "billingDomains": "Domény",
"billingRemoteExitNodes": "Aktivní Samostatně hostované uzly", "billingRemoteExitNodes": "Vzdálené uzly",
"billingNoLimitConfigured": "Žádný limit nenastaven", "billingNoLimitConfigured": "Žádný limit nenastaven",
"billingEstimatedPeriod": "Odhadované období fakturace", "billingEstimatedPeriod": "Odhadované období fakturace",
"billingIncludedUsage": "Zahrnuto využití", "billingIncludedUsage": "Zahrnuto využití",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Nepodařilo se získat URL portálu", "billingFailedToGetPortalUrl": "Nepodařilo se získat URL portálu",
"billingPortalError": "Chyba portálu", "billingPortalError": "Chyba portálu",
"billingDataUsageInfo": "Pokud jste připojeni k cloudu, jsou vám účtována všechna data přenášená prostřednictvím zabezpečených tunelů. To zahrnuje příchozí i odchozí provoz na všech vašich stránkách. Jakmile dosáhnete svého limitu, vaše stránky se odpojí, dokud neaktualizujete svůj tarif nebo nezmenšíte jeho používání. Data nejsou nabírána při používání uzlů.", "billingDataUsageInfo": "Pokud jste připojeni k cloudu, jsou vám účtována všechna data přenášená prostřednictvím zabezpečených tunelů. To zahrnuje příchozí i odchozí provoz na všech vašich stránkách. Jakmile dosáhnete svého limitu, vaše stránky se odpojí, dokud neaktualizujete svůj tarif nebo nezmenšíte jeho používání. Data nejsou nabírána při používání uzlů.",
"billingOnlineTimeInfo": "Platíte na základě toho, jak dlouho budou vaše stránky připojeny k cloudu. Například, 44,640 minut se rovná jedné stránce 24/7 po celý měsíc. Jakmile dosáhnete svého limitu, vaše stránky se odpojí, dokud neaktualizujete svůj tarif nebo nezkrátíte jeho používání. Čas není vybírán při používání uzlů.", "billingSInfo": "Kolik stránek můžete použít",
"billingUsersInfo": "Každý uživatel v organizaci je účtován denně. Fakturace je počítána na základě počtu aktivních uživatelských účtů na Vašem org.", "billingUsersInfo": "Kolik uživatelů můžete použít",
"billingDomainInfo": "Objednávka je účtována za každou doménu v organizaci. Fakturace je počítána denně na základě počtu aktivních doménových účtů na Vašem org.", "billingDomainInfo": "Kolik domén můžete použít",
"billingRemoteExitNodesInfo": "Za každý spravovaný uzel v organizaci se vám účtuje denně. Fakturace je vypočítávána na základě počtu aktivních spravovaných uzlů ve vašem org.", "billingRemoteExitNodesInfo": "Kolik vzdálených uzlů můžete použít",
"billingLicenseKeys": "Licenční klíče",
"billingLicenseKeysDescription": "Spravovat předplatné licenčního klíče",
"billingLicenseSubscription": "Předplatné licence",
"billingInactive": "Neaktivní",
"billingLicenseItem": "Položka licence",
"billingQuantity": "Množství",
"billingTotal": "celkem",
"billingModifyLicenses": "Upravit předplatné licence",
"domainNotFound": "Doména nenalezena", "domainNotFound": "Doména nenalezena",
"domainNotFoundDescription": "Tento dokument je zakázán, protože doména již neexistuje náš systém. Nastavte prosím novou doménu pro tento dokument.", "domainNotFoundDescription": "Tento dokument je zakázán, protože doména již neexistuje náš systém. Nastavte prosím novou doménu pro tento dokument.",
"failed": "Selhalo", "failed": "Selhalo",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Bezpečnostní klíč byl úspěšně odstraněn", "securityKeyRemoveSuccess": "Bezpečnostní klíč byl úspěšně odstraněn",
"securityKeyRemoveError": "Odstranění bezpečnostního klíče se nezdařilo", "securityKeyRemoveError": "Odstranění bezpečnostního klíče se nezdařilo",
"securityKeyLoadError": "Nepodařilo se načíst bezpečnostní klíče", "securityKeyLoadError": "Nepodařilo se načíst bezpečnostní klíče",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Použít bezpečnostní klíč",
"securityKeyAuthError": "Ověření bezpečnostním klíčem se nezdařilo", "securityKeyAuthError": "Ověření bezpečnostním klíčem se nezdařilo",
"securityKeyRecommendation": "Registrujte záložní bezpečnostní klíč na jiném zařízení, abyste zajistili, že budete mít vždy přístup ke svému účtu.", "securityKeyRecommendation": "Registrujte záložní bezpečnostní klíč na jiném zařízení, abyste zajistili, že budete mít vždy přístup ke svému účtu.",
"registering": "Registrace...", "registering": "Registrace...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Pro neHTTP zdroje je vyžadováno číslo portu", "resourcePortRequired": "Pro neHTTP zdroje je vyžadováno číslo portu",
"resourcePortNotAllowed": "Číslo portu by nemělo být nastaveno pro HTTP zdroje", "resourcePortNotAllowed": "Číslo portu by nemělo být nastaveno pro HTTP zdroje",
"billingPricingCalculatorLink": "Cenová kalkulačka", "billingPricingCalculatorLink": "Cenová kalkulačka",
"billingYourPlan": "Váš plán",
"billingViewOrModifyPlan": "Zobrazit nebo upravit aktuální tarif",
"billingViewPlanDetails": "Zobrazit detaily plánu",
"billingUsageAndLimits": "Limity a použití",
"billingViewUsageAndLimits": "Zobrazit limity vašeho plánu a aktuální využití",
"billingCurrentUsage": "Aktuální využití",
"billingMaximumLimits": "Maximální limity",
"billingRemoteNodes": "Vzdálené uzly",
"billingUnlimited": "Bez omezení",
"billingPaidLicenseKeys": "Placené licenční klíče",
"billingManageLicenseSubscription": "Spravujte své předplatné za placené samohostované licenční klíče",
"billingCurrentKeys": "Aktuální klíče",
"billingModifyCurrentPlan": "Upravit aktuální tarif",
"billingConfirmUpgrade": "Potvrdit aktualizaci",
"billingConfirmDowngrade": "Potvrdit downgrade",
"billingConfirmUpgradeDescription": "Chystáte se povýšit svůj tarif. Přečtěte si nové limity a ceny.",
"billingConfirmDowngradeDescription": "Chystáte se snížit svůj tarif. Přečtěte si nové limity a ceny níže.",
"billingPlanIncludes": "Plán zahrnuje",
"billingProcessing": "Zpracovávám...",
"billingConfirmUpgradeButton": "Potvrdit aktualizaci",
"billingConfirmDowngradeButton": "Potvrdit downgrade",
"billingLimitViolationWarning": "Využití překročilo limity nového plánu",
"billingLimitViolationDescription": "Vaše současné využití překračuje meze tohoto plánu. Po ponížení budou všechny akce zakázány, dokud nesnížíte využití v rámci nových limitů. Přečtěte si prosím níže uvedené funkce překračující limity. Limity při porušení:",
"billingFeatureLossWarning": "Upozornění na dostupnost funkce",
"billingFeatureLossDescription": "Po pomenutí budou funkce v novém plánu automaticky zakázány. Některá nastavení a konfigurace mohou být ztraceny. Zkontrolujte cenovou matrici, abyste pochopili, které funkce již nebudou k dispozici.",
"billingUsageExceedsLimit": "Aktuální využití ({current}) překračuje limit ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Souhlasím s", "IAgreeToThe": "Souhlasím s",
"termsOfService": "podmínky služby", "termsOfService": "podmínky služby",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Interval zdraví", "IntervalSeconds": "Interval zdraví",
"timeoutSeconds": "Časový limit (sek)", "timeoutSeconds": "Časový limit (sek)",
"timeIsInSeconds": "Čas je v sekundách", "timeIsInSeconds": "Čas je v sekundách",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Vyžadovat schválení zařízení",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Uživatelé s touto rolí potřebují nová zařízení schválená správcem, než se mohou připojit a přistupovat ke zdrojům.",
"retryAttempts": "Opakovat pokusy", "retryAttempts": "Opakovat pokusy",
"expectedResponseCodes": "Očekávané kódy odezvy", "expectedResponseCodes": "Očekávané kódy odezvy",
"expectedResponseCodesDescription": "HTTP kód stavu, který označuje zdravý stav. Ponecháte-li prázdné, 200-300 je považováno za zdravé.", "expectedResponseCodesDescription": "HTTP kód stavu, který označuje zdravý stav. Ponecháte-li prázdné, 200-300 je považováno za zdravé.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Nebyly nalezeny žádné vnitřní zdroje.", "resourcesTableNoInternalResourcesFound": "Nebyly nalezeny žádné vnitřní zdroje.",
"resourcesTableDestination": "Místo určení", "resourcesTableDestination": "Místo určení",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Adresa aliasu",
"resourcesTableAliasAddressInfo": "Tato adresa je součástí subsítě veřejných služeb organizace. Používá se k řešení záznamů aliasů pomocí interního rozlišení DNS.",
"resourcesTableClients": "Klienti", "resourcesTableClients": "Klienti",
"resourcesTableAndOnlyAccessibleInternally": "a jsou interně přístupné pouze v případě, že jsou propojeni s klientem.", "resourcesTableAndOnlyAccessibleInternally": "a jsou interně přístupné pouze v případě, že jsou propojeni s klientem.",
"resourcesTableNoTargets": "Žádné cíle", "resourcesTableNoTargets": "Žádné cíle",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Chcete-li pokračovat, vyberte svého poskytovatele identity", "orgAuthChooseIdpDescription": "Chcete-li pokračovat, vyberte svého poskytovatele identity",
"orgAuthNoIdpConfigured": "Tato organizace nemá nakonfigurovány žádné poskytovatele identity. Místo toho se můžete přihlásit s vaší Pangolinovou identitou.", "orgAuthNoIdpConfigured": "Tato organizace nemá nakonfigurovány žádné poskytovatele identity. Místo toho se můžete přihlásit s vaší Pangolinovou identitou.",
"orgAuthSignInWithPangolin": "Přihlásit se pomocí Pangolinu", "orgAuthSignInWithPangolin": "Přihlásit se pomocí Pangolinu",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Přihlásit se do organizace",
"orgAuthSelectOrgTitle": "Přihlášení do organizace", "orgAuthSelectOrgTitle": "Přihlášení do organizace",
"orgAuthSelectOrgDescription": "Zadejte ID vaší organizace pro pokračování", "orgAuthSelectOrgDescription": "Zadejte ID vaší organizace pro pokračování",
"orgAuthOrgIdPlaceholder": "vaše-organizace", "orgAuthOrgIdPlaceholder": "vaše-organizace",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Zpět ke standardnímu přihlášení", "orgAuthBackToSignIn": "Zpět ke standardnímu přihlášení",
"orgAuthNoAccount": "Nemáte účet?", "orgAuthNoAccount": "Nemáte účet?",
"subscriptionRequiredToUse": "Pro použití této funkce je vyžadováno předplatné.", "subscriptionRequiredToUse": "Pro použití této funkce je vyžadováno předplatné.",
"mustUpgradeToUse": "Pro použití této funkce musíte aktualizovat své předplatné.",
"subscriptionRequiredTierToUse": "Tato funkce vyžaduje <tierLink>{tier}</tierLink> nebo vyšší.",
"upgradeToTierToUse": "Pro použití této funkce upgradujte na <tierLink>{tier}</tierLink> nebo vyšší.",
"subscriptionTierTier1": "Domů",
"subscriptionTierTier2": "Tým",
"subscriptionTierTier3": "Podniky",
"subscriptionTierEnterprise": "Podniky",
"idpDisabled": "Poskytovatelé identit jsou zakázáni.", "idpDisabled": "Poskytovatelé identit jsou zakázáni.",
"orgAuthPageDisabled": "Ověřovací stránka organizace je zakázána.", "orgAuthPageDisabled": "Ověřovací stránka organizace je zakázána.",
"domainRestartedDescription": "Ověření domény bylo úspěšně restartováno", "domainRestartedDescription": "Ověření domény bylo úspěšně restartováno",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Získat licenci",
"description": "Vyberte si plán a řekněte nám, jak plánujete používat Pangolin.",
"chooseTier": "Vyberte si svůj plán",
"viewPricingLink": "Zobrazit ceny, funkce a limity",
"tiers": {
"starter": {
"title": "Počáteční",
"description": "Firemní funkce, 25 uživatelů, 25 stránek a komunitní podpory."
},
"scale": {
"title": "Měřítko",
"description": "Podnikové funkce, 50 uživatelů, 50 míst a prioritní podpory."
}
},
"personalUseOnly": "Pouze osobní použití (bezplatná licence bez platby)",
"buttons": {
"continueToCheckout": "Pokračovat do pokladny"
},
"toasts": {
"checkoutError": {
"title": "Chyba při objednávce",
"description": "Nelze spustit objednávku. Zkuste to prosím znovu."
}
}
},
"priority": "Priorita", "priority": "Priorita",
"priorityDescription": "Vyšší priorita je vyhodnocena jako první. Priorita = 100 znamená automatické řazení (rozhodnutí systému). Pro vynucení manuální priority použijte jiné číslo.", "priorityDescription": "Vyšší priorita je vyhodnocena jako první. Priorita = 100 znamená automatické řazení (rozhodnutí systému). Pro vynucení manuální priority použijte jiné číslo.",
"instanceName": "Název instance", "instanceName": "Název instance",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Konec následujícího roku", "logRetentionEndOfFollowingYear": "Konec následujícího roku",
"actionLogsDescription": "Zobrazit historii akcí provedených v této organizaci", "actionLogsDescription": "Zobrazit historii akcí provedených v této organizaci",
"accessLogsDescription": "Zobrazit žádosti o ověření přístupu pro zdroje v této organizaci", "accessLogsDescription": "Zobrazit žádosti o ověření přístupu pro zdroje v této organizaci",
"licenseRequiredToUse": "Pro použití této funkce je vyžadována licence pro podnikání.", "licenseRequiredToUse": "Pro použití této funkce je vyžadována licence <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> . Tato funkce je také dostupná v <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "<enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> je vyžadována pro použití této funkce. Tato funkce je také k dispozici v <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Oddělovač certifikátů", "certResolver": "Oddělovač certifikátů",
"certResolverDescription": "Vyberte řešitele certifikátů pro tento dokument.", "certResolverDescription": "Vyberte řešitele certifikátů pro tento dokument.",
"selectCertResolver": "Vyberte řešič certifikátů", "selectCertResolver": "Vyberte řešič certifikátů",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Kód musí být 9 znaků (např. A1AJ-N5JD)", "deviceCodeInvalidFormat": "Kód musí být 9 znaků (např. A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Neplatný nebo prošlý kód", "deviceCodeInvalidOrExpired": "Neplatný nebo prošlý kód",
"deviceCodeVerifyFailed": "Ověření kódu zařízení se nezdařilo", "deviceCodeVerifyFailed": "Ověření kódu zařízení se nezdařilo",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Ověřování kódu zařízení...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Ověřování autorizace zařízení...",
"signedInAs": "Přihlášen jako", "signedInAs": "Přihlášen jako",
"deviceCodeEnterPrompt": "Zadejte kód zobrazený na zařízení", "deviceCodeEnterPrompt": "Zadejte kód zobrazený na zařízení",
"continue": "Pokračovat", "continue": "Pokračovat",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Přístup ke všem organizacím má přístup k vašemu účtu", "deviceOrganizationsAccess": "Přístup ke všem organizacím má přístup k vašemu účtu",
"deviceAuthorize": "Autorizovat {applicationName}", "deviceAuthorize": "Autorizovat {applicationName}",
"deviceConnected": "Zařízení připojeno!", "deviceConnected": "Zařízení připojeno!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Zařízení má oprávnění k přístupu k vašemu účtu. Vraťte se prosím do klientské aplikace.",
"pangolinCloud": "Pangolin Cloud", "pangolinCloud": "Pangolin Cloud",
"viewDevices": "Zobrazit zařízení", "viewDevices": "Zobrazit zařízení",
"viewDevicesDescription": "Spravovat připojená zařízení", "viewDevicesDescription": "Spravovat připojená zařízení",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Nejste vy? Použijte jiný účet.", "deviceLoginUseDifferentAccount": "Nejste vy? Použijte jiný účet.",
"deviceLoginDeviceRequestingAccessToAccount": "Zařízení žádá o přístup k tomuto účtu.", "deviceLoginDeviceRequestingAccessToAccount": "Zařízení žádá o přístup k tomuto účtu.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Chcete-li pokračovat, vyberte metodu ověřování.",
"noData": "Žádná data", "noData": "Žádná data",
"machineClients": "Strojoví klienti", "machineClients": "Strojoví klienti",
"install": "Instalovat", "install": "Instalovat",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Momentálně máme technické potíže. Zkontrolujte později.", "maintenanceScreenMessage": "Momentálně máme technické potíže. Zkontrolujte později.",
"maintenanceScreenEstimatedCompletion": "Odhadované dokončení:", "maintenanceScreenEstimatedCompletion": "Odhadované dokončení:",
"createInternalResourceDialogDestinationRequired": "Cíl je povinný", "createInternalResourceDialogDestinationRequired": "Cíl je povinný",
"available": "Available", "available": "Dostupné",
"archived": "Archived", "archived": "Archivováno",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Nebyla nalezena žádná archivovaná zařízení",
"deviceArchived": "Device archived", "deviceArchived": "Zařízení archivováno",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Zařízení bylo úspěšně archivováno.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Chyba při archivaci zařízení",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Archivace zařízení se nezdařila",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Opravdu chcete archivovat toto zařízení?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Zařízení bude archivováno a odebráno ze seznamu aktivních zařízení.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Archivovat zařízení",
"archiveDevice": "Archive Device", "archiveDevice": "Archivovat zařízení",
"archive": "Archive", "archive": "Archiv",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Zařízení bylo odarchivováno",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Zařízení bylo úspěšně odarchivováno.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Chyba při odarchivování zařízení",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Nepodařilo se odarchivovat zařízení",
"unarchive": "Unarchive", "unarchive": "Zrušit archiv",
"archiveClient": "Archive Client", "archiveClient": "Archivovat klienta",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Jste si jisti, že chcete archivovat tohoto klienta?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Klient bude archivován a odstraněn z vašeho aktivního seznamu klientů.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Archivovat klienta",
"blockClient": "Block Client", "blockClient": "Blokovat klienta",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Jste si jisti, že chcete zablokovat tohoto klienta?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Zařízení bude nuceno odpojit, pokud je připojeno. Zařízení můžete později odblokovat.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Blokovat klienta",
"active": "Active", "active": "Aktiv",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Uživatelské jméno nebo e-mail",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Vyberte vaši organizaci",
"signInTo": "Log in in to", "signInTo": "Přihlásit se do",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Pokračovat s heslem",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Pro tuto organizaci nejsou k dispozici žádné metody ověřování.",
"enterPassword": "Enter your password", "enterPassword": "Zadejte své heslo",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Zadejte kód z vaší ověřovací aplikace",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Pro přihlášení použijte svůj bezpečnostní klíč.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Potřebujete použít jiný účet?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Kliknutím na tlačítka níže potvrzujete, že jste si přečetli, chápali, a souhlasím s <termsOfService>obchodními podmínkami</termsOfService> a <privacyPolicy>Zásadami ochrany osobních údajů</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Podmínky služby",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Ochrana osobních údajů",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Nebyl nalezen žádný uživatel s tímto uživatelským jménem.",
"verify": "Verify", "verify": "Ověřit",
"signIn": "Sign In", "signIn": "Přihlásit se",
"forgotPassword": "Forgot password?", "forgotPassword": "Zapomněli jste heslo?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Pokud jste se přihlásili dříve, můžete místo toho zadat své uživatelské jméno nebo e-mail výše pro ověření u poskytovatele identity vaší organizace. Je to jednodušší!",
"continueAnyway": "Continue anyway", "continueAnyway": "Přesto pokračovat",
"dontShowAgain": "Don't show again", "dontShowAgain": "Znovu nezobrazovat",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Věděli jste, že?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Chcete se přihlásit?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Snažíte se přihlásit prostřednictvím poskytovatele identity vaší organizace?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Namísto toho se přihlaste nebo se zaregistrujte pomocí své organizace",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Použít jiný účet",
"logIn": "Log In", "logIn": "Přihlásit se",
"deviceInformation": "Device Information", "deviceInformation": "Informace o zařízení",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informace o zařízení a agentovi",
"platform": "Platform", "deviceSecurity": "Zabezpečení zařízení",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Informace o bezpečnostní pozici zařízení",
"windowsVersion": "Windows Version", "platform": "Platforma",
"iosVersion": "iOS Version", "macosVersion": "macOS verze",
"androidVersion": "Android Version", "windowsVersion": "Verze Windows",
"osVersion": "OS Version", "iosVersion": "Verze iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Verze Androidu",
"deviceModel": "Device Model", "osVersion": "Verze OS",
"serialNumber": "Serial Number", "kernelVersion": "Verze jádra",
"deviceModel": "Model zařízení",
"serialNumber": "Pořadové číslo",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "První vidění",
"lastSeen": "Last Seen", "lastSeen": "Naposledy viděno",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometrie povolena",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Šifrovaný disk",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Firewall povolen",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Automatické aktualizace povoleny",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM k dispozici",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirus povolen",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Ochrana systémové integrity (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Režim neviditelnosti firewallu",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "Pancíř aplikace",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Zobrazit informace o zařízení a nastavení",
"devicePendingApprovalDescription": "Toto zařízení čeká na schválení",
"deviceBlockedDescription": "Toto zařízení je momentálně blokováno. Nebude se moci připojit k žádným zdrojům, dokud nebude odblokováno.",
"unblockClient": "Odblokovat klienta",
"unblockClientDescription": "Zařízení bylo odblokováno",
"unarchiveClient": "Zrušit archiv klienta",
"unarchiveClientDescription": "Zařízení bylo odarchivováno",
"block": "Blokovat",
"unblock": "Odblokovat",
"deviceActions": "Akce zařízení",
"deviceActionsDescription": "Spravovat stav zařízení a přístup",
"devicePendingApprovalBannerDescription": "Toto zařízení čeká na schválení. Nebude se moci připojit ke zdrojům, dokud nebude schváleno.",
"connected": "Připojeno",
"disconnected": "Odpojeno",
"approvalsEmptyStateTitle": "Schvalování zařízení není povoleno",
"approvalsEmptyStateDescription": "Povolte oprávnění oprávnění pro role správce před připojením nových zařízení.",
"approvalsEmptyStateStep1Title": "Přejít na role",
"approvalsEmptyStateStep1Description": "Přejděte do nastavení rolí vaší organizace pro konfiguraci schválení zařízení.",
"approvalsEmptyStateStep2Title": "Povolit schválení zařízení",
"approvalsEmptyStateStep2Description": "Upravte roli a povolte možnost 'Vyžadovat schválení zařízení'. Uživatelé s touto rolí budou potřebovat schválení pro nová zařízení správce.",
"approvalsEmptyStatePreviewDescription": "Náhled: Pokud je povoleno, čekající na zařízení se zde zobrazí žádosti o recenzi",
"approvalsEmptyStateButtonText": "Spravovat role"
} }
+223 -122
View File
@@ -18,6 +18,8 @@
"componentsMember": "Du bist Mitglied von {count, plural, =0 {keiner Organisation} one {einer Organisation} other {# Organisationen}}.", "componentsMember": "Du bist Mitglied von {count, plural, =0 {keiner Organisation} one {einer Organisation} other {# Organisationen}}.",
"componentsInvalidKey": "Ungültige oder abgelaufene Lizenzschlüssel erkannt. Beachte die Lizenzbedingungen, um alle Funktionen weiterhin zu nutzen.", "componentsInvalidKey": "Ungültige oder abgelaufene Lizenzschlüssel erkannt. Beachte die Lizenzbedingungen, um alle Funktionen weiterhin zu nutzen.",
"dismiss": "Verwerfen", "dismiss": "Verwerfen",
"subscriptionViolationMessage": "Sie überschreiten Ihre Grenzen für Ihr aktuelles Paket. Korrigieren Sie das Problem, indem Sie Webseiten, Benutzer oder andere Ressourcen entfernen, um in Ihrem Paket zu bleiben.",
"subscriptionViolationViewBilling": "Rechnung anzeigen",
"componentsLicenseViolation": "Lizenzverstoß: Dieser Server benutzt {usedSites} Standorte, was das Lizenzlimit von {maxSites} Standorten überschreitet. Beachte die Lizenzbedingungen, um alle Funktionen weiterhin zu nutzen.", "componentsLicenseViolation": "Lizenzverstoß: Dieser Server benutzt {usedSites} Standorte, was das Lizenzlimit von {maxSites} Standorten überschreitet. Beachte die Lizenzbedingungen, um alle Funktionen weiterhin zu nutzen.",
"componentsSupporterMessage": "Vielen Dank für die Unterstützung von Pangolin als {tier}!", "componentsSupporterMessage": "Vielen Dank für die Unterstützung von Pangolin als {tier}!",
"inviteErrorNotValid": "Es tut uns leid, aber es sieht so aus, als wäre die Einladung, auf die du zugreifen möchtest, entweder nicht angenommen worden oder nicht mehr gültig.", "inviteErrorNotValid": "Es tut uns leid, aber es sieht so aus, als wäre die Einladung, auf die du zugreifen möchtest, entweder nicht angenommen worden oder nicht mehr gültig.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Verbinde ein beliebiges Netzwerk", "sitesBannerTitle": "Verbinde ein beliebiges Netzwerk",
"sitesBannerDescription": "Ein Standort ist eine Verbindung zu einem Remote-Netzwerk, die es Pangolin ermöglicht, Zugriff auf öffentliche oder private Ressourcen für Benutzer überall zu gewähren. Installieren Sie den Site Netzwerk Connector (Newt) wo auch immer Sie eine Binärdatei oder einen Container starten können, um die Verbindung herzustellen.", "sitesBannerDescription": "Ein Standort ist eine Verbindung zu einem Remote-Netzwerk, die es Pangolin ermöglicht, Zugriff auf öffentliche oder private Ressourcen für Benutzer überall zu gewähren. Installieren Sie den Site Netzwerk Connector (Newt) wo auch immer Sie eine Binärdatei oder einen Container starten können, um die Verbindung herzustellen.",
"sitesBannerButtonText": "Standort installieren", "sitesBannerButtonText": "Standort installieren",
"approvalsBannerTitle": "Gerätezugriff genehmigen oder verweigern",
"approvalsBannerDescription": "Überprüfen und genehmigen oder verweigern Gerätezugriffsanfragen von Benutzern. Wenn Gerätegenehmigungen erforderlich sind, müssen Benutzer eine Administratorgenehmigung erhalten, bevor ihre Geräte sich mit den Ressourcen Ihrer Organisation verbinden können.",
"approvalsBannerButtonText": "Mehr erfahren",
"siteCreate": "Standort erstellen", "siteCreate": "Standort erstellen",
"siteCreateDescription2": "Folge den nachfolgenden Schritten, um einen neuen Standort zu erstellen und zu verbinden", "siteCreateDescription2": "Folge den nachfolgenden Schritten, um einen neuen Standort zu erstellen und zu verbinden",
"siteCreateDescription": "Erstellen Sie einen neuen Standort, um Ressourcen zu verbinden", "siteCreateDescription": "Erstellen Sie einen neuen Standort, um Ressourcen zu verbinden",
@@ -94,7 +99,7 @@
"siteGeneralDescription": "Allgemeine Einstellungen für diesen Standort konfigurieren", "siteGeneralDescription": "Allgemeine Einstellungen für diesen Standort konfigurieren",
"siteSettingDescription": "Standorteinstellungen konfigurieren", "siteSettingDescription": "Standorteinstellungen konfigurieren",
"siteSetting": "{siteName} Einstellungen", "siteSetting": "{siteName} Einstellungen",
"siteNewtTunnel": "Neuer Standort (empfohlen)", "siteNewtTunnel": "Newt Standort (empfohlen)",
"siteNewtTunnelDescription": "Einfachster Weg, einen Einstiegspunkt in jedes Netzwerk zu erstellen. Keine zusätzliche Einrichtung.", "siteNewtTunnelDescription": "Einfachster Weg, einen Einstiegspunkt in jedes Netzwerk zu erstellen. Keine zusätzliche Einrichtung.",
"siteWg": "Einfacher WireGuard Tunnel", "siteWg": "Einfacher WireGuard Tunnel",
"siteWgDescription": "Verwende jeden WireGuard-Client, um einen Tunnel einzurichten. Manuelles NAT-Setup erforderlich.", "siteWgDescription": "Verwende jeden WireGuard-Client, um einen Tunnel einzurichten. Manuelles NAT-Setup erforderlich.",
@@ -104,7 +109,7 @@
"siteSeeAll": "Alle Standorte anzeigen", "siteSeeAll": "Alle Standorte anzeigen",
"siteTunnelDescription": "Legen Sie fest, wie Sie sich mit dem Standort verbinden möchten", "siteTunnelDescription": "Legen Sie fest, wie Sie sich mit dem Standort verbinden möchten",
"siteNewtCredentials": "Zugangsdaten", "siteNewtCredentials": "Zugangsdaten",
"siteNewtCredentialsDescription": "So wird sich die Seite mit dem Server authentifizieren", "siteNewtCredentialsDescription": "So wird sich der Standort mit dem Server authentifizieren",
"remoteNodeCredentialsDescription": "So wird sich der entfernte Node mit dem Server authentifizieren", "remoteNodeCredentialsDescription": "So wird sich der entfernte Node mit dem Server authentifizieren",
"siteCredentialsSave": "Anmeldedaten speichern", "siteCredentialsSave": "Anmeldedaten speichern",
"siteCredentialsSaveDescription": "Du kannst das nur einmal sehen. Stelle sicher, dass du es an einen sicheren Ort kopierst.", "siteCredentialsSaveDescription": "Du kannst das nur einmal sehen. Stelle sicher, dass du es an einen sicheren Ort kopierst.",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Rollen suchen...", "accessRolesSearch": "Rollen suchen...",
"accessRolesAdd": "Rolle hinzufügen", "accessRolesAdd": "Rolle hinzufügen",
"accessRoleDelete": "Rolle löschen", "accessRoleDelete": "Rolle löschen",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Genehmigungen verwalten",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Zeige und verwalte ausstehende Genehmigungen für den Zugriff auf diese Organisation",
"description": "Beschreibung", "description": "Beschreibung",
"inviteTitle": "Einladungen öffnen", "inviteTitle": "Einladungen öffnen",
"inviteDescription": "Einladungen für andere Benutzer verwalten, der Organisation beizutreten", "inviteDescription": "Einladungen für andere Benutzer verwalten, der Organisation beizutreten",
@@ -452,18 +457,18 @@
"selectDuration": "Dauer auswählen", "selectDuration": "Dauer auswählen",
"selectResource": "Ressource auswählen", "selectResource": "Ressource auswählen",
"filterByResource": "Nach Ressource filtern", "filterByResource": "Nach Ressource filtern",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Genehmigungsstatus auswählen",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtern nach Genehmigungsstatus",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Keine Genehmigungen",
"approvalState": "Approval State", "approvalState": "Genehmigungsstatus",
"approve": "Approve", "approve": "Bestätigen",
"approved": "Approved", "approved": "Genehmigt",
"denied": "Denied", "denied": "Verweigert",
"deniedApproval": "Denied Approval", "deniedApproval": "Genehmigung verweigert",
"all": "All", "all": "Alle",
"deny": "Deny", "deny": "Leugnen",
"viewDetails": "View Details", "viewDetails": "Details anzeigen",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "hat ein neues Gerät angefordert",
"resetFilters": "Filter zurücksetzen", "resetFilters": "Filter zurücksetzen",
"totalBlocked": "Anfragen blockiert von Pangolin", "totalBlocked": "Anfragen blockiert von Pangolin",
"totalRequests": "Gesamte Anfragen", "totalRequests": "Gesamte Anfragen",
@@ -743,28 +748,28 @@
"countries": "Länder", "countries": "Länder",
"accessRoleCreate": "Rolle erstellen", "accessRoleCreate": "Rolle erstellen",
"accessRoleCreateDescription": "Erstellen Sie eine neue Rolle, um Benutzer zu gruppieren und ihre Berechtigungen zu verwalten.", "accessRoleCreateDescription": "Erstellen Sie eine neue Rolle, um Benutzer zu gruppieren und ihre Berechtigungen zu verwalten.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Rolle bearbeiten",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Rolleninformationen bearbeiten.",
"accessRoleCreateSubmit": "Rolle erstellen", "accessRoleCreateSubmit": "Rolle erstellen",
"accessRoleCreated": "Rolle erstellt", "accessRoleCreated": "Rolle erstellt",
"accessRoleCreatedDescription": "Die Rolle wurde erfolgreich erstellt.", "accessRoleCreatedDescription": "Die Rolle wurde erfolgreich erstellt.",
"accessRoleErrorCreate": "Fehler beim Erstellen der Rolle", "accessRoleErrorCreate": "Fehler beim Erstellen der Rolle",
"accessRoleErrorCreateDescription": "Beim Erstellen der Rolle ist ein Fehler aufgetreten.", "accessRoleErrorCreateDescription": "Beim Erstellen der Rolle ist ein Fehler aufgetreten.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Rolle aktualisieren",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Rolle aktualisiert",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Die Rolle wurde erfolgreich aktualisiert.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Genehmigung bearbeitet",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Entscheidung für Genehmigungsanfrage setzen.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Entscheidung für Genehmigungsanfrage ablehnen.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Fehler beim Aktualisieren der Rolle",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Beim Aktualisieren der Rolle ist ein Fehler aufgetreten.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Genehmigung konnte nicht verarbeitet werden",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Bei der Bearbeitung der Genehmigung ist ein Fehler aufgetreten.",
"accessRoleErrorNewRequired": "Neue Rolle ist erforderlich", "accessRoleErrorNewRequired": "Neue Rolle ist erforderlich",
"accessRoleErrorRemove": "Fehler beim Entfernen der Rolle", "accessRoleErrorRemove": "Fehler beim Entfernen der Rolle",
"accessRoleErrorRemoveDescription": "Beim Entfernen der Rolle ist ein Fehler aufgetreten.", "accessRoleErrorRemoveDescription": "Beim Entfernen der Rolle ist ein Fehler aufgetreten.",
"accessRoleName": "Rollenname", "accessRoleName": "Rollenname",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Du bist dabei die Rolle `{name}` zu löschen. Du kannst diese Aktion nicht rückgängig machen.",
"accessRoleRemove": "Rolle entfernen", "accessRoleRemove": "Rolle entfernen",
"accessRoleRemoveDescription": "Eine Rolle aus der Organisation entfernen", "accessRoleRemoveDescription": "Eine Rolle aus der Organisation entfernen",
"accessRoleRemoveSubmit": "Rolle entfernen", "accessRoleRemoveSubmit": "Rolle entfernen",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Anzahl der Standorte erhöhen", "sitestCountIncrease": "Anzahl der Standorte erhöhen",
"idpManage": "Identitätsanbieter verwalten", "idpManage": "Identitätsanbieter verwalten",
"idpManageDescription": "Identitätsanbieter im System anzeigen und verwalten", "idpManageDescription": "Identitätsanbieter im System anzeigen und verwalten",
"idpGlobalModeBanner": "Identitätsanbieter (IdPs) pro Organisation sind auf diesem Server deaktiviert. Es verwendet globale IdPs (geteilt über alle Organisationen). Verwalten Sie globale IdPs im <adminPanelLink>Admin-Panel</adminPanelLink>. Um IdPs pro Organisation zu aktivieren, bearbeiten Sie die Server-Konfiguration und setzen Sie den IdP-Modus auf org. <configDocsLink>Siehe Dokumentation</configDocsLink>. Wenn Sie weiterhin globale IdPs verwenden und diese in den Organisationseinstellungen verschwinden lassen wollen, setzen Sie den Modus explizit auf global in der Konfiguration.",
"idpGlobalModeBannerUpgradeRequired": "Identitätsanbieter (IdPs) pro Organisation sind auf diesem Server deaktiviert. Es verwendet globale IdPs (geteilt in allen Organisationen). Globale IdPs im <adminPanelLink>Admin-Panel</adminPanelLink>verwalten. Um Identitätsanbieter pro Organisation nutzen zu können, müssen Sie zur Enterprise Edition upgraden.",
"idpGlobalModeBannerLicenseRequired": "Identitätsanbieter (IdPs) pro Organisation sind auf diesem Server deaktiviert. Es verwendet globale IdPs (geteilt in allen Organisationen). Globale IdPs im <adminPanelLink>Admin-Panel</adminPanelLink>verwalten. Um Identitätsanbieter pro Organisation zu verwenden, ist eine Enterprise-Lizenz erforderlich.",
"idpDeletedDescription": "Identitätsanbieter erfolgreich gelöscht", "idpDeletedDescription": "Identitätsanbieter erfolgreich gelöscht",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Sind Sie sicher, dass Sie den Identitätsanbieter dauerhaft löschen möchten?", "idpQuestionRemove": "Sind Sie sicher, dass Sie den Identitätsanbieter dauerhaft löschen möchten?",
@@ -900,7 +908,7 @@
"inviteAlready": "Sieht aus, als wären Sie eingeladen worden!", "inviteAlready": "Sieht aus, als wären Sie eingeladen worden!",
"inviteAlreadyDescription": "Um die Einladung anzunehmen, müssen Sie sich einloggen oder ein Konto erstellen.", "inviteAlreadyDescription": "Um die Einladung anzunehmen, müssen Sie sich einloggen oder ein Konto erstellen.",
"signupQuestion": "Haben Sie bereits ein Konto?", "signupQuestion": "Haben Sie bereits ein Konto?",
"login": "Log In", "login": "Anmelden",
"resourceNotFound": "Ressource nicht gefunden", "resourceNotFound": "Ressource nicht gefunden",
"resourceNotFoundDescription": "Die Ressource, auf die Sie zugreifen möchten, existiert nicht.", "resourceNotFoundDescription": "Die Ressource, auf die Sie zugreifen möchten, existiert nicht.",
"pincodeRequirementsLength": "PIN muss genau 6 Ziffern lang sein", "pincodeRequirementsLength": "PIN muss genau 6 Ziffern lang sein",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Diese Organisation erfordert, dass Sie Ihr Passwort alle {maxDays} Tage ändern.", "passwordExpiryDescription": "Diese Organisation erfordert, dass Sie Ihr Passwort alle {maxDays} Tage ändern.",
"changePasswordNow": "Passwort jetzt ändern", "changePasswordNow": "Passwort jetzt ändern",
"pincodeAuth": "Authentifizierungscode", "pincodeAuth": "Authentifizierungscode",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Code einreichen",
"passwordResetSubmit": "Zurücksetzung anfordern", "passwordResetSubmit": "Zurücksetzung anfordern",
"passwordResetAlreadyHaveCode": "Code eingeben", "passwordResetAlreadyHaveCode": "Code eingeben",
"passwordResetSmtpRequired": "Bitte kontaktieren Sie Ihren Administrator", "passwordResetSmtpRequired": "Bitte kontaktieren Sie Ihren Administrator",
"passwordResetSmtpRequiredDescription": "Zum Zurücksetzen Ihres Passworts ist ein Passwort erforderlich. Bitte wenden Sie sich an Ihren Administrator.", "passwordResetSmtpRequiredDescription": "Zum Zurücksetzen Ihres Passworts ist ein Passwort erforderlich. Bitte wenden Sie sich an Ihren Administrator.",
"passwordBack": "Zurück zum Passwort", "passwordBack": "Zurück zum Passwort",
"loginBack": "Go back to main login page", "loginBack": "Zurück zur Haupt-Login-Seite",
"signup": "Registrieren", "signup": "Registrieren",
"loginStart": "Melden Sie sich an, um zu beginnen", "loginStart": "Melden Sie sich an, um zu beginnen",
"idpOidcTokenValidating": "OIDC-Token wird validiert", "idpOidcTokenValidating": "OIDC-Token wird validiert",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "IDP-Organisation aktualisieren", "actionUpdateIdpOrg": "IDP-Organisation aktualisieren",
"actionCreateClient": "Client erstellen", "actionCreateClient": "Client erstellen",
"actionDeleteClient": "Client löschen", "actionDeleteClient": "Client löschen",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Client archivieren",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Client dearchivieren",
"actionBlockClient": "Block Client", "actionBlockClient": "Klient sperren",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Client entsperren",
"actionUpdateClient": "Client aktualisieren", "actionUpdateClient": "Client aktualisieren",
"actionListClients": "Clients auflisten", "actionListClients": "Clients auflisten",
"actionGetClient": "Clients abrufen", "actionGetClient": "Clients abrufen",
@@ -1164,14 +1172,14 @@
"searchProgress": "Suche...", "searchProgress": "Suche...",
"create": "Erstellen", "create": "Erstellen",
"orgs": "Organisationen", "orgs": "Organisationen",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut.",
"loginRequiredForDevice": "Anmeldung ist für Ihr Gerät erforderlich.", "loginRequiredForDevice": "Anmeldung ist für Ihr Gerät erforderlich.",
"passwordForgot": "Passwort vergessen?", "passwordForgot": "Passwort vergessen?",
"otpAuth": "Zwei-Faktor-Authentifizierung", "otpAuth": "Zwei-Faktor-Authentifizierung",
"otpAuthDescription": "Geben Sie den Code aus Ihrer Authenticator-App oder einen Ihrer einmaligen Backup-Codes ein.", "otpAuthDescription": "Geben Sie den Code aus Ihrer Authenticator-App oder einen Ihrer einmaligen Backup-Codes ein.",
"otpAuthSubmit": "Code absenden", "otpAuthSubmit": "Code absenden",
"idpContinue": "Oder weiter mit", "idpContinue": "Oder weiter mit",
"otpAuthBack": "Back to Password", "otpAuthBack": "Zurück zum Passwort",
"navbar": "Navigationsmenü", "navbar": "Navigationsmenü",
"navbarDescription": "Hauptnavigationsmenü für die Anwendung", "navbarDescription": "Hauptnavigationsmenü für die Anwendung",
"navbarDocsLink": "Dokumentation", "navbarDocsLink": "Dokumentation",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Übersicht", "sidebarOverview": "Übersicht",
"sidebarHome": "Zuhause", "sidebarHome": "Zuhause",
"sidebarSites": "Standorte", "sidebarSites": "Standorte",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Genehmigungsanfragen",
"sidebarResources": "Ressourcen", "sidebarResources": "Ressourcen",
"sidebarProxyResources": "Öffentlich", "sidebarProxyResources": "Öffentlich",
"sidebarClientResources": "Privat", "sidebarClientResources": "Privat",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Identitätsanbieter", "sidebarIdentityProviders": "Identitätsanbieter",
"sidebarLicense": "Lizenz", "sidebarLicense": "Lizenz",
"sidebarClients": "Clients", "sidebarClients": "Clients",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Benutzer-Geräte",
"sidebarMachineClients": "Maschinen", "sidebarMachineClients": "Maschinen",
"sidebarDomains": "Domänen", "sidebarDomains": "Domänen",
"sidebarGeneral": "Verwalten", "sidebarGeneral": "Verwalten",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Beim Erstellen des Server-Admin-Kontos ist ein Fehler aufgetreten.", "setupErrorCreateAdmin": "Beim Erstellen des Server-Admin-Kontos ist ein Fehler aufgetreten.",
"certificateStatus": "Zertifikatsstatus", "certificateStatus": "Zertifikatsstatus",
"loading": "Laden", "loading": "Laden",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Analytik wird geladen",
"restart": "Neustart", "restart": "Neustart",
"domains": "Domänen", "domains": "Domänen",
"domainsDescription": "Erstellen und verwalten der in der Organisation verfügbaren Domänen", "domainsDescription": "Erstellen und verwalten der in der Organisation verfügbaren Domänen",
@@ -1336,7 +1344,7 @@
"refreshError": "Datenaktualisierung fehlgeschlagen", "refreshError": "Datenaktualisierung fehlgeschlagen",
"verified": "Verifiziert", "verified": "Verifiziert",
"pending": "Ausstehend", "pending": "Ausstehend",
"pendingApproval": "Pending Approval", "pendingApproval": "Ausstehende Genehmigung",
"sidebarBilling": "Abrechnung", "sidebarBilling": "Abrechnung",
"billing": "Abrechnung", "billing": "Abrechnung",
"orgBillingDescription": "Zahlungsinformationen und Abonnements verwalten", "orgBillingDescription": "Zahlungsinformationen und Abonnements verwalten",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Übersicht über Nutzungsgrenzen", "billingUsageLimitsOverview": "Übersicht über Nutzungsgrenzen",
"billingMonitorUsage": "Überwachen Sie Ihren Verbrauch im Vergleich zu konfigurierten Grenzwerten. Wenn Sie eine Erhöhung der Limits benötigen, kontaktieren Sie uns bitte support@pangolin.net.", "billingMonitorUsage": "Überwachen Sie Ihren Verbrauch im Vergleich zu konfigurierten Grenzwerten. Wenn Sie eine Erhöhung der Limits benötigen, kontaktieren Sie uns bitte support@pangolin.net.",
"billingDataUsage": "Datenverbrauch", "billingDataUsage": "Datenverbrauch",
"billingOnlineTime": "Online-Zeit der Seite", "billingSites": "Seiten",
"billingUsers": "Aktive Benutzer", "billingUsers": "Benutzergeräte",
"billingDomains": "Aktive Domains", "billingDomains": "Domänen",
"billingRemoteExitNodes": "Aktive selbstgehostete Nodes", "billingRemoteExitNodes": "Entfernte Knoten",
"billingNoLimitConfigured": "Kein Limit konfiguriert", "billingNoLimitConfigured": "Kein Limit konfiguriert",
"billingEstimatedPeriod": "Geschätzter Abrechnungszeitraum", "billingEstimatedPeriod": "Geschätzter Abrechnungszeitraum",
"billingIncludedUsage": "Inklusive Nutzung", "billingIncludedUsage": "Inklusive Nutzung",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Fehler beim Abrufen der Portal-URL", "billingFailedToGetPortalUrl": "Fehler beim Abrufen der Portal-URL",
"billingPortalError": "Portalfehler", "billingPortalError": "Portalfehler",
"billingDataUsageInfo": "Wenn Sie mit der Cloud verbunden sind, werden alle Daten über Ihre sicheren Tunnel belastet. Dies schließt eingehenden und ausgehenden Datenverkehr über alle Ihre Websites ein. Wenn Sie Ihr Limit erreichen, werden Ihre Seiten die Verbindung trennen, bis Sie Ihr Paket upgraden oder die Nutzung verringern. Daten werden nicht belastet, wenn Sie Knoten verwenden.", "billingDataUsageInfo": "Wenn Sie mit der Cloud verbunden sind, werden alle Daten über Ihre sicheren Tunnel belastet. Dies schließt eingehenden und ausgehenden Datenverkehr über alle Ihre Websites ein. Wenn Sie Ihr Limit erreichen, werden Ihre Seiten die Verbindung trennen, bis Sie Ihr Paket upgraden oder die Nutzung verringern. Daten werden nicht belastet, wenn Sie Knoten verwenden.",
"billingOnlineTimeInfo": "Sie werden belastet, abhängig davon, wie lange Ihre Seiten mit der Cloud verbunden bleiben. Zum Beispiel 44.640 Minuten entspricht einer Site, die 24 Stunden am Tag des Monats läuft. Wenn Sie Ihr Limit erreichen, werden Ihre Seiten die Verbindung trennen, bis Sie Ihr Paket upgraden oder die Nutzung verringern. Die Zeit wird nicht belastet, wenn Sie Knoten verwenden.", "billingSInfo": "Anzahl der Sites die Sie verwenden können",
"billingUsersInfo": "Sie werden für jeden Benutzer in der Organisation berechnet. Die Abrechnung wird täglich anhand der Anzahl der aktiven Benutzerkonten in Ihrer Org berechnet.", "billingUsersInfo": "Wie viele Benutzer Sie verwenden können",
"billingDomainInfo": "Sie werden für jede Domain in der Organisation berechnet. Die Abrechnung wird täglich anhand der Anzahl der aktiven Domain-Konten in Ihrer Org berechnet.", "billingDomainInfo": "Wie viele Domains Sie verwenden können",
"billingRemoteExitNodesInfo": "Sie werden für jeden verwalteten Knoten in der Organisation berechnet. Die Abrechnung wird täglich anhand der Anzahl der aktiven verwalteten Knoten in Ihrer Org berechnet.", "billingRemoteExitNodesInfo": "Wie viele entfernte Knoten Sie verwenden können",
"billingLicenseKeys": "Lizenzschlüssel",
"billingLicenseKeysDescription": "Verwalten Sie Ihre Lizenzschlüssel Abonnements",
"billingLicenseSubscription": "Lizenzabonnement",
"billingInactive": "Inaktiv",
"billingLicenseItem": "Lizenz-Element",
"billingQuantity": "Menge",
"billingTotal": "gesamt",
"billingModifyLicenses": "Lizenzabonnement ändern",
"domainNotFound": "Domain nicht gefunden", "domainNotFound": "Domain nicht gefunden",
"domainNotFoundDescription": "Diese Ressource ist deaktiviert, weil die Domain nicht mehr in unserem System existiert. Bitte setzen Sie eine neue Domain für diese Ressource.", "domainNotFoundDescription": "Diese Ressource ist deaktiviert, weil die Domain nicht mehr in unserem System existiert. Bitte setzen Sie eine neue Domain für diese Ressource.",
"failed": "Fehlgeschlagen", "failed": "Fehlgeschlagen",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Sicherheitsschlüssel erfolgreich entfernt", "securityKeyRemoveSuccess": "Sicherheitsschlüssel erfolgreich entfernt",
"securityKeyRemoveError": "Fehler beim Entfernen des Sicherheitsschlüssels", "securityKeyRemoveError": "Fehler beim Entfernen des Sicherheitsschlüssels",
"securityKeyLoadError": "Fehler beim Laden der Sicherheitsschlüssel", "securityKeyLoadError": "Fehler beim Laden der Sicherheitsschlüssel",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Sicherheitsschlüssel verwenden",
"securityKeyAuthError": "Fehler bei der Authentifizierung mit Sicherheitsschlüssel", "securityKeyAuthError": "Fehler bei der Authentifizierung mit Sicherheitsschlüssel",
"securityKeyRecommendation": "Erwägen Sie die Registrierung eines weiteren Sicherheitsschlüssels auf einem anderen Gerät, um sicherzustellen, dass Sie sich nicht aus Ihrem Konto aussperren.", "securityKeyRecommendation": "Erwägen Sie die Registrierung eines weiteren Sicherheitsschlüssels auf einem anderen Gerät, um sicherzustellen, dass Sie sich nicht aus Ihrem Konto aussperren.",
"registering": "Registrierung...", "registering": "Registrierung...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Portnummer ist für nicht-HTTP-Ressourcen erforderlich", "resourcePortRequired": "Portnummer ist für nicht-HTTP-Ressourcen erforderlich",
"resourcePortNotAllowed": "Portnummer sollte für HTTP-Ressourcen nicht gesetzt werden", "resourcePortNotAllowed": "Portnummer sollte für HTTP-Ressourcen nicht gesetzt werden",
"billingPricingCalculatorLink": "Preisrechner", "billingPricingCalculatorLink": "Preisrechner",
"billingYourPlan": "Ihr Plan",
"billingViewOrModifyPlan": "Zeige oder ändere dein aktuelles Paket",
"billingViewPlanDetails": "Plan Details anzeigen",
"billingUsageAndLimits": "Nutzung und Einschränkungen",
"billingViewUsageAndLimits": "Schau dir die Grenzen und die aktuelle Nutzung deines Plans an",
"billingCurrentUsage": "Aktuelle Nutzung",
"billingMaximumLimits": "Maximale Grenzen",
"billingRemoteNodes": "Entfernte Knoten",
"billingUnlimited": "Unbegrenzt",
"billingPaidLicenseKeys": "Bezahlte Lizenzschlüssel",
"billingManageLicenseSubscription": "Verwalten Sie Ihr Abonnement für kostenpflichtige selbstgehostete Lizenzschlüssel",
"billingCurrentKeys": "Aktuelle Tasten",
"billingModifyCurrentPlan": "Aktuelles Paket ändern",
"billingConfirmUpgrade": "Upgrade bestätigen",
"billingConfirmDowngrade": "Downgrade bestätigen",
"billingConfirmUpgradeDescription": "Sie sind dabei, Ihr Paket zu aktualisieren. Schauen Sie sich die neuen Limits und Preise unten an.",
"billingConfirmDowngradeDescription": "Sie sind dabei, Ihren Plan herunterzustufen. Überprüfen Sie die neuen Limits und Preise unten.",
"billingPlanIncludes": "Plan beinhaltet",
"billingProcessing": "Verarbeitung...",
"billingConfirmUpgradeButton": "Upgrade bestätigen",
"billingConfirmDowngradeButton": "Downgrade bestätigen",
"billingLimitViolationWarning": "Nutzung überschreitet neue Plan-Grenzen",
"billingLimitViolationDescription": "Ihre aktuelle Nutzung überschreitet die Grenzen dieses Plans. Nach dem Downgrade werden alle Aktionen deaktiviert, bis Sie die Nutzung innerhalb der neuen Grenzen reduzieren. Bitte überprüfen Sie die Funktionen unten, die derzeit über den Grenzen liegen. Grenzwerte verletzen:",
"billingFeatureLossWarning": "Verfügbarkeitshinweis",
"billingFeatureLossDescription": "Durch Herabstufung werden Funktionen, die im neuen Paket nicht verfügbar sind, automatisch deaktiviert. Einige Einstellungen und Konfigurationen können verloren gehen. Bitte überprüfen Sie die Preismatrix um zu verstehen, welche Funktionen nicht mehr verfügbar sein werden.",
"billingUsageExceedsLimit": "Aktuelle Nutzung ({current}) überschreitet das Limit ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Ich stimme den", "IAgreeToThe": "Ich stimme den",
"termsOfService": "Nutzungsbedingungen zu", "termsOfService": "Nutzungsbedingungen zu",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Gesunder Intervall", "IntervalSeconds": "Gesunder Intervall",
"timeoutSeconds": "Timeout (Sek.)", "timeoutSeconds": "Timeout (Sek.)",
"timeIsInSeconds": "Zeit ist in Sekunden", "timeIsInSeconds": "Zeit ist in Sekunden",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Gerätegenehmigungen erforderlich",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Benutzer mit dieser Rolle benötigen neue Geräte, die von einem Administrator genehmigt wurden, bevor sie sich verbinden und auf Ressourcen zugreifen können.",
"retryAttempts": "Wiederholungsversuche", "retryAttempts": "Wiederholungsversuche",
"expectedResponseCodes": "Erwartete Antwortcodes", "expectedResponseCodes": "Erwartete Antwortcodes",
"expectedResponseCodesDescription": "HTTP-Statuscode, der einen gesunden Zustand anzeigt. Wenn leer gelassen, wird 200-300 als gesund angesehen.", "expectedResponseCodesDescription": "HTTP-Statuscode, der einen gesunden Zustand anzeigt. Wenn leer gelassen, wird 200-300 als gesund angesehen.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Keine internen Ressourcen gefunden.", "resourcesTableNoInternalResourcesFound": "Keine internen Ressourcen gefunden.",
"resourcesTableDestination": "Ziel", "resourcesTableDestination": "Ziel",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Alias-Adresse",
"resourcesTableAliasAddressInfo": "Diese Adresse ist Teil des Utility-Subnetzes der Organisation. Sie wird verwendet, um Alias-Einträge mit interner DNS-Auflösung aufzulösen.",
"resourcesTableClients": "Clients", "resourcesTableClients": "Clients",
"resourcesTableAndOnlyAccessibleInternally": "und sind nur intern zugänglich, wenn mit einem Client verbunden.", "resourcesTableAndOnlyAccessibleInternally": "und sind nur intern zugänglich, wenn mit einem Client verbunden.",
"resourcesTableNoTargets": "Keine Ziele", "resourcesTableNoTargets": "Keine Ziele",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Wähle deinen Identitätsanbieter um fortzufahren", "orgAuthChooseIdpDescription": "Wähle deinen Identitätsanbieter um fortzufahren",
"orgAuthNoIdpConfigured": "Diese Organisation hat keine Identitätsanbieter konfiguriert. Sie können sich stattdessen mit Ihrer Pangolin-Identität anmelden.", "orgAuthNoIdpConfigured": "Diese Organisation hat keine Identitätsanbieter konfiguriert. Sie können sich stattdessen mit Ihrer Pangolin-Identität anmelden.",
"orgAuthSignInWithPangolin": "Mit Pangolin anmelden", "orgAuthSignInWithPangolin": "Mit Pangolin anmelden",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Bei einer Organisation anmelden",
"orgAuthSelectOrgTitle": "Organisations-Anmeldung", "orgAuthSelectOrgTitle": "Organisations-Anmeldung",
"orgAuthSelectOrgDescription": "Geben Sie Ihre Organisations-ID ein, um fortzufahren", "orgAuthSelectOrgDescription": "Geben Sie Ihre Organisations-ID ein, um fortzufahren",
"orgAuthOrgIdPlaceholder": "Ihre Organisation", "orgAuthOrgIdPlaceholder": "Ihre Organisation",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Zurück zum Standard Login", "orgAuthBackToSignIn": "Zurück zum Standard Login",
"orgAuthNoAccount": "Sie haben noch kein Konto?", "orgAuthNoAccount": "Sie haben noch kein Konto?",
"subscriptionRequiredToUse": "Um diese Funktion nutzen zu können, ist ein Abonnement erforderlich.", "subscriptionRequiredToUse": "Um diese Funktion nutzen zu können, ist ein Abonnement erforderlich.",
"mustUpgradeToUse": "Sie müssen Ihr Abonnement aktualisieren, um diese Funktion nutzen zu können.",
"subscriptionRequiredTierToUse": "Diese Funktion erfordert <tierLink>{tier}</tierLink> oder höher.",
"upgradeToTierToUse": "Upgrade auf <tierLink>{tier}</tierLink> oder höher, um diese Funktion zu nutzen.",
"subscriptionTierTier1": "Zuhause",
"subscriptionTierTier2": "Team",
"subscriptionTierTier3": "Geschäftlich",
"subscriptionTierEnterprise": "Firma",
"idpDisabled": "Identitätsanbieter sind deaktiviert.", "idpDisabled": "Identitätsanbieter sind deaktiviert.",
"orgAuthPageDisabled": "Organisations-Authentifizierungsseite ist deaktiviert.", "orgAuthPageDisabled": "Organisations-Authentifizierungsseite ist deaktiviert.",
"domainRestartedDescription": "Domain-Verifizierung erfolgreich neu gestartet", "domainRestartedDescription": "Domain-Verifizierung erfolgreich neu gestartet",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Lizenz erhalten",
"description": "Wählen Sie einen Plan und teilen Sie uns mit, wie Sie Pangolin verwenden möchten.",
"chooseTier": "Wählen Sie Ihren Plan",
"viewPricingLink": "Siehe Preise, Funktionen und Limits",
"tiers": {
"starter": {
"title": "Starter",
"description": "Enterprise Features, 25 Benutzer, 25 Sites und Community-Unterstützung."
},
"scale": {
"title": "Maßstab",
"description": "Enterprise Features, 50 Benutzer, 50 Sites und Prioritätsunterstützung."
}
},
"personalUseOnly": "Nur persönliche Nutzung (kostenlose Lizenz — keine Kasse)",
"buttons": {
"continueToCheckout": "Weiter zur Kasse"
},
"toasts": {
"checkoutError": {
"title": "Checkout-Fehler",
"description": "Kasse konnte nicht gestartet werden. Bitte versuchen Sie es erneut."
}
}
},
"priority": "Priorität", "priority": "Priorität",
"priorityDescription": "Die Routen mit höherer Priorität werden zuerst ausgewertet. Priorität = 100 bedeutet automatische Bestellung (Systementscheidung). Verwenden Sie eine andere Nummer, um manuelle Priorität zu erzwingen.", "priorityDescription": "Die Routen mit höherer Priorität werden zuerst ausgewertet. Priorität = 100 bedeutet automatische Bestellung (Systementscheidung). Verwenden Sie eine andere Nummer, um manuelle Priorität zu erzwingen.",
"instanceName": "Instanzname", "instanceName": "Instanzname",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Ende des folgenden Jahres", "logRetentionEndOfFollowingYear": "Ende des folgenden Jahres",
"actionLogsDescription": "Verlauf der in dieser Organisation durchgeführten Aktionen anzeigen", "actionLogsDescription": "Verlauf der in dieser Organisation durchgeführten Aktionen anzeigen",
"accessLogsDescription": "Zugriffsauth-Anfragen für Ressourcen in dieser Organisation anzeigen", "accessLogsDescription": "Zugriffsauth-Anfragen für Ressourcen in dieser Organisation anzeigen",
"licenseRequiredToUse": "Um diese Funktion nutzen zu können, ist eine Enterprise-Lizenz erforderlich.", "licenseRequiredToUse": "Um diese Funktion nutzen zu können, ist eine <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> Lizenz erforderlich. Diese Funktion ist auch in der <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink> verfügbar.",
"ossEnterpriseEditionRequired": "Um diese Funktion nutzen zu können, ist die <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> erforderlich. Diese Funktion ist auch in der <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink> verfügbar.",
"certResolver": "Zertifikatsauflöser", "certResolver": "Zertifikatsauflöser",
"certResolverDescription": "Wählen Sie den Zertifikatslöser aus, der für diese Ressource verwendet werden soll.", "certResolverDescription": "Wählen Sie den Zertifikatslöser aus, der für diese Ressource verwendet werden soll.",
"selectCertResolver": "Zertifikatsauflöser auswählen", "selectCertResolver": "Zertifikatsauflöser auswählen",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Code muss 9 Zeichen lang sein (z.B. A1AJ-N5JD)", "deviceCodeInvalidFormat": "Code muss 9 Zeichen lang sein (z.B. A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Ungültiger oder abgelaufener Code", "deviceCodeInvalidOrExpired": "Ungültiger oder abgelaufener Code",
"deviceCodeVerifyFailed": "Fehler beim Überprüfen des Gerätecodes", "deviceCodeVerifyFailed": "Fehler beim Überprüfen des Gerätecodes",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Überprüfe Gerätecode...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Geräteautorisierung wird überprüft...",
"signedInAs": "Angemeldet als", "signedInAs": "Angemeldet als",
"deviceCodeEnterPrompt": "Geben Sie den auf dem Gerät angezeigten Code ein", "deviceCodeEnterPrompt": "Geben Sie den auf dem Gerät angezeigten Code ein",
"continue": "Weiter", "continue": "Weiter",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Nicht du? Verwenden Sie ein anderes Konto.", "deviceLoginUseDifferentAccount": "Nicht du? Verwenden Sie ein anderes Konto.",
"deviceLoginDeviceRequestingAccessToAccount": "Ein Gerät fordert Zugriff auf dieses Konto an.", "deviceLoginDeviceRequestingAccessToAccount": "Ein Gerät fordert Zugriff auf dieses Konto an.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Wählen Sie eine Authentifizierungsmethode aus, um fortzufahren.",
"noData": "Keine Daten", "noData": "Keine Daten",
"machineClients": "Maschinen-Clients", "machineClients": "Maschinen-Clients",
"install": "Installieren", "install": "Installieren",
@@ -2445,69 +2523,92 @@
"deviceArchiveConfirm": "Gerät archivieren", "deviceArchiveConfirm": "Gerät archivieren",
"archiveDevice": "Gerät archivieren", "archiveDevice": "Gerät archivieren",
"archive": "Archiv", "archive": "Archiv",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Gerät nicht archiviert",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Das Gerät wurde erfolgreich deinstalliert.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Fehler beim Entarchivieren des Geräts",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Fehler beim Entfernen des Geräts",
"unarchive": "Unarchive", "unarchive": "Archivieren",
"archiveClient": "Archive Client", "archiveClient": "Client archivieren",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Sind Sie sicher, dass Sie diesen Client archivieren möchten?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Der Client wird archiviert und aus der Liste Ihrer aktiven Clients entfernt.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Client archivieren",
"blockClient": "Block Client", "blockClient": "Klient sperren",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Sind Sie sicher, dass Sie diesen Client blockieren möchten?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Das Gerät wird gezwungen, die Verbindung zu trennen, wenn es gerade verbunden ist. Sie können das Gerät später entsperren.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Klient sperren",
"active": "Active", "active": "Aktiv",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Benutzername oder E-Mail",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Wählen Sie Ihre Organisation",
"signInTo": "Log in in to", "signInTo": "Einloggen in",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Mit Passwort fortfahren",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Keine Authentifizierungsmethoden für diese Organisation verfügbar.",
"enterPassword": "Enter your password", "enterPassword": "Geben Sie Ihr Passwort ein",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Geben Sie den Code aus Ihrer Authentifizierungs-App ein",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Bitte verwenden Sie Ihren Sicherheitsschlüssel zum Anmelden.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Benötigen Sie ein anderes Konto?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Indem Sie auf die Buttons unten klicken, bestätigen Sie, dass Sie gelesen haben, verstehen, und stimmen den <termsOfService>Nutzungsbedingungen</termsOfService> und <privacyPolicy>Datenschutzrichtlinien</privacyPolicy> zu.",
"termsOfService": "Terms of Service", "termsOfService": "Nutzungsbedingungen",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Datenschutzerklärung",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Kein Benutzer mit diesem Benutzernamen gefunden.",
"verify": "Verify", "verify": "Überprüfen",
"signIn": "Sign In", "signIn": "Anmelden",
"forgotPassword": "Forgot password?", "forgotPassword": "Passwort vergessen?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Wenn Sie sich vorher angemeldet haben, können Sie Ihren Benutzernamen oder Ihre E-Mail-Adresse eingeben, um sich stattdessen beim Identifikationsprovider Ihrer Organisation zu authentifizieren. Es ist einfacher!",
"continueAnyway": "Continue anyway", "continueAnyway": "Trotzdem fortfahren",
"dontShowAgain": "Don't show again", "dontShowAgain": "Nicht mehr anzeigen",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Wussten Sie schon?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Versucht sich anzumelden?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Versuchen Sie, sich über den Identitätsanbieter Ihrer Organisation anzumelden?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Melden Sie sich an oder melden Sie sich stattdessen bei Ihrer Organisation an",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Anderes Konto verwenden",
"logIn": "Log In", "logIn": "Anmelden",
"deviceInformation": "Device Information", "deviceInformation": "Geräteinformationen",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informationen über das Gerät und den Agent",
"platform": "Platform", "deviceSecurity": "Gerätesicherheit",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Informationen zur Gerätesicherheit",
"windowsVersion": "Windows Version", "platform": "Plattform",
"iosVersion": "iOS Version", "macosVersion": "macOS-Version",
"androidVersion": "Android Version", "windowsVersion": "Windows-Version",
"osVersion": "OS Version", "iosVersion": "iOS-Version",
"kernelVersion": "Kernel Version", "androidVersion": "Android-Version",
"deviceModel": "Device Model", "osVersion": "OS-Version",
"serialNumber": "Serial Number", "kernelVersion": "Kernel-Version",
"deviceModel": "Gerätemodell",
"serialNumber": "Seriennummer",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Zuerst gesehen",
"lastSeen": "Last Seen", "lastSeen": "Zuletzt gesehen",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometrie aktiviert",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Festplatte verschlüsselt",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Firewall aktiviert",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Automatische Updates aktiviert",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM verfügbar",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirus aktiviert",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Schutz der Systemintegrität (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Firewall Stealth-Modus",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "AppRüstung",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Geräteinformationen und -einstellungen anzeigen",
"devicePendingApprovalDescription": "Dieses Gerät wartet auf Freigabe",
"deviceBlockedDescription": "Dieses Gerät ist derzeit gesperrt. Es kann keine Verbindung zu anderen Ressourcen herstellen, es sei denn, es entsperrt.",
"unblockClient": "Client entsperren",
"unblockClientDescription": "Das Gerät wurde entsperrt",
"unarchiveClient": "Client dearchivieren",
"unarchiveClientDescription": "Das Gerät wurde nicht archiviert",
"block": "Blockieren",
"unblock": "Entsperren",
"deviceActions": "Geräte-Aktionen",
"deviceActionsDescription": "Gerätestatus und Zugriff verwalten",
"devicePendingApprovalBannerDescription": "Dieses Gerät wartet auf Genehmigung. Es kann sich erst mit Ressourcen verbinden.",
"connected": "Verbunden",
"disconnected": "Verbindung getrennt",
"approvalsEmptyStateTitle": "Gerätezulassungen nicht aktiviert",
"approvalsEmptyStateDescription": "Aktiviere Gerätegenehmigungen für Rollen, um Administratorgenehmigungen zu benötigen, bevor Benutzer neue Geräte verbinden können.",
"approvalsEmptyStateStep1Title": "Gehe zu Rollen",
"approvalsEmptyStateStep1Description": "Navigieren Sie zu den Rolleneinstellungen Ihrer Organisation, um die Gerätefreigaben zu konfigurieren.",
"approvalsEmptyStateStep2Title": "Gerätegenehmigungen aktivieren",
"approvalsEmptyStateStep2Description": "Bearbeite eine Rolle und aktiviere die Option 'Gerätegenehmigung erforderlich'. Benutzer mit dieser Rolle benötigen Administrator-Genehmigung für neue Geräte.",
"approvalsEmptyStatePreviewDescription": "Vorschau: Wenn aktiviert, werden ausstehende Geräteanfragen hier zur Überprüfung angezeigt",
"approvalsEmptyStateButtonText": "Rollen verwalten"
} }
+241 -25
View File
@@ -18,6 +18,8 @@
"componentsMember": "You're a member of {count, plural, =0 {no organization} one {one organization} other {# organizations}}.", "componentsMember": "You're a member of {count, plural, =0 {no organization} one {one organization} other {# organizations}}.",
"componentsInvalidKey": "Invalid or expired license keys detected. Follow license terms to continue using all features.", "componentsInvalidKey": "Invalid or expired license keys detected. Follow license terms to continue using all features.",
"dismiss": "Dismiss", "dismiss": "Dismiss",
"subscriptionViolationMessage": "You're beyond your limits for your current plan. Correct the problem by removing sites, users, or other resources to stay within your plan.",
"subscriptionViolationViewBilling": "View billing",
"componentsLicenseViolation": "License Violation: This server is using {usedSites} sites which exceeds its licensed limit of {maxSites} sites. Follow license terms to continue using all features.", "componentsLicenseViolation": "License Violation: This server is using {usedSites} sites which exceeds its licensed limit of {maxSites} sites. Follow license terms to continue using all features.",
"componentsSupporterMessage": "Thank you for supporting Pangolin as a {tier}!", "componentsSupporterMessage": "Thank you for supporting Pangolin as a {tier}!",
"inviteErrorNotValid": "We're sorry, but it looks like the invite you're trying to access has not been accepted or is no longer valid.", "inviteErrorNotValid": "We're sorry, but it looks like the invite you're trying to access has not been accepted or is no longer valid.",
@@ -55,7 +57,10 @@
"siteDescription": "Create and manage sites to enable connectivity to private networks", "siteDescription": "Create and manage sites to enable connectivity to private networks",
"sitesBannerTitle": "Connect Any Network", "sitesBannerTitle": "Connect Any Network",
"sitesBannerDescription": "A site is a connection to a remote network that allows Pangolin to provide access to resources, whether public or private, to users anywhere. Install the site network connector (Newt) anywhere you can run a binary or container to establish the connection.", "sitesBannerDescription": "A site is a connection to a remote network that allows Pangolin to provide access to resources, whether public or private, to users anywhere. Install the site network connector (Newt) anywhere you can run a binary or container to establish the connection.",
"sitesBannerButtonText": "Install Site", "sitesBannerButtonText": "Install Site Connector",
"approvalsBannerTitle": "Approve or Deny Device Access",
"approvalsBannerDescription": "Review and approve or deny device access requests from users. When device approvals are required, users must get admin approval before their devices can connect to your organization's resources.",
"approvalsBannerButtonText": "Learn More",
"siteCreate": "Create Site", "siteCreate": "Create Site",
"siteCreateDescription2": "Follow the steps below to create and connect a new site", "siteCreateDescription2": "Follow the steps below to create and connect a new site",
"siteCreateDescription": "Create a new site to start connecting resources", "siteCreateDescription": "Create a new site to start connecting resources",
@@ -76,8 +81,8 @@
"siteConfirmCopy": "I have copied the config", "siteConfirmCopy": "I have copied the config",
"searchSitesProgress": "Search sites...", "searchSitesProgress": "Search sites...",
"siteAdd": "Add Site", "siteAdd": "Add Site",
"siteInstallNewt": "Install Newt", "siteInstallNewt": "Install Site",
"siteInstallNewtDescription": "Get Newt running on your system", "siteInstallNewtDescription": "Install the site connector for your system",
"WgConfiguration": "WireGuard Configuration", "WgConfiguration": "WireGuard Configuration",
"WgConfigurationDescription": "Use the following configuration to connect to the network", "WgConfigurationDescription": "Use the following configuration to connect to the network",
"operatingSystem": "Operating System", "operatingSystem": "Operating System",
@@ -257,6 +262,8 @@
"accessRolesSearch": "Search roles...", "accessRolesSearch": "Search roles...",
"accessRolesAdd": "Add Role", "accessRolesAdd": "Add Role",
"accessRoleDelete": "Delete Role", "accessRoleDelete": "Delete Role",
"accessApprovalsManage": "Manage Approvals",
"accessApprovalsDescription": "View and manage pending approvals for access to this organization",
"description": "Description", "description": "Description",
"inviteTitle": "Open Invitations", "inviteTitle": "Open Invitations",
"inviteDescription": "Manage invitations for other users to join the organization", "inviteDescription": "Manage invitations for other users to join the organization",
@@ -450,6 +457,18 @@
"selectDuration": "Select duration", "selectDuration": "Select duration",
"selectResource": "Select Resource", "selectResource": "Select Resource",
"filterByResource": "Filter By Resource", "filterByResource": "Filter By Resource",
"selectApprovalState": "Select Approval State",
"filterByApprovalState": "Filter By Approval State",
"approvalListEmpty": "No approvals",
"approvalState": "Approval State",
"approve": "Approve",
"approved": "Approved",
"denied": "Denied",
"deniedApproval": "Denied Approval",
"all": "All",
"deny": "Deny",
"viewDetails": "View Details",
"requestingNewDeviceApproval": "requested a new device",
"resetFilters": "Reset Filters", "resetFilters": "Reset Filters",
"totalBlocked": "Requests Blocked By Pangolin", "totalBlocked": "Requests Blocked By Pangolin",
"totalRequests": "Total Requests", "totalRequests": "Total Requests",
@@ -729,16 +748,28 @@
"countries": "Countries", "countries": "Countries",
"accessRoleCreate": "Create Role", "accessRoleCreate": "Create Role",
"accessRoleCreateDescription": "Create a new role to group users and manage their permissions.", "accessRoleCreateDescription": "Create a new role to group users and manage their permissions.",
"accessRoleEdit": "Edit Role",
"accessRoleEditDescription": "Edit role information.",
"accessRoleCreateSubmit": "Create Role", "accessRoleCreateSubmit": "Create Role",
"accessRoleCreated": "Role created", "accessRoleCreated": "Role created",
"accessRoleCreatedDescription": "The role has been successfully created.", "accessRoleCreatedDescription": "The role has been successfully created.",
"accessRoleErrorCreate": "Failed to create role", "accessRoleErrorCreate": "Failed to create role",
"accessRoleErrorCreateDescription": "An error occurred while creating the role.", "accessRoleErrorCreateDescription": "An error occurred while creating the role.",
"accessRoleUpdateSubmit": "Update Role",
"accessRoleUpdated": "Role updated",
"accessRoleUpdatedDescription": "The role has been successfully updated.",
"accessApprovalUpdated": "Approval processed",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.",
"accessRoleErrorUpdate": "Failed to update role",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.",
"accessApprovalErrorUpdate": "Failed to process approval",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.",
"accessRoleErrorNewRequired": "New role is required", "accessRoleErrorNewRequired": "New role is required",
"accessRoleErrorRemove": "Failed to remove role", "accessRoleErrorRemove": "Failed to remove role",
"accessRoleErrorRemoveDescription": "An error occurred while removing the role.", "accessRoleErrorRemoveDescription": "An error occurred while removing the role.",
"accessRoleName": "Role Name", "accessRoleName": "Role Name",
"accessRoleQuestionRemove": "You're about to delete the {name} role. You cannot undo this action.", "accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.",
"accessRoleRemove": "Remove Role", "accessRoleRemove": "Remove Role",
"accessRoleRemoveDescription": "Remove a role from the organization", "accessRoleRemoveDescription": "Remove a role from the organization",
"accessRoleRemoveSubmit": "Remove Role", "accessRoleRemoveSubmit": "Remove Role",
@@ -760,6 +791,9 @@
"sitestCountIncrease": "Increase site count", "sitestCountIncrease": "Increase site count",
"idpManage": "Manage Identity Providers", "idpManage": "Manage Identity Providers",
"idpManageDescription": "View and manage identity providers in the system", "idpManageDescription": "View and manage identity providers in the system",
"idpGlobalModeBanner": "Identity providers (IdPs) per organization are disabled on this server. It is using global IdPs (shared across all organizations). Manage global IdPs in the <adminPanelLink>admin panel</adminPanelLink>. To enable IdPs per organization, edit the server config and set IdP mode to org. <configDocsLink>See the docs</configDocsLink>. If you want to continue using global IdPs and make this disappear from the organization settings, explicitly set the mode to global in the config.",
"idpGlobalModeBannerUpgradeRequired": "Identity providers (IdPs) per organization are disabled on this server. It is using global IdPs (shared across all organizations). Manage global IdPs in the <adminPanelLink>admin panel</adminPanelLink>. To use identity providers per organization, you must upgrade to the Enterprise edition.",
"idpGlobalModeBannerLicenseRequired": "Identity providers (IdPs) per organization are disabled on this server. It is using global IdPs (shared across all organizations). Manage global IdPs in the <adminPanelLink>admin panel</adminPanelLink>. To use identity providers per organization, an Enterprise license is required.",
"idpDeletedDescription": "Identity provider deleted successfully", "idpDeletedDescription": "Identity provider deleted successfully",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Are you sure you want to permanently delete the identity provider?", "idpQuestionRemove": "Are you sure you want to permanently delete the identity provider?",
@@ -874,7 +908,7 @@
"inviteAlready": "Looks like you've been invited!", "inviteAlready": "Looks like you've been invited!",
"inviteAlreadyDescription": "To accept the invite, you must log in or create an account.", "inviteAlreadyDescription": "To accept the invite, you must log in or create an account.",
"signupQuestion": "Already have an account?", "signupQuestion": "Already have an account?",
"login": "Log in", "login": "Log In",
"resourceNotFound": "Resource Not Found", "resourceNotFound": "Resource Not Found",
"resourceNotFoundDescription": "The resource you're trying to access does not exist.", "resourceNotFoundDescription": "The resource you're trying to access does not exist.",
"pincodeRequirementsLength": "PIN must be exactly 6 digits", "pincodeRequirementsLength": "PIN must be exactly 6 digits",
@@ -954,13 +988,13 @@
"passwordExpiryDescription": "This organization requires you to change your password every {maxDays} days.", "passwordExpiryDescription": "This organization requires you to change your password every {maxDays} days.",
"changePasswordNow": "Change Password Now", "changePasswordNow": "Change Password Now",
"pincodeAuth": "Authenticator Code", "pincodeAuth": "Authenticator Code",
"pincodeSubmit2": "Submit Code", "pincodeSubmit2": "Submit code",
"passwordResetSubmit": "Request Reset", "passwordResetSubmit": "Request Reset",
"passwordResetAlreadyHaveCode": "Enter Code", "passwordResetAlreadyHaveCode": "Enter Code",
"passwordResetSmtpRequired": "Please contact your administrator", "passwordResetSmtpRequired": "Please contact your administrator",
"passwordResetSmtpRequiredDescription": "A password reset code is required to reset your password. Please contact your administrator for assistance.", "passwordResetSmtpRequiredDescription": "A password reset code is required to reset your password. Please contact your administrator for assistance.",
"passwordBack": "Back to Password", "passwordBack": "Back to Password",
"loginBack": "Go back to log in", "loginBack": "Go back to main login page",
"signup": "Sign up", "signup": "Sign up",
"loginStart": "Log in to get started", "loginStart": "Log in to get started",
"idpOidcTokenValidating": "Validating OIDC token", "idpOidcTokenValidating": "Validating OIDC token",
@@ -1118,6 +1152,10 @@
"actionUpdateIdpOrg": "Update IDP Org", "actionUpdateIdpOrg": "Update IDP Org",
"actionCreateClient": "Create Client", "actionCreateClient": "Create Client",
"actionDeleteClient": "Delete Client", "actionDeleteClient": "Delete Client",
"actionArchiveClient": "Archive Client",
"actionUnarchiveClient": "Unarchive Client",
"actionBlockClient": "Block Client",
"actionUnblockClient": "Unblock Client",
"actionUpdateClient": "Update Client", "actionUpdateClient": "Update Client",
"actionListClients": "List Clients", "actionListClients": "List Clients",
"actionGetClient": "Get Client", "actionGetClient": "Get Client",
@@ -1134,14 +1172,14 @@
"searchProgress": "Search...", "searchProgress": "Search...",
"create": "Create", "create": "Create",
"orgs": "Organizations", "orgs": "Organizations",
"loginError": "An error occurred while logging in", "loginError": "An unexpected error occurred. Please try again.",
"loginRequiredForDevice": "Login is required to authenticate your device.", "loginRequiredForDevice": "Login is required for your device.",
"passwordForgot": "Forgot your password?", "passwordForgot": "Forgot your password?",
"otpAuth": "Two-Factor Authentication", "otpAuth": "Two-Factor Authentication",
"otpAuthDescription": "Enter the code from your authenticator app or one of your single-use backup codes.", "otpAuthDescription": "Enter the code from your authenticator app or one of your single-use backup codes.",
"otpAuthSubmit": "Submit Code", "otpAuthSubmit": "Submit Code",
"idpContinue": "Or continue with", "idpContinue": "Or continue with",
"otpAuthBack": "Back to Log In", "otpAuthBack": "Back to Password",
"navbar": "Navigation Menu", "navbar": "Navigation Menu",
"navbarDescription": "Main navigation menu for the application", "navbarDescription": "Main navigation menu for the application",
"navbarDocsLink": "Documentation", "navbarDocsLink": "Documentation",
@@ -1189,6 +1227,7 @@
"sidebarOverview": "Overview", "sidebarOverview": "Overview",
"sidebarHome": "Home", "sidebarHome": "Home",
"sidebarSites": "Sites", "sidebarSites": "Sites",
"sidebarApprovals": "Approval Requests",
"sidebarResources": "Resources", "sidebarResources": "Resources",
"sidebarProxyResources": "Public", "sidebarProxyResources": "Public",
"sidebarClientResources": "Private", "sidebarClientResources": "Private",
@@ -1205,7 +1244,7 @@
"sidebarIdentityProviders": "Identity Providers", "sidebarIdentityProviders": "Identity Providers",
"sidebarLicense": "License", "sidebarLicense": "License",
"sidebarClients": "Clients", "sidebarClients": "Clients",
"sidebarUserDevices": "Users", "sidebarUserDevices": "User Devices",
"sidebarMachineClients": "Machines", "sidebarMachineClients": "Machines",
"sidebarDomains": "Domains", "sidebarDomains": "Domains",
"sidebarGeneral": "Manage", "sidebarGeneral": "Manage",
@@ -1277,6 +1316,7 @@
"setupErrorCreateAdmin": "An error occurred while creating the server admin account.", "setupErrorCreateAdmin": "An error occurred while creating the server admin account.",
"certificateStatus": "Certificate Status", "certificateStatus": "Certificate Status",
"loading": "Loading", "loading": "Loading",
"loadingAnalytics": "Loading Analytics",
"restart": "Restart", "restart": "Restart",
"domains": "Domains", "domains": "Domains",
"domainsDescription": "Create and manage domains available in the organization", "domainsDescription": "Create and manage domains available in the organization",
@@ -1304,6 +1344,7 @@
"refreshError": "Failed to refresh data", "refreshError": "Failed to refresh data",
"verified": "Verified", "verified": "Verified",
"pending": "Pending", "pending": "Pending",
"pendingApproval": "Pending Approval",
"sidebarBilling": "Billing", "sidebarBilling": "Billing",
"billing": "Billing", "billing": "Billing",
"orgBillingDescription": "Manage billing information and subscriptions", "orgBillingDescription": "Manage billing information and subscriptions",
@@ -1368,10 +1409,10 @@
"billingUsageLimitsOverview": "Usage Limits Overview", "billingUsageLimitsOverview": "Usage Limits Overview",
"billingMonitorUsage": "Monitor your usage against configured limits. If you need limits increased please contact us support@pangolin.net.", "billingMonitorUsage": "Monitor your usage against configured limits. If you need limits increased please contact us support@pangolin.net.",
"billingDataUsage": "Data Usage", "billingDataUsage": "Data Usage",
"billingOnlineTime": "Site Online Time", "billingSites": "Sites",
"billingUsers": "Active Users", "billingUsers": "Users",
"billingDomains": "Active Domains", "billingDomains": "Domains",
"billingRemoteExitNodes": "Active Self-hosted Nodes", "billingRemoteExitNodes": "Remote Nodes",
"billingNoLimitConfigured": "No limit configured", "billingNoLimitConfigured": "No limit configured",
"billingEstimatedPeriod": "Estimated Billing Period", "billingEstimatedPeriod": "Estimated Billing Period",
"billingIncludedUsage": "Included Usage", "billingIncludedUsage": "Included Usage",
@@ -1396,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Failed to get portal URL", "billingFailedToGetPortalUrl": "Failed to get portal URL",
"billingPortalError": "Portal Error", "billingPortalError": "Portal Error",
"billingDataUsageInfo": "You're charged for all data transferred through your secure tunnels when connected to the cloud. This includes both incoming and outgoing traffic across all your sites. When you reach your limit, your sites will disconnect until you upgrade your plan or reduce usage. Data is not charged when using nodes.", "billingDataUsageInfo": "You're charged for all data transferred through your secure tunnels when connected to the cloud. This includes both incoming and outgoing traffic across all your sites. When you reach your limit, your sites will disconnect until you upgrade your plan or reduce usage. Data is not charged when using nodes.",
"billingOnlineTimeInfo": "You're charged based on how long your sites stay connected to the cloud. For example, 44,640 minutes equals one site running 24/7 for a full month. When you reach your limit, your sites will disconnect until you upgrade your plan or reduce usage. Time is not charged when using nodes.", "billingSInfo": "How many sites you can use",
"billingUsersInfo": "You're charged for each user in the organization. Billing is calculated daily based on the number of active user accounts in your org.", "billingUsersInfo": "How many users you can use",
"billingDomainInfo": "You're charged for each domain in the organization. Billing is calculated daily based on the number of active domain accounts in your org.", "billingDomainInfo": "How many domains you can use",
"billingRemoteExitNodesInfo": "You're charged for each managed Node in the organization. Billing is calculated daily based on the number of active managed Nodes in your org.", "billingRemoteExitNodesInfo": "How many remote nodes you can use",
"billingLicenseKeys": "License Keys",
"billingLicenseKeysDescription": "Manage your license key subscriptions",
"billingLicenseSubscription": "License Subscription",
"billingInactive": "Inactive",
"billingLicenseItem": "License Item",
"billingQuantity": "Quantity",
"billingTotal": "total",
"billingModifyLicenses": "Modify License Subscription",
"domainNotFound": "Domain Not Found", "domainNotFound": "Domain Not Found",
"domainNotFoundDescription": "This resource is disabled because the domain no longer exists our system. Please set a new domain for this resource.", "domainNotFoundDescription": "This resource is disabled because the domain no longer exists our system. Please set a new domain for this resource.",
"failed": "Failed", "failed": "Failed",
@@ -1420,7 +1469,7 @@
"securityKeyRemoveSuccess": "Security key removed successfully", "securityKeyRemoveSuccess": "Security key removed successfully",
"securityKeyRemoveError": "Failed to remove security key", "securityKeyRemoveError": "Failed to remove security key",
"securityKeyLoadError": "Failed to load security keys", "securityKeyLoadError": "Failed to load security keys",
"securityKeyLogin": "Continue with security key", "securityKeyLogin": "Use Security Key",
"securityKeyAuthError": "Failed to authenticate with security key", "securityKeyAuthError": "Failed to authenticate with security key",
"securityKeyRecommendation": "Register a backup security key on another device to ensure you always have access to your account.", "securityKeyRecommendation": "Register a backup security key on another device to ensure you always have access to your account.",
"registering": "Registering...", "registering": "Registering...",
@@ -1476,6 +1525,32 @@
"resourcePortRequired": "Port number is required for non-HTTP resources", "resourcePortRequired": "Port number is required for non-HTTP resources",
"resourcePortNotAllowed": "Port number should not be set for HTTP resources", "resourcePortNotAllowed": "Port number should not be set for HTTP resources",
"billingPricingCalculatorLink": "Pricing Calculator", "billingPricingCalculatorLink": "Pricing Calculator",
"billingYourPlan": "Your Plan",
"billingViewOrModifyPlan": "View or modify your current plan",
"billingViewPlanDetails": "View Plan Details",
"billingUsageAndLimits": "Usage and Limits",
"billingViewUsageAndLimits": "View your plan's limits and current usage",
"billingCurrentUsage": "Current Usage",
"billingMaximumLimits": "Maximum Limits",
"billingRemoteNodes": "Remote Nodes",
"billingUnlimited": "Unlimited",
"billingPaidLicenseKeys": "Paid License Keys",
"billingManageLicenseSubscription": "Manage your subscription for paid self-hosted license keys",
"billingCurrentKeys": "Current Keys",
"billingModifyCurrentPlan": "Modify Current Plan",
"billingConfirmUpgrade": "Confirm Upgrade",
"billingConfirmDowngrade": "Confirm Downgrade",
"billingConfirmUpgradeDescription": "You are about to upgrade your plan. Review the new limits and pricing below.",
"billingConfirmDowngradeDescription": "You are about to downgrade your plan. Review the new limits and pricing below.",
"billingPlanIncludes": "Plan Includes",
"billingProcessing": "Processing...",
"billingConfirmUpgradeButton": "Confirm Upgrade",
"billingConfirmDowngradeButton": "Confirm Downgrade",
"billingLimitViolationWarning": "Usage Exceeds New Plan Limits",
"billingLimitViolationDescription": "Your current usage exceeds the limits of this plan. After downgrading, all actions will be disabled until you reduce usage within the new limits. Please review the features below that are currently over the limits. Limits in violation:",
"billingFeatureLossWarning": "Feature Availability Notice",
"billingFeatureLossDescription": "By downgrading, features not available in the new plan will be automatically disabled. Some settings and configurations may be lost. Please review the pricing matrix to understand which features will no longer be available.",
"billingUsageExceedsLimit": "Current usage ({current}) exceeds limit ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "I agree to the", "IAgreeToThe": "I agree to the",
"termsOfService": "terms of service", "termsOfService": "terms of service",
@@ -1500,8 +1575,8 @@
"addressDescription": "The internal address of the client. Must fall within the organization's subnet.", "addressDescription": "The internal address of the client. Must fall within the organization's subnet.",
"selectSites": "Select sites", "selectSites": "Select sites",
"sitesDescription": "The client will have connectivity to the selected sites", "sitesDescription": "The client will have connectivity to the selected sites",
"clientInstallOlm": "Install Olm", "clientInstallOlm": "Install Machine Client",
"clientInstallOlmDescription": "Get Olm running on your system", "clientInstallOlmDescription": "Install the machine client for your system",
"clientOlmCredentials": "Credentials", "clientOlmCredentials": "Credentials",
"clientOlmCredentialsDescription": "This is how the client will authenticate with the server", "clientOlmCredentialsDescription": "This is how the client will authenticate with the server",
"olmEndpoint": "Endpoint", "olmEndpoint": "Endpoint",
@@ -1547,6 +1622,8 @@
"IntervalSeconds": "Healthy Interval", "IntervalSeconds": "Healthy Interval",
"timeoutSeconds": "Timeout (sec)", "timeoutSeconds": "Timeout (sec)",
"timeIsInSeconds": "Time is in seconds", "timeIsInSeconds": "Time is in seconds",
"requireDeviceApproval": "Require Device Approvals",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.",
"retryAttempts": "Retry Attempts", "retryAttempts": "Retry Attempts",
"expectedResponseCodes": "Expected Response Codes", "expectedResponseCodes": "Expected Response Codes",
"expectedResponseCodesDescription": "HTTP status code that indicates healthy status. If left blank, 200-300 is considered healthy.", "expectedResponseCodesDescription": "HTTP status code that indicates healthy status. If left blank, 200-300 is considered healthy.",
@@ -1587,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "No internal resources found.", "resourcesTableNoInternalResourcesFound": "No internal resources found.",
"resourcesTableDestination": "Destination", "resourcesTableDestination": "Destination",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Alias Address",
"resourcesTableAliasAddressInfo": "This address is part of the organization's utility subnet. It's used to resolve alias records using internal DNS resolution.",
"resourcesTableClients": "Clients", "resourcesTableClients": "Clients",
"resourcesTableAndOnlyAccessibleInternally": "and are only accessible internally when connected with a client.", "resourcesTableAndOnlyAccessibleInternally": "and are only accessible internally when connected with a client.",
"resourcesTableNoTargets": "No targets", "resourcesTableNoTargets": "No targets",
@@ -1886,6 +1965,13 @@
"orgAuthBackToSignIn": "Back to standard sign in", "orgAuthBackToSignIn": "Back to standard sign in",
"orgAuthNoAccount": "Don't have an account?", "orgAuthNoAccount": "Don't have an account?",
"subscriptionRequiredToUse": "A subscription is required to use this feature.", "subscriptionRequiredToUse": "A subscription is required to use this feature.",
"mustUpgradeToUse": "You must upgrade your subscription to use this feature.",
"subscriptionRequiredTierToUse": "This feature requires <tierLink>{tier}</tierLink> or higher.",
"upgradeToTierToUse": "Upgrade to <tierLink>{tier}</tierLink> or higher to use this feature.",
"subscriptionTierTier1": "Home",
"subscriptionTierTier2": "Team",
"subscriptionTierTier3": "Business",
"subscriptionTierEnterprise": "Enterprise",
"idpDisabled": "Identity providers are disabled.", "idpDisabled": "Identity providers are disabled.",
"orgAuthPageDisabled": "Organization auth page is disabled.", "orgAuthPageDisabled": "Organization auth page is disabled.",
"domainRestartedDescription": "Domain verification restarted successfully", "domainRestartedDescription": "Domain verification restarted successfully",
@@ -2073,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Get a license",
"description": "Choose a plan and tell us how you plan to use Pangolin.",
"chooseTier": "Choose your plan",
"viewPricingLink": "See pricing, features, and limits",
"tiers": {
"starter": {
"title": "Starter",
"description": "Enterprise features, 25 users, 25 sites, and community support."
},
"scale": {
"title": "Scale",
"description": "Enterprise features, 50 users, 50 sites, and priority support."
}
},
"personalUseOnly": "Personal use only (free license — no checkout)",
"buttons": {
"continueToCheckout": "Continue to Checkout"
},
"toasts": {
"checkoutError": {
"title": "Checkout error",
"description": "Could not start checkout. Please try again."
}
}
},
"priority": "Priority", "priority": "Priority",
"priorityDescription": "Higher priority routes are evaluated first. Priority = 100 means automatic ordering (system decides). Use another number to enforce manual priority.", "priorityDescription": "Higher priority routes are evaluated first. Priority = 100 means automatic ordering (system decides). Use another number to enforce manual priority.",
"instanceName": "Instance Name", "instanceName": "Instance Name",
@@ -2171,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "End of following year", "logRetentionEndOfFollowingYear": "End of following year",
"actionLogsDescription": "View a history of actions performed in this organization", "actionLogsDescription": "View a history of actions performed in this organization",
"accessLogsDescription": "View access auth requests for resources in this organization", "accessLogsDescription": "View access auth requests for resources in this organization",
"licenseRequiredToUse": "An Enterprise license is required to use this feature.", "licenseRequiredToUse": "An <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> license is required to use this feature. This feature is also available in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "The <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> is required to use this feature. This feature is also available in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Certificate Resolver", "certResolver": "Certificate Resolver",
"certResolverDescription": "Select the certificate resolver to use for this resource.", "certResolverDescription": "Select the certificate resolver to use for this resource.",
"selectCertResolver": "Select Certificate Resolver", "selectCertResolver": "Select Certificate Resolver",
@@ -2232,6 +2345,8 @@
"deviceCodeInvalidFormat": "Code must be 9 characters (e.g., A1AJ-N5JD)", "deviceCodeInvalidFormat": "Code must be 9 characters (e.g., A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Invalid or expired code", "deviceCodeInvalidOrExpired": "Invalid or expired code",
"deviceCodeVerifyFailed": "Failed to verify device code", "deviceCodeVerifyFailed": "Failed to verify device code",
"deviceCodeValidating": "Validating device code...",
"deviceCodeVerifying": "Verifying device authorization...",
"signedInAs": "Signed in as", "signedInAs": "Signed in as",
"deviceCodeEnterPrompt": "Enter the code displayed on the device", "deviceCodeEnterPrompt": "Enter the code displayed on the device",
"continue": "Continue", "continue": "Continue",
@@ -2244,7 +2359,7 @@
"deviceOrganizationsAccess": "Access to all organizations your account has access to", "deviceOrganizationsAccess": "Access to all organizations your account has access to",
"deviceAuthorize": "Authorize {applicationName}", "deviceAuthorize": "Authorize {applicationName}",
"deviceConnected": "Device Connected!", "deviceConnected": "Device Connected!",
"deviceAuthorizedMessage": "Device is authorized to access your account.", "deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.",
"pangolinCloud": "Pangolin Cloud", "pangolinCloud": "Pangolin Cloud",
"viewDevices": "View Devices", "viewDevices": "View Devices",
"viewDevicesDescription": "Manage your connected devices", "viewDevicesDescription": "Manage your connected devices",
@@ -2306,6 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Not you? Use a different account.", "deviceLoginUseDifferentAccount": "Not you? Use a different account.",
"deviceLoginDeviceRequestingAccessToAccount": "A device is requesting access to this account.", "deviceLoginDeviceRequestingAccessToAccount": "A device is requesting access to this account.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.",
"noData": "No Data", "noData": "No Data",
"machineClients": "Machine Clients", "machineClients": "Machine Clients",
"install": "Install", "install": "Install",
@@ -2394,5 +2510,105 @@
"maintenanceScreenTitle": "Service Temporarily Unavailable", "maintenanceScreenTitle": "Service Temporarily Unavailable",
"maintenanceScreenMessage": "We are currently experiencing technical difficulties. Please check back soon.", "maintenanceScreenMessage": "We are currently experiencing technical difficulties. Please check back soon.",
"maintenanceScreenEstimatedCompletion": "Estimated Completion:", "maintenanceScreenEstimatedCompletion": "Estimated Completion:",
"createInternalResourceDialogDestinationRequired": "Destination is required" "createInternalResourceDialogDestinationRequired": "Destination is required",
"available": "Available",
"archived": "Archived",
"noArchivedDevices": "No archived devices found",
"deviceArchived": "Device archived",
"deviceArchivedDescription": "The device has been successfully archived.",
"errorArchivingDevice": "Error archiving device",
"failedToArchiveDevice": "Failed to archive device",
"deviceQuestionArchive": "Are you sure you want to archive this device?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.",
"deviceArchiveConfirm": "Archive Device",
"archiveDevice": "Archive Device",
"archive": "Archive",
"deviceUnarchived": "Device unarchived",
"deviceUnarchivedDescription": "The device has been successfully unarchived.",
"errorUnarchivingDevice": "Error unarchiving device",
"failedToUnarchiveDevice": "Failed to unarchive device",
"unarchive": "Unarchive",
"archiveClient": "Archive Client",
"archiveClientQuestion": "Are you sure you want to archive this client?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.",
"archiveClientConfirm": "Archive Client",
"blockClient": "Block Client",
"blockClientQuestion": "Are you sure you want to block this client?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.",
"blockClientConfirm": "Block Client",
"active": "Active",
"usernameOrEmail": "Username or Email",
"selectYourOrganization": "Select your organization",
"signInTo": "Log in in to",
"signInWithPassword": "Continue with Password",
"noAuthMethodsAvailable": "No authentication methods available for this organization.",
"enterPassword": "Enter your password",
"enterMfaCode": "Enter the code from your authenticator app",
"securityKeyRequired": "Please use your security key to sign in.",
"needToUseAnotherAccount": "Need to use a different account?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.",
"termsOfService": "Terms of Service",
"privacyPolicy": "Privacy Policy",
"userNotFoundWithUsername": "No user found with that username.",
"verify": "Verify",
"signIn": "Sign In",
"forgotPassword": "Forgot password?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!",
"continueAnyway": "Continue anyway",
"dontShowAgain": "Don't show again",
"orgSignInNotice": "Did you know?",
"signupOrgNotice": "Trying to sign in?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?",
"signupOrgLink": "Sign in or sign up with your organization instead",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account",
"logIn": "Log In",
"deviceInformation": "Device Information",
"deviceInformationDescription": "Information about the device and agent",
"deviceSecurity": "Device Security",
"deviceSecurityDescription": "Device security posture information",
"platform": "Platform",
"macosVersion": "macOS Version",
"windowsVersion": "Windows Version",
"iosVersion": "iOS Version",
"androidVersion": "Android Version",
"osVersion": "OS Version",
"kernelVersion": "Kernel Version",
"deviceModel": "Device Model",
"serialNumber": "Serial Number",
"hostname": "Hostname",
"firstSeen": "First Seen",
"lastSeen": "Last Seen",
"biometricsEnabled": "Biometrics Enabled",
"diskEncrypted": "Disk Encrypted",
"firewallEnabled": "Firewall Enabled",
"autoUpdatesEnabled": "Auto Updates Enabled",
"tpmAvailable": "TPM Available",
"windowsAntivirusEnabled": "Antivirus Enabled",
"macosSipEnabled": "System Integrity Protection (SIP)",
"macosGatekeeperEnabled": "Gatekeeper",
"macosFirewallStealthMode": "Firewall Stealth Mode",
"linuxAppArmorEnabled": "AppArmor",
"linuxSELinuxEnabled": "SELinux",
"deviceSettingsDescription": "View device information and settings",
"devicePendingApprovalDescription": "This device is waiting for approval",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.",
"unblockClient": "Unblock Client",
"unblockClientDescription": "The device has been unblocked",
"unarchiveClient": "Unarchive Client",
"unarchiveClientDescription": "The device has been unarchived",
"block": "Block",
"unblock": "Unblock",
"deviceActions": "Device Actions",
"deviceActionsDescription": "Manage device status and access",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved.",
"connected": "Connected",
"disconnected": "Disconnected",
"approvalsEmptyStateTitle": "Device Approvals Not Enabled",
"approvalsEmptyStateDescription": "Enable device approvals for roles to require admin approval before users can connect new devices.",
"approvalsEmptyStateStep1Title": "Go to Roles",
"approvalsEmptyStateStep1Description": "Navigate to your organization's roles settings to configure device approvals.",
"approvalsEmptyStateStep2Title": "Enable Device Approvals",
"approvalsEmptyStateStep2Description": "Edit a role and enable the 'Require Device Approvals' option. Users with this role will need admin approval for new devices.",
"approvalsEmptyStatePreviewDescription": "Preview: When enabled, pending device requests will appear here for review",
"approvalsEmptyStateButtonText": "Manage Roles"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "Eres un miembro de {count, plural, =0 {ninguna organización} one {una organización} other {# organizaciones}}.", "componentsMember": "Eres un miembro de {count, plural, =0 {ninguna organización} one {una organización} other {# organizaciones}}.",
"componentsInvalidKey": "Se han detectado claves de licencia inválidas o caducadas. Siga los términos de licencia para seguir usando todas las características.", "componentsInvalidKey": "Se han detectado claves de licencia inválidas o caducadas. Siga los términos de licencia para seguir usando todas las características.",
"dismiss": "Descartar", "dismiss": "Descartar",
"subscriptionViolationMessage": "Estás más allá de tus límites para tu plan actual. Corrija el problema eliminando sitios, usuarios u otros recursos para permanecer dentro de tu plan.",
"subscriptionViolationViewBilling": "Ver facturación",
"componentsLicenseViolation": "Violación de la Licencia: Este servidor está usando sitios {usedSites} que exceden su límite de licencias de sitios {maxSites} . Siga los términos de licencia para seguir usando todas las características.", "componentsLicenseViolation": "Violación de la Licencia: Este servidor está usando sitios {usedSites} que exceden su límite de licencias de sitios {maxSites} . Siga los términos de licencia para seguir usando todas las características.",
"componentsSupporterMessage": "¡Gracias por apoyar a Pangolin como {tier}!", "componentsSupporterMessage": "¡Gracias por apoyar a Pangolin como {tier}!",
"inviteErrorNotValid": "Lo sentimos, pero parece que la invitación a la que intentas acceder no ha sido aceptada o ya no es válida.", "inviteErrorNotValid": "Lo sentimos, pero parece que la invitación a la que intentas acceder no ha sido aceptada o ya no es válida.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Conectar cualquier red", "sitesBannerTitle": "Conectar cualquier red",
"sitesBannerDescription": "Un sitio es una conexión a una red remota que permite a Pangolin proporcionar acceso a recursos, públicos o privados, a usuarios en cualquier lugar. Instale el conector de red del sitio (Newt) en cualquier lugar donde pueda ejecutar un binario o contenedor para establecer la conexión.", "sitesBannerDescription": "Un sitio es una conexión a una red remota que permite a Pangolin proporcionar acceso a recursos, públicos o privados, a usuarios en cualquier lugar. Instale el conector de red del sitio (Newt) en cualquier lugar donde pueda ejecutar un binario o contenedor para establecer la conexión.",
"sitesBannerButtonText": "Instalar sitio", "sitesBannerButtonText": "Instalar sitio",
"approvalsBannerTitle": "Aprobar o denegar el acceso al dispositivo",
"approvalsBannerDescription": "Revisar y aprobar o denegar las solicitudes de acceso al dispositivo de los usuarios. Cuando se requieren aprobaciones de dispositivos, los usuarios deben obtener la aprobación del administrador antes de que sus dispositivos puedan conectarse a los recursos de su organización.",
"approvalsBannerButtonText": "Saber más",
"siteCreate": "Crear sitio", "siteCreate": "Crear sitio",
"siteCreateDescription2": "Siga los pasos siguientes para crear y conectar un nuevo sitio", "siteCreateDescription2": "Siga los pasos siguientes para crear y conectar un nuevo sitio",
"siteCreateDescription": "Crear un nuevo sitio para empezar a conectar recursos", "siteCreateDescription": "Crear un nuevo sitio para empezar a conectar recursos",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Buscar roles...", "accessRolesSearch": "Buscar roles...",
"accessRolesAdd": "Añadir rol", "accessRolesAdd": "Añadir rol",
"accessRoleDelete": "Eliminar rol", "accessRoleDelete": "Eliminar rol",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Administrar aprobaciones",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Ver y administrar aprobaciones pendientes para el acceso a esta organización",
"description": "Descripción", "description": "Descripción",
"inviteTitle": "Invitaciones abiertas", "inviteTitle": "Invitaciones abiertas",
"inviteDescription": "Administrar invitaciones para que otros usuarios se unan a la organización", "inviteDescription": "Administrar invitaciones para que otros usuarios se unan a la organización",
@@ -452,18 +457,18 @@
"selectDuration": "Seleccionar duración", "selectDuration": "Seleccionar duración",
"selectResource": "Seleccionar Recurso", "selectResource": "Seleccionar Recurso",
"filterByResource": "Filtrar por Recurso", "filterByResource": "Filtrar por Recurso",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Seleccionar Estado de Aprobación",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtrar por estado de aprobación",
"approvalListEmpty": "No approvals", "approvalListEmpty": "No hay aprobaciones",
"approvalState": "Approval State", "approvalState": "Estado de aprobación",
"approve": "Approve", "approve": "Aprobar",
"approved": "Approved", "approved": "Aprobado",
"denied": "Denied", "denied": "Denegado",
"deniedApproval": "Denied Approval", "deniedApproval": "Aprobación denegada",
"all": "All", "all": "Todo",
"deny": "Deny", "deny": "Denegar",
"viewDetails": "View Details", "viewDetails": "Ver detalles",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "solicitó un nuevo dispositivo",
"resetFilters": "Reiniciar filtros", "resetFilters": "Reiniciar filtros",
"totalBlocked": "Solicitudes bloqueadas por Pangolin", "totalBlocked": "Solicitudes bloqueadas por Pangolin",
"totalRequests": "Solicitudes totales", "totalRequests": "Solicitudes totales",
@@ -743,28 +748,28 @@
"countries": "Países", "countries": "Países",
"accessRoleCreate": "Crear rol", "accessRoleCreate": "Crear rol",
"accessRoleCreateDescription": "Crear un nuevo rol para agrupar usuarios y administrar sus permisos.", "accessRoleCreateDescription": "Crear un nuevo rol para agrupar usuarios y administrar sus permisos.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Editar rol",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Editar información de rol.",
"accessRoleCreateSubmit": "Crear rol", "accessRoleCreateSubmit": "Crear rol",
"accessRoleCreated": "Rol creado", "accessRoleCreated": "Rol creado",
"accessRoleCreatedDescription": "El rol se ha creado correctamente.", "accessRoleCreatedDescription": "El rol se ha creado correctamente.",
"accessRoleErrorCreate": "Error al crear el rol", "accessRoleErrorCreate": "Error al crear el rol",
"accessRoleErrorCreateDescription": "Se ha producido un error al crear el rol.", "accessRoleErrorCreateDescription": "Se ha producido un error al crear el rol.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Actualizar rol",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Rol actualizado",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "El rol se ha actualizado correctamente.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Aprobación procesada",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Establezca la decisión de Solicitud de Aprobación a aprobar.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Define la decisión de Solicitud de Aprobación a denegar.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Error al actualizar el rol",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Se ha producido un error al actualizar el rol.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Error al procesar la aprobación",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Se ha producido un error al procesar la aprobación.",
"accessRoleErrorNewRequired": "Se requiere un nuevo rol", "accessRoleErrorNewRequired": "Se requiere un nuevo rol",
"accessRoleErrorRemove": "Error al eliminar el rol", "accessRoleErrorRemove": "Error al eliminar el rol",
"accessRoleErrorRemoveDescription": "Ocurrió un error mientras se eliminaba el rol.", "accessRoleErrorRemoveDescription": "Ocurrió un error mientras se eliminaba el rol.",
"accessRoleName": "Nombre del Rol", "accessRoleName": "Nombre del Rol",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Estás a punto de eliminar el rol `{name}`. No puedes deshacer esta acción.",
"accessRoleRemove": "Quitar rol", "accessRoleRemove": "Quitar rol",
"accessRoleRemoveDescription": "Eliminar un rol de la organización", "accessRoleRemoveDescription": "Eliminar un rol de la organización",
"accessRoleRemoveSubmit": "Quitar rol", "accessRoleRemoveSubmit": "Quitar rol",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Aumentar el número de sitios", "sitestCountIncrease": "Aumentar el número de sitios",
"idpManage": "Administrar proveedores de identidad", "idpManage": "Administrar proveedores de identidad",
"idpManageDescription": "Ver y administrar proveedores de identidad en el sistema", "idpManageDescription": "Ver y administrar proveedores de identidad en el sistema",
"idpGlobalModeBanner": "Los proveedores de identidad (IdPs) por organización están deshabilitados en este servidor. Está utilizando IdPs globales (compartidos entre todas las organizaciones). Administra los IdPs globales en el <adminPanelLink>panel de administración</adminPanelLink>. Para habilitar los IdPs por organización, edita la configuración del servidor y establece el modo de IdP en org. <configDocsLink>Consulta la documentación</configDocsLink>. Si deseas seguir utilizando IdPs globales y hacer que esto desaparezca de las configuraciones de la organización, establece explícitamente el modo en global en la configuración.",
"idpGlobalModeBannerUpgradeRequired": "Los proveedores de identidad (IdPs) por organización están deshabilitados en este servidor. Está utilizando IdPs globales (compartidos entre todas las organizaciones). Administra los IdPs globales en el <adminPanelLink>panel de administración</adminPanelLink>. Para usar proveedores de identidad por organización, debes actualizar a la edición Empresarial.",
"idpGlobalModeBannerLicenseRequired": "Los proveedores de identidad (IdPs) por organización están deshabilitados en este servidor. Está utilizando identificadores globales (compartidos en todas las organizaciones). Gestionar identificaciones globales en el panel <adminPanelLink>de administración</adminPanelLink>. Para utilizar proveedores de identidad por organización, se requiere una licencia de empresa.",
"idpDeletedDescription": "Proveedor de identidad eliminado correctamente", "idpDeletedDescription": "Proveedor de identidad eliminado correctamente",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "¿Está seguro que desea eliminar permanentemente el proveedor de identidad?", "idpQuestionRemove": "¿Está seguro que desea eliminar permanentemente el proveedor de identidad?",
@@ -900,7 +908,7 @@
"inviteAlready": "¡Parece que has sido invitado!", "inviteAlready": "¡Parece que has sido invitado!",
"inviteAlreadyDescription": "Para aceptar la invitación, debes iniciar sesión o crear una cuenta.", "inviteAlreadyDescription": "Para aceptar la invitación, debes iniciar sesión o crear una cuenta.",
"signupQuestion": "¿Ya tienes una cuenta?", "signupQuestion": "¿Ya tienes una cuenta?",
"login": "Log In", "login": "Iniciar sesión",
"resourceNotFound": "Recurso no encontrado", "resourceNotFound": "Recurso no encontrado",
"resourceNotFoundDescription": "El recurso al que intentas acceder no existe.", "resourceNotFoundDescription": "El recurso al que intentas acceder no existe.",
"pincodeRequirementsLength": "El PIN debe tener exactamente 6 dígitos", "pincodeRequirementsLength": "El PIN debe tener exactamente 6 dígitos",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Esta organización requiere que cambies tu contraseña cada {maxDays} días.", "passwordExpiryDescription": "Esta organización requiere que cambies tu contraseña cada {maxDays} días.",
"changePasswordNow": "Cambiar Contraseña Ahora", "changePasswordNow": "Cambiar Contraseña Ahora",
"pincodeAuth": "Código de autenticación", "pincodeAuth": "Código de autenticación",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Enviar código",
"passwordResetSubmit": "Reiniciar Solicitud", "passwordResetSubmit": "Reiniciar Solicitud",
"passwordResetAlreadyHaveCode": "Ingresar código", "passwordResetAlreadyHaveCode": "Ingresar código",
"passwordResetSmtpRequired": "Póngase en contacto con su administrador", "passwordResetSmtpRequired": "Póngase en contacto con su administrador",
"passwordResetSmtpRequiredDescription": "Se requiere un código de restablecimiento de contraseña para restablecer su contraseña. Póngase en contacto con su administrador para obtener asistencia.", "passwordResetSmtpRequiredDescription": "Se requiere un código de restablecimiento de contraseña para restablecer su contraseña. Póngase en contacto con su administrador para obtener asistencia.",
"passwordBack": "Volver a la contraseña", "passwordBack": "Volver a la contraseña",
"loginBack": "Go back to main login page", "loginBack": "Volver a la página principal de acceso",
"signup": "Regístrate", "signup": "Regístrate",
"loginStart": "Inicia sesión para empezar", "loginStart": "Inicia sesión para empezar",
"idpOidcTokenValidating": "Validando token OIDC", "idpOidcTokenValidating": "Validando token OIDC",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Actualizar IDP Org", "actionUpdateIdpOrg": "Actualizar IDP Org",
"actionCreateClient": "Crear cliente", "actionCreateClient": "Crear cliente",
"actionDeleteClient": "Eliminar cliente", "actionDeleteClient": "Eliminar cliente",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Archivar cliente",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Desarchivar cliente",
"actionBlockClient": "Block Client", "actionBlockClient": "Bloquear cliente",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Desbloquear cliente",
"actionUpdateClient": "Actualizar cliente", "actionUpdateClient": "Actualizar cliente",
"actionListClients": "Listar clientes", "actionListClients": "Listar clientes",
"actionGetClient": "Obtener cliente", "actionGetClient": "Obtener cliente",
@@ -1164,14 +1172,14 @@
"searchProgress": "Buscar...", "searchProgress": "Buscar...",
"create": "Crear", "create": "Crear",
"orgs": "Organizaciones", "orgs": "Organizaciones",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Ocurrió un error inesperado. Por favor, inténtelo de nuevo.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Es necesario iniciar sesión para tu dispositivo.",
"passwordForgot": "¿Olvidaste tu contraseña?", "passwordForgot": "¿Olvidaste tu contraseña?",
"otpAuth": "Autenticación de dos factores", "otpAuth": "Autenticación de dos factores",
"otpAuthDescription": "Introduzca el código de su aplicación de autenticación o uno de sus códigos de copia de seguridad de un solo uso.", "otpAuthDescription": "Introduzca el código de su aplicación de autenticación o uno de sus códigos de copia de seguridad de un solo uso.",
"otpAuthSubmit": "Enviar código", "otpAuthSubmit": "Enviar código",
"idpContinue": "O continuar con", "idpContinue": "O continuar con",
"otpAuthBack": "Back to Password", "otpAuthBack": "Volver a la contraseña",
"navbar": "Menú de navegación", "navbar": "Menú de navegación",
"navbarDescription": "Menú de navegación principal para la aplicación", "navbarDescription": "Menú de navegación principal para la aplicación",
"navbarDocsLink": "Documentación", "navbarDocsLink": "Documentación",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Resumen", "sidebarOverview": "Resumen",
"sidebarHome": "Inicio", "sidebarHome": "Inicio",
"sidebarSites": "Sitios", "sidebarSites": "Sitios",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Solicitudes de aprobación",
"sidebarResources": "Recursos", "sidebarResources": "Recursos",
"sidebarProxyResources": "Público", "sidebarProxyResources": "Público",
"sidebarClientResources": "Privado", "sidebarClientResources": "Privado",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Proveedores de identidad", "sidebarIdentityProviders": "Proveedores de identidad",
"sidebarLicense": "Licencia", "sidebarLicense": "Licencia",
"sidebarClients": "Clientes", "sidebarClients": "Clientes",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Dispositivos de usuario",
"sidebarMachineClients": "Máquinas", "sidebarMachineClients": "Máquinas",
"sidebarDomains": "Dominios", "sidebarDomains": "Dominios",
"sidebarGeneral": "Gestionar", "sidebarGeneral": "Gestionar",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Se produjo un error al crear la cuenta de administrador del servidor.", "setupErrorCreateAdmin": "Se produjo un error al crear la cuenta de administrador del servidor.",
"certificateStatus": "Estado del certificado", "certificateStatus": "Estado del certificado",
"loading": "Cargando", "loading": "Cargando",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Cargando analíticas",
"restart": "Reiniciar", "restart": "Reiniciar",
"domains": "Dominios", "domains": "Dominios",
"domainsDescription": "Crear y administrar dominios disponibles en la organización", "domainsDescription": "Crear y administrar dominios disponibles en la organización",
@@ -1336,7 +1344,7 @@
"refreshError": "Error al actualizar datos", "refreshError": "Error al actualizar datos",
"verified": "Verificado", "verified": "Verificado",
"pending": "Pendiente", "pending": "Pendiente",
"pendingApproval": "Pending Approval", "pendingApproval": "Pendientes de aprobación",
"sidebarBilling": "Facturación", "sidebarBilling": "Facturación",
"billing": "Facturación", "billing": "Facturación",
"orgBillingDescription": "Administrar información de facturación y suscripciones", "orgBillingDescription": "Administrar información de facturación y suscripciones",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Descripción general de los límites de uso", "billingUsageLimitsOverview": "Descripción general de los límites de uso",
"billingMonitorUsage": "Monitorea tu uso comparado con los límites configurados. Si necesitas que aumenten los límites, contáctanos a soporte@pangolin.net.", "billingMonitorUsage": "Monitorea tu uso comparado con los límites configurados. Si necesitas que aumenten los límites, contáctanos a soporte@pangolin.net.",
"billingDataUsage": "Uso de datos", "billingDataUsage": "Uso de datos",
"billingOnlineTime": "Tiempo en línea del sitio", "billingSites": "Sitios",
"billingUsers": "Usuarios activos", "billingUsers": "Usuarios",
"billingDomains": "Dominios activos", "billingDomains": "Dominios",
"billingRemoteExitNodes": "Nodos autogestionados activos", "billingRemoteExitNodes": "Nodos remotos",
"billingNoLimitConfigured": "No se ha configurado ningún límite", "billingNoLimitConfigured": "No se ha configurado ningún límite",
"billingEstimatedPeriod": "Período de facturación estimado", "billingEstimatedPeriod": "Período de facturación estimado",
"billingIncludedUsage": "Uso incluido", "billingIncludedUsage": "Uso incluido",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Error al obtener la URL del portal", "billingFailedToGetPortalUrl": "Error al obtener la URL del portal",
"billingPortalError": "Error del portal", "billingPortalError": "Error del portal",
"billingDataUsageInfo": "Se le cobran todos los datos transferidos a través de sus túneles seguros cuando se conectan a la nube. Esto incluye tanto tráfico entrante como saliente a través de todos sus sitios. Cuando alcance su límite, sus sitios se desconectarán hasta que actualice su plan o reduzca el uso. Los datos no se cargan cuando se usan nodos.", "billingDataUsageInfo": "Se le cobran todos los datos transferidos a través de sus túneles seguros cuando se conectan a la nube. Esto incluye tanto tráfico entrante como saliente a través de todos sus sitios. Cuando alcance su límite, sus sitios se desconectarán hasta que actualice su plan o reduzca el uso. Los datos no se cargan cuando se usan nodos.",
"billingOnlineTimeInfo": "Se te cobrará en función del tiempo que tus sitios permanezcan conectados a la nube. Por ejemplo, 44.640 minutos equivale a un sitio que funciona 24/7 durante un mes completo. Cuando alcance su límite, sus sitios se desconectarán hasta que mejore su plan o reduzca el uso. No se cargará el tiempo al usar nodos.", "billingSInfo": "Cuántos sitios puedes usar",
"billingUsersInfo": "Se le cobra por cada usuario en la organización. La facturación se calcula diariamente según el número de cuentas de usuario activas en su órgano.", "billingUsersInfo": "Cuántos usuarios puedes usar",
"billingDomainInfo": "Se le cobra por cada dominio en la organización. La facturación se calcula diariamente en función del número de cuentas de dominio activas en su órgano.", "billingDomainInfo": "Cuántos dominios puedes usar",
"billingRemoteExitNodesInfo": "Se le cobra por cada nodo administrado en la organización. La facturación se calcula diariamente en función del número de nodos activos gestionados en su órgano.", "billingRemoteExitNodesInfo": "Cuántos nodos remotos puedes usar",
"billingLicenseKeys": "Claves de licencia",
"billingLicenseKeysDescription": "Administrar las suscripciones de su clave de licencia",
"billingLicenseSubscription": "Suscripción de licencia",
"billingInactive": "Inactivo",
"billingLicenseItem": "Licencia",
"billingQuantity": "Cantidad",
"billingTotal": "total",
"billingModifyLicenses": "Modificar suscripción de licencia",
"domainNotFound": "Dominio no encontrado", "domainNotFound": "Dominio no encontrado",
"domainNotFoundDescription": "Este recurso está deshabilitado porque el dominio ya no existe en nuestro sistema. Por favor, establece un nuevo dominio para este recurso.", "domainNotFoundDescription": "Este recurso está deshabilitado porque el dominio ya no existe en nuestro sistema. Por favor, establece un nuevo dominio para este recurso.",
"failed": "Fallido", "failed": "Fallido",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Llave de seguridad eliminada exitosamente", "securityKeyRemoveSuccess": "Llave de seguridad eliminada exitosamente",
"securityKeyRemoveError": "Error al eliminar la llave de seguridad", "securityKeyRemoveError": "Error al eliminar la llave de seguridad",
"securityKeyLoadError": "Error al cargar las llaves de seguridad", "securityKeyLoadError": "Error al cargar las llaves de seguridad",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Usar clave de seguridad",
"securityKeyAuthError": "Error al autenticar con llave de seguridad", "securityKeyAuthError": "Error al autenticar con llave de seguridad",
"securityKeyRecommendation": "Considere registrar otra llave de seguridad en un dispositivo diferente para asegurarse de no quedar bloqueado de su cuenta.", "securityKeyRecommendation": "Considere registrar otra llave de seguridad en un dispositivo diferente para asegurarse de no quedar bloqueado de su cuenta.",
"registering": "Registrando...", "registering": "Registrando...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Se requiere número de puerto para recursos no HTTP", "resourcePortRequired": "Se requiere número de puerto para recursos no HTTP",
"resourcePortNotAllowed": "El número de puerto no debe establecerse para recursos HTTP", "resourcePortNotAllowed": "El número de puerto no debe establecerse para recursos HTTP",
"billingPricingCalculatorLink": "Calculadora de Precios", "billingPricingCalculatorLink": "Calculadora de Precios",
"billingYourPlan": "Su plan",
"billingViewOrModifyPlan": "Ver o modificar su plan actual",
"billingViewPlanDetails": "Ver detalles del plan",
"billingUsageAndLimits": "Uso y límites",
"billingViewUsageAndLimits": "Ver los límites de tu plan y el uso actual",
"billingCurrentUsage": "Uso actual",
"billingMaximumLimits": "Límites máximos",
"billingRemoteNodes": "Nodos remotos",
"billingUnlimited": "Ilimitado",
"billingPaidLicenseKeys": "Claves de licencia pagadas",
"billingManageLicenseSubscription": "Administra tu suscripción para las claves de licencia autoalojadas pagadas",
"billingCurrentKeys": "Claves actuales",
"billingModifyCurrentPlan": "Modificar plan actual",
"billingConfirmUpgrade": "Confirmar actualización",
"billingConfirmDowngrade": "Confirmar descenso",
"billingConfirmUpgradeDescription": "Estás a punto de actualizar tu plan. Revisa los nuevos límites y precios a continuación.",
"billingConfirmDowngradeDescription": "Está a punto de rebajar su plan. Revise los nuevos límites y los precios a continuación.",
"billingPlanIncludes": "Plan Incluye",
"billingProcessing": "Procesando...",
"billingConfirmUpgradeButton": "Confirmar actualización",
"billingConfirmDowngradeButton": "Confirmar descenso",
"billingLimitViolationWarning": "El uso excede los nuevos límites del plan",
"billingLimitViolationDescription": "Su uso actual excede los límites de este plan. Después de degradar, todas las acciones se desactivarán hasta que reduzca el uso dentro de los nuevos límites. Por favor, revisa las siguientes características que están actualmente por encima de los límites. Límites en violación:",
"billingFeatureLossWarning": "Aviso de disponibilidad de funcionalidad",
"billingFeatureLossDescription": "Al degradar, las características no disponibles en el nuevo plan se desactivarán automáticamente. Algunas configuraciones y configuraciones pueden perderse. Por favor, revise la matriz de precios para entender qué características ya no estarán disponibles.",
"billingUsageExceedsLimit": "El uso actual ({current}) supera el límite ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Estoy de acuerdo con los", "IAgreeToThe": "Estoy de acuerdo con los",
"termsOfService": "términos del servicio", "termsOfService": "términos del servicio",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Intervalo Saludable", "IntervalSeconds": "Intervalo Saludable",
"timeoutSeconds": "Tiempo agotado (seg)", "timeoutSeconds": "Tiempo agotado (seg)",
"timeIsInSeconds": "El tiempo está en segundos", "timeIsInSeconds": "El tiempo está en segundos",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Requiere aprobaciones del dispositivo",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Los usuarios con este rol necesitan nuevos dispositivos aprobados por un administrador antes de poder conectarse y acceder a los recursos.",
"retryAttempts": "Intentos de Reintento", "retryAttempts": "Intentos de Reintento",
"expectedResponseCodes": "Códigos de respuesta esperados", "expectedResponseCodes": "Códigos de respuesta esperados",
"expectedResponseCodesDescription": "Código de estado HTTP que indica un estado saludable. Si se deja en blanco, se considera saludable de 200 a 300.", "expectedResponseCodesDescription": "Código de estado HTTP que indica un estado saludable. Si se deja en blanco, se considera saludable de 200 a 300.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "No se encontraron recursos internos.", "resourcesTableNoInternalResourcesFound": "No se encontraron recursos internos.",
"resourcesTableDestination": "Destino", "resourcesTableDestination": "Destino",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Dirección del alias",
"resourcesTableAliasAddressInfo": "Esta dirección es parte de la subred de utilidad de la organización. Se utiliza para resolver registros de alias usando resolución DNS interna.",
"resourcesTableClients": "Clientes", "resourcesTableClients": "Clientes",
"resourcesTableAndOnlyAccessibleInternally": "y solo son accesibles internamente cuando se conectan con un cliente.", "resourcesTableAndOnlyAccessibleInternally": "y solo son accesibles internamente cuando se conectan con un cliente.",
"resourcesTableNoTargets": "Sin objetivos", "resourcesTableNoTargets": "Sin objetivos",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Elige tu proveedor de identidad para continuar", "orgAuthChooseIdpDescription": "Elige tu proveedor de identidad para continuar",
"orgAuthNoIdpConfigured": "Esta organización no tiene ningún proveedor de identidad configurado. En su lugar puedes iniciar sesión con tu identidad de Pangolin.", "orgAuthNoIdpConfigured": "Esta organización no tiene ningún proveedor de identidad configurado. En su lugar puedes iniciar sesión con tu identidad de Pangolin.",
"orgAuthSignInWithPangolin": "Iniciar sesión con Pangolin", "orgAuthSignInWithPangolin": "Iniciar sesión con Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Iniciar sesión en una organización",
"orgAuthSelectOrgTitle": "Inicio de sesión de organización", "orgAuthSelectOrgTitle": "Inicio de sesión de organización",
"orgAuthSelectOrgDescription": "Ingrese el ID de su organización para continuar", "orgAuthSelectOrgDescription": "Ingrese el ID de su organización para continuar",
"orgAuthOrgIdPlaceholder": "tu-organización", "orgAuthOrgIdPlaceholder": "tu-organización",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Volver a iniciar sesión estándar", "orgAuthBackToSignIn": "Volver a iniciar sesión estándar",
"orgAuthNoAccount": "¿No tienes una cuenta?", "orgAuthNoAccount": "¿No tienes una cuenta?",
"subscriptionRequiredToUse": "Se requiere una suscripción para utilizar esta función.", "subscriptionRequiredToUse": "Se requiere una suscripción para utilizar esta función.",
"mustUpgradeToUse": "Debes actualizar tu suscripción para usar esta función.",
"subscriptionRequiredTierToUse": "Esta función requiere <tierLink>{tier}</tierLink> o superior.",
"upgradeToTierToUse": "Actualiza a <tierLink>{tier}</tierLink> o superior para usar esta función.",
"subscriptionTierTier1": "Inicio",
"subscriptionTierTier2": "Equipo",
"subscriptionTierTier3": "Negocio",
"subscriptionTierEnterprise": "Empresa",
"idpDisabled": "Los proveedores de identidad están deshabilitados.", "idpDisabled": "Los proveedores de identidad están deshabilitados.",
"orgAuthPageDisabled": "La página de autenticación de la organización está deshabilitada.", "orgAuthPageDisabled": "La página de autenticación de la organización está deshabilitada.",
"domainRestartedDescription": "Verificación de dominio reiniciada con éxito", "domainRestartedDescription": "Verificación de dominio reiniciada con éxito",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Obtener una licencia",
"description": "Elige un plan y dinos cómo planeas usar Pangolin.",
"chooseTier": "Elige tu plan",
"viewPricingLink": "Ver precios, características y límites",
"tiers": {
"starter": {
"title": "Interruptor",
"description": "Características de la empresa, 25 usuarios, 25 sitios y soporte comunitario."
},
"scale": {
"title": "Escala",
"description": "Características de la empresa, 50 usuarios, 50 sitios y soporte prioritario."
}
},
"personalUseOnly": "Solo uso personal (licencia gratuita, sin pago)",
"buttons": {
"continueToCheckout": "Continuar con el pago"
},
"toasts": {
"checkoutError": {
"title": "Error de pago",
"description": "No se pudo iniciar el pago. Por favor, inténtelo de nuevo."
}
}
},
"priority": "Prioridad", "priority": "Prioridad",
"priorityDescription": "Las rutas de prioridad más alta son evaluadas primero. Prioridad = 100 significa orden automático (decisiones del sistema). Utilice otro número para hacer cumplir la prioridad manual.", "priorityDescription": "Las rutas de prioridad más alta son evaluadas primero. Prioridad = 100 significa orden automático (decisiones del sistema). Utilice otro número para hacer cumplir la prioridad manual.",
"instanceName": "Nombre de instancia", "instanceName": "Nombre de instancia",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Fin del año siguiente", "logRetentionEndOfFollowingYear": "Fin del año siguiente",
"actionLogsDescription": "Ver un historial de acciones realizadas en esta organización", "actionLogsDescription": "Ver un historial de acciones realizadas en esta organización",
"accessLogsDescription": "Ver solicitudes de acceso a los recursos de esta organización", "accessLogsDescription": "Ver solicitudes de acceso a los recursos de esta organización",
"licenseRequiredToUse": "Se requiere una licencia Enterprise para utilizar esta función.", "licenseRequiredToUse": "Se requiere una licencia <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> para utilizar esta función. Esta característica también está disponible en <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "La <enterpriseEditionLink>versión Enterprise</enterpriseEditionLink> es necesaria para utilizar esta función. Esta función también está disponible en <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Resolver certificado", "certResolver": "Resolver certificado",
"certResolverDescription": "Seleccione la resolución de certificados a utilizar para este recurso.", "certResolverDescription": "Seleccione la resolución de certificados a utilizar para este recurso.",
"selectCertResolver": "Seleccionar Resolver Certificado", "selectCertResolver": "Seleccionar Resolver Certificado",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "El código debe tener 9 caracteres (por ejemplo, A1AJ-N5JD)", "deviceCodeInvalidFormat": "El código debe tener 9 caracteres (por ejemplo, A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Código no válido o caducado", "deviceCodeInvalidOrExpired": "Código no válido o caducado",
"deviceCodeVerifyFailed": "Error al verificar el código del dispositivo", "deviceCodeVerifyFailed": "Error al verificar el código del dispositivo",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Validando código de dispositivo...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Verificando autorización del dispositivo...",
"signedInAs": "Conectado como", "signedInAs": "Conectado como",
"deviceCodeEnterPrompt": "Introduzca el código mostrado en el dispositivo", "deviceCodeEnterPrompt": "Introduzca el código mostrado en el dispositivo",
"continue": "Continuar", "continue": "Continuar",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Acceso a todas las organizaciones a las que su cuenta tiene acceso", "deviceOrganizationsAccess": "Acceso a todas las organizaciones a las que su cuenta tiene acceso",
"deviceAuthorize": "Autorizar a {applicationName}", "deviceAuthorize": "Autorizar a {applicationName}",
"deviceConnected": "¡Dispositivo conectado!", "deviceConnected": "¡Dispositivo conectado!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "El dispositivo está autorizado para acceder a su cuenta. Por favor, vuelva a la aplicación cliente.",
"pangolinCloud": "Nube de Pangolin", "pangolinCloud": "Nube de Pangolin",
"viewDevices": "Ver dispositivos", "viewDevices": "Ver dispositivos",
"viewDevicesDescription": "Administra tus dispositivos conectados", "viewDevicesDescription": "Administra tus dispositivos conectados",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "¿No tú? Utilice una cuenta diferente.", "deviceLoginUseDifferentAccount": "¿No tú? Utilice una cuenta diferente.",
"deviceLoginDeviceRequestingAccessToAccount": "Un dispositivo está solicitando acceso a esta cuenta.", "deviceLoginDeviceRequestingAccessToAccount": "Un dispositivo está solicitando acceso a esta cuenta.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Seleccione un método de autenticación para continuar.",
"noData": "Sin datos", "noData": "Sin datos",
"machineClients": "Clientes de la máquina", "machineClients": "Clientes de la máquina",
"install": "Instalar", "install": "Instalar",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Actualmente estamos experimentando dificultades técnicas. Por favor regrese pronto.", "maintenanceScreenMessage": "Actualmente estamos experimentando dificultades técnicas. Por favor regrese pronto.",
"maintenanceScreenEstimatedCompletion": "Estimado completado:", "maintenanceScreenEstimatedCompletion": "Estimado completado:",
"createInternalResourceDialogDestinationRequired": "Se requiere destino", "createInternalResourceDialogDestinationRequired": "Se requiere destino",
"available": "Available", "available": "Disponible",
"archived": "Archived", "archived": "Archivado",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "No se encontraron dispositivos archivados",
"deviceArchived": "Device archived", "deviceArchived": "Dispositivo archivado",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "El dispositivo se ha archivado correctamente.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Error al archivar dispositivo",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Error al archivar el dispositivo",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "¿Está seguro que desea archivar este dispositivo?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "El dispositivo será archivado y eliminado de su lista de dispositivos activos.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Archivar dispositivo",
"archiveDevice": "Archive Device", "archiveDevice": "Archivar dispositivo",
"archive": "Archive", "archive": "Archivar",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Dispositivo desarchivado",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "El dispositivo se ha desarchivado correctamente.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Error al desarchivar dispositivo",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Error al desarchivar el dispositivo",
"unarchive": "Unarchive", "unarchive": "Desarchivar",
"archiveClient": "Archive Client", "archiveClient": "Archivar cliente",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "¿Está seguro que desea archivar este cliente?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "El cliente será archivado y eliminado de su lista de clientes activos.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Archivar cliente",
"blockClient": "Block Client", "blockClient": "Bloquear cliente",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "¿Estás seguro de que quieres bloquear a este cliente?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "El dispositivo será forzado a desconectarse si está conectado actualmente. Puede desbloquear el dispositivo más tarde.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Bloquear cliente",
"active": "Active", "active": "Activo",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Nombre de usuario o email",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Seleccione su organización",
"signInTo": "Log in in to", "signInTo": "Iniciar sesión en",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Continuar con la contraseña",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "No hay métodos de autenticación disponibles para esta organización.",
"enterPassword": "Enter your password", "enterPassword": "Introduzca su contraseña",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Introduzca el código de su aplicación de autenticación",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Utilice su clave de seguridad para iniciar sesión.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "¿Necesitas usar una cuenta diferente?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Al hacer clic en los botones de abajo, reconoces que has leído, comprendido, y acepta los <termsOfService>Términos de Servicio</termsOfService> y <privacyPolicy>Política de Privacidad</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Términos de Servicio",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Política de privacidad",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Ningún usuario encontrado con ese nombre de usuario.",
"verify": "Verify", "verify": "Verificar",
"signIn": "Sign In", "signIn": "Iniciar sesión",
"forgotPassword": "Forgot password?", "forgotPassword": "¿Olvidaste la contraseña?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Si has iniciado sesión antes, puedes introducir tu nombre de usuario o correo electrónico arriba para autenticarte con el proveedor de identidad de tu organización. ¡Es más fácil!",
"continueAnyway": "Continue anyway", "continueAnyway": "Continuar de todos modos",
"dontShowAgain": "Don't show again", "dontShowAgain": "No volver a mostrar",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "¿Sabía usted?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "¿Intentando iniciar sesión?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "¿Estás intentando iniciar sesión a través del proveedor de identidad de tu organización?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Inicia sesión o regístrate con tu organización",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Usar una cuenta diferente",
"logIn": "Log In", "logIn": "Iniciar sesión",
"deviceInformation": "Device Information", "deviceInformation": "Información del dispositivo",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Información sobre el dispositivo y el agente",
"platform": "Platform", "deviceSecurity": "Seguridad del dispositivo",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Información de postura de seguridad del dispositivo",
"windowsVersion": "Windows Version", "platform": "Plataforma",
"iosVersion": "iOS Version", "macosVersion": "versión macOS",
"androidVersion": "Android Version", "windowsVersion": "Versión de Windows",
"osVersion": "OS Version", "iosVersion": "Versión de iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Versión de Android",
"deviceModel": "Device Model", "osVersion": "Versión del SO",
"serialNumber": "Serial Number", "kernelVersion": "Versión de Kernel",
"deviceModel": "Modelo de dispositivo",
"serialNumber": "Número Serial",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Primer detectado",
"lastSeen": "Last Seen", "lastSeen": "Último Visto",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometría habilitada",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Disco cifrado",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Cortafuegos activado",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Actualizaciones automáticas habilitadas",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM disponible",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirus activado",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Protección de integridad del sistema (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Modo Sigilo Firewall",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "AppArmor",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Ver información y ajustes del dispositivo",
"devicePendingApprovalDescription": "Este dispositivo está esperando su aprobación",
"deviceBlockedDescription": "Este dispositivo está actualmente bloqueado. No podrá conectarse a ningún recurso a menos que sea desbloqueado.",
"unblockClient": "Desbloquear cliente",
"unblockClientDescription": "El dispositivo ha sido desbloqueado",
"unarchiveClient": "Desarchivar cliente",
"unarchiveClientDescription": "El dispositivo ha sido desarchivado",
"block": "Bloque",
"unblock": "Desbloquear",
"deviceActions": "Acciones del dispositivo",
"deviceActionsDescription": "Administrar estado y acceso al dispositivo",
"devicePendingApprovalBannerDescription": "Este dispositivo está pendiente de aprobación. No podrá conectarse a recursos hasta que sea aprobado.",
"connected": "Conectado",
"disconnected": "Desconectado",
"approvalsEmptyStateTitle": "Aprobaciones de dispositivo no habilitadas",
"approvalsEmptyStateDescription": "Habilita las aprobaciones de dispositivos para que los roles requieran aprobación del administrador antes de que los usuarios puedan conectar nuevos dispositivos.",
"approvalsEmptyStateStep1Title": "Ir a roles",
"approvalsEmptyStateStep1Description": "Navega a la configuración de roles de tu organización para configurar las aprobaciones de dispositivos.",
"approvalsEmptyStateStep2Title": "Habilitar aprobaciones de dispositivo",
"approvalsEmptyStateStep2Description": "Editar un rol y habilitar la opción 'Requerir aprobaciones de dispositivos'. Los usuarios con este rol necesitarán la aprobación del administrador para nuevos dispositivos.",
"approvalsEmptyStatePreviewDescription": "Vista previa: Cuando está habilitado, las solicitudes de dispositivo pendientes aparecerán aquí para su revisión",
"approvalsEmptyStateButtonText": "Administrar roles"
} }
+234 -133
View File
@@ -18,6 +18,8 @@
"componentsMember": "Vous {count, plural, =0 {n'} other {} }êtes membre {count, plural, =0 {d'aucune organisation} one {d'une organisation} other {de # organisations}}.", "componentsMember": "Vous {count, plural, =0 {n'} other {} }êtes membre {count, plural, =0 {d'aucune organisation} one {d'une organisation} other {de # organisations}}.",
"componentsInvalidKey": "Clés de licence invalides ou expirées détectées. Veuillez respecter les conditions de licence pour continuer à utiliser toutes les fonctionnalités.", "componentsInvalidKey": "Clés de licence invalides ou expirées détectées. Veuillez respecter les conditions de licence pour continuer à utiliser toutes les fonctionnalités.",
"dismiss": "Rejeter", "dismiss": "Rejeter",
"subscriptionViolationMessage": "Vous dépassez vos limites pour votre forfait actuel. Corrigez le problème en supprimant des sites, des utilisateurs ou d'autres ressources pour rester dans votre forfait.",
"subscriptionViolationViewBilling": "Voir la facturation",
"componentsLicenseViolation": "Violation de licence : ce serveur utilise {usedSites} nœuds, ce qui dépasse la limite autorisée de {maxSites} nœuds. Respectez les conditions de licence pour continuer à utiliser toutes les fonctionnalités.", "componentsLicenseViolation": "Violation de licence : ce serveur utilise {usedSites} nœuds, ce qui dépasse la limite autorisée de {maxSites} nœuds. Respectez les conditions de licence pour continuer à utiliser toutes les fonctionnalités.",
"componentsSupporterMessage": "Merci de soutenir Pangolin en tant que {tier}!", "componentsSupporterMessage": "Merci de soutenir Pangolin en tant que {tier}!",
"inviteErrorNotValid": "Nous sommes désolés, mais il semble que l'invitation à laquelle vous essayez d'accéder n'ait pas été acceptée ou ne soit plus valide.", "inviteErrorNotValid": "Nous sommes désolés, mais il semble que l'invitation à laquelle vous essayez d'accéder n'ait pas été acceptée ou ne soit plus valide.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Se connecter à n'importe quel réseau", "sitesBannerTitle": "Se connecter à n'importe quel réseau",
"sitesBannerDescription": "Un site est une connexion à un réseau distant qui permet à Pangolin de fournir aux utilisateurs l'accès à des ressources, publiques ou privées, n'importe où. Installez le connecteur de réseau du site (Newt) partout où vous pouvez exécuter un binaire ou un conteneur pour établir la connexion.", "sitesBannerDescription": "Un site est une connexion à un réseau distant qui permet à Pangolin de fournir aux utilisateurs l'accès à des ressources, publiques ou privées, n'importe où. Installez le connecteur de réseau du site (Newt) partout où vous pouvez exécuter un binaire ou un conteneur pour établir la connexion.",
"sitesBannerButtonText": "Installer le site", "sitesBannerButtonText": "Installer le site",
"approvalsBannerTitle": "Approuver ou refuser l'accès à l'appareil",
"approvalsBannerDescription": "Examinez et approuvez ou refusez les demandes d'accès à l'appareil des utilisateurs. Lorsque les autorisations de l'appareil sont requises, les utilisateurs doivent obtenir l'approbation de l'administrateur avant que leurs appareils puissent se connecter aux ressources de votre organisation.",
"approvalsBannerButtonText": "En savoir plus",
"siteCreate": "Créer un nœud", "siteCreate": "Créer un nœud",
"siteCreateDescription2": "Suivez les étapes ci-dessous pour créer et connecter un nouveau nœud", "siteCreateDescription2": "Suivez les étapes ci-dessous pour créer et connecter un nouveau nœud",
"siteCreateDescription": "Créer un nouveau site pour commencer à connecter des ressources", "siteCreateDescription": "Créer un nouveau site pour commencer à connecter des ressources",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Chercher des rôles...", "accessRolesSearch": "Chercher des rôles...",
"accessRolesAdd": "Ajouter un rôle", "accessRolesAdd": "Ajouter un rôle",
"accessRoleDelete": "Supprimer le rôle", "accessRoleDelete": "Supprimer le rôle",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Gérer les approbations",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Voir et gérer les approbations en attente pour accéder à cette organisation",
"description": "Libellé", "description": "Libellé",
"inviteTitle": "Invitations actives", "inviteTitle": "Invitations actives",
"inviteDescription": "Gérer les invitations des autres utilisateurs à rejoindre l'organisation", "inviteDescription": "Gérer les invitations des autres utilisateurs à rejoindre l'organisation",
@@ -452,18 +457,18 @@
"selectDuration": "Sélectionner la durée", "selectDuration": "Sélectionner la durée",
"selectResource": "Sélectionner une ressource", "selectResource": "Sélectionner une ressource",
"filterByResource": "Filtrer par ressource", "filterByResource": "Filtrer par ressource",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Sélectionnez l'État d'Approbation",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtrer par État d'Approbation",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Aucune approbation",
"approvalState": "Approval State", "approvalState": "État d'approbation",
"approve": "Approve", "approve": "Approuver",
"approved": "Approved", "approved": "Approuvé",
"denied": "Denied", "denied": "Refusé",
"deniedApproval": "Denied Approval", "deniedApproval": "Approbation refusée",
"all": "All", "all": "Tous",
"deny": "Deny", "deny": "Refuser",
"viewDetails": "View Details", "viewDetails": "Voir les détails",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "a demandé un nouvel appareil",
"resetFilters": "Réinitialiser les filtres", "resetFilters": "Réinitialiser les filtres",
"totalBlocked": "Demandes bloquées par le Pangolin", "totalBlocked": "Demandes bloquées par le Pangolin",
"totalRequests": "Total des demandes", "totalRequests": "Total des demandes",
@@ -743,28 +748,28 @@
"countries": "Pays", "countries": "Pays",
"accessRoleCreate": "Créer un rôle", "accessRoleCreate": "Créer un rôle",
"accessRoleCreateDescription": "Créer un nouveau rôle pour regrouper les utilisateurs et gérer leurs permissions.", "accessRoleCreateDescription": "Créer un nouveau rôle pour regrouper les utilisateurs et gérer leurs permissions.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Modifier le rôle",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Modifier les informations du rôle.",
"accessRoleCreateSubmit": "Créer un rôle", "accessRoleCreateSubmit": "Créer un rôle",
"accessRoleCreated": "Rôle créé", "accessRoleCreated": "Rôle créé",
"accessRoleCreatedDescription": "Le rôle a été créé avec succès.", "accessRoleCreatedDescription": "Le rôle a été créé avec succès.",
"accessRoleErrorCreate": "Échec de la création du rôle", "accessRoleErrorCreate": "Échec de la création du rôle",
"accessRoleErrorCreateDescription": "Une erreur s'est produite lors de la création du rôle.", "accessRoleErrorCreateDescription": "Une erreur s'est produite lors de la création du rôle.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Mettre à jour un rôle",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Rôle mis à jour",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Le rôle a été mis à jour avec succès.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Approbation traitée",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Définir la décision de la demande d'approbation à approuver.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Définir la décision de la demande d'approbation comme refusée.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Impossible de mettre à jour le rôle",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Une erreur s'est produite lors de la mise à jour du rôle.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Impossible de traiter l'approbation",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Une erreur s'est produite lors du traitement de l'approbation.",
"accessRoleErrorNewRequired": "Un nouveau rôle est requis", "accessRoleErrorNewRequired": "Un nouveau rôle est requis",
"accessRoleErrorRemove": "Échec de la suppression du rôle", "accessRoleErrorRemove": "Échec de la suppression du rôle",
"accessRoleErrorRemoveDescription": "Une erreur s'est produite lors de la suppression du rôle.", "accessRoleErrorRemoveDescription": "Une erreur s'est produite lors de la suppression du rôle.",
"accessRoleName": "Nom du rôle", "accessRoleName": "Nom du rôle",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Vous êtes sur le point de supprimer le rôle `{name}`. Vous ne pouvez pas annuler cette action.",
"accessRoleRemove": "Supprimer le rôle", "accessRoleRemove": "Supprimer le rôle",
"accessRoleRemoveDescription": "Retirer un rôle de l'organisation", "accessRoleRemoveDescription": "Retirer un rôle de l'organisation",
"accessRoleRemoveSubmit": "Supprimer le rôle", "accessRoleRemoveSubmit": "Supprimer le rôle",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Augmenter le nombre de sites", "sitestCountIncrease": "Augmenter le nombre de sites",
"idpManage": "Gérer les fournisseurs d'identité", "idpManage": "Gérer les fournisseurs d'identité",
"idpManageDescription": "Voir et gérer les fournisseurs d'identité dans le système", "idpManageDescription": "Voir et gérer les fournisseurs d'identité dans le système",
"idpGlobalModeBanner": "Les fournisseurs d'identité (IdPs) par organisation sont désactivés sur ce serveur. Il utilise des IdPs globaux (partagés entre toutes les organisations). Gérez les IdPs globaux dans le panneau d'administration <adminPanelLink></adminPanelLink>. Pour activer les IdPs par organisation, éditez la configuration du serveur et réglez le mode IdP sur org. <configDocsLink>Voir la documentation</configDocsLink>. Si vous voulez continuer à utiliser les IdPs globaux et faire disparaître cela des paramètres de l'organisation, définissez explicitement le mode à global dans la configuration.",
"idpGlobalModeBannerUpgradeRequired": "Les fournisseurs d'identité (IdPs) par organisation sont désactivés sur ce serveur. Il utilise des IdPs globaux (partagés entre toutes les organisations). Gérer les IdPs globaux dans le panneau d'administration <adminPanelLink></adminPanelLink>. Pour utiliser les fournisseurs d'identité par organisation, vous devez passer à l'édition Entreprise.",
"idpGlobalModeBannerLicenseRequired": "Les fournisseurs d'identité (IdPs) par organisation sont désactivés sur ce serveur. Il utilise des IdPs globaux (partagés entre toutes les organisations). Gérer les IdPs globaux dans le panneau d'administration <adminPanelLink></adminPanelLink>. Pour utiliser les fournisseurs d'identité par organisation, une licence d'entreprise est requise.",
"idpDeletedDescription": "Fournisseur d'identité supprimé avec succès", "idpDeletedDescription": "Fournisseur d'identité supprimé avec succès",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Êtes-vous sûr de vouloir supprimer définitivement le fournisseur d'identité?", "idpQuestionRemove": "Êtes-vous sûr de vouloir supprimer définitivement le fournisseur d'identité?",
@@ -900,7 +908,7 @@
"inviteAlready": "On dirait que vous avez été invité !", "inviteAlready": "On dirait que vous avez été invité !",
"inviteAlreadyDescription": "Pour accepter l'invitation, vous devez vous connecter ou créer un compte.", "inviteAlreadyDescription": "Pour accepter l'invitation, vous devez vous connecter ou créer un compte.",
"signupQuestion": "Vous avez déjà un compte ?", "signupQuestion": "Vous avez déjà un compte ?",
"login": "Log In", "login": "Se connecter",
"resourceNotFound": "Ressource introuvable", "resourceNotFound": "Ressource introuvable",
"resourceNotFoundDescription": "La ressource que vous essayez d'accéder n'existe pas.", "resourceNotFoundDescription": "La ressource que vous essayez d'accéder n'existe pas.",
"pincodeRequirementsLength": "Le code PIN doit comporter exactement 6 chiffres", "pincodeRequirementsLength": "Le code PIN doit comporter exactement 6 chiffres",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Cette organisation vous demande de changer votre mot de passe tous les {maxDays} jours.", "passwordExpiryDescription": "Cette organisation vous demande de changer votre mot de passe tous les {maxDays} jours.",
"changePasswordNow": "Changer le mot de passe maintenant", "changePasswordNow": "Changer le mot de passe maintenant",
"pincodeAuth": "Code d'authentification", "pincodeAuth": "Code d'authentification",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Soumettre le code",
"passwordResetSubmit": "Demander la réinitialisation", "passwordResetSubmit": "Demander la réinitialisation",
"passwordResetAlreadyHaveCode": "Entrer le code", "passwordResetAlreadyHaveCode": "Entrer le code",
"passwordResetSmtpRequired": "Veuillez contacter votre administrateur", "passwordResetSmtpRequired": "Veuillez contacter votre administrateur",
"passwordResetSmtpRequiredDescription": "Un code de réinitialisation du mot de passe est requis pour réinitialiser votre mot de passe. Veuillez contacter votre administrateur pour obtenir de l'aide.", "passwordResetSmtpRequiredDescription": "Un code de réinitialisation du mot de passe est requis pour réinitialiser votre mot de passe. Veuillez contacter votre administrateur pour obtenir de l'aide.",
"passwordBack": "Retour au mot de passe", "passwordBack": "Retour au mot de passe",
"loginBack": "Go back to main login page", "loginBack": "Revenir à la page de connexion principale",
"signup": "S'inscrire", "signup": "S'inscrire",
"loginStart": "Connectez-vous pour commencer", "loginStart": "Connectez-vous pour commencer",
"idpOidcTokenValidating": "Validation du jeton OIDC", "idpOidcTokenValidating": "Validation du jeton OIDC",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Mettre à jour une organisation IDP", "actionUpdateIdpOrg": "Mettre à jour une organisation IDP",
"actionCreateClient": "Créer un client", "actionCreateClient": "Créer un client",
"actionDeleteClient": "Supprimer le client", "actionDeleteClient": "Supprimer le client",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Archiver le client",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Désarchiver le client",
"actionBlockClient": "Block Client", "actionBlockClient": "Bloquer le client",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "bloquer le client",
"actionUpdateClient": "Mettre à jour le client", "actionUpdateClient": "Mettre à jour le client",
"actionListClients": "Liste des clients", "actionListClients": "Liste des clients",
"actionGetClient": "Obtenir le client", "actionGetClient": "Obtenir le client",
@@ -1164,14 +1172,14 @@
"searchProgress": "Rechercher...", "searchProgress": "Rechercher...",
"create": "Créer", "create": "Créer",
"orgs": "Organisations", "orgs": "Organisations",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Une erreur inattendue s'est produite. Veuillez réessayer.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "La connexion est requise pour votre appareil.",
"passwordForgot": "Mot de passe oublié ?", "passwordForgot": "Mot de passe oublié ?",
"otpAuth": "Authentification à deux facteurs", "otpAuth": "Authentification à deux facteurs",
"otpAuthDescription": "Entrez le code de votre application d'authentification ou l'un de vos codes de secours à usage unique.", "otpAuthDescription": "Entrez le code de votre application d'authentification ou l'un de vos codes de secours à usage unique.",
"otpAuthSubmit": "Soumettre le code", "otpAuthSubmit": "Soumettre le code",
"idpContinue": "Ou continuer avec", "idpContinue": "Ou continuer avec",
"otpAuthBack": "Back to Password", "otpAuthBack": "Retour au mot de passe",
"navbar": "Menu de navigation", "navbar": "Menu de navigation",
"navbarDescription": "Menu de navigation principal de l'application", "navbarDescription": "Menu de navigation principal de l'application",
"navbarDocsLink": "Documentation", "navbarDocsLink": "Documentation",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Aperçu", "sidebarOverview": "Aperçu",
"sidebarHome": "Domicile", "sidebarHome": "Domicile",
"sidebarSites": "Nœuds", "sidebarSites": "Nœuds",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Demandes d'approbation",
"sidebarResources": "Ressource", "sidebarResources": "Ressource",
"sidebarProxyResources": "Publique", "sidebarProxyResources": "Publique",
"sidebarClientResources": "Privé", "sidebarClientResources": "Privé",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Fournisseurs d'identité", "sidebarIdentityProviders": "Fournisseurs d'identité",
"sidebarLicense": "Licence", "sidebarLicense": "Licence",
"sidebarClients": "Clients", "sidebarClients": "Clients",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Périphériques utilisateur",
"sidebarMachineClients": "Machines", "sidebarMachineClients": "Machines",
"sidebarDomains": "Domaines", "sidebarDomains": "Domaines",
"sidebarGeneral": "Gérer", "sidebarGeneral": "Gérer",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Une erreur s'est produite lors de la création du compte administrateur du serveur.", "setupErrorCreateAdmin": "Une erreur s'est produite lors de la création du compte administrateur du serveur.",
"certificateStatus": "Statut du certificat", "certificateStatus": "Statut du certificat",
"loading": "Chargement", "loading": "Chargement",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Chargement de l'analyse",
"restart": "Redémarrer", "restart": "Redémarrer",
"domains": "Domaines", "domains": "Domaines",
"domainsDescription": "Créer et gérer les domaines disponibles dans l'organisation", "domainsDescription": "Créer et gérer les domaines disponibles dans l'organisation",
@@ -1336,7 +1344,7 @@
"refreshError": "Échec de l'actualisation des données", "refreshError": "Échec de l'actualisation des données",
"verified": "Vérifié", "verified": "Vérifié",
"pending": "En attente", "pending": "En attente",
"pendingApproval": "Pending Approval", "pendingApproval": "En attente d'approbation",
"sidebarBilling": "Facturation", "sidebarBilling": "Facturation",
"billing": "Facturation", "billing": "Facturation",
"orgBillingDescription": "Gérer les informations de facturation et les abonnements", "orgBillingDescription": "Gérer les informations de facturation et les abonnements",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Vue d'ensemble des limites d'utilisation", "billingUsageLimitsOverview": "Vue d'ensemble des limites d'utilisation",
"billingMonitorUsage": "Surveillez votre consommation par rapport aux limites configurées. Si vous avez besoin d'une augmentation des limites, veuillez nous contacter à support@pangolin.net.", "billingMonitorUsage": "Surveillez votre consommation par rapport aux limites configurées. Si vous avez besoin d'une augmentation des limites, veuillez nous contacter à support@pangolin.net.",
"billingDataUsage": "Utilisation des données", "billingDataUsage": "Utilisation des données",
"billingOnlineTime": "Temps en ligne du site", "billingSites": "Nœuds",
"billingUsers": "Utilisateurs actifs", "billingUsers": "Utilisateurs",
"billingDomains": "Domaines actifs", "billingDomains": "Domaines",
"billingRemoteExitNodes": "Nœuds auto-hébergés actifs", "billingRemoteExitNodes": "Nœuds distants",
"billingNoLimitConfigured": "Aucune limite configurée", "billingNoLimitConfigured": "Aucune limite configurée",
"billingEstimatedPeriod": "Période de facturation estimée", "billingEstimatedPeriod": "Période de facturation estimée",
"billingIncludedUsage": "Utilisation incluse", "billingIncludedUsage": "Utilisation incluse",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Échec pour obtenir l'URL du portail", "billingFailedToGetPortalUrl": "Échec pour obtenir l'URL du portail",
"billingPortalError": "Erreur du portail", "billingPortalError": "Erreur du portail",
"billingDataUsageInfo": "Vous êtes facturé pour toutes les données transférées via vos tunnels sécurisés lorsque vous êtes connecté au cloud. Cela inclut le trafic entrant et sortant sur tous vos sites. Lorsque vous atteignez votre limite, vos sites se déconnecteront jusqu'à ce que vous mettiez à niveau votre plan ou réduisiez l'utilisation. Les données ne sont pas facturées lors de l'utilisation de nœuds.", "billingDataUsageInfo": "Vous êtes facturé pour toutes les données transférées via vos tunnels sécurisés lorsque vous êtes connecté au cloud. Cela inclut le trafic entrant et sortant sur tous vos sites. Lorsque vous atteignez votre limite, vos sites se déconnecteront jusqu'à ce que vous mettiez à niveau votre plan ou réduisiez l'utilisation. Les données ne sont pas facturées lors de l'utilisation de nœuds.",
"billingOnlineTimeInfo": "Vous êtes facturé en fonction de la durée de connexion de vos sites au cloud. Par exemple, 44 640 minutes équivaut à un site fonctionnant 24/7 pendant un mois complet. Lorsque vous atteignez votre limite, vos sites se déconnecteront jusqu'à ce que vous mettiez à niveau votre forfait ou réduisiez votre consommation. Le temps n'est pas facturé lors de l'utilisation de nœuds.", "billingSInfo": "Combien de sites vous pouvez utiliser",
"billingUsersInfo": "Vous êtes facturé pour chaque utilisateur de l'organisation. La facturation est calculée quotidiennement en fonction du nombre de comptes d'utilisateurs actifs dans votre organisation.", "billingUsersInfo": "Combien d'utilisateurs vous pouvez utiliser",
"billingDomainInfo": "Vous êtes facturé pour chaque domaine de l'organisation. La facturation est calculée quotidiennement en fonction du nombre de comptes de domaine actifs dans votre organisation.", "billingDomainInfo": "Combien de domaines vous pouvez utiliser",
"billingRemoteExitNodesInfo": "Vous êtes facturé pour chaque noeud géré dans l'organisation. La facturation est calculée quotidiennement en fonction du nombre de nœuds gérés actifs dans votre organisation.", "billingRemoteExitNodesInfo": "Combien de nœuds distants vous pouvez utiliser",
"billingLicenseKeys": "Clés de licence",
"billingLicenseKeysDescription": "Gérer vos abonnements à la clé de licence",
"billingLicenseSubscription": "Abonnement à la licence",
"billingInactive": "Inactif",
"billingLicenseItem": "Article de la licence",
"billingQuantity": "Quantité",
"billingTotal": "total",
"billingModifyLicenses": "Modifier l'abonnement à la licence",
"domainNotFound": "Domaine introuvable", "domainNotFound": "Domaine introuvable",
"domainNotFoundDescription": "Cette ressource est désactivée car le domaine n'existe plus dans notre système. Veuillez définir un nouveau domaine pour cette ressource.", "domainNotFoundDescription": "Cette ressource est désactivée car le domaine n'existe plus dans notre système. Veuillez définir un nouveau domaine pour cette ressource.",
"failed": "Échec", "failed": "Échec",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Clé de sécurité supprimée avec succès", "securityKeyRemoveSuccess": "Clé de sécurité supprimée avec succès",
"securityKeyRemoveError": "Échec de la suppression de la clé de sécurité", "securityKeyRemoveError": "Échec de la suppression de la clé de sécurité",
"securityKeyLoadError": "Échec du chargement des clés de sécurité", "securityKeyLoadError": "Échec du chargement des clés de sécurité",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Utiliser la clé de sécurité",
"securityKeyAuthError": "Échec de l'authentification avec la clé de sécurité", "securityKeyAuthError": "Échec de l'authentification avec la clé de sécurité",
"securityKeyRecommendation": "Envisagez d'enregistrer une autre clé de sécurité sur un appareil différent pour vous assurer de ne pas être bloqué de votre compte.", "securityKeyRecommendation": "Envisagez d'enregistrer une autre clé de sécurité sur un appareil différent pour vous assurer de ne pas être bloqué de votre compte.",
"registering": "Enregistrement...", "registering": "Enregistrement...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Le numéro de port est requis pour les ressources non-HTTP", "resourcePortRequired": "Le numéro de port est requis pour les ressources non-HTTP",
"resourcePortNotAllowed": "Le numéro de port ne doit pas être défini pour les ressources HTTP", "resourcePortNotAllowed": "Le numéro de port ne doit pas être défini pour les ressources HTTP",
"billingPricingCalculatorLink": "Calculateur de prix", "billingPricingCalculatorLink": "Calculateur de prix",
"billingYourPlan": "Votre plan",
"billingViewOrModifyPlan": "Voir ou modifier votre forfait actuel",
"billingViewPlanDetails": "Voir les détails du plan",
"billingUsageAndLimits": "Utilisation et limites",
"billingViewUsageAndLimits": "Voir les limites de votre plan et l'utilisation actuelle",
"billingCurrentUsage": "Utilisation actuelle",
"billingMaximumLimits": "Limites maximum",
"billingRemoteNodes": "Nœuds distants",
"billingUnlimited": "Illimité",
"billingPaidLicenseKeys": "Clés de licence payantes",
"billingManageLicenseSubscription": "Gérer votre abonnement pour les clés de licence auto-hébergées payantes",
"billingCurrentKeys": "Clés actuelles",
"billingModifyCurrentPlan": "Modifier le plan actuel",
"billingConfirmUpgrade": "Confirmer la mise à niveau",
"billingConfirmDowngrade": "Confirmer la rétrogradation",
"billingConfirmUpgradeDescription": "Vous êtes sur le point de mettre à niveau votre offre. Examinez les nouvelles limites et les nouveaux prix ci-dessous.",
"billingConfirmDowngradeDescription": "Vous êtes sur le point de rétrograder votre forfait. Examinez les nouvelles limites et les prix ci-dessous.",
"billingPlanIncludes": "Le forfait comprend",
"billingProcessing": "Traitement en cours...",
"billingConfirmUpgradeButton": "Confirmer la mise à niveau",
"billingConfirmDowngradeButton": "Confirmer la rétrogradation",
"billingLimitViolationWarning": "Utilisation dépassée les nouvelles limites de plan",
"billingLimitViolationDescription": "Votre utilisation actuelle dépasse les limites de ce plan. Après rétrogradation, toutes les actions seront désactivées jusqu'à ce que vous réduisiez l'utilisation dans les nouvelles limites. Veuillez consulter les fonctionnalités ci-dessous qui dépassent actuellement les limites. Limites en violation :",
"billingFeatureLossWarning": "Avis de disponibilité des fonctionnalités",
"billingFeatureLossDescription": "En rétrogradant, les fonctionnalités non disponibles dans le nouveau plan seront automatiquement désactivées. Certains paramètres et configurations peuvent être perdus. Veuillez consulter la matrice de prix pour comprendre quelles fonctionnalités ne seront plus disponibles.",
"billingUsageExceedsLimit": "L'utilisation actuelle ({current}) dépasse la limite ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Je suis d'accord avec", "IAgreeToThe": "Je suis d'accord avec",
"termsOfService": "les conditions d'utilisation", "termsOfService": "les conditions d'utilisation",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Intervalle sain", "IntervalSeconds": "Intervalle sain",
"timeoutSeconds": "Délai d'attente (sec)", "timeoutSeconds": "Délai d'attente (sec)",
"timeIsInSeconds": "Le temps est exprimé en secondes", "timeIsInSeconds": "Le temps est exprimé en secondes",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Exiger les autorisations de l'appareil",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Les utilisateurs ayant ce rôle ont besoin de nouveaux périphériques approuvés par un administrateur avant de pouvoir se connecter et accéder aux ressources.",
"retryAttempts": "Tentatives de réessai", "retryAttempts": "Tentatives de réessai",
"expectedResponseCodes": "Codes de réponse attendus", "expectedResponseCodes": "Codes de réponse attendus",
"expectedResponseCodesDescription": "Code de statut HTTP indiquant un état de santé satisfaisant. Si non renseigné, 200-300 est considéré comme satisfaisant.", "expectedResponseCodesDescription": "Code de statut HTTP indiquant un état de santé satisfaisant. Si non renseigné, 200-300 est considéré comme satisfaisant.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Aucune ressource interne trouvée.", "resourcesTableNoInternalResourcesFound": "Aucune ressource interne trouvée.",
"resourcesTableDestination": "Destination", "resourcesTableDestination": "Destination",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Adresse de l'alias",
"resourcesTableAliasAddressInfo": "Cette adresse fait partie du sous-réseau utilitaire de l'organisation. Elle est utilisée pour résoudre les enregistrements d'alias en utilisant une résolution DNS interne.",
"resourcesTableClients": "Clients", "resourcesTableClients": "Clients",
"resourcesTableAndOnlyAccessibleInternally": "et sont uniquement accessibles en interne lorsqu'elles sont connectées avec un client.", "resourcesTableAndOnlyAccessibleInternally": "et sont uniquement accessibles en interne lorsqu'elles sont connectées avec un client.",
"resourcesTableNoTargets": "Aucune cible", "resourcesTableNoTargets": "Aucune cible",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Choisissez votre fournisseur d'identité pour continuer", "orgAuthChooseIdpDescription": "Choisissez votre fournisseur d'identité pour continuer",
"orgAuthNoIdpConfigured": "Cette organisation n'a aucun fournisseur d'identité configuré. Vous pouvez vous connecter avec votre identité Pangolin à la place.", "orgAuthNoIdpConfigured": "Cette organisation n'a aucun fournisseur d'identité configuré. Vous pouvez vous connecter avec votre identité Pangolin à la place.",
"orgAuthSignInWithPangolin": "Se connecter avec Pangolin", "orgAuthSignInWithPangolin": "Se connecter avec Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Se connecter à une organisation",
"orgAuthSelectOrgTitle": "Connexion à l'organisation", "orgAuthSelectOrgTitle": "Connexion à l'organisation",
"orgAuthSelectOrgDescription": "Entrez votre identifiant d'organisation pour continuer", "orgAuthSelectOrgDescription": "Entrez votre identifiant d'organisation pour continuer",
"orgAuthOrgIdPlaceholder": "votre-organisation", "orgAuthOrgIdPlaceholder": "votre-organisation",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Retour à la connexion standard", "orgAuthBackToSignIn": "Retour à la connexion standard",
"orgAuthNoAccount": "Vous n'avez pas de compte ?", "orgAuthNoAccount": "Vous n'avez pas de compte ?",
"subscriptionRequiredToUse": "Un abonnement est requis pour utiliser cette fonctionnalité.", "subscriptionRequiredToUse": "Un abonnement est requis pour utiliser cette fonctionnalité.",
"mustUpgradeToUse": "Vous devez mettre à jour votre abonnement pour utiliser cette fonctionnalité.",
"subscriptionRequiredTierToUse": "Cette fonctionnalité nécessite <tierLink>{tier}</tierLink> ou supérieur.",
"upgradeToTierToUse": "Passez à <tierLink>{tier}</tierLink> ou plus pour utiliser cette fonctionnalité.",
"subscriptionTierTier1": "Domicile",
"subscriptionTierTier2": "Equipe",
"subscriptionTierTier3": "Entreprise",
"subscriptionTierEnterprise": "Entreprise",
"idpDisabled": "Les fournisseurs d'identité sont désactivés.", "idpDisabled": "Les fournisseurs d'identité sont désactivés.",
"orgAuthPageDisabled": "La page d'authentification de l'organisation est désactivée.", "orgAuthPageDisabled": "La page d'authentification de l'organisation est désactivée.",
"domainRestartedDescription": "La vérification du domaine a été redémarrée avec succès", "domainRestartedDescription": "La vérification du domaine a été redémarrée avec succès",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Obtenir une licence",
"description": "Choisissez un plan et dites-nous comment vous comptez utiliser Pangolin.",
"chooseTier": "Choisissez votre forfait",
"viewPricingLink": "Voir les prix, les fonctionnalités et les limites",
"tiers": {
"starter": {
"title": "Démarrage",
"description": "Fonctionnalités d'entreprise, 25 utilisateurs, 25 sites et un support communautaire."
},
"scale": {
"title": "Échelle",
"description": "Fonctionnalités d'entreprise, 50 utilisateurs, 50 sites et une prise en charge prioritaire."
}
},
"personalUseOnly": "Utilisation personnelle uniquement (licence gratuite — sans checkout)",
"buttons": {
"continueToCheckout": "Continuer vers le paiement"
},
"toasts": {
"checkoutError": {
"title": "Erreur de paiement",
"description": "Impossible de commencer la commande. Veuillez réessayer."
}
}
},
"priority": "Priorité", "priority": "Priorité",
"priorityDescription": "Les routes de haute priorité sont évaluées en premier. La priorité = 100 signifie l'ordre automatique (décision du système). Utilisez un autre nombre pour imposer la priorité manuelle.", "priorityDescription": "Les routes de haute priorité sont évaluées en premier. La priorité = 100 signifie l'ordre automatique (décision du système). Utilisez un autre nombre pour imposer la priorité manuelle.",
"instanceName": "Nom de l'instance", "instanceName": "Nom de l'instance",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Fin de l'année suivante", "logRetentionEndOfFollowingYear": "Fin de l'année suivante",
"actionLogsDescription": "Voir l'historique des actions effectuées dans cette organisation", "actionLogsDescription": "Voir l'historique des actions effectuées dans cette organisation",
"accessLogsDescription": "Voir les demandes d'authentification d'accès aux ressources de cette organisation", "accessLogsDescription": "Voir les demandes d'authentification d'accès aux ressources de cette organisation",
"licenseRequiredToUse": "Une licence Entreprise est nécessaire pour utiliser cette fonctionnalité.", "licenseRequiredToUse": "Une licence <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> est nécessaire pour utiliser cette fonctionnalité. Cette fonctionnalité est également disponible dans <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "La version <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> est requise pour utiliser cette fonctionnalité. Cette fonctionnalité est également disponible dans <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Résolveur de certificat", "certResolver": "Résolveur de certificat",
"certResolverDescription": "Sélectionnez le solveur de certificat à utiliser pour cette ressource.", "certResolverDescription": "Sélectionnez le solveur de certificat à utiliser pour cette ressource.",
"selectCertResolver": "Sélectionnez le résolveur de certificat", "selectCertResolver": "Sélectionnez le résolveur de certificat",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Le code doit contenir 9 caractères (par exemple, A1AJ-N5JD)", "deviceCodeInvalidFormat": "Le code doit contenir 9 caractères (par exemple, A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Code invalide ou expiré", "deviceCodeInvalidOrExpired": "Code invalide ou expiré",
"deviceCodeVerifyFailed": "Impossible de vérifier le code de l'appareil", "deviceCodeVerifyFailed": "Impossible de vérifier le code de l'appareil",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Validation du code de l'appareil...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Vérification de l'autorisation de l'appareil...",
"signedInAs": "Connecté en tant que", "signedInAs": "Connecté en tant que",
"deviceCodeEnterPrompt": "Entrez le code affiché sur l'appareil", "deviceCodeEnterPrompt": "Entrez le code affiché sur l'appareil",
"continue": "Continuer", "continue": "Continuer",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Accès à toutes les organisations auxquelles votre compte a accès", "deviceOrganizationsAccess": "Accès à toutes les organisations auxquelles votre compte a accès",
"deviceAuthorize": "Autoriser {applicationName}", "deviceAuthorize": "Autoriser {applicationName}",
"deviceConnected": "Appareil connecté !", "deviceConnected": "Appareil connecté !",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "L'appareil est autorisé à accéder à votre compte. Veuillez retourner à l'application client.",
"pangolinCloud": "Nuage de Pangolin", "pangolinCloud": "Nuage de Pangolin",
"viewDevices": "Voir les appareils", "viewDevices": "Voir les appareils",
"viewDevicesDescription": "Gérer vos appareils connectés", "viewDevicesDescription": "Gérer vos appareils connectés",
@@ -2343,7 +2421,7 @@
"identifier": "Identifiant", "identifier": "Identifiant",
"deviceLoginUseDifferentAccount": "Pas vous ? Utilisez un autre compte.", "deviceLoginUseDifferentAccount": "Pas vous ? Utilisez un autre compte.",
"deviceLoginDeviceRequestingAccessToAccount": "Un appareil demande l'accès à ce compte.", "deviceLoginDeviceRequestingAccessToAccount": "Un appareil demande l'accès à ce compte.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Sélectionnez une méthode d'authentification pour continuer.",
"noData": "Aucune donnée", "noData": "Aucune donnée",
"machineClients": "Clients Machines", "machineClients": "Clients Machines",
"install": "Installer", "install": "Installer",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Nous rencontrons actuellement des difficultés techniques. Veuillez vérifier ultérieurement.", "maintenanceScreenMessage": "Nous rencontrons actuellement des difficultés techniques. Veuillez vérifier ultérieurement.",
"maintenanceScreenEstimatedCompletion": "Achèvement estimé :", "maintenanceScreenEstimatedCompletion": "Achèvement estimé :",
"createInternalResourceDialogDestinationRequired": "La destination est requise", "createInternalResourceDialogDestinationRequired": "La destination est requise",
"available": "Available", "available": "Disponible",
"archived": "Archived", "archived": "Archivé",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Aucun périphérique archivé trouvé",
"deviceArchived": "Device archived", "deviceArchived": "Appareil archivé",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "L'appareil a été archivé avec succès.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Erreur lors de l'archivage du périphérique",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Impossible d'archiver l'appareil",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Êtes-vous sûr de vouloir archiver cet appareil ?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Le périphérique sera archivé et retiré de la liste des périphériques actifs.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Dispositif d'archivage",
"archiveDevice": "Archive Device", "archiveDevice": "Dispositif d'archivage",
"archive": "Archive", "archive": "Archive",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Appareil désarchivé",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "L'appareil a été désarchivé avec succès.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Erreur lors de la désarchivage du périphérique",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Échec de la désarchivage de l'appareil",
"unarchive": "Unarchive", "unarchive": "Désarchiver",
"archiveClient": "Archive Client", "archiveClient": "Archiver le client",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Êtes-vous sûr de vouloir archiver ce client?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Le client sera archivé et retiré de votre liste de clients actifs.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Archiver le client",
"blockClient": "Block Client", "blockClient": "Bloquer le client",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Êtes-vous sûr de vouloir bloquer ce client?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "L'appareil sera forcé de se déconnecter si vous êtes actuellement connecté. Vous pourrez débloquer l'appareil plus tard.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Bloquer le client",
"active": "Active", "active": "Actif",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Nom d'utilisateur ou email",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Sélectionnez votre organisation",
"signInTo": "Log in in to", "signInTo": "Se connecter à",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Continuer avec le mot de passe",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Aucune méthode d'authentification disponible pour cette organisation.",
"enterPassword": "Enter your password", "enterPassword": "Entrez votre mot de passe",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Entrez le code de votre application d'authentification",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Veuillez utiliser votre clé de sécurité pour vous connecter.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Besoin d'un autre compte ?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "En cliquant sur les boutons ci-dessous, vous reconnaissez avoir lu, compris et accepté les <termsOfService>Conditions d'utilisation</termsOfService> et la <privacyPolicy>Politique de confidentialité</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Conditions d'utilisation",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Politique de confidentialité",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Aucun utilisateur trouvé avec ce nom d'utilisateur.",
"verify": "Verify", "verify": "Vérifier",
"signIn": "Sign In", "signIn": "Se connecter",
"forgotPassword": "Forgot password?", "forgotPassword": "Mot de passe oublié ?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Si vous vous êtes déjà connecté, vous pouvez entrer votre nom d'utilisateur ou votre e-mail ci-dessus pour vous authentifier auprès du fournisseur d'identité de votre organisation. C'est plus facile !",
"continueAnyway": "Continue anyway", "continueAnyway": "Continuer quand même",
"dontShowAgain": "Don't show again", "dontShowAgain": "Ne plus afficher",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Le saviez-vous ?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Vous essayez de vous connecter ?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Essayez-vous de vous connecter par l'intermédiaire du fournisseur d'identité de votre organisme?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Connectez-vous ou inscrivez-vous avec votre organisation à la place",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Utiliser un compte différent",
"logIn": "Log In", "logIn": "Se connecter",
"deviceInformation": "Device Information", "deviceInformation": "Informations sur l'appareil",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informations sur l'appareil et l'agent",
"platform": "Platform", "deviceSecurity": "Sécurité de l'appareil",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Informations sur la posture de sécurité de l'appareil",
"windowsVersion": "Windows Version", "platform": "Plateforme",
"iosVersion": "iOS Version", "macosVersion": "Version macOS",
"androidVersion": "Android Version", "windowsVersion": "Version de Windows",
"osVersion": "OS Version", "iosVersion": "Version iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Version d'Android",
"deviceModel": "Device Model", "osVersion": "Version du système d'exploitation",
"serialNumber": "Serial Number", "kernelVersion": "Version du noyau",
"deviceModel": "Modèle de l'appareil",
"serialNumber": "Numéro de série",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Première vue",
"lastSeen": "Last Seen", "lastSeen": "Dernière vue",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "biométrique activée",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Disque chiffré",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Pare-feu activé",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Mises à jour automatiques activées",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM disponible",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirus activé",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Protection contre l'intégrité du système (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Mode furtif du pare-feu",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "Armure d'application",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Afficher les informations et les paramètres de l'appareil",
"devicePendingApprovalDescription": "Cet appareil est en attente d'approbation",
"deviceBlockedDescription": "Cet appareil est actuellement bloqué. Il ne pourra se connecter à aucune ressource à moins d'être débloqué.",
"unblockClient": "Débloquer le client",
"unblockClientDescription": "L'appareil a été débloqué",
"unarchiveClient": "Désarchiver le client",
"unarchiveClientDescription": "L'appareil a été désarchivé",
"block": "Bloquer",
"unblock": "Débloquer",
"deviceActions": "Actions de l'appareil",
"deviceActionsDescription": "Gérer le statut et l'accès de l'appareil",
"devicePendingApprovalBannerDescription": "Cet appareil est en attente d'approbation. Il ne sera pas en mesure de se connecter aux ressources jusqu'à ce qu'il soit approuvé.",
"connected": "Connecté",
"disconnected": "Déconnecté",
"approvalsEmptyStateTitle": "Approbations de l'appareil non activées",
"approvalsEmptyStateDescription": "Activer les autorisations de l'appareil pour les rôles qui nécessitent l'approbation de l'administrateur avant que les utilisateurs puissent connecter de nouveaux appareils.",
"approvalsEmptyStateStep1Title": "Aller aux Rôles",
"approvalsEmptyStateStep1Description": "Accédez aux paramètres de rôles de votre organisation pour configurer les autorisations de l'appareil.",
"approvalsEmptyStateStep2Title": "Activer les autorisations de l'appareil",
"approvalsEmptyStateStep2Description": "Modifier un rôle et activer l'option 'Exiger les autorisations de l'appareil'. Les utilisateurs avec ce rôle auront besoin de l'approbation de l'administrateur pour les nouveaux appareils.",
"approvalsEmptyStatePreviewDescription": "Aperçu: Lorsque cette option est activée, les demandes de périphérique en attente apparaîtront ici pour vérification",
"approvalsEmptyStateButtonText": "Gérer les rôles"
} }
+233 -132
View File
@@ -18,6 +18,8 @@
"componentsMember": "Sei un membro di {count, plural, =0 {nessuna organizzazione} one {un'organizzazione} other {# organizzazioni}}.", "componentsMember": "Sei un membro di {count, plural, =0 {nessuna organizzazione} one {un'organizzazione} other {# organizzazioni}}.",
"componentsInvalidKey": "Rilevata chiave di licenza non valida o scaduta. Segui i termini di licenza per continuare a utilizzare tutte le funzionalità.", "componentsInvalidKey": "Rilevata chiave di licenza non valida o scaduta. Segui i termini di licenza per continuare a utilizzare tutte le funzionalità.",
"dismiss": "Ignora", "dismiss": "Ignora",
"subscriptionViolationMessage": "Hai superato i tuoi limiti per il tuo piano attuale. Correggi il problema rimuovendo siti, utenti o altre risorse per rimanere all'interno del tuo piano.",
"subscriptionViolationViewBilling": "Visualizza fatturazione",
"componentsLicenseViolation": "Violazione della licenza: Questo server sta usando i siti {usedSites} che superano il suo limite concesso in licenza per i siti {maxSites} . Segui i termini di licenza per continuare a usare tutte le funzionalità.", "componentsLicenseViolation": "Violazione della licenza: Questo server sta usando i siti {usedSites} che superano il suo limite concesso in licenza per i siti {maxSites} . Segui i termini di licenza per continuare a usare tutte le funzionalità.",
"componentsSupporterMessage": "Grazie per aver supportato Pangolin come {tier}!", "componentsSupporterMessage": "Grazie per aver supportato Pangolin come {tier}!",
"inviteErrorNotValid": "Siamo spiacenti, ma sembra che l'invito che stai cercando di accedere non sia stato accettato o non sia più valido.", "inviteErrorNotValid": "Siamo spiacenti, ma sembra che l'invito che stai cercando di accedere non sia stato accettato o non sia più valido.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Connetti Qualsiasi Rete", "sitesBannerTitle": "Connetti Qualsiasi Rete",
"sitesBannerDescription": "Un sito è una connessione a una rete remota che consente a Pangolin di fornire accesso alle risorse, pubbliche o private, agli utenti ovunque. Installa il connettore di rete del sito (Newt) ovunque tu possa eseguire un binario o un container per stabilire la connessione.", "sitesBannerDescription": "Un sito è una connessione a una rete remota che consente a Pangolin di fornire accesso alle risorse, pubbliche o private, agli utenti ovunque. Installa il connettore di rete del sito (Newt) ovunque tu possa eseguire un binario o un container per stabilire la connessione.",
"sitesBannerButtonText": "Installa Sito", "sitesBannerButtonText": "Installa Sito",
"approvalsBannerTitle": "Approva o nega l'accesso al dispositivo",
"approvalsBannerDescription": "Controlla e approva o nega le richieste di accesso al dispositivo da parte degli utenti. Quando le approvazioni del dispositivo sono richieste, gli utenti devono ottenere l'approvazione dell'amministratore prima che i loro dispositivi possano connettersi alle risorse della vostra organizzazione.",
"approvalsBannerButtonText": "Scopri di più",
"siteCreate": "Crea Sito", "siteCreate": "Crea Sito",
"siteCreateDescription2": "Segui i passaggi qui sotto per creare e collegare un nuovo sito", "siteCreateDescription2": "Segui i passaggi qui sotto per creare e collegare un nuovo sito",
"siteCreateDescription": "Crea un nuovo sito per iniziare a connettere le risorse", "siteCreateDescription": "Crea un nuovo sito per iniziare a connettere le risorse",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Ricerca ruoli...", "accessRolesSearch": "Ricerca ruoli...",
"accessRolesAdd": "Aggiungi Ruolo", "accessRolesAdd": "Aggiungi Ruolo",
"accessRoleDelete": "Elimina Ruolo", "accessRoleDelete": "Elimina Ruolo",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Gestisci Approvazioni",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Visualizza e gestisci le approvazioni in attesa per accedere a questa organizzazione",
"description": "Descrizione", "description": "Descrizione",
"inviteTitle": "Inviti Aperti", "inviteTitle": "Inviti Aperti",
"inviteDescription": "Gestisci gli inviti per gli altri utenti a unirsi all'organizzazione", "inviteDescription": "Gestisci gli inviti per gli altri utenti a unirsi all'organizzazione",
@@ -452,18 +457,18 @@
"selectDuration": "Seleziona durata", "selectDuration": "Seleziona durata",
"selectResource": "Seleziona Risorsa", "selectResource": "Seleziona Risorsa",
"filterByResource": "Filtra Per Risorsa", "filterByResource": "Filtra Per Risorsa",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Seleziona Stato Di Approvazione",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtra Per Stato Di Approvazione",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Nessuna approvazione",
"approvalState": "Approval State", "approvalState": "Stato Di Approvazione",
"approve": "Approve", "approve": "Approva",
"approved": "Approved", "approved": "Approvato",
"denied": "Denied", "denied": "Negato",
"deniedApproval": "Denied Approval", "deniedApproval": "Omologazione Negata",
"all": "All", "all": "Tutti",
"deny": "Deny", "deny": "Nega",
"viewDetails": "View Details", "viewDetails": "Visualizza Dettagli",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "ha richiesto un nuovo dispositivo",
"resetFilters": "Ripristina Filtri", "resetFilters": "Ripristina Filtri",
"totalBlocked": "Richieste Bloccate Da Pangolino", "totalBlocked": "Richieste Bloccate Da Pangolino",
"totalRequests": "Totale Richieste", "totalRequests": "Totale Richieste",
@@ -743,28 +748,28 @@
"countries": "Paesi", "countries": "Paesi",
"accessRoleCreate": "Crea Ruolo", "accessRoleCreate": "Crea Ruolo",
"accessRoleCreateDescription": "Crea un nuovo ruolo per raggruppare gli utenti e gestire i loro permessi.", "accessRoleCreateDescription": "Crea un nuovo ruolo per raggruppare gli utenti e gestire i loro permessi.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Modifica Ruolo",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Modifica informazioni sul ruolo.",
"accessRoleCreateSubmit": "Crea Ruolo", "accessRoleCreateSubmit": "Crea Ruolo",
"accessRoleCreated": "Ruolo creato", "accessRoleCreated": "Ruolo creato",
"accessRoleCreatedDescription": "Il ruolo è stato creato con successo.", "accessRoleCreatedDescription": "Il ruolo è stato creato con successo.",
"accessRoleErrorCreate": "Impossibile creare il ruolo", "accessRoleErrorCreate": "Impossibile creare il ruolo",
"accessRoleErrorCreateDescription": "Si è verificato un errore durante la creazione del ruolo.", "accessRoleErrorCreateDescription": "Si è verificato un errore durante la creazione del ruolo.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Aggiorna Ruolo",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Ruolo aggiornato",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Il ruolo è stato aggiornato con successo.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Approvazione trattata",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Impostare la decisione di richiesta di approvazione da approvare.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Imposta la decisione di richiesta di approvazione negata.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Impossibile aggiornare il ruolo",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Si è verificato un errore nell'aggiornamento del ruolo.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Impossibile elaborare l'approvazione",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Si è verificato un errore durante l'elaborazione dell'approvazione.",
"accessRoleErrorNewRequired": "Nuovo ruolo richiesto", "accessRoleErrorNewRequired": "Nuovo ruolo richiesto",
"accessRoleErrorRemove": "Impossibile rimuovere il ruolo", "accessRoleErrorRemove": "Impossibile rimuovere il ruolo",
"accessRoleErrorRemoveDescription": "Si è verificato un errore durante la rimozione del ruolo.", "accessRoleErrorRemoveDescription": "Si è verificato un errore durante la rimozione del ruolo.",
"accessRoleName": "Nome Del Ruolo", "accessRoleName": "Nome Del Ruolo",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Stai per eliminare il ruolo `{name}`. Non puoi annullare questa azione.",
"accessRoleRemove": "Rimuovi Ruolo", "accessRoleRemove": "Rimuovi Ruolo",
"accessRoleRemoveDescription": "Rimuovi un ruolo dall'organizzazione", "accessRoleRemoveDescription": "Rimuovi un ruolo dall'organizzazione",
"accessRoleRemoveSubmit": "Rimuovi Ruolo", "accessRoleRemoveSubmit": "Rimuovi Ruolo",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Aumenta conteggio siti", "sitestCountIncrease": "Aumenta conteggio siti",
"idpManage": "Gestisci Provider di Identità", "idpManage": "Gestisci Provider di Identità",
"idpManageDescription": "Visualizza e gestisci i provider di identità nel sistema", "idpManageDescription": "Visualizza e gestisci i provider di identità nel sistema",
"idpGlobalModeBanner": "I provider di identità (IdP) per organizzazione sono disabilitati su questo server. Sta utilizzando IdP globali (condivisi in tutte le organizzazioni). Gestisci IdP globali nel pannello di amministrazione <adminPanelLink></adminPanelLink>. Per abilitare IdP per organizzazione, modificare la configurazione del server e impostare la modalità IdP su org. <configDocsLink>Vedere i documenti</configDocsLink>. Se si desidera continuare a utilizzare IdP globali e far sparire questo dalle impostazioni dell'organizzazione, impostare esplicitamente la modalità globale nella configurazione.",
"idpGlobalModeBannerUpgradeRequired": "I provider di identità (IdP) per organizzazione sono disabilitati su questo server. Utilizza IdP globali (condivisi tra tutte le organizzazioni). Gestisci gli IdP globali nel pannello di amministrazione <adminPanelLink></adminPanelLink>. Per utilizzare i provider di identità per organizzazione, è necessario aggiornare all'edizione Enterprise.",
"idpGlobalModeBannerLicenseRequired": "I provider di identità (IdP) per organizzazione sono disabilitati su questo server. Utilizza IdP globali (condivisi tra tutte le organizzazioni). Gestisci IdP globali nel pannello di amministrazione <adminPanelLink></adminPanelLink>. Per utilizzare provider di identità per organizzazione, è richiesta una licenza Enterprise.",
"idpDeletedDescription": "Provider di identità eliminato con successo", "idpDeletedDescription": "Provider di identità eliminato con successo",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Sei sicuro di voler eliminare definitivamente il provider di identità?", "idpQuestionRemove": "Sei sicuro di voler eliminare definitivamente il provider di identità?",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Questa organizzazione richiede di cambiare la password ogni {maxDays} giorni.", "passwordExpiryDescription": "Questa organizzazione richiede di cambiare la password ogni {maxDays} giorni.",
"changePasswordNow": "Cambia Password Ora", "changePasswordNow": "Cambia Password Ora",
"pincodeAuth": "Codice Autenticatore", "pincodeAuth": "Codice Autenticatore",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Invia codice",
"passwordResetSubmit": "Richiedi Reset", "passwordResetSubmit": "Richiedi Reset",
"passwordResetAlreadyHaveCode": "Inserisci Codice", "passwordResetAlreadyHaveCode": "Inserisci Codice",
"passwordResetSmtpRequired": "Si prega di contattare l'amministratore", "passwordResetSmtpRequired": "Si prega di contattare l'amministratore",
"passwordResetSmtpRequiredDescription": "Per reimpostare la password è necessario un codice di reimpostazione della password. Si prega di contattare l'amministratore per assistenza.", "passwordResetSmtpRequiredDescription": "Per reimpostare la password è necessario un codice di reimpostazione della password. Si prega di contattare l'amministratore per assistenza.",
"passwordBack": "Torna alla Password", "passwordBack": "Torna alla Password",
"loginBack": "Go back to main login page", "loginBack": "Torna alla pagina di accesso principale",
"signup": "Registrati", "signup": "Registrati",
"loginStart": "Accedi per iniziare", "loginStart": "Accedi per iniziare",
"idpOidcTokenValidating": "Convalida token OIDC", "idpOidcTokenValidating": "Convalida token OIDC",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Aggiorna Org IDP", "actionUpdateIdpOrg": "Aggiorna Org IDP",
"actionCreateClient": "Crea Client", "actionCreateClient": "Crea Client",
"actionDeleteClient": "Elimina Client", "actionDeleteClient": "Elimina Client",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Archivia Client",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Annulla Archiviazione Client",
"actionBlockClient": "Block Client", "actionBlockClient": "Blocca Client",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Sblocca Client",
"actionUpdateClient": "Aggiorna Client", "actionUpdateClient": "Aggiorna Client",
"actionListClients": "Elenco Clienti", "actionListClients": "Elenco Clienti",
"actionGetClient": "Ottieni Client", "actionGetClient": "Ottieni Client",
@@ -1164,14 +1172,14 @@
"searchProgress": "Ricerca...", "searchProgress": "Ricerca...",
"create": "Crea", "create": "Crea",
"orgs": "Organizzazioni", "orgs": "Organizzazioni",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Si è verificato un errore imprevisto. Riprova.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Il login è richiesto per il tuo dispositivo.",
"passwordForgot": "Password dimenticata?", "passwordForgot": "Password dimenticata?",
"otpAuth": "Autenticazione a Due Fattori", "otpAuth": "Autenticazione a Due Fattori",
"otpAuthDescription": "Inserisci il codice dalla tua app di autenticazione o uno dei tuoi codici di backup monouso.", "otpAuthDescription": "Inserisci il codice dalla tua app di autenticazione o uno dei tuoi codici di backup monouso.",
"otpAuthSubmit": "Invia Codice", "otpAuthSubmit": "Invia Codice",
"idpContinue": "O continua con", "idpContinue": "O continua con",
"otpAuthBack": "Back to Password", "otpAuthBack": "Torna alla Password",
"navbar": "Menu di Navigazione", "navbar": "Menu di Navigazione",
"navbarDescription": "Menu di navigazione principale dell'applicazione", "navbarDescription": "Menu di navigazione principale dell'applicazione",
"navbarDocsLink": "Documentazione", "navbarDocsLink": "Documentazione",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Panoramica", "sidebarOverview": "Panoramica",
"sidebarHome": "Home", "sidebarHome": "Home",
"sidebarSites": "Siti", "sidebarSites": "Siti",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Richieste Di Approvazione",
"sidebarResources": "Risorse", "sidebarResources": "Risorse",
"sidebarProxyResources": "Pubblico", "sidebarProxyResources": "Pubblico",
"sidebarClientResources": "Privato", "sidebarClientResources": "Privato",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Fornitori Di Identità", "sidebarIdentityProviders": "Fornitori Di Identità",
"sidebarLicense": "Licenza", "sidebarLicense": "Licenza",
"sidebarClients": "Client", "sidebarClients": "Client",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Dispositivi Utente",
"sidebarMachineClients": "Macchine", "sidebarMachineClients": "Macchine",
"sidebarDomains": "Domini", "sidebarDomains": "Domini",
"sidebarGeneral": "Gestisci", "sidebarGeneral": "Gestisci",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Si è verificato un errore durante la creazione dell'account amministratore del server.", "setupErrorCreateAdmin": "Si è verificato un errore durante la creazione dell'account amministratore del server.",
"certificateStatus": "Stato del Certificato", "certificateStatus": "Stato del Certificato",
"loading": "Caricamento", "loading": "Caricamento",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Caricamento Delle Analisi",
"restart": "Riavvia", "restart": "Riavvia",
"domains": "Domini", "domains": "Domini",
"domainsDescription": "Creare e gestire i domini disponibili nell'organizzazione", "domainsDescription": "Creare e gestire i domini disponibili nell'organizzazione",
@@ -1336,7 +1344,7 @@
"refreshError": "Impossibile aggiornare i dati", "refreshError": "Impossibile aggiornare i dati",
"verified": "Verificato", "verified": "Verificato",
"pending": "In attesa", "pending": "In attesa",
"pendingApproval": "Pending Approval", "pendingApproval": "Approvazione In Attesa",
"sidebarBilling": "Fatturazione", "sidebarBilling": "Fatturazione",
"billing": "Fatturazione", "billing": "Fatturazione",
"orgBillingDescription": "Gestisci le informazioni di fatturazione e gli abbonamenti", "orgBillingDescription": "Gestisci le informazioni di fatturazione e gli abbonamenti",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Panoramica dei Limiti di Utilizzo", "billingUsageLimitsOverview": "Panoramica dei Limiti di Utilizzo",
"billingMonitorUsage": "Monitora il tuo utilizzo rispetto ai limiti configurati. Se hai bisogno di aumentare i limiti, contattaci all'indirizzo support@pangolin.net.", "billingMonitorUsage": "Monitora il tuo utilizzo rispetto ai limiti configurati. Se hai bisogno di aumentare i limiti, contattaci all'indirizzo support@pangolin.net.",
"billingDataUsage": "Utilizzo dei Dati", "billingDataUsage": "Utilizzo dei Dati",
"billingOnlineTime": "Tempo Online del Sito", "billingSites": "Siti",
"billingUsers": "Utenti Attivi", "billingUsers": "Utenti",
"billingDomains": "Domini Attivi", "billingDomains": "Domini",
"billingRemoteExitNodes": "Nodi Self-hosted Attivi", "billingRemoteExitNodes": "Nodi Remoti",
"billingNoLimitConfigured": "Nessun limite configurato", "billingNoLimitConfigured": "Nessun limite configurato",
"billingEstimatedPeriod": "Periodo di Fatturazione Stimato", "billingEstimatedPeriod": "Periodo di Fatturazione Stimato",
"billingIncludedUsage": "Utilizzo Incluso", "billingIncludedUsage": "Utilizzo Incluso",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Errore durante l'ottenimento dell'URL del portale", "billingFailedToGetPortalUrl": "Errore durante l'ottenimento dell'URL del portale",
"billingPortalError": "Errore del Portale", "billingPortalError": "Errore del Portale",
"billingDataUsageInfo": "Hai addebitato tutti i dati trasferiti attraverso i tunnel sicuri quando sei connesso al cloud. Questo include sia il traffico in entrata e in uscita attraverso tutti i siti. Quando si raggiunge il limite, i siti si disconnetteranno fino a quando non si aggiorna il piano o si riduce l'utilizzo. I dati non vengono caricati quando si utilizzano nodi.", "billingDataUsageInfo": "Hai addebitato tutti i dati trasferiti attraverso i tunnel sicuri quando sei connesso al cloud. Questo include sia il traffico in entrata e in uscita attraverso tutti i siti. Quando si raggiunge il limite, i siti si disconnetteranno fino a quando non si aggiorna il piano o si riduce l'utilizzo. I dati non vengono caricati quando si utilizzano nodi.",
"billingOnlineTimeInfo": "Ti viene addebitato in base al tempo in cui i tuoi siti rimangono connessi al cloud. Ad esempio, 44,640 minuti è uguale a un sito in esecuzione 24/7 per un mese intero. Quando raggiungi il tuo limite, i tuoi siti si disconnetteranno fino a quando non aggiorni il tuo piano o riduci l'utilizzo. Il tempo non viene caricato quando si usano i nodi.", "billingSInfo": "Quanti siti puoi usare",
"billingUsersInfo": "Sei addebitato per ogni utente nell'organizzazione. La fatturazione viene calcolata quotidianamente in base al numero di account utente attivi nel tuo org.", "billingUsersInfo": "Quanti utenti puoi usare",
"billingDomainInfo": "Sei addebitato per ogni dominio nell'organizzazione. La fatturazione viene calcolata quotidianamente in base al numero di account di dominio attivi nel tuo org.", "billingDomainInfo": "Quanti domini puoi usare",
"billingRemoteExitNodesInfo": "Sei addebitato per ogni nodo gestito nell'organizzazione. La fatturazione viene calcolata quotidianamente in base al numero di nodi gestiti attivi nel tuo org.", "billingRemoteExitNodesInfo": "Quanti nodi remoti puoi usare",
"billingLicenseKeys": "Chiavi di Licenza",
"billingLicenseKeysDescription": "Gestisci le sottoscrizioni alla chiave di licenza",
"billingLicenseSubscription": "Abbonamento Licenza",
"billingInactive": "Inattivo",
"billingLicenseItem": "Elemento Licenza",
"billingQuantity": "Quantità",
"billingTotal": "totale",
"billingModifyLicenses": "Modifica Abbonamento Licenza",
"domainNotFound": "Domini Non Trovati", "domainNotFound": "Domini Non Trovati",
"domainNotFoundDescription": "Questa risorsa è disabilitata perché il dominio non esiste più nel nostro sistema. Si prega di impostare un nuovo dominio per questa risorsa.", "domainNotFoundDescription": "Questa risorsa è disabilitata perché il dominio non esiste più nel nostro sistema. Si prega di impostare un nuovo dominio per questa risorsa.",
"failed": "Fallito", "failed": "Fallito",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Chiave di sicurezza rimossa con successo", "securityKeyRemoveSuccess": "Chiave di sicurezza rimossa con successo",
"securityKeyRemoveError": "Errore durante la rimozione della chiave di sicurezza", "securityKeyRemoveError": "Errore durante la rimozione della chiave di sicurezza",
"securityKeyLoadError": "Errore durante il caricamento delle chiavi di sicurezza", "securityKeyLoadError": "Errore durante il caricamento delle chiavi di sicurezza",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Usa Chiave Di Sicurezza",
"securityKeyAuthError": "Errore durante l'autenticazione con chiave di sicurezza", "securityKeyAuthError": "Errore durante l'autenticazione con chiave di sicurezza",
"securityKeyRecommendation": "Considera di registrare un'altra chiave di sicurezza su un dispositivo diverso per assicurarti di non rimanere bloccato fuori dal tuo account.", "securityKeyRecommendation": "Considera di registrare un'altra chiave di sicurezza su un dispositivo diverso per assicurarti di non rimanere bloccato fuori dal tuo account.",
"registering": "Registrazione in corso...", "registering": "Registrazione in corso...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Numero di porta richiesto per risorse non-HTTP", "resourcePortRequired": "Numero di porta richiesto per risorse non-HTTP",
"resourcePortNotAllowed": "Il numero di porta non deve essere impostato per risorse HTTP", "resourcePortNotAllowed": "Il numero di porta non deve essere impostato per risorse HTTP",
"billingPricingCalculatorLink": "Calcolatore di Prezzi", "billingPricingCalculatorLink": "Calcolatore di Prezzi",
"billingYourPlan": "Il Tuo Piano",
"billingViewOrModifyPlan": "Visualizza o modifica il tuo piano corrente",
"billingViewPlanDetails": "Visualizza Dettagli Piano",
"billingUsageAndLimits": "Utilizzo e limiti",
"billingViewUsageAndLimits": "Visualizza i limiti del tuo piano e l'utilizzo corrente",
"billingCurrentUsage": "Utilizzo Corrente",
"billingMaximumLimits": "Limiti Massimi",
"billingRemoteNodes": "Nodi Remoti",
"billingUnlimited": "Illimitato",
"billingPaidLicenseKeys": "Chiavi Di Licenza Pagate",
"billingManageLicenseSubscription": "Gestisci il tuo abbonamento per le chiavi di licenza self-hosted a pagamento",
"billingCurrentKeys": "Tasti Attuali",
"billingModifyCurrentPlan": "Modifica Il Piano Corrente",
"billingConfirmUpgrade": "Conferma Aggiornamento",
"billingConfirmDowngrade": "Conferma Downgrade",
"billingConfirmUpgradeDescription": "Stai per aggiornare il tuo piano. Controlla i nuovi limiti e prezzi qui sotto.",
"billingConfirmDowngradeDescription": "Stai per effettuare il downgrade del tuo piano. Controlla i nuovi limiti e i prezzi qui sotto.",
"billingPlanIncludes": "Piano Include",
"billingProcessing": "Elaborazione...",
"billingConfirmUpgradeButton": "Conferma Aggiornamento",
"billingConfirmDowngradeButton": "Conferma Downgrade",
"billingLimitViolationWarning": "Utilizzo Supera I Nuovi Limiti Del Piano",
"billingLimitViolationDescription": "Il tuo utilizzo attuale supera i limiti di questo piano. Dopo il downgrading, tutte le azioni saranno disabilitate fino a ridurre l'utilizzo entro i nuovi limiti. Si prega di rivedere le caratteristiche qui sotto che sono attualmente oltre i limiti. Limiti di violazione:",
"billingFeatureLossWarning": "Avviso Di Disponibilità Caratteristica",
"billingFeatureLossDescription": "Con il downgrading, le funzioni non disponibili nel nuovo piano saranno disattivate automaticamente. Alcune impostazioni e configurazioni potrebbero andare perse. Controlla la matrice dei prezzi per capire quali funzioni non saranno più disponibili.",
"billingUsageExceedsLimit": "L'utilizzo corrente ({current}) supera il limite ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Accetto i", "IAgreeToThe": "Accetto i",
"termsOfService": "termini di servizio", "termsOfService": "termini di servizio",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Intervallo Sano", "IntervalSeconds": "Intervallo Sano",
"timeoutSeconds": "Timeout (sec)", "timeoutSeconds": "Timeout (sec)",
"timeIsInSeconds": "Il tempo è in secondi", "timeIsInSeconds": "Il tempo è in secondi",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Richiede Approvazioni Dispositivo",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Gli utenti con questo ruolo hanno bisogno di nuovi dispositivi approvati da un amministratore prima di poter connettersi e accedere alle risorse.",
"retryAttempts": "Tentativi di Riprova", "retryAttempts": "Tentativi di Riprova",
"expectedResponseCodes": "Codici di Risposta Attesi", "expectedResponseCodes": "Codici di Risposta Attesi",
"expectedResponseCodesDescription": "Codice di stato HTTP che indica lo stato di salute. Se lasciato vuoto, considerato sano è compreso tra 200-300.", "expectedResponseCodesDescription": "Codice di stato HTTP che indica lo stato di salute. Se lasciato vuoto, considerato sano è compreso tra 200-300.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Nessuna risorsa interna trovata.", "resourcesTableNoInternalResourcesFound": "Nessuna risorsa interna trovata.",
"resourcesTableDestination": "Destinazione", "resourcesTableDestination": "Destinazione",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Indirizzo Alias",
"resourcesTableAliasAddressInfo": "Questo indirizzo fa parte della subnet di utilità dell'organizzazione. È usato per risolvere i record alias usando la risoluzione DNS interna.",
"resourcesTableClients": "Client", "resourcesTableClients": "Client",
"resourcesTableAndOnlyAccessibleInternally": "e sono accessibili solo internamente quando connessi con un client.", "resourcesTableAndOnlyAccessibleInternally": "e sono accessibili solo internamente quando connessi con un client.",
"resourcesTableNoTargets": "Nessun obiettivo", "resourcesTableNoTargets": "Nessun obiettivo",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Scegli il tuo provider di identità per continuare", "orgAuthChooseIdpDescription": "Scegli il tuo provider di identità per continuare",
"orgAuthNoIdpConfigured": "Questa organizzazione non ha nessun provider di identità configurato. Puoi accedere con la tua identità Pangolin.", "orgAuthNoIdpConfigured": "Questa organizzazione non ha nessun provider di identità configurato. Puoi accedere con la tua identità Pangolin.",
"orgAuthSignInWithPangolin": "Accedi con Pangolino", "orgAuthSignInWithPangolin": "Accedi con Pangolino",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Accedi a un'organizzazione",
"orgAuthSelectOrgTitle": "Accesso Organizzazione", "orgAuthSelectOrgTitle": "Accesso Organizzazione",
"orgAuthSelectOrgDescription": "Inserisci l'ID dell'organizzazione per continuare", "orgAuthSelectOrgDescription": "Inserisci l'ID dell'organizzazione per continuare",
"orgAuthOrgIdPlaceholder": "la-tua-organizzazione", "orgAuthOrgIdPlaceholder": "la-tua-organizzazione",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Torna alla modalità di accesso standard", "orgAuthBackToSignIn": "Torna alla modalità di accesso standard",
"orgAuthNoAccount": "Non hai un account?", "orgAuthNoAccount": "Non hai un account?",
"subscriptionRequiredToUse": "Per utilizzare questa funzionalità è necessario un abbonamento.", "subscriptionRequiredToUse": "Per utilizzare questa funzionalità è necessario un abbonamento.",
"mustUpgradeToUse": "Devi aggiornare il tuo abbonamento per utilizzare questa funzionalità.",
"subscriptionRequiredTierToUse": "Questa funzione richiede <tierLink>{tier}</tierLink> o superiore.",
"upgradeToTierToUse": "Aggiorna ad <tierLink>{tier}</tierLink> o superiore per utilizzare questa funzionalità.",
"subscriptionTierTier1": "Home",
"subscriptionTierTier2": "Squadra",
"subscriptionTierTier3": "Business",
"subscriptionTierEnterprise": "Impresa",
"idpDisabled": "I provider di identità sono disabilitati.", "idpDisabled": "I provider di identità sono disabilitati.",
"orgAuthPageDisabled": "La pagina di autenticazione dell'organizzazione è disabilitata.", "orgAuthPageDisabled": "La pagina di autenticazione dell'organizzazione è disabilitata.",
"domainRestartedDescription": "Verifica del dominio riavviata con successo", "domainRestartedDescription": "Verifica del dominio riavviata con successo",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Ottieni una licenza",
"description": "Scegli un piano e ci dica come intendi usare Pangolin.",
"chooseTier": "Scegli il tuo piano",
"viewPricingLink": "Vedi prezzi, funzionalità e limiti",
"tiers": {
"starter": {
"title": "Avviatore",
"description": "Caratteristiche aziendali, 25 utenti, 25 siti e supporto alla comunità."
},
"scale": {
"title": "Scala",
"description": "Funzionalità aziendali, 50 utenti, 50 siti e supporto prioritario."
}
},
"personalUseOnly": "Solo uso personale (licenza gratuita — nessun checkout)",
"buttons": {
"continueToCheckout": "Continua al Checkout"
},
"toasts": {
"checkoutError": {
"title": "Errore di pagamento",
"description": "Impossibile avviare il checkout. Per favore riprova."
}
}
},
"priority": "Priorità", "priority": "Priorità",
"priorityDescription": "I percorsi prioritari più alti sono valutati prima. Priorità = 100 significa ordinamento automatico (decidi di sistema). Usa un altro numero per applicare la priorità manuale.", "priorityDescription": "I percorsi prioritari più alti sono valutati prima. Priorità = 100 significa ordinamento automatico (decidi di sistema). Usa un altro numero per applicare la priorità manuale.",
"instanceName": "Nome Istanza", "instanceName": "Nome Istanza",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Fine dell'anno successivo", "logRetentionEndOfFollowingYear": "Fine dell'anno successivo",
"actionLogsDescription": "Visualizza una cronologia delle azioni eseguite in questa organizzazione", "actionLogsDescription": "Visualizza una cronologia delle azioni eseguite in questa organizzazione",
"accessLogsDescription": "Visualizza le richieste di autenticazione di accesso per le risorse in questa organizzazione", "accessLogsDescription": "Visualizza le richieste di autenticazione di accesso per le risorse in questa organizzazione",
"licenseRequiredToUse": "Per utilizzare questa funzione è necessaria una licenza Enterprise.", "licenseRequiredToUse": "Per utilizzare questa funzione è necessaria una licenza <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> . Questa funzionalità è disponibile anche in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "L' <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> è necessaria per utilizzare questa funzione. Questa funzionalità è disponibile anche in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Risolutore Di Certificato", "certResolver": "Risolutore Di Certificato",
"certResolverDescription": "Selezionare il risolutore di certificati da usare per questa risorsa.", "certResolverDescription": "Selezionare il risolutore di certificati da usare per questa risorsa.",
"selectCertResolver": "Seleziona Risolutore Di Certificato", "selectCertResolver": "Seleziona Risolutore Di Certificato",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Il codice deve contenere 9 caratteri (es. A1AJ-N5JD)", "deviceCodeInvalidFormat": "Il codice deve contenere 9 caratteri (es. A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Codice non valido o scaduto", "deviceCodeInvalidOrExpired": "Codice non valido o scaduto",
"deviceCodeVerifyFailed": "Impossibile verificare il codice del dispositivo", "deviceCodeVerifyFailed": "Impossibile verificare il codice del dispositivo",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Convalida codice dispositivo...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Verifica autorizzazione dispositivo...",
"signedInAs": "Accesso come", "signedInAs": "Accesso come",
"deviceCodeEnterPrompt": "Inserisci il codice visualizzato sul dispositivo", "deviceCodeEnterPrompt": "Inserisci il codice visualizzato sul dispositivo",
"continue": "Continua", "continue": "Continua",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Accesso a tutte le organizzazioni a cui il tuo account ha accesso", "deviceOrganizationsAccess": "Accesso a tutte le organizzazioni a cui il tuo account ha accesso",
"deviceAuthorize": "Autorizza {applicationName}", "deviceAuthorize": "Autorizza {applicationName}",
"deviceConnected": "Dispositivo Connesso!", "deviceConnected": "Dispositivo Connesso!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Il dispositivo è autorizzato ad accedere al tuo account. Ritorna all'applicazione client.",
"pangolinCloud": "Pangolin Cloud", "pangolinCloud": "Pangolin Cloud",
"viewDevices": "Visualizza Dispositivi", "viewDevices": "Visualizza Dispositivi",
"viewDevicesDescription": "Gestisci i tuoi dispositivi connessi", "viewDevicesDescription": "Gestisci i tuoi dispositivi connessi",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Non tu? Usa un account diverso.", "deviceLoginUseDifferentAccount": "Non tu? Usa un account diverso.",
"deviceLoginDeviceRequestingAccessToAccount": "Un dispositivo sta richiedendo l'accesso a questo account.", "deviceLoginDeviceRequestingAccessToAccount": "Un dispositivo sta richiedendo l'accesso a questo account.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Selezionare un metodo di autenticazione per continuare.",
"noData": "Nessun Dato", "noData": "Nessun Dato",
"machineClients": "Machine Clients", "machineClients": "Machine Clients",
"install": "Installa", "install": "Installa",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Stiamo attualmente riscontrando difficoltà tecniche. Si prega di ricontrollare a breve.", "maintenanceScreenMessage": "Stiamo attualmente riscontrando difficoltà tecniche. Si prega di ricontrollare a breve.",
"maintenanceScreenEstimatedCompletion": "Completamento Stimato:", "maintenanceScreenEstimatedCompletion": "Completamento Stimato:",
"createInternalResourceDialogDestinationRequired": "Destinazione richiesta", "createInternalResourceDialogDestinationRequired": "Destinazione richiesta",
"available": "Available", "available": "Disponibile",
"archived": "Archived", "archived": "Archiviato",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Nessun dispositivo archiviato trovato",
"deviceArchived": "Device archived", "deviceArchived": "Dispositivo archiviato",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Il dispositivo è stato archiviato con successo.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Errore nell'archiviazione del dispositivo",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Impossibile archiviare il dispositivo",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "È sicuro di voler archiviare questo dispositivo?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Il dispositivo verrà archiviato e rimosso dalla lista dei dispositivi attivi.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Archivia Dispositivo",
"archiveDevice": "Archive Device", "archiveDevice": "Archivia Dispositivo",
"archive": "Archive", "archive": "Archivio",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Dispositivo non archiviato",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Il dispositivo è stato disarchiviato con successo.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Errore nel disarchiviare il dispositivo",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Disarchiviazione del dispositivo non riuscita",
"unarchive": "Unarchive", "unarchive": "Disarchivia",
"archiveClient": "Archive Client", "archiveClient": "Archivia Client",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "È sicuro di voler archiviare questo client?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Il client verrà archiviato e rimosso dalla lista dei client attivi.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Archivia Client",
"blockClient": "Block Client", "blockClient": "Blocca Client",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Sei sicuro di voler bloccare questo client?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Il dispositivo sarà forzato a disconnettersi se attualmente connesso. Puoi sbloccare il dispositivo più tardi.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Blocca Client",
"active": "Active", "active": "Attivo",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Nome utente o Email",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Seleziona la tua organizzazione",
"signInTo": "Log in in to", "signInTo": "Accedi a",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Continua con la password",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Nessun metodo di autenticazione disponibile per questa organizzazione.",
"enterPassword": "Enter your password", "enterPassword": "Inserisci la tua password",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Inserisci il codice dalla tua app di autenticazione",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Utilizza la tua chiave di sicurezza per accedere.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Hai bisogno di utilizzare un account diverso?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Facendo clic sui pulsanti qui sotto, si riconosce di aver letto, capire, e accettare i Termini di Servizio <termsOfService></termsOfService> e <privacyPolicy>Privacy Policy</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Termini di servizio",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Politica Sulla Privacy",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Nessun utente trovato con questo nome utente.",
"verify": "Verify", "verify": "Verifica",
"signIn": "Sign In", "signIn": "Accedi",
"forgotPassword": "Forgot password?", "forgotPassword": "Password dimenticata?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Se hai effettuato l'accesso prima, puoi inserire il tuo nome utente o email qui sopra per autenticarti con il provider di identità della tua organizzazione. È più facile!",
"continueAnyway": "Continue anyway", "continueAnyway": "Continua comunque",
"dontShowAgain": "Don't show again", "dontShowAgain": "Non mostrare più",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Lo sapevate?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Cercando di accedere?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Stai cercando di accedere tramite il provider di identità della tua organizzazione?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Accedi o registrati con la tua organizzazione",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Usa un account diverso",
"logIn": "Log In", "logIn": "Log In",
"deviceInformation": "Device Information", "deviceInformation": "Informazioni Sul Dispositivo",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informazioni sul dispositivo e sull'agente",
"platform": "Platform", "deviceSecurity": "Sicurezza Del Dispositivo",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Informazioni postura sicurezza dispositivo",
"windowsVersion": "Windows Version", "platform": "Piattaforma",
"iosVersion": "iOS Version", "macosVersion": "versione macOS",
"androidVersion": "Android Version", "windowsVersion": "Versione Windows",
"osVersion": "OS Version", "iosVersion": "Versione iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Versione Android",
"deviceModel": "Device Model", "osVersion": "Versione OS",
"serialNumber": "Serial Number", "kernelVersion": "Versione Del Kernel",
"deviceModel": "Modello Di Dispositivo",
"serialNumber": "Numero D'Ordine",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Prima Visto",
"lastSeen": "Last Seen", "lastSeen": "Visto L'Ultima",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometria Abilitata",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Cifratura Del Disco",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Firewall Abilitato",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Aggiornamenti Automatici Abilitati",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM Disponibile",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirus Abilitato",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Protezione Dell'Integrità Del Sistema (Sip)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Modo Furtivo Del Firewall",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "AppArmor",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Visualizza informazioni e impostazioni del dispositivo",
"devicePendingApprovalDescription": "Questo dispositivo è in attesa di approvazione",
"deviceBlockedDescription": "Questo dispositivo è attualmente bloccato. Non sarà in grado di connettersi a nessuna risorsa a meno che non sia sbloccato.",
"unblockClient": "Sblocca Client",
"unblockClientDescription": "Il dispositivo è stato sbloccato",
"unarchiveClient": "Annulla Archiviazione Client",
"unarchiveClientDescription": "Il dispositivo è stato disarchiviato",
"block": "Blocca",
"unblock": "Sblocca",
"deviceActions": "Azioni Dispositivo",
"deviceActionsDescription": "Gestisci lo stato del dispositivo e l'accesso",
"devicePendingApprovalBannerDescription": "Questo dispositivo è in attesa di approvazione. Non sarà in grado di connettersi alle risorse fino all'approvazione.",
"connected": "Connesso",
"disconnected": "Disconnesso",
"approvalsEmptyStateTitle": "Approvazioni Dispositivo Non Abilitato",
"approvalsEmptyStateDescription": "Abilita le approvazioni del dispositivo per i ruoli per richiedere l'approvazione dell'amministratore prima che gli utenti possano collegare nuovi dispositivi.",
"approvalsEmptyStateStep1Title": "Vai ai ruoli",
"approvalsEmptyStateStep1Description": "Vai alle impostazioni dei ruoli della tua organizzazione per configurare le approvazioni del dispositivo.",
"approvalsEmptyStateStep2Title": "Abilita Approvazioni Dispositivo",
"approvalsEmptyStateStep2Description": "Modifica un ruolo e abilita l'opzione 'Richiedi l'approvazione del dispositivo'. Gli utenti con questo ruolo avranno bisogno dell'approvazione dell'amministratore per i nuovi dispositivi.",
"approvalsEmptyStatePreviewDescription": "Anteprima: quando abilitato, le richieste di dispositivo in attesa appariranno qui per la revisione",
"approvalsEmptyStateButtonText": "Gestisci Ruoli"
} }
+236 -135
View File
@@ -18,6 +18,8 @@
"componentsMember": "당신은 {count, plural, =0 {조직이 없습니다} one {하나의 조직} other {# 개의 조직}}의 구성원입니다.", "componentsMember": "당신은 {count, plural, =0 {조직이 없습니다} one {하나의 조직} other {# 개의 조직}}의 구성원입니다.",
"componentsInvalidKey": "유효하지 않거나 만료된 라이센스 키가 감지되었습니다. 모든 기능을 계속 사용하려면 라이센스 조건을 따르십시오.", "componentsInvalidKey": "유효하지 않거나 만료된 라이센스 키가 감지되었습니다. 모든 기능을 계속 사용하려면 라이센스 조건을 따르십시오.",
"dismiss": "해제", "dismiss": "해제",
"subscriptionViolationMessage": "현재 계획의 한계를 초과했습니다. 사이트, 사용자 또는 기타 리소스를 제거하여 계획 내에 머물도록 해결하세요.",
"subscriptionViolationViewBilling": "청구 보기",
"componentsLicenseViolation": "라이센스 위반: 이 서버는 {usedSites} 사이트를 사용하고 있으며, 이는 {maxSites} 사이트의 라이센스 한도를 초과합니다. 모든 기능을 계속 사용하려면 라이센스 조건을 따르십시오.", "componentsLicenseViolation": "라이센스 위반: 이 서버는 {usedSites} 사이트를 사용하고 있으며, 이는 {maxSites} 사이트의 라이센스 한도를 초과합니다. 모든 기능을 계속 사용하려면 라이센스 조건을 따르십시오.",
"componentsSupporterMessage": "{tier}로 판골린을 지원해 주셔서 감사합니다!", "componentsSupporterMessage": "{tier}로 판골린을 지원해 주셔서 감사합니다!",
"inviteErrorNotValid": "죄송하지만, 접근하려는 초대가 수락되지 않았거나 더 이상 유효하지 않은 것 같습니다.", "inviteErrorNotValid": "죄송하지만, 접근하려는 초대가 수락되지 않았거나 더 이상 유효하지 않은 것 같습니다.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "모든 네트워크 연결", "sitesBannerTitle": "모든 네트워크 연결",
"sitesBannerDescription": "사이트는 원격 네트워크와의 연결로 Pangolin이 어디서나 사용자에게 공공 및 개인 리소스에 대한 접근을 제공할 수 있게 해 줍니다. 연결을 설정하려면 바이너리 또는 컨테이너로 실행할 수 있는 어디서든 사이트 네트워크 커넥터(Newt)를 설치하세요.", "sitesBannerDescription": "사이트는 원격 네트워크와의 연결로 Pangolin이 어디서나 사용자에게 공공 및 개인 리소스에 대한 접근을 제공할 수 있게 해 줍니다. 연결을 설정하려면 바이너리 또는 컨테이너로 실행할 수 있는 어디서든 사이트 네트워크 커넥터(Newt)를 설치하세요.",
"sitesBannerButtonText": "사이트 설치", "sitesBannerButtonText": "사이트 설치",
"approvalsBannerTitle": "장치 접근 승인 또는 거부",
"approvalsBannerDescription": "사용자의 장치 접근 요청을 검토하고 승인하거나 거부하세요. 장치 승인 요구 시, 관리자의 승인이 필요합니다.",
"approvalsBannerButtonText": "자세히 알아보기",
"siteCreate": "사이트 생성", "siteCreate": "사이트 생성",
"siteCreateDescription2": "아래 단계를 따라 새 사이트를 생성하고 연결하십시오", "siteCreateDescription2": "아래 단계를 따라 새 사이트를 생성하고 연결하십시오",
"siteCreateDescription": "리소스를 연결하기 위해 새 사이트를 생성하세요.", "siteCreateDescription": "리소스를 연결하기 위해 새 사이트를 생성하세요.",
@@ -257,8 +262,8 @@
"accessRolesSearch": "역할 검색...", "accessRolesSearch": "역할 검색...",
"accessRolesAdd": "역할 추가", "accessRolesAdd": "역할 추가",
"accessRoleDelete": "역할 삭제", "accessRoleDelete": "역할 삭제",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "승인 관리",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "이 조직의 접근 승인 대기를 보고 관리하세요.",
"description": "설명", "description": "설명",
"inviteTitle": "열린 초대", "inviteTitle": "열린 초대",
"inviteDescription": "다른 사용자가 조직에 참여하도록 초대장을 관리합니다.", "inviteDescription": "다른 사용자가 조직에 참여하도록 초대장을 관리합니다.",
@@ -452,18 +457,18 @@
"selectDuration": "지속 시간 선택", "selectDuration": "지속 시간 선택",
"selectResource": "리소스 선택", "selectResource": "리소스 선택",
"filterByResource": "리소스별 필터", "filterByResource": "리소스별 필터",
"selectApprovalState": "Select Approval State", "selectApprovalState": "승인 상태 선택",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "승인 상태로 필터링",
"approvalListEmpty": "No approvals", "approvalListEmpty": "승인이 없습니다.",
"approvalState": "Approval State", "approvalState": "승인 상태",
"approve": "Approve", "approve": "승인",
"approved": "Approved", "approved": "승인됨",
"denied": "Denied", "denied": "거부됨",
"deniedApproval": "Denied Approval", "deniedApproval": "승인 거부됨",
"all": "All", "all": "모두",
"deny": "Deny", "deny": "거부",
"viewDetails": "View Details", "viewDetails": "세부 정보 보기",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "새 장치를 요청함",
"resetFilters": "필터 재설정", "resetFilters": "필터 재설정",
"totalBlocked": "Pangolin으로 차단된 요청", "totalBlocked": "Pangolin으로 차단된 요청",
"totalRequests": "총 요청 수", "totalRequests": "총 요청 수",
@@ -743,28 +748,28 @@
"countries": "국가", "countries": "국가",
"accessRoleCreate": "역할 생성", "accessRoleCreate": "역할 생성",
"accessRoleCreateDescription": "사용자를 그룹화하고 권한을 관리하기 위해 새 역할을 생성하세요.", "accessRoleCreateDescription": "사용자를 그룹화하고 권한을 관리하기 위해 새 역할을 생성하세요.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "역할 편집",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "역할 정보 편집.",
"accessRoleCreateSubmit": "역할 생성", "accessRoleCreateSubmit": "역할 생성",
"accessRoleCreated": "역할이 생성되었습니다.", "accessRoleCreated": "역할이 생성되었습니다.",
"accessRoleCreatedDescription": "역할이 성공적으로 생성되었습니다.", "accessRoleCreatedDescription": "역할이 성공적으로 생성되었습니다.",
"accessRoleErrorCreate": "역할 생성 실패", "accessRoleErrorCreate": "역할 생성 실패",
"accessRoleErrorCreateDescription": "역할 생성 중 오류가 발생했습니다.", "accessRoleErrorCreateDescription": "역할 생성 중 오류가 발생했습니다.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "역할 업데이트",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "역할 업데이트됨",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "역할이 성공적으로 업데이트되었습니다.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "승인 처리됨",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "승인 요청을 승인으로 설정.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "승인 요청을 거부로 설정.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "역할 업데이트 실패",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "역할 업데이트 중 오류 발생.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "승인 처리 실패",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "승인 처리 중 오류가 발생했습니다.",
"accessRoleErrorNewRequired": "새 역할이 필요합니다.", "accessRoleErrorNewRequired": "새 역할이 필요합니다.",
"accessRoleErrorRemove": "역할 제거에 실패했습니다.", "accessRoleErrorRemove": "역할 제거에 실패했습니다.",
"accessRoleErrorRemoveDescription": "역할을 제거하는 동안 오류가 발생했습니다.", "accessRoleErrorRemoveDescription": "역할을 제거하는 동안 오류가 발생했습니다.",
"accessRoleName": "역할 이름", "accessRoleName": "역할 이름",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "`{name}` 역할을 삭제하려고 합니다. 이 작업은 되돌릴 수 없습니다.",
"accessRoleRemove": "역할 제거", "accessRoleRemove": "역할 제거",
"accessRoleRemoveDescription": "조직에서 역할 제거", "accessRoleRemoveDescription": "조직에서 역할 제거",
"accessRoleRemoveSubmit": "역할 제거", "accessRoleRemoveSubmit": "역할 제거",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "사이트 수 증가", "sitestCountIncrease": "사이트 수 증가",
"idpManage": "아이덴티티 공급자 관리", "idpManage": "아이덴티티 공급자 관리",
"idpManageDescription": "시스템에서 ID 제공자를 보고 관리합니다", "idpManageDescription": "시스템에서 ID 제공자를 보고 관리합니다",
"idpGlobalModeBanner": "조직별 신원 제공자(IdP)는 이 서버에서 비활성화되었습니다. 이 서버는 모든 조직에 걸쳐 공유된 글로벌 IdP를 사용 중입니다. <adminPanelLink>관리자 패널</adminPanelLink>에서 글로벌 IdP를 관리하십시오. 조직별 IdP를 활성화하려면 서버 설정을 편집하고 IdP 모드를 조직으로 설정하십시오. <configDocsLink>문서 보기</configDocsLink>. 글로벌 IdP 사용을 계속하고 조직 설정에서 이 항목을 제거하려면 설정에서 모드를 글로벌로 명시적으로 설정하십시오.",
"idpGlobalModeBannerUpgradeRequired": "조직별 신원 제공자(IdP)는 이 서버에서 비활성화되었습니다. 이 서버는 모든 조직에 걸쳐 공유된 글로벌 IdP를 사용 중입니다. <adminPanelLink>관리자 패널</adminPanelLink>에서 글로벌 IdP를 관리하십시오. 조직별 신원 제공자를 사용하려면 Enterprise 에디션으로 업그레이드해야 합니다.",
"idpGlobalModeBannerLicenseRequired": "조직별 신원 제공자(IdP)는 이 서버에서 비활성화되었습니다. 이 서버는 모든 조직에 걸쳐 공유된 글로벌 IdP를 사용 중입니다. <adminPanelLink>관리자 패널</adminPanelLink>에서 글로벌 IdP를 관리하십시오. 조직별 신원 제공자를 사용하려면 엔터프라이즈 라이선스가 필요합니다.",
"idpDeletedDescription": "신원 공급자가 성공적으로 삭제되었습니다", "idpDeletedDescription": "신원 공급자가 성공적으로 삭제되었습니다",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "아이덴티티 공급자를 영구적으로 삭제하시겠습니까?", "idpQuestionRemove": "아이덴티티 공급자를 영구적으로 삭제하시겠습니까?",
@@ -900,7 +908,7 @@
"inviteAlready": "초대받은 것 같습니다!", "inviteAlready": "초대받은 것 같습니다!",
"inviteAlreadyDescription": "초대를 수락하려면 로그인하거나 계정을 생성해야 합니다.", "inviteAlreadyDescription": "초대를 수락하려면 로그인하거나 계정을 생성해야 합니다.",
"signupQuestion": "이미 계정이 있습니까?", "signupQuestion": "이미 계정이 있습니까?",
"login": "Log In", "login": "로그인",
"resourceNotFound": "리소스를 찾을 수 없습니다", "resourceNotFound": "리소스를 찾을 수 없습니다",
"resourceNotFoundDescription": "접근하려는 리소스가 존재하지 않습니다.", "resourceNotFoundDescription": "접근하려는 리소스가 존재하지 않습니다.",
"pincodeRequirementsLength": "PIN은 정확히 6자리여야 합니다", "pincodeRequirementsLength": "PIN은 정확히 6자리여야 합니다",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "이 조직은 {maxDays}일마다 비밀번호 변경을 요구합니다.", "passwordExpiryDescription": "이 조직은 {maxDays}일마다 비밀번호 변경을 요구합니다.",
"changePasswordNow": "지금 비밀번호 변경", "changePasswordNow": "지금 비밀번호 변경",
"pincodeAuth": "인증 코드", "pincodeAuth": "인증 코드",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "코드 제출",
"passwordResetSubmit": "재설정 요청", "passwordResetSubmit": "재설정 요청",
"passwordResetAlreadyHaveCode": "코드를 입력하십시오.", "passwordResetAlreadyHaveCode": "코드를 입력하십시오.",
"passwordResetSmtpRequired": "관리자에게 문의하십시오", "passwordResetSmtpRequired": "관리자에게 문의하십시오",
"passwordResetSmtpRequiredDescription": "비밀번호를 재설정하려면 비밀번호 초기화 코드가 필요합니다. 지원을 받으려면 관리자에게 문의하십시오.", "passwordResetSmtpRequiredDescription": "비밀번호를 재설정하려면 비밀번호 초기화 코드가 필요합니다. 지원을 받으려면 관리자에게 문의하십시오.",
"passwordBack": "비밀번호로 돌아가기", "passwordBack": "비밀번호로 돌아가기",
"loginBack": "Go back to main login page", "loginBack": "메인 로그인 페이지로 돌아갑니다.",
"signup": "가입하기", "signup": "가입하기",
"loginStart": "시작하려면 로그인하세요.", "loginStart": "시작하려면 로그인하세요.",
"idpOidcTokenValidating": "OIDC 토큰 검증 중", "idpOidcTokenValidating": "OIDC 토큰 검증 중",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "IDP 조직 업데이트", "actionUpdateIdpOrg": "IDP 조직 업데이트",
"actionCreateClient": "클라이언트 생성", "actionCreateClient": "클라이언트 생성",
"actionDeleteClient": "클라이언트 삭제", "actionDeleteClient": "클라이언트 삭제",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "클라이언트 보관",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "클라이언트 보관 취소",
"actionBlockClient": "Block Client", "actionBlockClient": "클라이언트 차단",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "클라이언트 차단 해제",
"actionUpdateClient": "클라이언트 업데이트", "actionUpdateClient": "클라이언트 업데이트",
"actionListClients": "클라이언트 목록", "actionListClients": "클라이언트 목록",
"actionGetClient": "클라이언트 가져오기", "actionGetClient": "클라이언트 가져오기",
@@ -1164,14 +1172,14 @@
"searchProgress": "검색...", "searchProgress": "검색...",
"create": "생성", "create": "생성",
"orgs": "조직", "orgs": "조직",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "예기치 않은 오류가 발생했습니다. 다시 시도해주세요.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "로그인이 필요합니다.",
"passwordForgot": "비밀번호를 잊으셨나요?", "passwordForgot": "비밀번호를 잊으셨나요?",
"otpAuth": "이중 인증", "otpAuth": "이중 인증",
"otpAuthDescription": "인증 앱에서 코드를 입력하거나 단일 사용 백업 코드 중 하나를 입력하세요.", "otpAuthDescription": "인증 앱에서 코드를 입력하거나 단일 사용 백업 코드 중 하나를 입력하세요.",
"otpAuthSubmit": "코드 제출", "otpAuthSubmit": "코드 제출",
"idpContinue": "또는 계속 진행하십시오.", "idpContinue": "또는 계속 진행하십시오.",
"otpAuthBack": "Back to Password", "otpAuthBack": "비밀번호로 돌아가기",
"navbar": "탐색 메뉴", "navbar": "탐색 메뉴",
"navbarDescription": "애플리케이션의 주요 탐색 메뉴", "navbarDescription": "애플리케이션의 주요 탐색 메뉴",
"navbarDocsLink": "문서", "navbarDocsLink": "문서",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "개요", "sidebarOverview": "개요",
"sidebarHome": "홈", "sidebarHome": "홈",
"sidebarSites": "사이트", "sidebarSites": "사이트",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "승인 요청",
"sidebarResources": "리소스", "sidebarResources": "리소스",
"sidebarProxyResources": "공유", "sidebarProxyResources": "공유",
"sidebarClientResources": "비공개", "sidebarClientResources": "비공개",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "신원 공급자", "sidebarIdentityProviders": "신원 공급자",
"sidebarLicense": "라이선스", "sidebarLicense": "라이선스",
"sidebarClients": "클라이언트", "sidebarClients": "클라이언트",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "사용자 장치",
"sidebarMachineClients": "기계", "sidebarMachineClients": "기계",
"sidebarDomains": "도메인", "sidebarDomains": "도메인",
"sidebarGeneral": "관리", "sidebarGeneral": "관리",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "서버 관리자 계정을 생성하는 동안 오류가 발생했습니다.", "setupErrorCreateAdmin": "서버 관리자 계정을 생성하는 동안 오류가 발생했습니다.",
"certificateStatus": "인증서 상태", "certificateStatus": "인증서 상태",
"loading": "로딩 중", "loading": "로딩 중",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "분석 로딩 중",
"restart": "재시작", "restart": "재시작",
"domains": "도메인", "domains": "도메인",
"domainsDescription": "조직에서 사용 가능한 도메인 생성 및 관리", "domainsDescription": "조직에서 사용 가능한 도메인 생성 및 관리",
@@ -1336,7 +1344,7 @@
"refreshError": "데이터 새로고침 실패", "refreshError": "데이터 새로고침 실패",
"verified": "검증됨", "verified": "검증됨",
"pending": "대기 중", "pending": "대기 중",
"pendingApproval": "Pending Approval", "pendingApproval": "승인 대기 중",
"sidebarBilling": "청구", "sidebarBilling": "청구",
"billing": "청구", "billing": "청구",
"orgBillingDescription": "청구 정보 및 구독을 관리하세요", "orgBillingDescription": "청구 정보 및 구독을 관리하세요",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "사용 한도 개요", "billingUsageLimitsOverview": "사용 한도 개요",
"billingMonitorUsage": "설정된 한도에 대한 사용량을 모니터링합니다. 한도를 늘려야 하는 경우 support@pangolin.net로 연락하십시오.", "billingMonitorUsage": "설정된 한도에 대한 사용량을 모니터링합니다. 한도를 늘려야 하는 경우 support@pangolin.net로 연락하십시오.",
"billingDataUsage": "데이터 사용량", "billingDataUsage": "데이터 사용량",
"billingOnlineTime": "사이트 온라인 시간", "billingSites": "사이트",
"billingUsers": "활성 사용자", "billingUsers": "사용자",
"billingDomains": "활성 도메인", "billingDomains": "도메인",
"billingRemoteExitNodes": "활성 자체 호스팅 노드", "billingRemoteExitNodes": "원격 노드",
"billingNoLimitConfigured": "구성된 한도가 없습니다.", "billingNoLimitConfigured": "구성된 한도가 없습니다.",
"billingEstimatedPeriod": "예상 청구 기간", "billingEstimatedPeriod": "예상 청구 기간",
"billingIncludedUsage": "포함 사용량", "billingIncludedUsage": "포함 사용량",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "포털 URL을 가져오는 데 실패했습니다.", "billingFailedToGetPortalUrl": "포털 URL을 가져오는 데 실패했습니다.",
"billingPortalError": "포털 오류", "billingPortalError": "포털 오류",
"billingDataUsageInfo": "클라우드에 연결할 때 보안 터널을 통해 전송된 모든 데이터에 대해 비용이 청구됩니다. 여기에는 모든 사이트의 들어오고 나가는 트래픽이 포함됩니다. 사용량 한도에 도달하면 플랜을 업그레이드하거나 사용량을 줄일 때까지 사이트가 연결 해제됩니다. 노드를 사용하는 경우 데이터는 요금이 청구되지 않습니다.", "billingDataUsageInfo": "클라우드에 연결할 때 보안 터널을 통해 전송된 모든 데이터에 대해 비용이 청구됩니다. 여기에는 모든 사이트의 들어오고 나가는 트래픽이 포함됩니다. 사용량 한도에 도달하면 플랜을 업그레이드하거나 사용량을 줄일 때까지 사이트가 연결 해제됩니다. 노드를 사용하는 경우 데이터는 요금이 청구되지 않습니다.",
"billingOnlineTimeInfo": "사이트가 클라우드에 연결된 시간에 따라 요금이 청구됩니다. 예를 들어, 44,640분은 사이트가 한 달 내내 24시간 작동하는 것과 같습니다. 사용량 한도에 도달하면 플랜을 업그레이드하거나 사용량을 줄일 때까지 사이트가 연결 해제됩니다. 노드를 사용할 때 시간은 요금이 청구되지 않습니다.", "billingSInfo": "사용할 수 있는 사이트 수",
"billingUsersInfo": "조직의 사용자마다 요금이 청구됩니다. 청구는 조직의 활성 사용자 계정 수에 따라 매일 계산됩니다.", "billingUsersInfo": "사용할 수 있는 사용자 수",
"billingDomainInfo": "조직의 도메인마다 요금이 청구됩니다. 청구는 조직의 활성 도메인 계정 수에 따라 매일 계산됩니다.", "billingDomainInfo": "사용할 수 있는 도메인 수",
"billingRemoteExitNodesInfo": "조직의 관리 노드마다 요금이 청구됩니다. 청구는 조직의 활성 관리 노드 수에 따라 매일 계산됩니다.", "billingRemoteExitNodesInfo": "사용할 수 있는 원격 노드 수",
"billingLicenseKeys": "라이센스 키",
"billingLicenseKeysDescription": "라이센스 키 구독을 관리하세요",
"billingLicenseSubscription": "라이센스 구독",
"billingInactive": "비활성화됨",
"billingLicenseItem": "라이센스 항목",
"billingQuantity": "수량",
"billingTotal": "총계",
"billingModifyLicenses": "라이센스 구독 수정",
"domainNotFound": "도메인을 찾을 수 없습니다", "domainNotFound": "도메인을 찾을 수 없습니다",
"domainNotFoundDescription": "이 리소스는 도메인이 더 이상 시스템에 존재하지 않아 비활성화되었습니다. 이 리소스에 대한 새 도메인을 설정하세요.", "domainNotFoundDescription": "이 리소스는 도메인이 더 이상 시스템에 존재하지 않아 비활성화되었습니다. 이 리소스에 대한 새 도메인을 설정하세요.",
"failed": "실패", "failed": "실패",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "보안 키가 성공적으로 제거되었습니다", "securityKeyRemoveSuccess": "보안 키가 성공적으로 제거되었습니다",
"securityKeyRemoveError": "보안 키 제거 실패", "securityKeyRemoveError": "보안 키 제거 실패",
"securityKeyLoadError": "보안 키를 불러오는 데 실패했습니다", "securityKeyLoadError": "보안 키를 불러오는 데 실패했습니다",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "보안 키 사용",
"securityKeyAuthError": "보안 키를 사용한 인증 실패", "securityKeyAuthError": "보안 키를 사용한 인증 실패",
"securityKeyRecommendation": "항상 계정에 액세스할 수 있도록 다른 장치에 백업 보안 키를 등록하세요.", "securityKeyRecommendation": "항상 계정에 액세스할 수 있도록 다른 장치에 백업 보안 키를 등록하세요.",
"registering": "등록 중...", "registering": "등록 중...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "HTTP 리소스가 아닌 경우 포트 번호가 필요합니다", "resourcePortRequired": "HTTP 리소스가 아닌 경우 포트 번호가 필요합니다",
"resourcePortNotAllowed": "HTTP 리소스에 대해 포트 번호를 설정하지 마세요", "resourcePortNotAllowed": "HTTP 리소스에 대해 포트 번호를 설정하지 마세요",
"billingPricingCalculatorLink": "가격 계산기", "billingPricingCalculatorLink": "가격 계산기",
"billingYourPlan": "귀하의 계획",
"billingViewOrModifyPlan": "현재 계획 보기 또는 수정",
"billingViewPlanDetails": "계획 세부정보 보기",
"billingUsageAndLimits": "사용량 및 제한",
"billingViewUsageAndLimits": "계획의 제한 및 현재 사용량 보기",
"billingCurrentUsage": "현재 사용량",
"billingMaximumLimits": "최대 제한",
"billingRemoteNodes": "원격 노드",
"billingUnlimited": "무제한",
"billingPaidLicenseKeys": "유료 라이센스 키",
"billingManageLicenseSubscription": "유료 독립 호스트 라이센스 키를 위한 구독 관리",
"billingCurrentKeys": "현재 키",
"billingModifyCurrentPlan": "현재 계획 수정",
"billingConfirmUpgrade": "업그레이드 확인",
"billingConfirmDowngrade": "다운그레이드 확인",
"billingConfirmUpgradeDescription": "계획을 업그레이드하려고 합니다. 아래의 새로운 제한 및 가격을 검토하세요.",
"billingConfirmDowngradeDescription": "계획을 다운그레이드하려고 합니다. 아래의 새로운 제한 및 가격을 검토하세요.",
"billingPlanIncludes": "계획 포함",
"billingProcessing": "처리 중...",
"billingConfirmUpgradeButton": "업그레이드 확인",
"billingConfirmDowngradeButton": "다운그레이드 확인",
"billingLimitViolationWarning": "사용량이 새 계획의 제한을 초과합니다.",
"billingLimitViolationDescription": "현재 사용량이 이 계획의 제한을 초과합니다. 다운그레이드 후 모든 작업은 새로운 제한 내로 사용량을 줄일 때까지 비활성화됩니다. 현재 초과된 제한 특징들을 검토하세요. 위반된 제한:",
"billingFeatureLossWarning": "기능 가용성 알림",
"billingFeatureLossDescription": "다운그레이드함으로써 새 계획에서 사용할 수 없는 기능은 자동으로 비활성화됩니다. 일부 설정 및 구성은 손실될 수 있습니다. 어떤 기능들이 더 이상 사용 불가능한지 이해하기 위해 가격표를 검토하세요.",
"billingUsageExceedsLimit": "현재 사용량 ({current})이 제한 ({limit})을 초과합니다",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "동의합니다", "IAgreeToThe": "동의합니다",
"termsOfService": "서비스 약관", "termsOfService": "서비스 약관",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "정상 간격", "IntervalSeconds": "정상 간격",
"timeoutSeconds": "타임아웃(초)", "timeoutSeconds": "타임아웃(초)",
"timeIsInSeconds": "시간은 초 단위입니다", "timeIsInSeconds": "시간은 초 단위입니다",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "장치 승인 요구",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "이 역할을 가진 사용자는 장치가 연결되기 전에 관리자의 승인이 필요합니다.",
"retryAttempts": "재시도 횟수", "retryAttempts": "재시도 횟수",
"expectedResponseCodes": "예상 응답 코드", "expectedResponseCodes": "예상 응답 코드",
"expectedResponseCodesDescription": "정상 상태를 나타내는 HTTP 상태 코드입니다. 비워 두면 200-300이 정상으로 간주됩니다.", "expectedResponseCodesDescription": "정상 상태를 나타내는 HTTP 상태 코드입니다. 비워 두면 200-300이 정상으로 간주됩니다.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "내부 리소스를 찾을 수 없습니다.", "resourcesTableNoInternalResourcesFound": "내부 리소스를 찾을 수 없습니다.",
"resourcesTableDestination": "대상지", "resourcesTableDestination": "대상지",
"resourcesTableAlias": "별칭", "resourcesTableAlias": "별칭",
"resourcesTableAliasAddress": "별칭 주소",
"resourcesTableAliasAddressInfo": "이 주소는 조직의 유틸리티 서브넷의 일부로, 내부 DNS 해석을 사용하여 별칭 레코드를 해석하는 데 사용됩니다.",
"resourcesTableClients": "클라이언트", "resourcesTableClients": "클라이언트",
"resourcesTableAndOnlyAccessibleInternally": "클라이언트와 연결되었을 때만 내부적으로 접근 가능합니다.", "resourcesTableAndOnlyAccessibleInternally": "클라이언트와 연결되었을 때만 내부적으로 접근 가능합니다.",
"resourcesTableNoTargets": "대상 없음", "resourcesTableNoTargets": "대상 없음",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "계속하려면 신원 공급자를 선택하세요.", "orgAuthChooseIdpDescription": "계속하려면 신원 공급자를 선택하세요.",
"orgAuthNoIdpConfigured": "이 조직은 구성된 신원 공급자가 없습니다. 대신 Pangolin 아이덴티티로 로그인할 수 있습니다.", "orgAuthNoIdpConfigured": "이 조직은 구성된 신원 공급자가 없습니다. 대신 Pangolin 아이덴티티로 로그인할 수 있습니다.",
"orgAuthSignInWithPangolin": "Pangolin으로 로그인", "orgAuthSignInWithPangolin": "Pangolin으로 로그인",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "조직에 로그인",
"orgAuthSelectOrgTitle": "조직 로그인", "orgAuthSelectOrgTitle": "조직 로그인",
"orgAuthSelectOrgDescription": "계속하려면 조직 ID를 입력하십시오.", "orgAuthSelectOrgDescription": "계속하려면 조직 ID를 입력하십시오.",
"orgAuthOrgIdPlaceholder": "your-organization", "orgAuthOrgIdPlaceholder": "your-organization",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "표준 로그인을 통해 돌아가기", "orgAuthBackToSignIn": "표준 로그인을 통해 돌아가기",
"orgAuthNoAccount": "계정이 없으신가요?", "orgAuthNoAccount": "계정이 없으신가요?",
"subscriptionRequiredToUse": "이 기능을 사용하려면 구독이 필요합니다.", "subscriptionRequiredToUse": "이 기능을 사용하려면 구독이 필요합니다.",
"mustUpgradeToUse": "이 기능을 사용하려면 구독을 업그레이드해야 합니다.",
"subscriptionRequiredTierToUse": "이 기능을 사용하려면 <tierLink>{tier}</tierLink> 이상의 등급이 필요합니다.",
"upgradeToTierToUse": "이 기능을 사용하려면 <tierLink>{tier}</tierLink> 이상으로 업그레이드하세요.",
"subscriptionTierTier1": "홈",
"subscriptionTierTier2": "팀",
"subscriptionTierTier3": "비즈니스",
"subscriptionTierEnterprise": "기업",
"idpDisabled": "신원 공급자가 비활성화되었습니다.", "idpDisabled": "신원 공급자가 비활성화되었습니다.",
"orgAuthPageDisabled": "조직 인증 페이지가 비활성화되었습니다.", "orgAuthPageDisabled": "조직 인증 페이지가 비활성화되었습니다.",
"domainRestartedDescription": "도메인 인증이 성공적으로 재시작되었습니다.", "domainRestartedDescription": "도메인 인증이 성공적으로 재시작되었습니다.",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "라이센스 가져오기",
"description": "계획을 선택하고 Pangolin을 어떻게 사용할지 알려주세요.",
"chooseTier": "계획 선택",
"viewPricingLink": "가격, 기능 및 제한 보기",
"tiers": {
"starter": {
"title": "스타터",
"description": "기업 기능, 25명의 사용자, 25개의 사이트, 커뮤니티 지원."
},
"scale": {
"title": "스케일",
"description": "기업 기능, 50명의 사용자, 50개의 사이트, 우선 지원."
}
},
"personalUseOnly": "개인 사용 전용 (무료 라이센스 — 체크아웃 없음)",
"buttons": {
"continueToCheckout": "결제로 진행"
},
"toasts": {
"checkoutError": {
"title": "체크아웃 오류",
"description": "체크아웃을 시작할 수 없습니다. 다시 시도하세요."
}
}
},
"priority": "우선순위", "priority": "우선순위",
"priorityDescription": "우선 순위가 높은 경로가 먼저 평가됩니다. 우선 순위 = 100은 자동 정렬(시스템 결정)이 의미합니다. 수동 우선 순위를 적용하려면 다른 숫자를 사용하세요.", "priorityDescription": "우선 순위가 높은 경로가 먼저 평가됩니다. 우선 순위 = 100은 자동 정렬(시스템 결정)이 의미합니다. 수동 우선 순위를 적용하려면 다른 숫자를 사용하세요.",
"instanceName": "인스턴스 이름", "instanceName": "인스턴스 이름",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "다음 연도 말", "logRetentionEndOfFollowingYear": "다음 연도 말",
"actionLogsDescription": "이 조직에서 수행된 작업의 기록을 봅니다", "actionLogsDescription": "이 조직에서 수행된 작업의 기록을 봅니다",
"accessLogsDescription": "이 조직의 자원에 대한 접근 인증 요청을 확인합니다", "accessLogsDescription": "이 조직의 자원에 대한 접근 인증 요청을 확인합니다",
"licenseRequiredToUse": "이 기능을 사용하려면 Enterprise 라이선스가 필요합니다.", "licenseRequiredToUse": "이 기능을 사용하려면 <enterpriseLicenseLink>엔터프라이즈 에디션</enterpriseLicenseLink> 라이선스가 필요합니다. 이 기능은 <pangolinCloudLink>판골린 클라우드</pangolinCloudLink>에서도 사용할 수 있습니다.",
"ossEnterpriseEditionRequired": "이 기능을 사용하려면 <enterpriseEditionLink>엔터프라이즈 에디션</enterpriseEditionLink>이 필요합니다. 이 기능은 <pangolinCloudLink>판골린 클라우드</pangolinCloudLink>에서도 사용할 수 있습니다.",
"certResolver": "인증서 해결사", "certResolver": "인증서 해결사",
"certResolverDescription": "이 리소스에 사용할 인증서 해결사를 선택하세요.", "certResolverDescription": "이 리소스에 사용할 인증서 해결사를 선택하세요.",
"selectCertResolver": "인증서 해결사 선택", "selectCertResolver": "인증서 해결사 선택",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "코드는 9자리여야 합니다 (예: A1AJ-N5JD)", "deviceCodeInvalidFormat": "코드는 9자리여야 합니다 (예: A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "무효하거나 만료된 코드", "deviceCodeInvalidOrExpired": "무효하거나 만료된 코드",
"deviceCodeVerifyFailed": "이메일 확인에 실패했습니다:", "deviceCodeVerifyFailed": "이메일 확인에 실패했습니다:",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "장치 코드 검증 중...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "장치 권한 검증 중...",
"signedInAs": "로그인한 사용자", "signedInAs": "로그인한 사용자",
"deviceCodeEnterPrompt": "기기에 표시된 코드를 입력하세요", "deviceCodeEnterPrompt": "기기에 표시된 코드를 입력하세요",
"continue": "계속 진행하기", "continue": "계속 진행하기",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "계정이 접근할 수 있는 모든 조직에 대한 접근", "deviceOrganizationsAccess": "계정이 접근할 수 있는 모든 조직에 대한 접근",
"deviceAuthorize": "{applicationName} 권한 부여", "deviceAuthorize": "{applicationName} 권한 부여",
"deviceConnected": "장치가 연결되었습니다!", "deviceConnected": "장치가 연결되었습니다!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "장치가 계정 접속을 승인받았습니다. 클라이언트 응용프로그램으로 돌아가세요.",
"pangolinCloud": "판골린 클라우드", "pangolinCloud": "판골린 클라우드",
"viewDevices": "장치 보기", "viewDevices": "장치 보기",
"viewDevicesDescription": "연결된 장치를 관리하십시오", "viewDevicesDescription": "연결된 장치를 관리하십시오",
@@ -2343,7 +2421,7 @@
"identifier": "식별자", "identifier": "식별자",
"deviceLoginUseDifferentAccount": "본인이 아닙니까? 다른 계정을 사용하세요.", "deviceLoginUseDifferentAccount": "본인이 아닙니까? 다른 계정을 사용하세요.",
"deviceLoginDeviceRequestingAccessToAccount": "장치가 이 계정에 접근하려고 합니다.", "deviceLoginDeviceRequestingAccessToAccount": "장치가 이 계정에 접근하려고 합니다.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "계속하려면 인증 방법을 선택하세요.",
"noData": "데이터 없음", "noData": "데이터 없음",
"machineClients": "기계 클라이언트", "machineClients": "기계 클라이언트",
"install": "설치", "install": "설치",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "현재 기술적 문제를 겪고 있습니다. 곧 다시 확인하십시오.", "maintenanceScreenMessage": "현재 기술적 문제를 겪고 있습니다. 곧 다시 확인하십시오.",
"maintenanceScreenEstimatedCompletion": "예상 완료:", "maintenanceScreenEstimatedCompletion": "예상 완료:",
"createInternalResourceDialogDestinationRequired": "목적지가 필요합니다.", "createInternalResourceDialogDestinationRequired": "목적지가 필요합니다.",
"available": "Available", "available": "사용 가능",
"archived": "Archived", "archived": "보관된",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "보관된 장치가 없습니다.",
"deviceArchived": "Device archived", "deviceArchived": "장치가 보관되었습니다.",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "장치가 성공적으로 보관되었습니다.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "장치를 보관하는 동안 오류가 발생했습니다.",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "장치를 보관하는 데 실패했습니다.",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "이 장치를 보관하시겠습니까?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "장치가 보관되며 당신의 활성 장치 목록에서 제거됩니다.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "장치 보관",
"archiveDevice": "Archive Device", "archiveDevice": "장치 보관",
"archive": "Archive", "archive": "보관",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "장치의 보관이 취소되었습니다.",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "장치의 보관이 성공적으로 취소되었습니다.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "장치 보관 해제 중 오류가 발생했습니다.",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "장치 보관 해제 실패",
"unarchive": "Unarchive", "unarchive": "보관 해제",
"archiveClient": "Archive Client", "archiveClient": "클라이언트 보관",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "이 클라이언트를 보관하시겠습니까?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "클라이언트가 보관되며 당신의 활성 클라이언트 목록에서 제거됩니다.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "클라이언트 보관 확인",
"blockClient": "Block Client", "blockClient": "클라이언트 차단",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "이 클라이언트를 차단하시겠습니까?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "장치가 현재 연결되어 있는 경우 강제로 연결이 해제됩니다. 이후에도 차단 해제가 가능합니다.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "클라이언트 차단 확인",
"active": "Active", "active": "활성",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "사용자 이름 또는 이메일",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "조직 선택",
"signInTo": "Log in in to", "signInTo": "로그인 중",
"signInWithPassword": "Continue with Password", "signInWithPassword": "비밀번호로 계속",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "이 조직에는 사용할 수 있는 인증 방법이 없습니다.",
"enterPassword": "Enter your password", "enterPassword": "비밀번호를 입력하세요.",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "인증 앱에서 제공한 코드를 입력하세요.",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "보안 키를 사용해 로그인하세요.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "다른 계정을 사용해야 합니까?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "아래 버튼을 클릭하여 <termsOfService>서비스 약관</termsOfService> <privacyPolicy>개인 정보 보호 정책</privacyPolicy>을 읽고 이해했으며 동의함을 인정합니다.",
"termsOfService": "Terms of Service", "termsOfService": "서비스 약관",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "개인 정보 보호 정책",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "해당 사용자 이름으로 사용자를 찾지 못했습니다.",
"verify": "Verify", "verify": "확인",
"signIn": "Sign In", "signIn": "로그인",
"forgotPassword": "Forgot password?", "forgotPassword": "비밀번호를 잊으셨나요?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "이전에 로그인한 적이 있다면, 위의 사용자 이름 또는 이메일을 입력하여 조직의 ID 공급자로 인증할 수 있습니다. 더 쉬워요!",
"continueAnyway": "Continue anyway", "continueAnyway": "계속하기",
"dontShowAgain": "Don't show again", "dontShowAgain": "다시 보기 않습니다.",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "아셨나요?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "로그인 중이신가요?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "조직의 ID 공급자를 통해 로그인하려고 하십니까?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "대신 조직을 사용하여 로그인 또는 가입",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "다른 계정 사용",
"logIn": "Log In", "logIn": "로그인",
"deviceInformation": "Device Information", "deviceInformation": "장치 정보",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "장치와 에이전트 정보",
"platform": "Platform", "deviceSecurity": "디바이스 보안",
"macosVersion": "macOS Version", "deviceSecurityDescription": "디바이스 보안 상태 정보",
"windowsVersion": "Windows Version", "platform": "플랫폼",
"iosVersion": "iOS Version", "macosVersion": "macOS 버전",
"androidVersion": "Android Version", "windowsVersion": "Windows 버전",
"osVersion": "OS Version", "iosVersion": "iOS 버전",
"kernelVersion": "Kernel Version", "androidVersion": "Android 버전",
"deviceModel": "Device Model", "osVersion": "OS 버전",
"serialNumber": "Serial Number", "kernelVersion": "커널 버전",
"hostname": "Hostname", "deviceModel": "장치 모델",
"firstSeen": "First Seen", "serialNumber": "일련 번호",
"lastSeen": "Last Seen", "hostname": "호스트 이름",
"deviceSettingsDescription": "View device information and settings", "firstSeen": "처음 발견됨",
"devicePendingApprovalDescription": "This device is waiting for approval", "lastSeen": "마지막으로 발견됨",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "biometricsEnabled": "생체 인식 활성화",
"unblockClient": "Unblock Client", "diskEncrypted": "디스크 암호화됨",
"unblockClientDescription": "The device has been unblocked", "firewallEnabled": "방화벽 활성화",
"unarchiveClient": "Unarchive Client", "autoUpdatesEnabled": "자동 업데이트 활성화",
"unarchiveClientDescription": "The device has been unarchived", "tpmAvailable": "TPM 사용 가능",
"block": "Block", "windowsAntivirusEnabled": "안티바이러스 활성화됨",
"unblock": "Unblock", "macosSipEnabled": "시스템 무결성 보호 (SIP)",
"deviceActions": "Device Actions", "macosGatekeeperEnabled": "Gatekeeper",
"deviceActionsDescription": "Manage device status and access", "macosFirewallStealthMode": "방화벽 스텔스 모드",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "linuxAppArmorEnabled": "AppArmor",
"linuxSELinuxEnabled": "SELinux",
"deviceSettingsDescription": "장치 정보 및 설정 보기",
"devicePendingApprovalDescription": "이 장치는 승인을 기다리고 있습니다.",
"deviceBlockedDescription": "이 장치는 현재 차단되었습니다. 차단이 해제되지 않으면 리소스에 연결할 수 없습니다.",
"unblockClient": "클라이언트 차단 해제",
"unblockClientDescription": "장치가 차단 해제되었습니다.",
"unarchiveClient": "클라이언트 보관 취소",
"unarchiveClientDescription": "장치가 보관 해제되었습니다.",
"block": "차단",
"unblock": "차단 해제",
"deviceActions": "장치 작업",
"deviceActionsDescription": "장치 상태 및 접근 관리",
"devicePendingApprovalBannerDescription": "이 장치는 승인 대기 중입니다. 승인될 때까지 리소스에 연결할 수 없습니다.",
"connected": "연결됨",
"disconnected": "연결 해제됨",
"approvalsEmptyStateTitle": "장치 승인 비활성화됨",
"approvalsEmptyStateDescription": "사용자가 새 장치를 연결하기 전에 관리자의 승인을 필요로 하도록 역할에 대해 장치 승인을 활성화하세요.",
"approvalsEmptyStateStep1Title": "역할로 이동",
"approvalsEmptyStateStep1Description": "조직의 역할 설정으로 이동하여 장치 승인을 구성하십시오.",
"approvalsEmptyStateStep2Title": "장치 승인 활성화",
"approvalsEmptyStateStep2Description": "역할을 편집하고 '장치 승인 요구' 옵션을 활성화하세요. 이 역할을 가진 사용자는 새 장치에 대해 관리자의 승인이 필요합니다.",
"approvalsEmptyStatePreviewDescription": "미리 보기: 활성화된 경우, 승인 대기 중인 장치 요청이 검토용으로 여기에 표시됩니다.",
"approvalsEmptyStateButtonText": "역할 관리"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "Du er {count, plural, =0 {ikke medlem av noen organisasjoner} one {medlem av en organisasjon} other {medlem av # organisasjoner}}.", "componentsMember": "Du er {count, plural, =0 {ikke medlem av noen organisasjoner} one {medlem av en organisasjon} other {medlem av # organisasjoner}}.",
"componentsInvalidKey": "Ugyldig eller utgått lisensnøkkel oppdaget. Følg lisensvilkårene for å fortsette å kunne bruke alle funksjonene.", "componentsInvalidKey": "Ugyldig eller utgått lisensnøkkel oppdaget. Følg lisensvilkårene for å fortsette å kunne bruke alle funksjonene.",
"dismiss": "Avvis", "dismiss": "Avvis",
"subscriptionViolationMessage": "Du er utenfor grensen for gjeldende plan. Rett problemet ved å fjerne nettsteder, brukere eller andre ressurser for å bli innenfor planen din.",
"subscriptionViolationViewBilling": "Vis fakturering",
"componentsLicenseViolation": "Lisens Brudd: Denne serveren bruker {usedSites} områder som overskrider den lisensierte grenser av {maxSites} områder. Følg lisensvilkårene for å fortsette å kunne bruke alle funksjonene.", "componentsLicenseViolation": "Lisens Brudd: Denne serveren bruker {usedSites} områder som overskrider den lisensierte grenser av {maxSites} områder. Følg lisensvilkårene for å fortsette å kunne bruke alle funksjonene.",
"componentsSupporterMessage": "Takk for at du støtter Pangolin som en {tier}!", "componentsSupporterMessage": "Takk for at du støtter Pangolin som en {tier}!",
"inviteErrorNotValid": "Beklager, men det ser ut som invitasjonen du prøver å bruke ikke har blitt akseptert eller ikke er gyldig lenger.", "inviteErrorNotValid": "Beklager, men det ser ut som invitasjonen du prøver å bruke ikke har blitt akseptert eller ikke er gyldig lenger.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Koble til alle nettverk", "sitesBannerTitle": "Koble til alle nettverk",
"sitesBannerDescription": "Et nettverk er en tilkobling til et eksternt nettverk som tillater Pangolin å gi tilgang til ressurser, enten offentlige eller private, til brukere hvor som helst. Installer nettverkskontaktet (Newt) hvor som helst du kan kjøre en binærfil eller container for å opprette forbindelsen.", "sitesBannerDescription": "Et nettverk er en tilkobling til et eksternt nettverk som tillater Pangolin å gi tilgang til ressurser, enten offentlige eller private, til brukere hvor som helst. Installer nettverkskontaktet (Newt) hvor som helst du kan kjøre en binærfil eller container for å opprette forbindelsen.",
"sitesBannerButtonText": "Installer nettsted", "sitesBannerButtonText": "Installer nettsted",
"approvalsBannerTitle": "Godkjenn eller avslå tilgang til enhet",
"approvalsBannerDescription": "Gjennomgå og godkjenne eller avslå forespørsler om tilgang fra brukere. Når enhetsgodkjenninger er nødvendig, må brukere få admingodkjenning før enhetene kan koble seg til organisasjonens ressurser.",
"approvalsBannerButtonText": "Lær mer",
"siteCreate": "Opprett område", "siteCreate": "Opprett område",
"siteCreateDescription2": "Følg trinnene nedenfor for å opprette og koble til et nytt område", "siteCreateDescription2": "Følg trinnene nedenfor for å opprette og koble til et nytt område",
"siteCreateDescription": "Opprett et nytt nettsted for å koble til ressurser", "siteCreateDescription": "Opprett et nytt nettsted for å koble til ressurser",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Søk etter roller...", "accessRolesSearch": "Søk etter roller...",
"accessRolesAdd": "Legg til rolle", "accessRolesAdd": "Legg til rolle",
"accessRoleDelete": "Slett rolle", "accessRoleDelete": "Slett rolle",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Behandle godkjenninger",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Se og administrer ventende godkjenninger for tilgang til denne organisasjonen",
"description": "Beskrivelse", "description": "Beskrivelse",
"inviteTitle": "Åpne invitasjoner", "inviteTitle": "Åpne invitasjoner",
"inviteDescription": "Administrer invitasjoner til andre brukere for å bli med i organisasjonen", "inviteDescription": "Administrer invitasjoner til andre brukere for å bli med i organisasjonen",
@@ -452,18 +457,18 @@
"selectDuration": "Velg varighet", "selectDuration": "Velg varighet",
"selectResource": "Velg ressurs", "selectResource": "Velg ressurs",
"filterByResource": "Filtrer etter ressurser", "filterByResource": "Filtrer etter ressurser",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Velg godkjenningsstatus",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtrer etter godkjenningsstatus",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Ingen godkjenninger",
"approvalState": "Approval State", "approvalState": "Godkjennings tilstand",
"approve": "Approve", "approve": "Godkjenn",
"approved": "Approved", "approved": "Godkjent",
"denied": "Denied", "denied": "Avvist",
"deniedApproval": "Denied Approval", "deniedApproval": "Avslått godkjenning",
"all": "All", "all": "Alle",
"deny": "Deny", "deny": "Avslå",
"viewDetails": "View Details", "viewDetails": "Vis detaljer",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "forespurt en ny enhet",
"resetFilters": "Tilbakestill filtre", "resetFilters": "Tilbakestill filtre",
"totalBlocked": "Forespørsler blokkert av Pangolin", "totalBlocked": "Forespørsler blokkert av Pangolin",
"totalRequests": "Totalt antall forespørsler", "totalRequests": "Totalt antall forespørsler",
@@ -743,28 +748,28 @@
"countries": "Land", "countries": "Land",
"accessRoleCreate": "Opprett rolle", "accessRoleCreate": "Opprett rolle",
"accessRoleCreateDescription": "Opprett en ny rolle for å gruppere brukere og administrere deres tillatelser.", "accessRoleCreateDescription": "Opprett en ny rolle for å gruppere brukere og administrere deres tillatelser.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Rediger rolle",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Rediger rolleinformasjon.",
"accessRoleCreateSubmit": "Opprett rolle", "accessRoleCreateSubmit": "Opprett rolle",
"accessRoleCreated": "Rolle opprettet", "accessRoleCreated": "Rolle opprettet",
"accessRoleCreatedDescription": "Rollen er vellykket opprettet.", "accessRoleCreatedDescription": "Rollen er vellykket opprettet.",
"accessRoleErrorCreate": "Klarte ikke å opprette rolle", "accessRoleErrorCreate": "Klarte ikke å opprette rolle",
"accessRoleErrorCreateDescription": "Det oppstod en feil under opprettelse av rollen.", "accessRoleErrorCreateDescription": "Det oppstod en feil under opprettelse av rollen.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Oppdater rolle",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Rollen oppdatert",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Rollen har blitt oppdatert.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Godkjenning behandlet",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Sett godkjenningsforespørsel om å godta.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Sett godkjenningsforespørsel om å nekte.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Kunne ikke oppdatere rolle",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Det oppstod en feil under oppdatering av rollen.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Kunne ikke behandle godkjenning",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Det oppstod en feil under behandling av godkjenningen.",
"accessRoleErrorNewRequired": "Ny rolle kreves", "accessRoleErrorNewRequired": "Ny rolle kreves",
"accessRoleErrorRemove": "Kunne ikke fjerne rolle", "accessRoleErrorRemove": "Kunne ikke fjerne rolle",
"accessRoleErrorRemoveDescription": "Det oppstod en feil under fjerning av rollen.", "accessRoleErrorRemoveDescription": "Det oppstod en feil under fjerning av rollen.",
"accessRoleName": "Rollenavn", "accessRoleName": "Rollenavn",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Du er ferd med å slette rollen `{name}. Du kan ikke angre denne handlingen.",
"accessRoleRemove": "Fjern Rolle", "accessRoleRemove": "Fjern Rolle",
"accessRoleRemoveDescription": "Fjern en rolle fra organisasjonen", "accessRoleRemoveDescription": "Fjern en rolle fra organisasjonen",
"accessRoleRemoveSubmit": "Fjern Rolle", "accessRoleRemoveSubmit": "Fjern Rolle",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Øk antall områder", "sitestCountIncrease": "Øk antall områder",
"idpManage": "Administrer Identitetsleverandører", "idpManage": "Administrer Identitetsleverandører",
"idpManageDescription": "Vis og administrer identitetsleverandører i systemet", "idpManageDescription": "Vis og administrer identitetsleverandører i systemet",
"idpGlobalModeBanner": "Identitetsleverandører (IdPs) per organisasjon er deaktivert på denne serveren. Den bruker globale IdP (delt over alle organisasjoner). Administrer globale IdP'er i <adminPanelLink>admin-panelet</adminPanelLink>. For å aktivere IdP per organisasjon, rediger serverkonfigurasjonen og sett IdP-modus til org. <configDocsLink>Se dokumentasjonen</configDocsLink>. Hvis du vil fortsette å bruke globale IdPs og få denne til å forsvinne fra organisasjonens innstillinger, satt eksplisitt modusen til global i konfigurasjonen.",
"idpGlobalModeBannerUpgradeRequired": "Identitetsleverandører (IdPs) per organisasjon er deaktivert på denne serveren. Den bruker globale IdPs (delt på tvers av alle organisasjoner). Administrer globale IdPs i <adminPanelLink>administrasjons-panelet</adminPanelLink>. For å bruke identitetsleverandører per organisasjon, må du oppgradere til Enterprise-utgaven.",
"idpGlobalModeBannerLicenseRequired": "Identitetsleverandører (IdPs) per organisasjon er deaktivert på denne serveren. Den bruker globale IdPs (delt på tvers av alle organisasjoner). Administrer globale IdPs i <adminPanelLink>administrasjons-panelet</adminPanelLink>. For å bruke identitetsleverandører per organisasjon, kreves en Enterprise-lisens.",
"idpDeletedDescription": "Identitetsleverandør slettet vellykket", "idpDeletedDescription": "Identitetsleverandør slettet vellykket",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Er du sikker på at du vil slette identitetsleverandøren permanent?", "idpQuestionRemove": "Er du sikker på at du vil slette identitetsleverandøren permanent?",
@@ -900,7 +908,7 @@
"inviteAlready": "Ser ut til at du har blitt invitert!", "inviteAlready": "Ser ut til at du har blitt invitert!",
"inviteAlreadyDescription": "For å godta invitasjonen, må du logge inn eller opprette en konto.", "inviteAlreadyDescription": "For å godta invitasjonen, må du logge inn eller opprette en konto.",
"signupQuestion": "Har du allerede en konto?", "signupQuestion": "Har du allerede en konto?",
"login": "Log In", "login": "Logg inn",
"resourceNotFound": "Ressurs ikke funnet", "resourceNotFound": "Ressurs ikke funnet",
"resourceNotFoundDescription": "Ressursen du prøver å få tilgang til eksisterer ikke.", "resourceNotFoundDescription": "Ressursen du prøver å få tilgang til eksisterer ikke.",
"pincodeRequirementsLength": "PIN må være nøyaktig 6 siffer", "pincodeRequirementsLength": "PIN må være nøyaktig 6 siffer",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Denne organisasjonen krever at du bytter passord hver {maxDays} dag.", "passwordExpiryDescription": "Denne organisasjonen krever at du bytter passord hver {maxDays} dag.",
"changePasswordNow": "Bytt passord nå", "changePasswordNow": "Bytt passord nå",
"pincodeAuth": "Autentiseringskode", "pincodeAuth": "Autentiseringskode",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Send kode",
"passwordResetSubmit": "Be om tilbakestilling", "passwordResetSubmit": "Be om tilbakestilling",
"passwordResetAlreadyHaveCode": "Skriv inn koden", "passwordResetAlreadyHaveCode": "Skriv inn koden",
"passwordResetSmtpRequired": "Kontakt din administrator", "passwordResetSmtpRequired": "Kontakt din administrator",
"passwordResetSmtpRequiredDescription": "En passord tilbakestillingskode kreves for å tilbakestille passordet. Kontakt systemansvarlig for assistanse.", "passwordResetSmtpRequiredDescription": "En passord tilbakestillingskode kreves for å tilbakestille passordet. Kontakt systemansvarlig for assistanse.",
"passwordBack": "Tilbake til passord", "passwordBack": "Tilbake til passord",
"loginBack": "Go back to main login page", "loginBack": "Gå tilbake til innloggingssiden for hovedkontoen",
"signup": "Registrer deg", "signup": "Registrer deg",
"loginStart": "Logg inn for å komme i gang", "loginStart": "Logg inn for å komme i gang",
"idpOidcTokenValidating": "Validerer OIDC-token", "idpOidcTokenValidating": "Validerer OIDC-token",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Oppdater IDP-organisasjon", "actionUpdateIdpOrg": "Oppdater IDP-organisasjon",
"actionCreateClient": "Opprett Klient", "actionCreateClient": "Opprett Klient",
"actionDeleteClient": "Slett klient", "actionDeleteClient": "Slett klient",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Arkiver klient",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Fjern arkivering klient",
"actionBlockClient": "Block Client", "actionBlockClient": "Blokker kunde",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Avblokker klient",
"actionUpdateClient": "Oppdater klient", "actionUpdateClient": "Oppdater klient",
"actionListClients": "List klienter", "actionListClients": "List klienter",
"actionGetClient": "Hent klient", "actionGetClient": "Hent klient",
@@ -1164,14 +1172,14 @@
"searchProgress": "Søker...", "searchProgress": "Søker...",
"create": "Opprett", "create": "Opprett",
"orgs": "Organisasjoner", "orgs": "Organisasjoner",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "En uventet feil oppstod. Vennligst prøv igjen.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Innlogging er nødvendig for enheten din.",
"passwordForgot": "Glemt passordet ditt?", "passwordForgot": "Glemt passordet ditt?",
"otpAuth": "Tofaktorautentisering", "otpAuth": "Tofaktorautentisering",
"otpAuthDescription": "Skriv inn koden fra autentiseringsappen din eller en av dine engangs reservekoder.", "otpAuthDescription": "Skriv inn koden fra autentiseringsappen din eller en av dine engangs reservekoder.",
"otpAuthSubmit": "Send inn kode", "otpAuthSubmit": "Send inn kode",
"idpContinue": "Eller fortsett med", "idpContinue": "Eller fortsett med",
"otpAuthBack": "Back to Password", "otpAuthBack": "Tilbake til passord",
"navbar": "Navigasjonsmeny", "navbar": "Navigasjonsmeny",
"navbarDescription": "Hovednavigasjonsmeny for applikasjonen", "navbarDescription": "Hovednavigasjonsmeny for applikasjonen",
"navbarDocsLink": "Dokumentasjon", "navbarDocsLink": "Dokumentasjon",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Oversikt", "sidebarOverview": "Oversikt",
"sidebarHome": "Hjem", "sidebarHome": "Hjem",
"sidebarSites": "Områder", "sidebarSites": "Områder",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Godkjenningsforespørsler",
"sidebarResources": "Ressurser", "sidebarResources": "Ressurser",
"sidebarProxyResources": "Offentlig", "sidebarProxyResources": "Offentlig",
"sidebarClientResources": "Privat", "sidebarClientResources": "Privat",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Identitetsleverandører", "sidebarIdentityProviders": "Identitetsleverandører",
"sidebarLicense": "Lisens", "sidebarLicense": "Lisens",
"sidebarClients": "Klienter", "sidebarClients": "Klienter",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Bruker Enheter",
"sidebarMachineClients": "Maskiner", "sidebarMachineClients": "Maskiner",
"sidebarDomains": "Domener", "sidebarDomains": "Domener",
"sidebarGeneral": "Administrer", "sidebarGeneral": "Administrer",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "En feil oppstod under opprettelsen av serveradministratorkontoen.", "setupErrorCreateAdmin": "En feil oppstod under opprettelsen av serveradministratorkontoen.",
"certificateStatus": "Sertifikatstatus", "certificateStatus": "Sertifikatstatus",
"loading": "Laster inn", "loading": "Laster inn",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Laster inn analyser",
"restart": "Start på nytt", "restart": "Start på nytt",
"domains": "Domener", "domains": "Domener",
"domainsDescription": "Opprett og behandle domener som er tilgjengelige i organisasjonen", "domainsDescription": "Opprett og behandle domener som er tilgjengelige i organisasjonen",
@@ -1336,7 +1344,7 @@
"refreshError": "Klarte ikke å oppdatere data", "refreshError": "Klarte ikke å oppdatere data",
"verified": "Verifisert", "verified": "Verifisert",
"pending": "Venter", "pending": "Venter",
"pendingApproval": "Pending Approval", "pendingApproval": "Venter på godkjenning",
"sidebarBilling": "Fakturering", "sidebarBilling": "Fakturering",
"billing": "Fakturering", "billing": "Fakturering",
"orgBillingDescription": "Administrer faktureringsinformasjon og abonnementer", "orgBillingDescription": "Administrer faktureringsinformasjon og abonnementer",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Oversikt over bruksgrenser", "billingUsageLimitsOverview": "Oversikt over bruksgrenser",
"billingMonitorUsage": "Overvåk bruken din i forhold til konfigurerte grenser. Hvis du trenger økte grenser, vennligst kontakt support@pangolin.net.", "billingMonitorUsage": "Overvåk bruken din i forhold til konfigurerte grenser. Hvis du trenger økte grenser, vennligst kontakt support@pangolin.net.",
"billingDataUsage": "Databruk", "billingDataUsage": "Databruk",
"billingOnlineTime": "Online tid for nettsteder", "billingSites": "Områder",
"billingUsers": "Aktive brukere", "billingUsers": "Brukere",
"billingDomains": "Aktive domener", "billingDomains": "Domener",
"billingRemoteExitNodes": "Aktive selvstyrte noder", "billingRemoteExitNodes": "Eksterne Noder",
"billingNoLimitConfigured": "Ingen grense konfigurert", "billingNoLimitConfigured": "Ingen grense konfigurert",
"billingEstimatedPeriod": "Estimert faktureringsperiode", "billingEstimatedPeriod": "Estimert faktureringsperiode",
"billingIncludedUsage": "Inkludert Bruk", "billingIncludedUsage": "Inkludert Bruk",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Mislyktes å hente portal URL", "billingFailedToGetPortalUrl": "Mislyktes å hente portal URL",
"billingPortalError": "Portalfeil", "billingPortalError": "Portalfeil",
"billingDataUsageInfo": "Du er ladet for all data som overføres gjennom dine sikre tunneler når du er koblet til skyen. Dette inkluderer både innkommende og utgående trafikk på alle dine nettsteder. Når du når grensen din, vil sidene koble fra til du oppgraderer planen eller reduserer bruken. Data belastes ikke ved bruk av EK-grupper.", "billingDataUsageInfo": "Du er ladet for all data som overføres gjennom dine sikre tunneler når du er koblet til skyen. Dette inkluderer både innkommende og utgående trafikk på alle dine nettsteder. Når du når grensen din, vil sidene koble fra til du oppgraderer planen eller reduserer bruken. Data belastes ikke ved bruk av EK-grupper.",
"billingOnlineTimeInfo": "Du er ladet på hvor lenge sidene dine forblir koblet til skyen. For eksempel tilsvarer 44,640 minutter ett nettsted som går 24/7 i en hel måned. Når du når grensen din, vil sidene koble fra til du oppgraderer planen eller reduserer bruken. Tid belastes ikke når du bruker noder.", "billingSInfo": "Hvor mange nettsteder du kan bruke",
"billingUsersInfo": "Du lades for hver bruker i organisasjonen. Fakturering beregnes daglig basert på antall aktive brukerkontoer i dine org.", "billingUsersInfo": "Hvor mange brukere du kan bruke",
"billingDomainInfo": "Du lades for hvert domene i organisasjonen. Fakturering beregnes daglig basert på antallet aktive domenekontoer i din org.", "billingDomainInfo": "Hvor mange domener du kan bruke",
"billingRemoteExitNodesInfo": "Du lades for hver håndterte node i organisasjonen. Fakturering beregnes daglig basert på antallet aktive håndterte noder i dine org.", "billingRemoteExitNodesInfo": "Hvor mange fjernnoder du kan bruke",
"billingLicenseKeys": "Lisensnøkler",
"billingLicenseKeysDescription": "Administrer dine lisensnøkkelabonnementer",
"billingLicenseSubscription": "Lisens abonnement",
"billingInactive": "Inaktiv",
"billingLicenseItem": "Lisens artikkel",
"billingQuantity": "Antall",
"billingTotal": "totalt",
"billingModifyLicenses": "Endre lisensabonnement",
"domainNotFound": "Domene ikke funnet", "domainNotFound": "Domene ikke funnet",
"domainNotFoundDescription": "Denne ressursen er deaktivert fordi domenet ikke lenger eksisterer i systemet vårt. Vennligst angi et nytt domene for denne ressursen.", "domainNotFoundDescription": "Denne ressursen er deaktivert fordi domenet ikke lenger eksisterer i systemet vårt. Vennligst angi et nytt domene for denne ressursen.",
"failed": "Mislyktes", "failed": "Mislyktes",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Sikkerhetsnøkkel fjernet", "securityKeyRemoveSuccess": "Sikkerhetsnøkkel fjernet",
"securityKeyRemoveError": "Klarte ikke å fjerne sikkerhetsnøkkel", "securityKeyRemoveError": "Klarte ikke å fjerne sikkerhetsnøkkel",
"securityKeyLoadError": "Klarte ikke å laste inn sikkerhetsnøkler", "securityKeyLoadError": "Klarte ikke å laste inn sikkerhetsnøkler",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Bruk sikkerhetsnøkkel",
"securityKeyAuthError": "Klarte ikke å autentisere med sikkerhetsnøkkel", "securityKeyAuthError": "Klarte ikke å autentisere med sikkerhetsnøkkel",
"securityKeyRecommendation": "Registrer en reservesikkerhetsnøkkel på en annen enhet for å sikre at du alltid har tilgang til kontoen din.", "securityKeyRecommendation": "Registrer en reservesikkerhetsnøkkel på en annen enhet for å sikre at du alltid har tilgang til kontoen din.",
"registering": "Registrerer...", "registering": "Registrerer...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Portnummer er påkrevd for ikke-HTTP-ressurser", "resourcePortRequired": "Portnummer er påkrevd for ikke-HTTP-ressurser",
"resourcePortNotAllowed": "Portnummer skal ikke angis for HTTP-ressurser", "resourcePortNotAllowed": "Portnummer skal ikke angis for HTTP-ressurser",
"billingPricingCalculatorLink": "Pris Kalkulator", "billingPricingCalculatorLink": "Pris Kalkulator",
"billingYourPlan": "Din funksjonsplan",
"billingViewOrModifyPlan": "Vis eller endre gjeldende abonnement",
"billingViewPlanDetails": "Se Planleggings detaljer",
"billingUsageAndLimits": "Bruk og grenser",
"billingViewUsageAndLimits": "Se planets grenser og gjeldende bruk",
"billingCurrentUsage": "Gjeldende bruk",
"billingMaximumLimits": "Maks antall grenser",
"billingRemoteNodes": "Eksterne Noder",
"billingUnlimited": "Ubegrenset",
"billingPaidLicenseKeys": "Betalt lisensnøkler",
"billingManageLicenseSubscription": "Administrer abonnementet for betalte lisensnøkler selv hostet",
"billingCurrentKeys": "Nåværende nøkler",
"billingModifyCurrentPlan": "Endre gjeldende plan",
"billingConfirmUpgrade": "Bekreft oppgradering",
"billingConfirmDowngrade": "Bekreft nedgradering",
"billingConfirmUpgradeDescription": "Du er i ferd med å oppgradere abonnementet ditt. Gå gjennom de nye grensene og pris nedenfor.",
"billingConfirmDowngradeDescription": "Du er i ferd med å nedgradere planen din. Gå gjennom de nye grensene og pris nedenfor.",
"billingPlanIncludes": "Plan Inkluderer",
"billingProcessing": "Behandler...",
"billingConfirmUpgradeButton": "Bekreft oppgradering",
"billingConfirmDowngradeButton": "Bekreft nedgradering",
"billingLimitViolationWarning": "Bruk overbelastede grenser for ny plan",
"billingLimitViolationDescription": "Gjeldende bruk overskrider grensene for denne planen. Etter nedgradering vil alle handlinger deaktiveres inntil du reduserer bruken innenfor de nye grensene. Vennligst se igjennom funksjonene under som er i øyeblikket over grensene. Begrensninger i vold:",
"billingFeatureLossWarning": "Fremhev tilgjengelig varsel",
"billingFeatureLossDescription": "Ved å nedgradere vil funksjoner som ikke er tilgjengelige i den nye planen automatisk bli deaktivert. Noen innstillinger og konfigurasjoner kan gå tapt. Vennligst gjennomgå prismatrisen for å forstå hvilke funksjoner som ikke lenger vil være tilgjengelige.",
"billingUsageExceedsLimit": "Gjeldende bruk ({current}) overskrider grensen ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Jeg godtar", "IAgreeToThe": "Jeg godtar",
"termsOfService": "brukervilkårene", "termsOfService": "brukervilkårene",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Sunt intervall", "IntervalSeconds": "Sunt intervall",
"timeoutSeconds": "Tidsavbrudd (sek)", "timeoutSeconds": "Tidsavbrudd (sek)",
"timeIsInSeconds": "Tid er i sekunder", "timeIsInSeconds": "Tid er i sekunder",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Krev enhetsgodkjenning",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Brukere med denne rollen trenger nye enheter godkjent av en admin før de kan koble seg og få tilgang til ressurser.",
"retryAttempts": "Forsøk på nytt", "retryAttempts": "Forsøk på nytt",
"expectedResponseCodes": "Forventede svarkoder", "expectedResponseCodes": "Forventede svarkoder",
"expectedResponseCodesDescription": "HTTP-statuskode som indikerer sunn status. Hvis den blir stående tom, regnes 200-300 som sunn.", "expectedResponseCodesDescription": "HTTP-statuskode som indikerer sunn status. Hvis den blir stående tom, regnes 200-300 som sunn.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Ingen interne ressurser funnet.", "resourcesTableNoInternalResourcesFound": "Ingen interne ressurser funnet.",
"resourcesTableDestination": "Destinasjon", "resourcesTableDestination": "Destinasjon",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Alias adresse",
"resourcesTableAliasAddressInfo": "Denne adressen er en del av organisasjonens undernettverk. Den brukes til å løse aliasposter ved hjelp av intern DNS-oppløsning.",
"resourcesTableClients": "Klienter", "resourcesTableClients": "Klienter",
"resourcesTableAndOnlyAccessibleInternally": "og er kun tilgjengelig internt når de er koblet til med en klient.", "resourcesTableAndOnlyAccessibleInternally": "og er kun tilgjengelig internt når de er koblet til med en klient.",
"resourcesTableNoTargets": "Ingen mål", "resourcesTableNoTargets": "Ingen mål",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Velg din identitet leverandør for å fortsette", "orgAuthChooseIdpDescription": "Velg din identitet leverandør for å fortsette",
"orgAuthNoIdpConfigured": "Denne organisasjonen har ikke noen identitetstjeneste konfigurert. Du kan i stedet logge inn med Pangolin identiteten din.", "orgAuthNoIdpConfigured": "Denne organisasjonen har ikke noen identitetstjeneste konfigurert. Du kan i stedet logge inn med Pangolin identiteten din.",
"orgAuthSignInWithPangolin": "Logg inn med Pangolin", "orgAuthSignInWithPangolin": "Logg inn med Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Logg inn på en organisasjon",
"orgAuthSelectOrgTitle": "Organisasjonsinnlogging", "orgAuthSelectOrgTitle": "Organisasjonsinnlogging",
"orgAuthSelectOrgDescription": "Skriv inn organisasjons-ID-en din for å fortsette", "orgAuthSelectOrgDescription": "Skriv inn organisasjons-ID-en din for å fortsette",
"orgAuthOrgIdPlaceholder": "din-organisasjon", "orgAuthOrgIdPlaceholder": "din-organisasjon",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Tilbake til standard innlogging", "orgAuthBackToSignIn": "Tilbake til standard innlogging",
"orgAuthNoAccount": "Har du ikke konto?", "orgAuthNoAccount": "Har du ikke konto?",
"subscriptionRequiredToUse": "Et abonnement er påkrevd for å bruke denne funksjonen.", "subscriptionRequiredToUse": "Et abonnement er påkrevd for å bruke denne funksjonen.",
"mustUpgradeToUse": "Du må oppgradere ditt abonnement for å bruke denne funksjonen.",
"subscriptionRequiredTierToUse": "Denne funksjonen krever <tierLink>{tier}</tierLink> eller høyere.",
"upgradeToTierToUse": "Oppgrader til <tierLink>{tier}</tierLink> eller høyere for å bruke denne funksjonen.",
"subscriptionTierTier1": "Hjem",
"subscriptionTierTier2": "Lag",
"subscriptionTierTier3": "Forretninger",
"subscriptionTierEnterprise": "Bedrift",
"idpDisabled": "Identitetsleverandører er deaktivert.", "idpDisabled": "Identitetsleverandører er deaktivert.",
"orgAuthPageDisabled": "Informasjons-siden for organisasjon er deaktivert.", "orgAuthPageDisabled": "Informasjons-siden for organisasjon er deaktivert.",
"domainRestartedDescription": "Domene-verifiseringen ble startet på nytt", "domainRestartedDescription": "Domene-verifiseringen ble startet på nytt",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Få en lisens",
"description": "Velg en plan og fortell oss hvordan du planlegger å bruke Pangolin.",
"chooseTier": "Velg din funksjonsplan",
"viewPricingLink": "Se prising, egenskaper og grenser",
"tiers": {
"starter": {
"title": "Begynner",
"description": "Enterprise features, 25 brukere, 25 sitater og støtte fra fellesskapet."
},
"scale": {
"title": "Skala",
"description": "Enterprise features, 50 brukere, 50 nettsteder og prioritetsstøtte."
}
},
"personalUseOnly": "Kun personlig bruk (gratis lisens - ingen utsjekking)",
"buttons": {
"continueToCheckout": "Fortsett til kassen"
},
"toasts": {
"checkoutError": {
"title": "Feil ved utsjekk",
"description": "Kan ikke starte kassen. Prøv på nytt."
}
}
},
"priority": "Prioritet", "priority": "Prioritet",
"priorityDescription": "Høyere prioriterte ruter evalueres først. Prioritet = 100 betyr automatisk bestilling (systembeslutninger). Bruk et annet nummer til å håndheve manuell prioritet.", "priorityDescription": "Høyere prioriterte ruter evalueres først. Prioritet = 100 betyr automatisk bestilling (systembeslutninger). Bruk et annet nummer til å håndheve manuell prioritet.",
"instanceName": "Forekomst navn", "instanceName": "Forekomst navn",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Slutt på neste år", "logRetentionEndOfFollowingYear": "Slutt på neste år",
"actionLogsDescription": "Vis historikk for handlinger som er utført i denne organisasjonen", "actionLogsDescription": "Vis historikk for handlinger som er utført i denne organisasjonen",
"accessLogsDescription": "Vis autoriseringsforespørsler for ressurser i denne organisasjonen", "accessLogsDescription": "Vis autoriseringsforespørsler for ressurser i denne organisasjonen",
"licenseRequiredToUse": "En Enterprise lisens er påkrevd for å bruke denne funksjonen.", "licenseRequiredToUse": "En <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> lisens er påkrevd for å bruke denne funksjonen. Denne funksjonen er også tilgjengelig i <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "<enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> er nødvendig for å bruke denne funksjonen. Denne funksjonen er også tilgjengelig i <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Sertifikat løser", "certResolver": "Sertifikat løser",
"certResolverDescription": "Velg sertifikatløser som skal brukes for denne ressursen.", "certResolverDescription": "Velg sertifikatløser som skal brukes for denne ressursen.",
"selectCertResolver": "Velg sertifikatløser", "selectCertResolver": "Velg sertifikatløser",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Kode må inneholde 9 tegn (f.eks A1AJ-N5JD)", "deviceCodeInvalidFormat": "Kode må inneholde 9 tegn (f.eks A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Ugyldig eller utløpt kode", "deviceCodeInvalidOrExpired": "Ugyldig eller utløpt kode",
"deviceCodeVerifyFailed": "Klarte ikke å bekrefte enhetskoden", "deviceCodeVerifyFailed": "Klarte ikke å bekrefte enhetskoden",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Validerer enhetskode...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Bekrefter enhetens godkjennelse...",
"signedInAs": "Logget inn som", "signedInAs": "Logget inn som",
"deviceCodeEnterPrompt": "Skriv inn koden som vises på enheten", "deviceCodeEnterPrompt": "Skriv inn koden som vises på enheten",
"continue": "Fortsett", "continue": "Fortsett",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Tilgang til alle organisasjoner din konto har tilgang til", "deviceOrganizationsAccess": "Tilgang til alle organisasjoner din konto har tilgang til",
"deviceAuthorize": "Autoriser {applicationName}", "deviceAuthorize": "Autoriser {applicationName}",
"deviceConnected": "Enhet tilkoblet!", "deviceConnected": "Enhet tilkoblet!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Enheten er autorisert for tilgang til kontoen. Vennligst gå tilbake til klientapplikasjonen.",
"pangolinCloud": "Pangolin Sky", "pangolinCloud": "Pangolin Sky",
"viewDevices": "Vis enheter", "viewDevices": "Vis enheter",
"viewDevicesDescription": "Administrer tilkoblede enheter", "viewDevicesDescription": "Administrer tilkoblede enheter",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Ikke du? Bruk en annen konto.", "deviceLoginUseDifferentAccount": "Ikke du? Bruk en annen konto.",
"deviceLoginDeviceRequestingAccessToAccount": "En enhet ber om tilgang til denne kontoen.", "deviceLoginDeviceRequestingAccessToAccount": "En enhet ber om tilgang til denne kontoen.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Velg en autentiseringsmetode for å fortsette.",
"noData": "Ingen data", "noData": "Ingen data",
"machineClients": "Maskinklienter", "machineClients": "Maskinklienter",
"install": "Installer", "install": "Installer",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Vi opplever for øyeblikket tekniske problemer. Vennligst sjekk igjen snart.", "maintenanceScreenMessage": "Vi opplever for øyeblikket tekniske problemer. Vennligst sjekk igjen snart.",
"maintenanceScreenEstimatedCompletion": "Estimert ferdigstillelse:", "maintenanceScreenEstimatedCompletion": "Estimert ferdigstillelse:",
"createInternalResourceDialogDestinationRequired": "Destinasjonen er nødvendig", "createInternalResourceDialogDestinationRequired": "Destinasjonen er nødvendig",
"available": "Available", "available": "Tilgjengelig",
"archived": "Archived", "archived": "Arkivert",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Ingen arkiverte enheter funnet",
"deviceArchived": "Device archived", "deviceArchived": "Enhet arkivert",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Enheten er blitt arkivert.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Feil ved arkivering av enhet",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Kunne ikke arkivere enhet",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Er du sikker på at du vil arkivere denne enheten?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Enheten blir arkivert og fjernet fra listen over aktive enheter.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Arkiver enhet",
"archiveDevice": "Archive Device", "archiveDevice": "Arkiver enhet",
"archive": "Archive", "archive": "Arkiv",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Enheten er uarkivert",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Enheten er blitt avarkivert.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Feil ved arkivering av enhet",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Kunne ikke fjerne arkivere enheten",
"unarchive": "Unarchive", "unarchive": "Avarkiver",
"archiveClient": "Archive Client", "archiveClient": "Arkiver klient",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Er du sikker på at du vil arkivere denne klienten?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Klienten arkiveres og fjernes fra listen over aktive klienter.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Arkiver klient",
"blockClient": "Block Client", "blockClient": "Blokker kunde",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Er du sikker på at du vil blokkere denne klienten?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Enheten blir tvunget til å koble fra hvis den er koblet til. Du kan fjerne blokkeringen av enheten senere.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Blokker kunde",
"active": "Active", "active": "Aktiv",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Brukernavn eller e-post",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Velg din organisasjon",
"signInTo": "Log in in to", "signInTo": "Logg inn på",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Fortsett med passord",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Ingen autentiseringsmetoder er tilgjengelige for denne organisasjonen.",
"enterPassword": "Enter your password", "enterPassword": "Angi ditt passord",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Angi koden fra din autentiseringsapp",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Vennligst bruk sikkerhetsnøkkelen til å logge på.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Trenger du å bruke en annen konto?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Ved å klikke på knappene nedenfor, erkjenner du at du har lest, forstår, og godtar <termsOfService>Vilkår for bruk</termsOfService> og <privacyPolicy>for Personvernerklæring</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Vilkår for bruk",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Retningslinjer for personvern",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Ingen bruker med det brukernavnet funnet.",
"verify": "Verify", "verify": "Verifiser",
"signIn": "Sign In", "signIn": "Logg inn",
"forgotPassword": "Forgot password?", "forgotPassword": "Glemt passord?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Hvis du har logget inn før, kan du skrive inn brukernavnet eller e-postadressen ovenfor for å autentisere med organisasjonens identitetstjeneste i stedet. Det er enklere!",
"continueAnyway": "Continue anyway", "continueAnyway": "Fortsett likevel",
"dontShowAgain": "Don't show again", "dontShowAgain": "Ikke vis igjen",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Visste du?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Prøver å logge inn?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Prøver du å logge inn gjennom din organisasjons identitetsleverandør?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Logg inn eller registrer deg med organisasjonen din i stedet",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Bruk en annen konto",
"logIn": "Log In", "logIn": "Logg inn",
"deviceInformation": "Device Information", "deviceInformation": "Enhetens informasjon",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informasjon om enheten og agenten",
"platform": "Platform", "deviceSecurity": "Enhetens sikkerhet",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Sikkerhetsstillings informasjon om utstyr",
"windowsVersion": "Windows Version", "platform": "Plattform",
"iosVersion": "iOS Version", "macosVersion": "macOS versjon",
"androidVersion": "Android Version", "windowsVersion": "Windows versjon",
"osVersion": "OS Version", "iosVersion": "iOS Versjon",
"kernelVersion": "Kernel Version", "androidVersion": "Android versjon",
"deviceModel": "Device Model", "osVersion": "OS versjon",
"serialNumber": "Serial Number", "kernelVersion": "Kjerne versjon",
"deviceModel": "Enhets modell",
"serialNumber": "Serienummer",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Først sett",
"lastSeen": "Last Seen", "lastSeen": "Sist sett",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometri aktivert",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Disk kryptert",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Brannmur aktivert",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Automatiske oppdateringer aktivert",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM tilgjengelig",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirus aktivert",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "System Integritetsbeskyttelse (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Brannmur Usynlig Modus",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "Rustning",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Vis enhetsinformasjon og innstillinger",
"devicePendingApprovalDescription": "Denne enheten venter på godkjenning",
"deviceBlockedDescription": "Denne enheten er blokkert. Det kan ikke kobles til noen ressurser med mindre de ikke blir blokkert.",
"unblockClient": "Avblokker klient",
"unblockClientDescription": "Enheten har blitt blokkert",
"unarchiveClient": "Fjern arkivering klient",
"unarchiveClientDescription": "Enheten er arkivert",
"block": "Blokker",
"unblock": "Avblokker",
"deviceActions": "Enhetens handlinger",
"deviceActionsDescription": "Administrer enhetsstatus og tilgang",
"devicePendingApprovalBannerDescription": "Denne enheten venter på godkjenning. Den kan ikke koble til ressurser før den er godkjent.",
"connected": "Tilkoblet",
"disconnected": "Frakoblet",
"approvalsEmptyStateTitle": "Enhetsgodkjenninger er ikke aktivert",
"approvalsEmptyStateDescription": "Aktivere godkjenninger av enheter for at roller må godkjennes av admin før brukere kan koble til nye enheter.",
"approvalsEmptyStateStep1Title": "Gå til roller",
"approvalsEmptyStateStep1Description": "Naviger til organisasjonens roller innstillinger for å konfigurere enhetsgodkjenninger.",
"approvalsEmptyStateStep2Title": "Aktiver enhetsgodkjenninger",
"approvalsEmptyStateStep2Description": "Rediger en rolle og aktiver alternativet 'Kreve enhetsgodkjenninger'. Brukere med denne rollen vil trenge administratorgodkjenning for nye enheter.",
"approvalsEmptyStatePreviewDescription": "Forhåndsvisning: Når aktivert, ventende enhets forespørsler vil vises her for vurdering",
"approvalsEmptyStateButtonText": "Administrer Roller"
} }
+234 -133
View File
@@ -18,6 +18,8 @@
"componentsMember": "Je bent lid van {count, plural, =0 {geen organisatie} one {één organisatie} other {# organisaties}}.", "componentsMember": "Je bent lid van {count, plural, =0 {geen organisatie} one {één organisatie} other {# organisaties}}.",
"componentsInvalidKey": "Ongeldige of verlopen licentiesleutels gedetecteerd. Volg de licentievoorwaarden om alle functies te blijven gebruiken.", "componentsInvalidKey": "Ongeldige of verlopen licentiesleutels gedetecteerd. Volg de licentievoorwaarden om alle functies te blijven gebruiken.",
"dismiss": "Uitschakelen", "dismiss": "Uitschakelen",
"subscriptionViolationMessage": "U overschrijdt uw huidige abonnement. Corrigeer het probleem door sites, gebruikers of andere bronnen te verwijderen om binnen uw plan te blijven.",
"subscriptionViolationViewBilling": "Facturering bekijken",
"componentsLicenseViolation": "Licentie overtreding: Deze server gebruikt {usedSites} sites die de gelicentieerde limiet van {maxSites} sites overschrijden. Volg de licentievoorwaarden om door te gaan met het gebruik van alle functies.", "componentsLicenseViolation": "Licentie overtreding: Deze server gebruikt {usedSites} sites die de gelicentieerde limiet van {maxSites} sites overschrijden. Volg de licentievoorwaarden om door te gaan met het gebruik van alle functies.",
"componentsSupporterMessage": "Bedankt voor het ondersteunen van Pangolin als {tier}!", "componentsSupporterMessage": "Bedankt voor het ondersteunen van Pangolin als {tier}!",
"inviteErrorNotValid": "Het spijt ons, maar de uitnodiging die je probeert te bezoeken is niet geaccepteerd of is niet meer geldig.", "inviteErrorNotValid": "Het spijt ons, maar de uitnodiging die je probeert te bezoeken is niet geaccepteerd of is niet meer geldig.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Verbind elk netwerk", "sitesBannerTitle": "Verbind elk netwerk",
"sitesBannerDescription": "Een site is een verbinding met een extern netwerk waarmee Pangolin toegang biedt tot bronnen, zowel openbaar als privé, aan gebruikers overal. Installeer de sitedatacenterconnector (Newt) overal waar je een binaire of container kunt uitvoeren om de verbinding tot stand te brengen.", "sitesBannerDescription": "Een site is een verbinding met een extern netwerk waarmee Pangolin toegang biedt tot bronnen, zowel openbaar als privé, aan gebruikers overal. Installeer de sitedatacenterconnector (Newt) overal waar je een binaire of container kunt uitvoeren om de verbinding tot stand te brengen.",
"sitesBannerButtonText": "Site installeren", "sitesBannerButtonText": "Site installeren",
"approvalsBannerTitle": "Toegang tot het apparaat goedkeuren of weigeren",
"approvalsBannerDescription": "Bekijk en keur toestelverzoeken goed of weiger toegang van gebruikers. Wanneer apparaatgoedkeuringen vereist zijn, moeten gebruikers de goedkeuring van beheerders krijgen voordat hun apparaten verbinding kunnen maken met de bronnen van uw organisatie.",
"approvalsBannerButtonText": "Meer informatie",
"siteCreate": "Site maken", "siteCreate": "Site maken",
"siteCreateDescription2": "Volg de onderstaande stappen om een nieuwe site aan te maken en te verbinden", "siteCreateDescription2": "Volg de onderstaande stappen om een nieuwe site aan te maken en te verbinden",
"siteCreateDescription": "Maak een nieuwe site aan om bronnen te verbinden", "siteCreateDescription": "Maak een nieuwe site aan om bronnen te verbinden",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Rollen zoeken...", "accessRolesSearch": "Rollen zoeken...",
"accessRolesAdd": "Rol toevoegen", "accessRolesAdd": "Rol toevoegen",
"accessRoleDelete": "Verwijder rol", "accessRoleDelete": "Verwijder rol",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Goedkeuringen beheren",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Bekijk en beheer openstaande goedkeuringen voor toegang tot deze organisatie",
"description": "Beschrijving", "description": "Beschrijving",
"inviteTitle": "Open uitnodigingen", "inviteTitle": "Open uitnodigingen",
"inviteDescription": "Beheer uitnodigingen voor andere gebruikers om deel te nemen aan de organisatie", "inviteDescription": "Beheer uitnodigingen voor andere gebruikers om deel te nemen aan de organisatie",
@@ -452,18 +457,18 @@
"selectDuration": "Selecteer duur", "selectDuration": "Selecteer duur",
"selectResource": "Selecteer Document", "selectResource": "Selecteer Document",
"filterByResource": "Filter op pagina", "filterByResource": "Filter op pagina",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Selecteer goedkeuringsstatus",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filter op goedkeuringsstatus",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Geen goedkeuringen",
"approvalState": "Approval State", "approvalState": "Goedkeuring status",
"approve": "Approve", "approve": "Goedkeuren",
"approved": "Approved", "approved": "Goedgekeurd",
"denied": "Denied", "denied": "Geweigerd",
"deniedApproval": "Denied Approval", "deniedApproval": "Geweigerde goedkeuring",
"all": "All", "all": "Alles",
"deny": "Deny", "deny": "Weigeren",
"viewDetails": "View Details", "viewDetails": "Details bekijken",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "heeft een nieuw apparaat aangevraagd",
"resetFilters": "Filters resetten", "resetFilters": "Filters resetten",
"totalBlocked": "Verzoeken geblokkeerd door Pangolin", "totalBlocked": "Verzoeken geblokkeerd door Pangolin",
"totalRequests": "Totaal verzoeken", "totalRequests": "Totaal verzoeken",
@@ -743,28 +748,28 @@
"countries": "Landen", "countries": "Landen",
"accessRoleCreate": "Rol aanmaken", "accessRoleCreate": "Rol aanmaken",
"accessRoleCreateDescription": "Maak een nieuwe rol aan om gebruikers te groeperen en hun rechten te beheren.", "accessRoleCreateDescription": "Maak een nieuwe rol aan om gebruikers te groeperen en hun rechten te beheren.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Rol bewerken",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Bewerk rol informatie.",
"accessRoleCreateSubmit": "Rol aanmaken", "accessRoleCreateSubmit": "Rol aanmaken",
"accessRoleCreated": "Rol aangemaakt", "accessRoleCreated": "Rol aangemaakt",
"accessRoleCreatedDescription": "De rol is succesvol aangemaakt.", "accessRoleCreatedDescription": "De rol is succesvol aangemaakt.",
"accessRoleErrorCreate": "Rol aanmaken mislukt", "accessRoleErrorCreate": "Rol aanmaken mislukt",
"accessRoleErrorCreateDescription": "Fout opgetreden tijdens het aanmaken van de rol.", "accessRoleErrorCreateDescription": "Fout opgetreden tijdens het aanmaken van de rol.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Rol bijwerken",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Rol bijgewerkt",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "De rol is succesvol bijgewerkt.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Afgewerkt met goedkeuring",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Stel het goedkeuringsverzoek in op goedkeuring.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Stel de beslissing over het goedkeuringsverzoek in als geweigerd.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Bijwerken van rol mislukt",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Fout opgetreden tijdens het bijwerken van de rol.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Kan goedkeuring niet verwerken",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Er is een fout opgetreden bij het verwerken van de goedkeuring.",
"accessRoleErrorNewRequired": "Nieuwe rol is vereist", "accessRoleErrorNewRequired": "Nieuwe rol is vereist",
"accessRoleErrorRemove": "Rol verwijderen mislukt", "accessRoleErrorRemove": "Rol verwijderen mislukt",
"accessRoleErrorRemoveDescription": "Er is een fout opgetreden tijdens het verwijderen van de rol.", "accessRoleErrorRemoveDescription": "Er is een fout opgetreden tijdens het verwijderen van de rol.",
"accessRoleName": "Rol naam", "accessRoleName": "Rol naam",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Je staat op het punt de `{name}` rol te verwijderen. Je kunt deze actie niet ongedaan maken.",
"accessRoleRemove": "Rol verwijderen", "accessRoleRemove": "Rol verwijderen",
"accessRoleRemoveDescription": "Verwijder een rol van de organisatie", "accessRoleRemoveDescription": "Verwijder een rol van de organisatie",
"accessRoleRemoveSubmit": "Rol verwijderen", "accessRoleRemoveSubmit": "Rol verwijderen",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Toename van site vergroten", "sitestCountIncrease": "Toename van site vergroten",
"idpManage": "Identiteitsaanbieders beheren", "idpManage": "Identiteitsaanbieders beheren",
"idpManageDescription": "Identiteitsaanbieders in het systeem bekijken en beheren", "idpManageDescription": "Identiteitsaanbieders in het systeem bekijken en beheren",
"idpGlobalModeBanner": "Identiteitsaanbieders (IdPs) per organisatie zijn uitgeschakeld op deze server. Het gebruikt globale IdPs (gedeeld tussen alle organisaties). Beheer globale IdPs in het <adminPanelLink>beheerderspaneel</adminPanelLink>. Om IdPs per organisatie in te schakelen, bewerk de server configuratie en zet IdP modus op org. <configDocsLink>Zie de documenten</configDocsLink>. Als je globale IdPs wilt blijven gebruiken en dit uit de organisatie-instellingen wilt laten verdwijnen, zet dan expliciet de modus naar globaal in de config.",
"idpGlobalModeBannerUpgradeRequired": "Identity providers (IdPs) per organisatie zijn uitgeschakeld op deze server. Het gebruikt globale IdPs (gedeeld in alle organisaties) Beheer globale IdPs in het <adminPanelLink>beheerderspaneel</adminPanelLink>. Om identiteitsproviders per organisatie te gebruiken, moet u upgraden naar de Enterprise editie.",
"idpGlobalModeBannerLicenseRequired": "Identity providers (IdPs) per organisatie zijn uitgeschakeld op deze server. Het gebruikt globale IdPs (gedeeld in alle organisaties) Beheer globale IdPs in het <adminPanelLink>beheerderspaneel</adminPanelLink>. Om identiteitsaanbieders per organisatie te gebruiken, is een Enterprise-licentie vereist.",
"idpDeletedDescription": "Identity provider succesvol verwijderd", "idpDeletedDescription": "Identity provider succesvol verwijderd",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Weet u zeker dat u de identiteitsprovider permanent wilt verwijderen?", "idpQuestionRemove": "Weet u zeker dat u de identiteitsprovider permanent wilt verwijderen?",
@@ -900,7 +908,7 @@
"inviteAlready": "Het lijkt erop dat je bent uitgenodigd!", "inviteAlready": "Het lijkt erop dat je bent uitgenodigd!",
"inviteAlreadyDescription": "Om de uitnodiging te accepteren, moet je inloggen of een account aanmaken.", "inviteAlreadyDescription": "Om de uitnodiging te accepteren, moet je inloggen of een account aanmaken.",
"signupQuestion": "Heeft u al een account?", "signupQuestion": "Heeft u al een account?",
"login": "Log In", "login": "Log in",
"resourceNotFound": "Bron niet gevonden", "resourceNotFound": "Bron niet gevonden",
"resourceNotFoundDescription": "De bron die u probeert te benaderen bestaat niet.", "resourceNotFoundDescription": "De bron die u probeert te benaderen bestaat niet.",
"pincodeRequirementsLength": "Pincode moet precies 6 cijfers zijn", "pincodeRequirementsLength": "Pincode moet precies 6 cijfers zijn",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Deze organisatie vereist dat u om de {maxDays} dagen uw wachtwoord wijzigt.", "passwordExpiryDescription": "Deze organisatie vereist dat u om de {maxDays} dagen uw wachtwoord wijzigt.",
"changePasswordNow": "Wijzig wachtwoord nu", "changePasswordNow": "Wijzig wachtwoord nu",
"pincodeAuth": "Authenticatiecode", "pincodeAuth": "Authenticatiecode",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Code indienen",
"passwordResetSubmit": "Opnieuw instellen aanvragen", "passwordResetSubmit": "Opnieuw instellen aanvragen",
"passwordResetAlreadyHaveCode": "Code invoeren", "passwordResetAlreadyHaveCode": "Code invoeren",
"passwordResetSmtpRequired": "Neem contact op met uw beheerder", "passwordResetSmtpRequired": "Neem contact op met uw beheerder",
"passwordResetSmtpRequiredDescription": "Er is een wachtwoord reset code nodig om uw wachtwoord opnieuw in te stellen. Neem contact op met uw beheerder voor hulp.", "passwordResetSmtpRequiredDescription": "Er is een wachtwoord reset code nodig om uw wachtwoord opnieuw in te stellen. Neem contact op met uw beheerder voor hulp.",
"passwordBack": "Terug naar wachtwoord", "passwordBack": "Terug naar wachtwoord",
"loginBack": "Go back to main login page", "loginBack": "Ga terug naar de hoofdinlogpagina",
"signup": "Registreer nu", "signup": "Registreer nu",
"loginStart": "Log in om te beginnen", "loginStart": "Log in om te beginnen",
"idpOidcTokenValidating": "Valideer OIDC-token", "idpOidcTokenValidating": "Valideer OIDC-token",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "IDP-org bijwerken", "actionUpdateIdpOrg": "IDP-org bijwerken",
"actionCreateClient": "Client aanmaken", "actionCreateClient": "Client aanmaken",
"actionDeleteClient": "Verwijder klant", "actionDeleteClient": "Verwijder klant",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Archiveer client",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Dearchiveer client",
"actionBlockClient": "Block Client", "actionBlockClient": "Blokkeer klant",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Deblokkeer client",
"actionUpdateClient": "Klant bijwerken", "actionUpdateClient": "Klant bijwerken",
"actionListClients": "Lijst klanten", "actionListClients": "Lijst klanten",
"actionGetClient": "Client ophalen", "actionGetClient": "Client ophalen",
@@ -1164,14 +1172,14 @@
"searchProgress": "Zoeken...", "searchProgress": "Zoeken...",
"create": "Aanmaken", "create": "Aanmaken",
"orgs": "Organisaties", "orgs": "Organisaties",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Er is een onverwachte fout opgetreden. Probeer het opnieuw.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Inloggen is vereist voor je apparaat.",
"passwordForgot": "Wachtwoord vergeten?", "passwordForgot": "Wachtwoord vergeten?",
"otpAuth": "Tweestapsverificatie verificatie", "otpAuth": "Tweestapsverificatie verificatie",
"otpAuthDescription": "Voer de code van je authenticator-app of een van je reservekopiecodes voor het eenmalig gebruik in.", "otpAuthDescription": "Voer de code van je authenticator-app of een van je reservekopiecodes voor het eenmalig gebruik in.",
"otpAuthSubmit": "Code indienen", "otpAuthSubmit": "Code indienen",
"idpContinue": "Of ga verder met", "idpContinue": "Of ga verder met",
"otpAuthBack": "Back to Password", "otpAuthBack": "Terug naar wachtwoord",
"navbar": "Navigatiemenu", "navbar": "Navigatiemenu",
"navbarDescription": "Hoofd navigatie menu voor de applicatie", "navbarDescription": "Hoofd navigatie menu voor de applicatie",
"navbarDocsLink": "Documentatie", "navbarDocsLink": "Documentatie",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Overzicht.", "sidebarOverview": "Overzicht.",
"sidebarHome": "Startpagina", "sidebarHome": "Startpagina",
"sidebarSites": "Werkruimtes", "sidebarSites": "Werkruimtes",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Goedkeuringsverzoeken",
"sidebarResources": "Bronnen", "sidebarResources": "Bronnen",
"sidebarProxyResources": "Openbaar", "sidebarProxyResources": "Openbaar",
"sidebarClientResources": "Privé", "sidebarClientResources": "Privé",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Identiteit aanbieders", "sidebarIdentityProviders": "Identiteit aanbieders",
"sidebarLicense": "Licentie", "sidebarLicense": "Licentie",
"sidebarClients": "Clienten", "sidebarClients": "Clienten",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Gebruiker Apparaten",
"sidebarMachineClients": "Machines", "sidebarMachineClients": "Machines",
"sidebarDomains": "Domeinen", "sidebarDomains": "Domeinen",
"sidebarGeneral": "Beheren", "sidebarGeneral": "Beheren",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Er is een fout opgetreden bij het maken van het serverbeheerdersaccount.", "setupErrorCreateAdmin": "Er is een fout opgetreden bij het maken van het serverbeheerdersaccount.",
"certificateStatus": "Certificaatstatus", "certificateStatus": "Certificaatstatus",
"loading": "Bezig met laden", "loading": "Bezig met laden",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Laden van Analytics",
"restart": "Herstarten", "restart": "Herstarten",
"domains": "Domeinen", "domains": "Domeinen",
"domainsDescription": "Maak en beheer domeinen die beschikbaar zijn in de organisatie", "domainsDescription": "Maak en beheer domeinen die beschikbaar zijn in de organisatie",
@@ -1336,7 +1344,7 @@
"refreshError": "Het vernieuwen van gegevens is mislukt", "refreshError": "Het vernieuwen van gegevens is mislukt",
"verified": "Gecontroleerd", "verified": "Gecontroleerd",
"pending": "In afwachting", "pending": "In afwachting",
"pendingApproval": "Pending Approval", "pendingApproval": "Wachten op goedkeuring",
"sidebarBilling": "Facturering", "sidebarBilling": "Facturering",
"billing": "Facturering", "billing": "Facturering",
"orgBillingDescription": "Beheer factureringsinformatie en abonnementen", "orgBillingDescription": "Beheer factureringsinformatie en abonnementen",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Overzicht gebruikslimieten", "billingUsageLimitsOverview": "Overzicht gebruikslimieten",
"billingMonitorUsage": "Houd uw gebruik in de gaten ten opzichte van de ingestelde limieten. Als u verhoogde limieten nodig heeft, neem dan contact met ons op support@pangolin.net.", "billingMonitorUsage": "Houd uw gebruik in de gaten ten opzichte van de ingestelde limieten. Als u verhoogde limieten nodig heeft, neem dan contact met ons op support@pangolin.net.",
"billingDataUsage": "Gegevensgebruik", "billingDataUsage": "Gegevensgebruik",
"billingOnlineTime": "Site Online Tijd", "billingSites": "Sites",
"billingUsers": "Actieve Gebruikers", "billingUsers": "Gebruikers",
"billingDomains": "Actieve Domeinen", "billingDomains": "Domeinen",
"billingRemoteExitNodes": "Actieve Zelfgehoste Nodes", "billingRemoteExitNodes": "Externe knooppunten",
"billingNoLimitConfigured": "Geen limiet ingesteld", "billingNoLimitConfigured": "Geen limiet ingesteld",
"billingEstimatedPeriod": "Geschatte Facturatie Periode", "billingEstimatedPeriod": "Geschatte Facturatie Periode",
"billingIncludedUsage": "Opgenomen Gebruik", "billingIncludedUsage": "Opgenomen Gebruik",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Niet gelukt om portal URL te krijgen", "billingFailedToGetPortalUrl": "Niet gelukt om portal URL te krijgen",
"billingPortalError": "Portal Fout", "billingPortalError": "Portal Fout",
"billingDataUsageInfo": "U bent in rekening gebracht voor alle gegevens die via uw beveiligde tunnels via de cloud worden verzonden. Dit omvat zowel inkomende als uitgaande verkeer over al uw sites. Wanneer u uw limiet bereikt zullen uw sites de verbinding verbreken totdat u uw abonnement upgradet of het gebruik vermindert. Gegevens worden niet in rekening gebracht bij het gebruik van knooppunten.", "billingDataUsageInfo": "U bent in rekening gebracht voor alle gegevens die via uw beveiligde tunnels via de cloud worden verzonden. Dit omvat zowel inkomende als uitgaande verkeer over al uw sites. Wanneer u uw limiet bereikt zullen uw sites de verbinding verbreken totdat u uw abonnement upgradet of het gebruik vermindert. Gegevens worden niet in rekening gebracht bij het gebruik van knooppunten.",
"billingOnlineTimeInfo": "U wordt in rekening gebracht op basis van hoe lang uw sites verbonden blijven met de cloud. Bijvoorbeeld 44,640 minuten is gelijk aan één site met 24/7 voor een volledige maand. Wanneer u uw limiet bereikt, zal de verbinding tussen uw sites worden verbroken totdat u een upgrade van uw abonnement uitvoert of het gebruik vermindert. Tijd wordt niet belast bij het gebruik van knooppunten.", "billingSInfo": "Hoeveel sites u kunt gebruiken",
"billingUsersInfo": "U bent in rekening gebracht voor elke gebruiker in de organisatie. Facturering wordt dagelijks berekend op basis van het aantal actieve gebruikersaccounts in uw org.", "billingUsersInfo": "Hoeveel gebruikers je kan gebruiken",
"billingDomainInfo": "U wordt voor elk domein in de organisatie in rekening gebracht. Facturering wordt dagelijks berekend op basis van het aantal actieve domeinaccounts in uw org.", "billingDomainInfo": "Hoeveel domeinen je kunt gebruiken",
"billingRemoteExitNodesInfo": "U bent belast voor elke beheerde node in de organisatie. Facturering wordt dagelijks berekend op basis van het aantal actieve beheerde knooppunten in uw org.", "billingRemoteExitNodesInfo": "Hoeveel externe nodes je kunt gebruiken",
"billingLicenseKeys": "Licentie Sleutels",
"billingLicenseKeysDescription": "Beheer uw licentiesleutelabonnementen",
"billingLicenseSubscription": "Licentie abonnement",
"billingInactive": "Inactief",
"billingLicenseItem": "Licentie artikel",
"billingQuantity": "Aantal",
"billingTotal": "totaal",
"billingModifyLicenses": "Licentieabonnement wijzigen",
"domainNotFound": "Domein niet gevonden", "domainNotFound": "Domein niet gevonden",
"domainNotFoundDescription": "Deze bron is uitgeschakeld omdat het domein niet langer in ons systeem bestaat. Stel een nieuw domein in voor deze bron.", "domainNotFoundDescription": "Deze bron is uitgeschakeld omdat het domein niet langer in ons systeem bestaat. Stel een nieuw domein in voor deze bron.",
"failed": "Mislukt", "failed": "Mislukt",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Beveiligingssleutel succesvol verwijderd", "securityKeyRemoveSuccess": "Beveiligingssleutel succesvol verwijderd",
"securityKeyRemoveError": "Fout bij verwijderen van beveiligingssleutel", "securityKeyRemoveError": "Fout bij verwijderen van beveiligingssleutel",
"securityKeyLoadError": "Fout bij laden van beveiligingssleutels", "securityKeyLoadError": "Fout bij laden van beveiligingssleutels",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Gebruik beveiligingssleutel",
"securityKeyAuthError": "Fout bij authenticatie met beveiligingssleutel", "securityKeyAuthError": "Fout bij authenticatie met beveiligingssleutel",
"securityKeyRecommendation": "Overweeg om een andere beveiligingssleutel te registreren op een ander apparaat om ervoor te zorgen dat u niet buitengesloten raakt van uw account.", "securityKeyRecommendation": "Overweeg om een andere beveiligingssleutel te registreren op een ander apparaat om ervoor te zorgen dat u niet buitengesloten raakt van uw account.",
"registering": "Registreren...", "registering": "Registreren...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Poortnummer is vereist voor niet-HTTP-bronnen", "resourcePortRequired": "Poortnummer is vereist voor niet-HTTP-bronnen",
"resourcePortNotAllowed": "Poortnummer mag niet worden ingesteld voor HTTP-bronnen", "resourcePortNotAllowed": "Poortnummer mag niet worden ingesteld voor HTTP-bronnen",
"billingPricingCalculatorLink": "Prijs Calculator", "billingPricingCalculatorLink": "Prijs Calculator",
"billingYourPlan": "Uw abonnement",
"billingViewOrModifyPlan": "Bekijk of wijzig uw huidige abonnement",
"billingViewPlanDetails": "Abonnementsdetails bekijken",
"billingUsageAndLimits": "Gebruik en limieten",
"billingViewUsageAndLimits": "Limiet van je abonnement en huidig gebruik bekijken",
"billingCurrentUsage": "Huidig gebruik",
"billingMaximumLimits": "Maximaal aantal limieten",
"billingRemoteNodes": "Externe knooppunten",
"billingUnlimited": "Onbeperkt",
"billingPaidLicenseKeys": "Betaalde licentiesleutels",
"billingManageLicenseSubscription": "Beheer je abonnement voor betaalde zelf gehoste licentiesleutels",
"billingCurrentKeys": "Huidige toetsen",
"billingModifyCurrentPlan": "Huidig plan wijzigen",
"billingConfirmUpgrade": "Bevestig Upgrade",
"billingConfirmDowngrade": "Downgraden bevestigen",
"billingConfirmUpgradeDescription": "U staat op het punt uw abonnement te upgraden. Controleer de nieuwe limieten en prijzen hieronder.",
"billingConfirmDowngradeDescription": "U staat op het punt om uw abonnement te downgraden. Controleer de nieuwe limieten en prijzen hieronder.",
"billingPlanIncludes": "Abonnement bevat",
"billingProcessing": "Verwerken...",
"billingConfirmUpgradeButton": "Bevestig Upgrade",
"billingConfirmDowngradeButton": "Downgraden bevestigen",
"billingLimitViolationWarning": "Gebruik Overschrijdt nieuwe Plan Limieten",
"billingLimitViolationDescription": "Uw huidige verbruik overschrijdt de limieten van dit plan. Na het downgraden worden alle acties uitgeschakeld totdat u het verbruik vermindert binnen de nieuwe grenzen. Controleer de onderstaande functies die de limieten overschrijden. Beperkingen in overtreding:",
"billingFeatureLossWarning": "Kennisgeving beschikbaarheid",
"billingFeatureLossDescription": "Door downgraden worden functies die niet beschikbaar zijn in het nieuwe abonnement automatisch uitgeschakeld. Sommige instellingen en configuraties kunnen verloren gaan. Raadpleeg de prijsmatrix om te begrijpen welke functies niet langer beschikbaar zijn.",
"billingUsageExceedsLimit": "Huidig gebruik ({current}) overschrijdt limiet ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Ik ga akkoord met de", "IAgreeToThe": "Ik ga akkoord met de",
"termsOfService": "servicevoorwaarden", "termsOfService": "servicevoorwaarden",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Gezonde Interval", "IntervalSeconds": "Gezonde Interval",
"timeoutSeconds": "Timeout (sec)", "timeoutSeconds": "Timeout (sec)",
"timeIsInSeconds": "Tijd is in seconden", "timeIsInSeconds": "Tijd is in seconden",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Vereist goedkeuring van apparaat",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Gebruikers met deze rol hebben nieuwe apparaten nodig die door een beheerder zijn goedgekeurd voordat ze verbinding kunnen maken met bronnen en deze kunnen gebruiken.",
"retryAttempts": "Herhaal Pogingen", "retryAttempts": "Herhaal Pogingen",
"expectedResponseCodes": "Verwachte Reactiecodes", "expectedResponseCodes": "Verwachte Reactiecodes",
"expectedResponseCodesDescription": "HTTP-statuscode die gezonde status aangeeft. Indien leeg wordt 200-300 als gezond beschouwd.", "expectedResponseCodesDescription": "HTTP-statuscode die gezonde status aangeeft. Indien leeg wordt 200-300 als gezond beschouwd.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Geen interne bronnen gevonden.", "resourcesTableNoInternalResourcesFound": "Geen interne bronnen gevonden.",
"resourcesTableDestination": "Bestemming", "resourcesTableDestination": "Bestemming",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Alias adres",
"resourcesTableAliasAddressInfo": "Dit adres is onderdeel van het hulpprogramma subnet van de organisatie. Het wordt gebruikt om aliasrecords op te lossen met behulp van interne DNS-resolutie.",
"resourcesTableClients": "Clienten", "resourcesTableClients": "Clienten",
"resourcesTableAndOnlyAccessibleInternally": "en zijn alleen intern toegankelijk wanneer verbonden met een client.", "resourcesTableAndOnlyAccessibleInternally": "en zijn alleen intern toegankelijk wanneer verbonden met een client.",
"resourcesTableNoTargets": "Geen doelen", "resourcesTableNoTargets": "Geen doelen",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Kies uw identiteitsprovider om door te gaan", "orgAuthChooseIdpDescription": "Kies uw identiteitsprovider om door te gaan",
"orgAuthNoIdpConfigured": "Deze organisatie heeft geen identiteitsproviders geconfigureerd. Je kunt in plaats daarvan inloggen met je Pangolin-identiteit.", "orgAuthNoIdpConfigured": "Deze organisatie heeft geen identiteitsproviders geconfigureerd. Je kunt in plaats daarvan inloggen met je Pangolin-identiteit.",
"orgAuthSignInWithPangolin": "Log in met Pangolin", "orgAuthSignInWithPangolin": "Log in met Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Log in bij een organisatie",
"orgAuthSelectOrgTitle": "Organisatie Inloggen", "orgAuthSelectOrgTitle": "Organisatie Inloggen",
"orgAuthSelectOrgDescription": "Voer je organisatie-ID in om verder te gaan", "orgAuthSelectOrgDescription": "Voer je organisatie-ID in om verder te gaan",
"orgAuthOrgIdPlaceholder": "jouw-organisatie", "orgAuthOrgIdPlaceholder": "jouw-organisatie",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Terug naar standaard aanmelden", "orgAuthBackToSignIn": "Terug naar standaard aanmelden",
"orgAuthNoAccount": "Nog geen account?", "orgAuthNoAccount": "Nog geen account?",
"subscriptionRequiredToUse": "Een abonnement is vereist om deze functie te gebruiken.", "subscriptionRequiredToUse": "Een abonnement is vereist om deze functie te gebruiken.",
"mustUpgradeToUse": "U moet uw abonnement upgraden om deze functie te gebruiken.",
"subscriptionRequiredTierToUse": "Deze functie vereist <tierLink>{tier}</tierLink> of hoger.",
"upgradeToTierToUse": "Upgrade naar <tierLink>{tier}</tierLink> of hoger om deze functie te gebruiken.",
"subscriptionTierTier1": "Startpagina",
"subscriptionTierTier2": "Team",
"subscriptionTierTier3": "Bedrijfsleven",
"subscriptionTierEnterprise": "Onderneming",
"idpDisabled": "Identiteitsaanbieders zijn uitgeschakeld.", "idpDisabled": "Identiteitsaanbieders zijn uitgeschakeld.",
"orgAuthPageDisabled": "Pagina voor organisatie-authenticatie is uitgeschakeld.", "orgAuthPageDisabled": "Pagina voor organisatie-authenticatie is uitgeschakeld.",
"domainRestartedDescription": "Domeinverificatie met succes opnieuw gestart", "domainRestartedDescription": "Domeinverificatie met succes opnieuw gestart",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Krijg een licentie",
"description": "Kies een plan en vertel ons hoe u Pangolin wilt gebruiken.",
"chooseTier": "Kies uw abonnement",
"viewPricingLink": "Zie prijzen, functies en limieten",
"tiers": {
"starter": {
"title": "Beginner",
"description": "Enterprise functies, 25 gebruikers, 25 sites en community ondersteuning."
},
"scale": {
"title": "Schaal",
"description": "Enterprise functies, 50 gebruikers, 50 sites en prioriteit ondersteuning."
}
},
"personalUseOnly": "Alleen persoonlijk gebruik (gratis licentie - geen afrekenen)",
"buttons": {
"continueToCheckout": "Doorgaan naar afrekenen"
},
"toasts": {
"checkoutError": {
"title": "Fout bij afrekenen",
"description": "Kan de afhandeling niet starten. Probeer het opnieuw."
}
}
},
"priority": "Prioriteit", "priority": "Prioriteit",
"priorityDescription": "routes met hogere prioriteit worden eerst geëvalueerd. Prioriteit = 100 betekent automatisch bestellen (systeem beslist de). Gebruik een ander nummer om handmatige prioriteit af te dwingen.", "priorityDescription": "routes met hogere prioriteit worden eerst geëvalueerd. Prioriteit = 100 betekent automatisch bestellen (systeem beslist de). Gebruik een ander nummer om handmatige prioriteit af te dwingen.",
"instanceName": "Naam instantie", "instanceName": "Naam instantie",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Einde van volgend jaar", "logRetentionEndOfFollowingYear": "Einde van volgend jaar",
"actionLogsDescription": "Bekijk een geschiedenis van acties die worden uitgevoerd in deze organisatie", "actionLogsDescription": "Bekijk een geschiedenis van acties die worden uitgevoerd in deze organisatie",
"accessLogsDescription": "Toegangsverificatieverzoeken voor resources in deze organisatie bekijken", "accessLogsDescription": "Toegangsverificatieverzoeken voor resources in deze organisatie bekijken",
"licenseRequiredToUse": "Een Enterprise-licentie is vereist om deze functie te gebruiken.", "licenseRequiredToUse": "Een <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> licentie is vereist om deze functie te gebruiken. Deze functie is ook beschikbaar in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "De <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> is vereist om deze functie te gebruiken. Deze functie is ook beschikbaar in <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Certificaat Resolver", "certResolver": "Certificaat Resolver",
"certResolverDescription": "Selecteer de certificaat resolver die moet worden gebruikt voor deze resource.", "certResolverDescription": "Selecteer de certificaat resolver die moet worden gebruikt voor deze resource.",
"selectCertResolver": "Certificaat Resolver selecteren", "selectCertResolver": "Certificaat Resolver selecteren",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Code moet 9 tekens bevatten (bijv. A1AJ-N5JD)", "deviceCodeInvalidFormat": "Code moet 9 tekens bevatten (bijv. A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Ongeldige of verlopen code", "deviceCodeInvalidOrExpired": "Ongeldige of verlopen code",
"deviceCodeVerifyFailed": "Apparaatcode verifiëren mislukt", "deviceCodeVerifyFailed": "Apparaatcode verifiëren mislukt",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Apparaatcode valideren...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Apparaatmachtiging verifiëren...",
"signedInAs": "Ingelogd als", "signedInAs": "Ingelogd als",
"deviceCodeEnterPrompt": "Voer de op het apparaat weergegeven code in", "deviceCodeEnterPrompt": "Voer de op het apparaat weergegeven code in",
"continue": "Doorgaan", "continue": "Doorgaan",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Toegang tot alle organisaties waar uw account toegang tot heeft", "deviceOrganizationsAccess": "Toegang tot alle organisaties waar uw account toegang tot heeft",
"deviceAuthorize": "Autoriseer {applicationName}", "deviceAuthorize": "Autoriseer {applicationName}",
"deviceConnected": "Apparaat verbonden!", "deviceConnected": "Apparaat verbonden!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Apparaat is gemachtigd om toegang te krijgen tot je account. Ga terug naar de client applicatie.",
"pangolinCloud": "Pangoline Cloud", "pangolinCloud": "Pangoline Cloud",
"viewDevices": "Bekijk apparaten", "viewDevices": "Bekijk apparaten",
"viewDevicesDescription": "Beheer uw aangesloten apparaten", "viewDevicesDescription": "Beheer uw aangesloten apparaten",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Niet u? Gebruik een ander account.", "deviceLoginUseDifferentAccount": "Niet u? Gebruik een ander account.",
"deviceLoginDeviceRequestingAccessToAccount": "Een apparaat vraagt om toegang tot dit account.", "deviceLoginDeviceRequestingAccessToAccount": "Een apparaat vraagt om toegang tot dit account.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Selecteer een verificatiemethode om door te gaan.",
"noData": "Geen gegevens", "noData": "Geen gegevens",
"machineClients": "Machine Clienten", "machineClients": "Machine Clienten",
"install": "Installeren", "install": "Installeren",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "We hebben momenteel technische problemen. Probeer het later opnieuw.", "maintenanceScreenMessage": "We hebben momenteel technische problemen. Probeer het later opnieuw.",
"maintenanceScreenEstimatedCompletion": "Geschatte voltooiing:", "maintenanceScreenEstimatedCompletion": "Geschatte voltooiing:",
"createInternalResourceDialogDestinationRequired": "Bestemming is vereist", "createInternalResourceDialogDestinationRequired": "Bestemming is vereist",
"available": "Available", "available": "Beschikbaar",
"archived": "Archived", "archived": "Gearchiveerd",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Geen gearchiveerde apparaten gevonden",
"deviceArchived": "Device archived", "deviceArchived": "Apparaat gearchiveerd",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Het apparaat is met succes gearchiveerd.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Fout bij archiveren apparaat",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Kan apparaat niet archiveren",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Weet u zeker dat u dit apparaat wilt archiveren?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Het apparaat wordt gearchiveerd en verwijderd uit de lijst met actieve apparaten.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Archiveer apparaat",
"archiveDevice": "Archive Device", "archiveDevice": "Archiveer apparaat",
"archive": "Archive", "archive": "Archief",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Apparaat niet gearchiveerd",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Het apparaat is met succes gedearchiveerd.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Fout bij dearchiveren van apparaat",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Apparaat dearchiveren mislukt",
"unarchive": "Unarchive", "unarchive": "Dearchiveren",
"archiveClient": "Archive Client", "archiveClient": "Archiveer client",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Weet u zeker dat u deze client wilt archiveren?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "De klant zal worden gearchiveerd en verwijderd uit de lijst met actieve cliënten.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Archiveer client",
"blockClient": "Block Client", "blockClient": "Blokkeer klant",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Weet u zeker dat u deze cliënt wilt blokkeren?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Het apparaat zal worden gedwongen de verbinding te verbreken als het momenteel is verbonden. U kunt het apparaat later deblokkeren.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Blokkeer klant",
"active": "Active", "active": "actief",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Gebruikersnaam of e-mailadres",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Selecteer uw organisatie",
"signInTo": "Log in in to", "signInTo": "Log in op",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Ga verder met wachtwoord",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Geen verificatiemethoden beschikbaar voor deze organisatie.",
"enterPassword": "Enter your password", "enterPassword": "Voer je wachtwoord in",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Voer de code van je authenticator-app in",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Gebruik uw beveiligingssleutel om in te loggen.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Wilt u een ander account gebruiken?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Door op de knoppen hieronder te klikken, erken je dat je gelezen en begrepen hebt en ga akkoord met de <termsOfService>Gebruiksvoorwaarden</termsOfService> en <privacyPolicy>Privacybeleid</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Algemene gebruiksvoorwaarden",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Privacy Beleid",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Geen gebruiker gevonden met die gebruikersnaam.",
"verify": "Verify", "verify": "Verifiëren",
"signIn": "Sign In", "signIn": "Log in",
"forgotPassword": "Forgot password?", "forgotPassword": "Wachtwoord vergeten?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Als u eerder bent ingelogd, kunt u uw gebruikersnaam of e-mail hierboven invoeren om in plaats daarvan te verifiëren met de identiteitsprovider van uw organisatie! Het is makkelijk!",
"continueAnyway": "Continue anyway", "continueAnyway": "Toch doorgaan",
"dontShowAgain": "Don't show again", "dontShowAgain": "Niet meer weergeven",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Wist u dat?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Proberen je aan te melden?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Probeert u zich aan te melden via de identiteitsprovider van uw organisatie?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Log in of meld je aan bij je organisatie",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Gebruik een ander account",
"logIn": "Log In", "logIn": "Log in",
"deviceInformation": "Device Information", "deviceInformation": "Apparaat informatie",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informatie over het apparaat en de agent",
"deviceSecurity": "Apparaat beveiliging",
"deviceSecurityDescription": "Apparaat beveiligingsinformatie",
"platform": "Platform", "platform": "Platform",
"macosVersion": "macOS Version", "macosVersion": "macOS versie",
"windowsVersion": "Windows Version", "windowsVersion": "Windows versie",
"iosVersion": "iOS Version", "iosVersion": "iOS versie",
"androidVersion": "Android Version", "androidVersion": "Android versie",
"osVersion": "OS Version", "osVersion": "OS versie",
"kernelVersion": "Kernel Version", "kernelVersion": "Kernel versie",
"deviceModel": "Device Model", "deviceModel": "Apparaat model",
"serialNumber": "Serial Number", "serialNumber": "Serienummer",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Eerst gezien",
"lastSeen": "Last Seen", "lastSeen": "Laatst gezien op",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometrie ingeschakeld",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Schijf versleuteld",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Firewall ingeschakeld",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Auto Updates Ingeschakeld",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM beschikbaar",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirus ingeschakeld",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Systeemintegriteitsbescherming (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Firewall Verberg Modus",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "Appharnas",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Apparaatinformatie en -instellingen bekijken",
"devicePendingApprovalDescription": "Dit apparaat wacht op goedkeuring",
"deviceBlockedDescription": "Dit apparaat is momenteel geblokkeerd. Het kan geen verbinding maken met bronnen tenzij het wordt gedeblokkeerd.",
"unblockClient": "Deblokkeer client",
"unblockClientDescription": "Het apparaat is gedeblokkeerd",
"unarchiveClient": "Dearchiveer client",
"unarchiveClientDescription": "Het apparaat is gedearchiveerd",
"block": "Blokkeren",
"unblock": "Deblokkeer",
"deviceActions": "Apparaat Acties",
"deviceActionsDescription": "Apparaatstatus en toegang beheren",
"devicePendingApprovalBannerDescription": "Dit apparaat wacht op goedkeuring. Het zal niet in staat zijn verbinding te maken met bronnen totdat het is goedgekeurd.",
"connected": "Verbonden",
"disconnected": "Losgekoppeld",
"approvalsEmptyStateTitle": "Apparaat goedkeuringen niet ingeschakeld",
"approvalsEmptyStateDescription": "Apparaatgoedkeuringen voor rollen inschakelen om goedkeuring van de beheerder te vereisen voordat gebruikers nieuwe apparaten kunnen koppelen.",
"approvalsEmptyStateStep1Title": "Ga naar rollen",
"approvalsEmptyStateStep1Description": "Navigeer naar de rolinstellingen van uw organisatie om apparaatgoedkeuringen te configureren.",
"approvalsEmptyStateStep2Title": "Toestel goedkeuringen inschakelen",
"approvalsEmptyStateStep2Description": "Bewerk een rol en schakel de optie 'Vereist Apparaat Goedkeuringen' in. Gebruikers met deze rol hebben admin goedkeuring nodig voor nieuwe apparaten.",
"approvalsEmptyStatePreviewDescription": "Voorbeeld: Indien ingeschakeld, zullen in afwachting van apparaatverzoeken hier verschijnen om te beoordelen",
"approvalsEmptyStateButtonText": "Rollen beheren"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "Jesteś członkiem {count, plural, =0 {żadna organizacja} one {jedna organizacja} few {# organizacje} many {# organizacji} other {# organizacji}}.", "componentsMember": "Jesteś członkiem {count, plural, =0 {żadna organizacja} one {jedna organizacja} few {# organizacje} many {# organizacji} other {# organizacji}}.",
"componentsInvalidKey": "Wykryto nieprawidłowe lub wygasłe klucze licencyjne. Postępuj zgodnie z warunkami licencji, aby kontynuować korzystanie ze wszystkich funkcji.", "componentsInvalidKey": "Wykryto nieprawidłowe lub wygasłe klucze licencyjne. Postępuj zgodnie z warunkami licencji, aby kontynuować korzystanie ze wszystkich funkcji.",
"dismiss": "Odrzuć", "dismiss": "Odrzuć",
"subscriptionViolationMessage": "Nie masz ograniczeń dla aktualnego planu. Popraw problem poprzez usunięcie stron, użytkowników lub innych zasobów, aby pozostać w swoim planie.",
"subscriptionViolationViewBilling": "Zobacz rozliczenie",
"componentsLicenseViolation": "Naruszenie licencji: Ten serwer używa stron {usedSites} , które przekraczają limit licencyjny stron {maxSites} . Postępuj zgodnie z warunkami licencji, aby kontynuować korzystanie ze wszystkich funkcji.", "componentsLicenseViolation": "Naruszenie licencji: Ten serwer używa stron {usedSites} , które przekraczają limit licencyjny stron {maxSites} . Postępuj zgodnie z warunkami licencji, aby kontynuować korzystanie ze wszystkich funkcji.",
"componentsSupporterMessage": "Dziękujemy za wsparcie Pangolina jako {tier}!", "componentsSupporterMessage": "Dziękujemy za wsparcie Pangolina jako {tier}!",
"inviteErrorNotValid": "Przykro nam, ale wygląda na to, że zaproszenie, do którego próbujesz uzyskać dostęp, nie zostało zaakceptowane lub jest już nieważne.", "inviteErrorNotValid": "Przykro nam, ale wygląda na to, że zaproszenie, do którego próbujesz uzyskać dostęp, nie zostało zaakceptowane lub jest już nieważne.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Połącz dowolną sieć", "sitesBannerTitle": "Połącz dowolną sieć",
"sitesBannerDescription": "Witryna to połączenie z siecią zdalną, które umożliwia Pangolinowi zapewnienie dostępu do zasobów, publicznych lub prywatnych, użytkownikom w dowolnym miejscu. Zainstaluj łącznik sieci w witrynie (Newt) w dowolnym miejscu, w którym możesz uruchomić binarkę lub kontener, aby ustanowić połączenie.", "sitesBannerDescription": "Witryna to połączenie z siecią zdalną, które umożliwia Pangolinowi zapewnienie dostępu do zasobów, publicznych lub prywatnych, użytkownikom w dowolnym miejscu. Zainstaluj łącznik sieci w witrynie (Newt) w dowolnym miejscu, w którym możesz uruchomić binarkę lub kontener, aby ustanowić połączenie.",
"sitesBannerButtonText": "Zainstaluj witrynę", "sitesBannerButtonText": "Zainstaluj witrynę",
"approvalsBannerTitle": "Zatwierdź lub odmów dostępu do urządzenia",
"approvalsBannerDescription": "Przejrzyj i zatwierdzaj lub odmawiaj użytkownikom dostępu do urządzenia. Gdy wymagane jest zatwierdzenie urządzenia, użytkownicy muszą uzyskać zatwierdzenie administratora, zanim ich urządzenia będą mogły połączyć się z zasobami Twojej organizacji.",
"approvalsBannerButtonText": "Dowiedz się więcej",
"siteCreate": "Utwórz witrynę", "siteCreate": "Utwórz witrynę",
"siteCreateDescription2": "Wykonaj poniższe kroki, aby utworzyć i połączyć nową witrynę", "siteCreateDescription2": "Wykonaj poniższe kroki, aby utworzyć i połączyć nową witrynę",
"siteCreateDescription": "Utwórz nową witrynę, aby rozpocząć łączenie zasobów", "siteCreateDescription": "Utwórz nową witrynę, aby rozpocząć łączenie zasobów",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Szukaj ról...", "accessRolesSearch": "Szukaj ról...",
"accessRolesAdd": "Dodaj rolę", "accessRolesAdd": "Dodaj rolę",
"accessRoleDelete": "Usuń rolę", "accessRoleDelete": "Usuń rolę",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Zarządzaj zatwierdzaniem",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Przeglądaj i zarządzaj oczekującymi zatwierdzeniami dostępu do tej organizacji",
"description": "Opis", "description": "Opis",
"inviteTitle": "Otwórz zaproszenia", "inviteTitle": "Otwórz zaproszenia",
"inviteDescription": "Zarządzaj zaproszeniami dla innych użytkowników do dołączenia do organizacji", "inviteDescription": "Zarządzaj zaproszeniami dla innych użytkowników do dołączenia do organizacji",
@@ -452,18 +457,18 @@
"selectDuration": "Wybierz okres", "selectDuration": "Wybierz okres",
"selectResource": "Wybierz zasób", "selectResource": "Wybierz zasób",
"filterByResource": "Filtruj według zasobów", "filterByResource": "Filtruj według zasobów",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Wybierz województwo zatwierdzające",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtruj według państwa zatwierdzenia",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Brak zatwierdzeń",
"approvalState": "Approval State", "approvalState": "Państwo zatwierdzające",
"approve": "Approve", "approve": "Zatwierdź",
"approved": "Approved", "approved": "Zatwierdzone",
"denied": "Denied", "denied": "Odmowa",
"deniedApproval": "Denied Approval", "deniedApproval": "Odrzucono zatwierdzenie",
"all": "All", "all": "Wszystko",
"deny": "Deny", "deny": "Odmowa",
"viewDetails": "View Details", "viewDetails": "Zobacz szczegóły",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "zażądano nowego urządzenia",
"resetFilters": "Resetuj filtry", "resetFilters": "Resetuj filtry",
"totalBlocked": "Żądania zablokowane przez Pangolina", "totalBlocked": "Żądania zablokowane przez Pangolina",
"totalRequests": "Wszystkich Żądań", "totalRequests": "Wszystkich Żądań",
@@ -743,28 +748,28 @@
"countries": "Kraje", "countries": "Kraje",
"accessRoleCreate": "Utwórz rolę", "accessRoleCreate": "Utwórz rolę",
"accessRoleCreateDescription": "Utwórz nową rolę aby zgrupować użytkowników i zarządzać ich uprawnieniami.", "accessRoleCreateDescription": "Utwórz nową rolę aby zgrupować użytkowników i zarządzać ich uprawnieniami.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Edytuj rolę",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Edytuj informacje o rolach.",
"accessRoleCreateSubmit": "Utwórz rolę", "accessRoleCreateSubmit": "Utwórz rolę",
"accessRoleCreated": "Rola utworzona", "accessRoleCreated": "Rola utworzona",
"accessRoleCreatedDescription": "Rola została pomyślnie utworzona.", "accessRoleCreatedDescription": "Rola została pomyślnie utworzona.",
"accessRoleErrorCreate": "Nie udało się utworzyć roli", "accessRoleErrorCreate": "Nie udało się utworzyć roli",
"accessRoleErrorCreateDescription": "Wystąpił błąd podczas tworzenia roli.", "accessRoleErrorCreateDescription": "Wystąpił błąd podczas tworzenia roli.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Aktualizuj rolę",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Rola zaktualizowana",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Rola została pomyślnie zaktualizowana.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Zatwierdzenie przetworzone",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Ustaw decyzję o zatwierdzeniu wniosku o zatwierdzenie.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Ustaw decyzję o odrzuceniu wniosku o zatwierdzenie.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Nie udało się zaktualizować roli",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Wystąpił błąd podczas aktualizowania roli.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Nie udało się przetworzyć zatwierdzenia",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Wystąpił błąd podczas przetwarzania zatwierdzenia.",
"accessRoleErrorNewRequired": "Nowa rola jest wymagana", "accessRoleErrorNewRequired": "Nowa rola jest wymagana",
"accessRoleErrorRemove": "Nie udało się usunąć roli", "accessRoleErrorRemove": "Nie udało się usunąć roli",
"accessRoleErrorRemoveDescription": "Wystąpił błąd podczas usuwania roli.", "accessRoleErrorRemoveDescription": "Wystąpił błąd podczas usuwania roli.",
"accessRoleName": "Nazwa roli", "accessRoleName": "Nazwa roli",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Zamierzasz usunąć rolę `{name}`. Nie możesz cofnąć tej czynności.",
"accessRoleRemove": "Usuń rolę", "accessRoleRemove": "Usuń rolę",
"accessRoleRemoveDescription": "Usuń rolę z organizacji", "accessRoleRemoveDescription": "Usuń rolę z organizacji",
"accessRoleRemoveSubmit": "Usuń rolę", "accessRoleRemoveSubmit": "Usuń rolę",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Zwiększ liczbę witryn", "sitestCountIncrease": "Zwiększ liczbę witryn",
"idpManage": "Zarządzaj dostawcami tożsamości", "idpManage": "Zarządzaj dostawcami tożsamości",
"idpManageDescription": "Wyświetl i zarządzaj dostawcami tożsamości w systemie", "idpManageDescription": "Wyświetl i zarządzaj dostawcami tożsamości w systemie",
"idpGlobalModeBanner": "Dostawcy tożsamości (IdPs) na organizację są wyłączeni na tym serwerze. Używa globalnych IdP (współdzielonych ze wszystkimi organizacjami). Zarządzaj globalnymi IdP w panelu administracyjnym <adminPanelLink></adminPanelLink>. Aby włączyć IdP na organizację, edytuj konfigurację serwera i ustaw tryb IdP na org. <configDocsLink>Zobacz dokumentację</configDocsLink>. Jeśli chcesz nadal używać globalnych IdP i sprawić, że zniknie to z ustawień organizacji, wyraźnie ustaw tryb globalny w konfiguracji.",
"idpGlobalModeBannerUpgradeRequired": "Dostawcy tożsamości (IdPs) na organizację są wyłączeni na tym serwerze. Używają globalnych IdP (współdzielonych między wszystkimi organizacjami). Zarządzaj globalnymi IdP w panelu administracyjnym <adminPanelLink></adminPanelLink>. Aby korzystać z dostawców tożsamości na organizację, musisz zaktualizować do edycji Enterprise.",
"idpGlobalModeBannerLicenseRequired": "Dostawcy tożsamości (IdPs) na organizację są wyłączeni na tym serwerze. Używają globalnych IdP (współdzielonych między wszystkimi organizacjami). Zarządzaj globalnymi IdP w panelu administracyjnym <adminPanelLink></adminPanelLink>. Aby korzystać z dostawców tożsamości na organizację, wymagana jest licencja Enterprise.",
"idpDeletedDescription": "Dostawca tożsamości został pomyślnie usunięty", "idpDeletedDescription": "Dostawca tożsamości został pomyślnie usunięty",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Czy na pewno chcesz trwale usunąć dostawcę tożsamości?", "idpQuestionRemove": "Czy na pewno chcesz trwale usunąć dostawcę tożsamości?",
@@ -900,7 +908,7 @@
"inviteAlready": "Wygląda na to, że zostałeś już zaproszony!", "inviteAlready": "Wygląda na to, że zostałeś już zaproszony!",
"inviteAlreadyDescription": "Aby zaakceptować zaproszenie, musisz się zalogować lub utworzyć konto.", "inviteAlreadyDescription": "Aby zaakceptować zaproszenie, musisz się zalogować lub utworzyć konto.",
"signupQuestion": "Masz już konto?", "signupQuestion": "Masz już konto?",
"login": "Log In", "login": "Zaloguj się",
"resourceNotFound": "Nie znaleziono zasobu", "resourceNotFound": "Nie znaleziono zasobu",
"resourceNotFoundDescription": "Zasób, do którego próbujesz uzyskać dostęp, nie istnieje.", "resourceNotFoundDescription": "Zasób, do którego próbujesz uzyskać dostęp, nie istnieje.",
"pincodeRequirementsLength": "PIN musi składać się dokładnie z 6 cyfr", "pincodeRequirementsLength": "PIN musi składać się dokładnie z 6 cyfr",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Organizacja wymaga zmiany hasła co {maxDays} dni.", "passwordExpiryDescription": "Organizacja wymaga zmiany hasła co {maxDays} dni.",
"changePasswordNow": "Zmień hasło teraz", "changePasswordNow": "Zmień hasło teraz",
"pincodeAuth": "Kod uwierzytelniający", "pincodeAuth": "Kod uwierzytelniający",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Prześlij kod",
"passwordResetSubmit": "Zażądaj resetowania", "passwordResetSubmit": "Zażądaj resetowania",
"passwordResetAlreadyHaveCode": "Wprowadź kod", "passwordResetAlreadyHaveCode": "Wprowadź kod",
"passwordResetSmtpRequired": "Skontaktuj się z administratorem", "passwordResetSmtpRequired": "Skontaktuj się z administratorem",
"passwordResetSmtpRequiredDescription": "Aby zresetować hasło, wymagany jest kod resetowania hasła. Skontaktuj się z administratorem.", "passwordResetSmtpRequiredDescription": "Aby zresetować hasło, wymagany jest kod resetowania hasła. Skontaktuj się z administratorem.",
"passwordBack": "Powrót do hasła", "passwordBack": "Powrót do hasła",
"loginBack": "Go back to main login page", "loginBack": "Wróć do strony logowania głównego",
"signup": "Zarejestruj się", "signup": "Zarejestruj się",
"loginStart": "Zaloguj się, aby rozpocząć", "loginStart": "Zaloguj się, aby rozpocząć",
"idpOidcTokenValidating": "Walidacja tokena OIDC", "idpOidcTokenValidating": "Walidacja tokena OIDC",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Aktualizuj organizację IDP", "actionUpdateIdpOrg": "Aktualizuj organizację IDP",
"actionCreateClient": "Utwórz klienta", "actionCreateClient": "Utwórz klienta",
"actionDeleteClient": "Usuń klienta", "actionDeleteClient": "Usuń klienta",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Zarchiwizuj klienta",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Usuń archiwizację klienta",
"actionBlockClient": "Block Client", "actionBlockClient": "Zablokuj klienta",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Odblokuj klienta",
"actionUpdateClient": "Aktualizuj klienta", "actionUpdateClient": "Aktualizuj klienta",
"actionListClients": "Lista klientów", "actionListClients": "Lista klientów",
"actionGetClient": "Pobierz klienta", "actionGetClient": "Pobierz klienta",
@@ -1164,14 +1172,14 @@
"searchProgress": "Szukaj...", "searchProgress": "Szukaj...",
"create": "Utwórz", "create": "Utwórz",
"orgs": "Organizacje", "orgs": "Organizacje",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Wystąpił nieoczekiwany błąd. Spróbuj ponownie.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Logowanie jest wymagane dla Twojego urządzenia.",
"passwordForgot": "Zapomniałeś hasła?", "passwordForgot": "Zapomniałeś hasła?",
"otpAuth": "Uwierzytelnianie dwuskładnikowe", "otpAuth": "Uwierzytelnianie dwuskładnikowe",
"otpAuthDescription": "Wprowadź kod z aplikacji uwierzytelniającej lub jeden z jednorazowych kodów zapasowych.", "otpAuthDescription": "Wprowadź kod z aplikacji uwierzytelniającej lub jeden z jednorazowych kodów zapasowych.",
"otpAuthSubmit": "Wyślij kod", "otpAuthSubmit": "Wyślij kod",
"idpContinue": "Lub kontynuuj z", "idpContinue": "Lub kontynuuj z",
"otpAuthBack": "Back to Password", "otpAuthBack": "Powrót do hasła",
"navbar": "Menu nawigacyjne", "navbar": "Menu nawigacyjne",
"navbarDescription": "Główne menu nawigacyjne aplikacji", "navbarDescription": "Główne menu nawigacyjne aplikacji",
"navbarDocsLink": "Dokumentacja", "navbarDocsLink": "Dokumentacja",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Przegląd", "sidebarOverview": "Przegląd",
"sidebarHome": "Strona główna", "sidebarHome": "Strona główna",
"sidebarSites": "Witryny", "sidebarSites": "Witryny",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Wnioski o zatwierdzenie",
"sidebarResources": "Zasoby", "sidebarResources": "Zasoby",
"sidebarProxyResources": "Publiczne", "sidebarProxyResources": "Publiczne",
"sidebarClientResources": "Prywatny", "sidebarClientResources": "Prywatny",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Dostawcy tożsamości", "sidebarIdentityProviders": "Dostawcy tożsamości",
"sidebarLicense": "Licencja", "sidebarLicense": "Licencja",
"sidebarClients": "Klienty", "sidebarClients": "Klienty",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Urządzenia użytkownika",
"sidebarMachineClients": "Maszyny", "sidebarMachineClients": "Maszyny",
"sidebarDomains": "Domeny", "sidebarDomains": "Domeny",
"sidebarGeneral": "Zarządzaj", "sidebarGeneral": "Zarządzaj",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Wystąpił błąd podczas tworzenia konta administratora serwera.", "setupErrorCreateAdmin": "Wystąpił błąd podczas tworzenia konta administratora serwera.",
"certificateStatus": "Status certyfikatu", "certificateStatus": "Status certyfikatu",
"loading": "Ładowanie", "loading": "Ładowanie",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Ładowanie Analityki",
"restart": "Uruchom ponownie", "restart": "Uruchom ponownie",
"domains": "Domeny", "domains": "Domeny",
"domainsDescription": "Tworzenie domen dostępnych w organizacji i zarządzanie nimi", "domainsDescription": "Tworzenie domen dostępnych w organizacji i zarządzanie nimi",
@@ -1336,7 +1344,7 @@
"refreshError": "Nie udało się odświeżyć danych", "refreshError": "Nie udało się odświeżyć danych",
"verified": "Zatwierdzony", "verified": "Zatwierdzony",
"pending": "Oczekuje", "pending": "Oczekuje",
"pendingApproval": "Pending Approval", "pendingApproval": "Oczekujące na zatwierdzenie",
"sidebarBilling": "Fakturowanie", "sidebarBilling": "Fakturowanie",
"billing": "Fakturowanie", "billing": "Fakturowanie",
"orgBillingDescription": "Zarządzaj informacjami rozliczeniowymi i subskrypcjami", "orgBillingDescription": "Zarządzaj informacjami rozliczeniowymi i subskrypcjami",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Przegląd Limitów Użytkowania", "billingUsageLimitsOverview": "Przegląd Limitów Użytkowania",
"billingMonitorUsage": "Monitoruj swoje wykorzystanie w porównaniu do skonfigurowanych limitów. Jeśli potrzebujesz zwiększenia limitów, skontaktuj się z nami pod adresem support@pangolin.net.", "billingMonitorUsage": "Monitoruj swoje wykorzystanie w porównaniu do skonfigurowanych limitów. Jeśli potrzebujesz zwiększenia limitów, skontaktuj się z nami pod adresem support@pangolin.net.",
"billingDataUsage": "Użycie danych", "billingDataUsage": "Użycie danych",
"billingOnlineTime": "Czas Online Strony", "billingSites": "Witryny",
"billingUsers": "Aktywni użytkownicy", "billingUsers": "Użytkownicy",
"billingDomains": "Aktywne domeny", "billingDomains": "Domeny",
"billingRemoteExitNodes": "Aktywne samodzielnie-hostowane węzły", "billingRemoteExitNodes": "Zdalne węzły",
"billingNoLimitConfigured": "Nie skonfigurowano limitu", "billingNoLimitConfigured": "Nie skonfigurowano limitu",
"billingEstimatedPeriod": "Szacowany Okres Rozliczeniowy", "billingEstimatedPeriod": "Szacowany Okres Rozliczeniowy",
"billingIncludedUsage": "Zawarte użycie", "billingIncludedUsage": "Zawarte użycie",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Nie udało się uzyskać adresu URL portalu", "billingFailedToGetPortalUrl": "Nie udało się uzyskać adresu URL portalu",
"billingPortalError": "Błąd Portalu", "billingPortalError": "Błąd Portalu",
"billingDataUsageInfo": "Jesteś obciążony za wszystkie dane przesyłane przez bezpieczne tunele, gdy jesteś podłączony do chmury. Obejmuje to zarówno ruch przychodzący, jak i wychodzący we wszystkich Twoich witrynach. Gdy osiągniesz swój limit, twoje strony zostaną rozłączone, dopóki nie zaktualizujesz planu lub nie ograniczysz użycia. Dane nie będą naliczane przy użyciu węzłów.", "billingDataUsageInfo": "Jesteś obciążony za wszystkie dane przesyłane przez bezpieczne tunele, gdy jesteś podłączony do chmury. Obejmuje to zarówno ruch przychodzący, jak i wychodzący we wszystkich Twoich witrynach. Gdy osiągniesz swój limit, twoje strony zostaną rozłączone, dopóki nie zaktualizujesz planu lub nie ograniczysz użycia. Dane nie będą naliczane przy użyciu węzłów.",
"billingOnlineTimeInfo": "Opłata zależy od tego, jak długo twoje strony pozostają połączone z chmurą. Na przykład 44,640 minut oznacza jedną stronę działającą 24/7 przez cały miesiąc. Kiedy osiągniesz swój limit, twoje strony zostaną rozłączone, dopóki nie zaktualizujesz planu lub nie zmniejsz jego wykorzystania. Czas nie będzie naliczany przy użyciu węzłów.", "billingSInfo": "Ile stron możesz użyć",
"billingUsersInfo": "Opłata za każdego użytkownika w organizacji. Płatność jest obliczana codziennie na podstawie liczby aktywnych kont użytkowników w Twojej organizacji.", "billingUsersInfo": "Ile użytkowników możesz użyć",
"billingDomainInfo": "Opłata za każdą domenę w organizacji. Płatność jest obliczana codziennie na podstawie liczby aktywnych kont domen w Twojej organizacji.", "billingDomainInfo": "Ile domen możesz użyć",
"billingRemoteExitNodesInfo": "Opłata za każdy zarządzany węzeł w organizacji. Płatność jest obliczana codziennie na podstawie liczby aktywnych zarządzanych węzłów w Twojej organizacji.", "billingRemoteExitNodesInfo": "Ile zdalnych węzłów możesz użyć",
"billingLicenseKeys": "Klucze licencyjne",
"billingLicenseKeysDescription": "Zarządzaj subskrypcjami kluczy licencyjnych",
"billingLicenseSubscription": "Subskrypcja licencji",
"billingInactive": "Nieaktywny",
"billingLicenseItem": "Element licencji",
"billingQuantity": "Ilość",
"billingTotal": "łącznie",
"billingModifyLicenses": "Modyfikuj subskrypcję licencji",
"domainNotFound": "Nie znaleziono domeny", "domainNotFound": "Nie znaleziono domeny",
"domainNotFoundDescription": "Zasób jest wyłączony, ponieważ domena nie istnieje już w naszym systemie. Proszę ustawić nową domenę dla tego zasobu.", "domainNotFoundDescription": "Zasób jest wyłączony, ponieważ domena nie istnieje już w naszym systemie. Proszę ustawić nową domenę dla tego zasobu.",
"failed": "Niepowodzenie", "failed": "Niepowodzenie",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Klucz bezpieczeństwa został pomyślnie usunięty", "securityKeyRemoveSuccess": "Klucz bezpieczeństwa został pomyślnie usunięty",
"securityKeyRemoveError": "Błąd podczas usuwania klucza bezpieczeństwa", "securityKeyRemoveError": "Błąd podczas usuwania klucza bezpieczeństwa",
"securityKeyLoadError": "Błąd podczas ładowania kluczy bezpieczeństwa", "securityKeyLoadError": "Błąd podczas ładowania kluczy bezpieczeństwa",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Użyj klucza bezpieczeństwa",
"securityKeyAuthError": "Błąd podczas uwierzytelniania kluczem bezpieczeństwa", "securityKeyAuthError": "Błąd podczas uwierzytelniania kluczem bezpieczeństwa",
"securityKeyRecommendation": "Rozważ zarejestrowanie innego klucza bezpieczeństwa na innym urządzeniu, aby upewnić się, że nie zostaniesz zablokowany z dostępu do swojego konta.", "securityKeyRecommendation": "Rozważ zarejestrowanie innego klucza bezpieczeństwa na innym urządzeniu, aby upewnić się, że nie zostaniesz zablokowany z dostępu do swojego konta.",
"registering": "Rejestracja...", "registering": "Rejestracja...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Numer portu jest wymagany dla zasobów non-HTTP", "resourcePortRequired": "Numer portu jest wymagany dla zasobów non-HTTP",
"resourcePortNotAllowed": "Numer portu nie powinien być ustawiony dla zasobów HTTP", "resourcePortNotAllowed": "Numer portu nie powinien być ustawiony dla zasobów HTTP",
"billingPricingCalculatorLink": "Kalkulator Cen", "billingPricingCalculatorLink": "Kalkulator Cen",
"billingYourPlan": "Twój plan",
"billingViewOrModifyPlan": "Wyświetl lub zmodyfikuj swój aktualny plan",
"billingViewPlanDetails": "Zobacz szczegóły planu",
"billingUsageAndLimits": "Stosowanie i ograniczenia",
"billingViewUsageAndLimits": "Zobacz limity swojego planu i bieżące użycie",
"billingCurrentUsage": "Bieżące użycie",
"billingMaximumLimits": "Maksymalne limity",
"billingRemoteNodes": "Zdalne węzły",
"billingUnlimited": "Nieograniczona",
"billingPaidLicenseKeys": "Płatne klucze licencyjne",
"billingManageLicenseSubscription": "Zarządzaj subskrypcją płatnych własnych kluczy licencyjnych",
"billingCurrentKeys": "Bieżące klucze",
"billingModifyCurrentPlan": "Modyfikuj bieżący plan",
"billingConfirmUpgrade": "Potwierdź aktualizację",
"billingConfirmDowngrade": "Potwierdź obniżenie",
"billingConfirmUpgradeDescription": "Zamierzasz ulepszyć swój plan. Przejrzyj nowe limity i ceny poniżej.",
"billingConfirmDowngradeDescription": "Zamierzasz obniżyć swój plan. Przejrzyj nowe limity i ceny poniżej.",
"billingPlanIncludes": "Plan zawiera",
"billingProcessing": "Przetwarzanie...",
"billingConfirmUpgradeButton": "Potwierdź aktualizację",
"billingConfirmDowngradeButton": "Potwierdź obniżenie",
"billingLimitViolationWarning": "Użycie przekracza nowe limity planu",
"billingLimitViolationDescription": "Bieżące użycie przekracza limity tego planu. Po obniżeniu, wszystkie działania zostaną wyłączone, dopóki nie zmniejsz zużycia w ramach nowych limitów. Zapoznaj się z poniższymi funkcjami, które obecnie przekraczają limity. Limity naruszenia:",
"billingFeatureLossWarning": "Powiadomienie o dostępności funkcji",
"billingFeatureLossDescription": "Po obniżeniu wartości funkcje niedostępne w nowym planie zostaną automatycznie wyłączone. Niektóre ustawienia i konfiguracje mogą zostać utracone. Zapoznaj się z matrycą cenową, aby zrozumieć, które funkcje nie będą już dostępne.",
"billingUsageExceedsLimit": "Bieżące użycie ({current}) przekracza limit ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Zgadzam się z", "IAgreeToThe": "Zgadzam się z",
"termsOfService": "warunkami usługi", "termsOfService": "warunkami usługi",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Interwał Zdrowy", "IntervalSeconds": "Interwał Zdrowy",
"timeoutSeconds": "Limit czasu (sek)", "timeoutSeconds": "Limit czasu (sek)",
"timeIsInSeconds": "Czas w sekundach", "timeIsInSeconds": "Czas w sekundach",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Wymagaj zatwierdzenia urządzenia",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Użytkownicy o tej roli potrzebują nowych urządzeń zatwierdzonych przez administratora, zanim będą mogli połączyć się i uzyskać dostęp do zasobów.",
"retryAttempts": "Próby Ponowienia", "retryAttempts": "Próby Ponowienia",
"expectedResponseCodes": "Oczekiwane Kody Odpowiedzi", "expectedResponseCodes": "Oczekiwane Kody Odpowiedzi",
"expectedResponseCodesDescription": "Kod statusu HTTP, który wskazuje zdrowy status. Jeśli pozostanie pusty, uznaje się 200-300 za zdrowy.", "expectedResponseCodesDescription": "Kod statusu HTTP, który wskazuje zdrowy status. Jeśli pozostanie pusty, uznaje się 200-300 za zdrowy.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Nie znaleziono wewnętrznych zasobów.", "resourcesTableNoInternalResourcesFound": "Nie znaleziono wewnętrznych zasobów.",
"resourcesTableDestination": "Miejsce docelowe", "resourcesTableDestination": "Miejsce docelowe",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Adres aliasu",
"resourcesTableAliasAddressInfo": "Ten adres jest częścią podsieci użyteczności organizacji. Jest używany do rozwiązywania rekordów aliasu przy użyciu wewnętrznej rozdzielczości DNS.",
"resourcesTableClients": "Klientami", "resourcesTableClients": "Klientami",
"resourcesTableAndOnlyAccessibleInternally": "i są dostępne tylko wewnętrznie po połączeniu z klientem.", "resourcesTableAndOnlyAccessibleInternally": "i są dostępne tylko wewnętrznie po połączeniu z klientem.",
"resourcesTableNoTargets": "Brak celów", "resourcesTableNoTargets": "Brak celów",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Wybierz swojego dostawcę tożsamości, aby kontynuować", "orgAuthChooseIdpDescription": "Wybierz swojego dostawcę tożsamości, aby kontynuować",
"orgAuthNoIdpConfigured": "Ta organizacja nie ma skonfigurowanych żadnych dostawców tożsamości. Zamiast tego możesz zalogować się za pomocą swojej tożsamości Pangolin.", "orgAuthNoIdpConfigured": "Ta organizacja nie ma skonfigurowanych żadnych dostawców tożsamości. Zamiast tego możesz zalogować się za pomocą swojej tożsamości Pangolin.",
"orgAuthSignInWithPangolin": "Zaloguj się używając Pangolin", "orgAuthSignInWithPangolin": "Zaloguj się używając Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Zaloguj się do organizacji",
"orgAuthSelectOrgTitle": "Logowanie do organizacji", "orgAuthSelectOrgTitle": "Logowanie do organizacji",
"orgAuthSelectOrgDescription": "Wprowadź identyfikator organizacji, aby kontynuować", "orgAuthSelectOrgDescription": "Wprowadź identyfikator organizacji, aby kontynuować",
"orgAuthOrgIdPlaceholder": "twoja-organizacja", "orgAuthOrgIdPlaceholder": "twoja-organizacja",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Powrót do standardowego logowania", "orgAuthBackToSignIn": "Powrót do standardowego logowania",
"orgAuthNoAccount": "Nie masz konta?", "orgAuthNoAccount": "Nie masz konta?",
"subscriptionRequiredToUse": "Do korzystania z tej funkcji wymagana jest subskrypcja.", "subscriptionRequiredToUse": "Do korzystania z tej funkcji wymagana jest subskrypcja.",
"mustUpgradeToUse": "Musisz uaktualnić subskrypcję, aby korzystać z tej funkcji.",
"subscriptionRequiredTierToUse": "Ta funkcja wymaga funkcji <tierLink>{tier}</tierLink> lub wyższej.",
"upgradeToTierToUse": "Aby skorzystać z tej funkcji, przejdź na <tierLink>{tier}</tierLink> lub wyższy pakiet.",
"subscriptionTierTier1": "Strona główna",
"subscriptionTierTier2": "Drużyna",
"subscriptionTierTier3": "Biznes",
"subscriptionTierEnterprise": "Przedsiębiorstwo",
"idpDisabled": "Dostawcy tożsamości są wyłączeni", "idpDisabled": "Dostawcy tożsamości są wyłączeni",
"orgAuthPageDisabled": "Strona autoryzacji organizacji jest wyłączona.", "orgAuthPageDisabled": "Strona autoryzacji organizacji jest wyłączona.",
"domainRestartedDescription": "Weryfikacja domeny zrestartowana pomyślnie", "domainRestartedDescription": "Weryfikacja domeny zrestartowana pomyślnie",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Uzyskaj licencję",
"description": "Wybierz plan i powiedz nam, jak planujesz korzystać z Pangolin.",
"chooseTier": "Wybierz swój plan",
"viewPricingLink": "Zobacz cenniki, funkcje i limity",
"tiers": {
"starter": {
"title": "Rozpocznij",
"description": "Środki te przeznaczone są na pokrycie wydatków na personel i wydatków administracyjnych Agencji (tytuły 1 i 2) oraz jej wydatków operacyjnych (tytuł 3)."
},
"scale": {
"title": "Skala",
"description": "Cechy przedsiębiorstw, 50 użytkowników, 50 obiektów i wsparcie priorytetowe."
}
},
"personalUseOnly": "Wyłącznie do użytku osobistego (bezpłatna licencja brak zamówień)",
"buttons": {
"continueToCheckout": "Przejdź do zamówienia"
},
"toasts": {
"checkoutError": {
"title": "Błąd zamówienia",
"description": "Nie można uruchomić zamówienia. Spróbuj ponownie."
}
}
},
"priority": "Priorytet", "priority": "Priorytet",
"priorityDescription": "Najpierw oceniane są trasy priorytetowe. Priorytet = 100 oznacza automatyczne zamawianie (decyzje systemowe). Użyj innego numeru, aby wyegzekwować ręczny priorytet.", "priorityDescription": "Najpierw oceniane są trasy priorytetowe. Priorytet = 100 oznacza automatyczne zamawianie (decyzje systemowe). Użyj innego numeru, aby wyegzekwować ręczny priorytet.",
"instanceName": "Nazwa instancji", "instanceName": "Nazwa instancji",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Koniec następnego roku", "logRetentionEndOfFollowingYear": "Koniec następnego roku",
"actionLogsDescription": "Zobacz historię działań wykonywanych w tej organizacji", "actionLogsDescription": "Zobacz historię działań wykonywanych w tej organizacji",
"accessLogsDescription": "Wyświetl prośby o autoryzację dostępu do zasobów w tej organizacji", "accessLogsDescription": "Wyświetl prośby o autoryzację dostępu do zasobów w tej organizacji",
"licenseRequiredToUse": "Licencja Enterprise jest wymagana do korzystania z tej funkcji.", "licenseRequiredToUse": "Do korzystania z tej funkcji wymagana jest licencja <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> . Ta funkcja jest również dostępna w <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "<enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> jest wymagany do korzystania z tej funkcji. Ta funkcja jest również dostępna w <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Rozwiązywanie certyfikatów", "certResolver": "Rozwiązywanie certyfikatów",
"certResolverDescription": "Wybierz resolver certyfikatów do użycia dla tego zasobu.", "certResolverDescription": "Wybierz resolver certyfikatów do użycia dla tego zasobu.",
"selectCertResolver": "Wybierz Resolver certyfikatów", "selectCertResolver": "Wybierz Resolver certyfikatów",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Kod musi mieć 9 znaków (np. A1AJ-N5JD)", "deviceCodeInvalidFormat": "Kod musi mieć 9 znaków (np. A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Nieprawidłowy lub wygasły kod", "deviceCodeInvalidOrExpired": "Nieprawidłowy lub wygasły kod",
"deviceCodeVerifyFailed": "Nie udało się zweryfikować kodu urządzenia", "deviceCodeVerifyFailed": "Nie udało się zweryfikować kodu urządzenia",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Sprawdzanie kodu urządzenia...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Weryfikowanie autoryzacji urządzenia...",
"signedInAs": "Zalogowany jako", "signedInAs": "Zalogowany jako",
"deviceCodeEnterPrompt": "Wprowadź kod wyświetlany na urządzeniu", "deviceCodeEnterPrompt": "Wprowadź kod wyświetlany na urządzeniu",
"continue": "Kontynuuj", "continue": "Kontynuuj",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Dostęp do wszystkich organizacji, do których Twoje konto ma dostęp", "deviceOrganizationsAccess": "Dostęp do wszystkich organizacji, do których Twoje konto ma dostęp",
"deviceAuthorize": "Autoryzuj {applicationName}", "deviceAuthorize": "Autoryzuj {applicationName}",
"deviceConnected": "Urządzenie podłączone!", "deviceConnected": "Urządzenie podłączone!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Urządzenie jest autoryzowane do uzyskania dostępu do Twojego konta. Proszę wróć do aplikacji klienckiej.",
"pangolinCloud": "Chmura Pangolin", "pangolinCloud": "Chmura Pangolin",
"viewDevices": "Zobacz urządzenia", "viewDevices": "Zobacz urządzenia",
"viewDevicesDescription": "Zarządzaj podłączonymi urządzeniami", "viewDevicesDescription": "Zarządzaj podłączonymi urządzeniami",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Nie ty? Użyj innego konta.", "deviceLoginUseDifferentAccount": "Nie ty? Użyj innego konta.",
"deviceLoginDeviceRequestingAccessToAccount": "Urządzenie żąda dostępu do tego konta.", "deviceLoginDeviceRequestingAccessToAccount": "Urządzenie żąda dostępu do tego konta.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Wybierz metodę uwierzytelniania aby kontynuować.",
"noData": "Brak danych", "noData": "Brak danych",
"machineClients": "Klienci maszyn", "machineClients": "Klienci maszyn",
"install": "Zainstaluj", "install": "Zainstaluj",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Obecnie doświadczamy problemów technicznych. Proszę sprawdzić ponownie wkrótce.", "maintenanceScreenMessage": "Obecnie doświadczamy problemów technicznych. Proszę sprawdzić ponownie wkrótce.",
"maintenanceScreenEstimatedCompletion": "Szacowane zakończenie:", "maintenanceScreenEstimatedCompletion": "Szacowane zakończenie:",
"createInternalResourceDialogDestinationRequired": "Miejsce docelowe jest wymagane", "createInternalResourceDialogDestinationRequired": "Miejsce docelowe jest wymagane",
"available": "Available", "available": "Dostępny",
"archived": "Archived", "archived": "Zarchiwizowane",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Nie znaleziono zarchiwizowanych urządzeń",
"deviceArchived": "Device archived", "deviceArchived": "Urządzenie zarchiwizowane",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Urządzenie zostało pomyślnie zarchiwizowane.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Błąd podczas archiwizacji urządzenia",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Nie udało się zarchiwizować urządzenia",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Czy na pewno chcesz zarchiwizować to urządzenie?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Urządzenie zostanie zarchiwizowane i usunięte z listy aktywnych urządzeń.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Archiwizuj urządzenie",
"archiveDevice": "Archive Device", "archiveDevice": "Archiwizuj urządzenie",
"archive": "Archive", "archive": "Archiwum",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Urządzenie niezarchiwizowane",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Urządzenie zostało pomyślnie usunięte.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Błąd podczas usuwania archiwizacji urządzenia",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Nie udało się odarchiwizować urządzenia",
"unarchive": "Unarchive", "unarchive": "Usuń z archiwum",
"archiveClient": "Archive Client", "archiveClient": "Zarchiwizuj klienta",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Czy na pewno chcesz zarchiwizować tego klienta?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Klient zostanie zarchiwizowany i usunięty z listy aktywnych klientów.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Zarchiwizuj klienta",
"blockClient": "Block Client", "blockClient": "Zablokuj klienta",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Czy na pewno chcesz zablokować tego klienta?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Urządzenie zostanie wymuszone do rozłączenia, jeśli jest obecnie podłączone. Możesz odblokować urządzenie później.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Zablokuj klienta",
"active": "Active", "active": "Aktywne",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Nazwa użytkownika lub e-mail",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Wybierz swoją organizację",
"signInTo": "Log in in to", "signInTo": "Zaloguj się do",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Kontynuuj z hasłem",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Brak dostępnych metod uwierzytelniania dla tej organizacji.",
"enterPassword": "Enter your password", "enterPassword": "Wprowadź hasło",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Wprowadź kod z aplikacji uwierzytelniającej",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Aby się zalogować, użyj klucza bezpieczeństwa.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Potrzebujesz użyć innego konta?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Klikając na przycisk poniżej, potwierdzasz, że przeczytałeś, rozumiesz, i zaakceptuj <termsOfService>Warunki świadczenia usługi</termsOfService> i <privacyPolicy>Polityka prywatności</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Warunki korzystania z usługi",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Polityka prywatności",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Nie znaleziono użytkownika o tej nazwie użytkownika.",
"verify": "Verify", "verify": "Weryfikacja",
"signIn": "Sign In", "signIn": "Zaloguj się",
"forgotPassword": "Forgot password?", "forgotPassword": "Zapomniałeś hasła?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Jeśli zalogowałeś się wcześniej, możesz wprowadzić nazwę użytkownika lub e-mail powyżej, aby uwierzytelnić się z dostawcą tożsamości organizacji. To łatwiejsze!",
"continueAnyway": "Continue anyway", "continueAnyway": "Kontynuuj mimo to",
"dontShowAgain": "Don't show again", "dontShowAgain": "Nie pokazuj ponownie",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Czy wiedziałeś?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Próbujesz się zalogować?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Czy próbujesz zalogować się za pośrednictwem dostawcy tożsamości organizacji?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Zamiast tego zaloguj się lub zarejestruj w swojej organizacji",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Użyj innego konta",
"logIn": "Log In", "logIn": "Zaloguj się",
"deviceInformation": "Device Information", "deviceInformation": "Informacje o urządzeniu",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informacje o urządzeniu i agentach",
"platform": "Platform", "deviceSecurity": "Bezpieczeństwo urządzenia",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Informacje o bezpieczeństwie urządzenia",
"windowsVersion": "Windows Version", "platform": "Platforma",
"iosVersion": "iOS Version", "macosVersion": "Wersja macOS",
"androidVersion": "Android Version", "windowsVersion": "Wersja Windows",
"osVersion": "OS Version", "iosVersion": "Wersja iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Wersja Androida",
"deviceModel": "Device Model", "osVersion": "Wersja systemu operacyjnego",
"serialNumber": "Serial Number", "kernelVersion": "Wersja jądra",
"deviceModel": "Model urządzenia",
"serialNumber": "Numer seryjny",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Widziany po raz pierwszy",
"lastSeen": "Last Seen", "lastSeen": "Ostatnio widziane",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometria włączona",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Dysk zaszyfrowany",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Zapora włączona",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Automatyczne aktualizacje włączone",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM dostępne",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antywirus włączony",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Ochrona integralności systemu (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Tryb Stealth zapory",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "Zbroja aplikacji",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Wyświetl informacje o urządzeniu i ustawienia",
"devicePendingApprovalDescription": "To urządzenie czeka na zatwierdzenie",
"deviceBlockedDescription": "To urządzenie jest obecnie zablokowane. Nie będzie można połączyć się z żadnymi zasobami, chyba że zostanie odblokowane.",
"unblockClient": "Odblokuj klienta",
"unblockClientDescription": "Urządzenie zostało odblokowane",
"unarchiveClient": "Usuń archiwizację klienta",
"unarchiveClientDescription": "Urządzenie zostało odarchiwizowane",
"block": "Blok",
"unblock": "Odblokuj",
"deviceActions": "Akcje urządzenia",
"deviceActionsDescription": "Zarządzaj stanem urządzenia i dostępem",
"devicePendingApprovalBannerDescription": "To urządzenie oczekuje na zatwierdzenie. Nie będzie można połączyć się z zasobami, dopóki nie zostanie zatwierdzone.",
"connected": "Połączono",
"disconnected": "Rozłączony",
"approvalsEmptyStateTitle": "Zatwierdzanie urządzenia nie włączone",
"approvalsEmptyStateDescription": "Włącz zatwierdzanie urządzeń dla ról aby wymagać zgody administratora, zanim użytkownicy będą mogli podłączyć nowe urządzenia.",
"approvalsEmptyStateStep1Title": "Przejdź do ról",
"approvalsEmptyStateStep1Description": "Przejdź do ustawień ról swojej organizacji, aby skonfigurować zatwierdzenia urządzenia.",
"approvalsEmptyStateStep2Title": "Włącz zatwierdzanie urządzenia",
"approvalsEmptyStateStep2Description": "Edytuj rolę i włącz opcję \"Wymagaj zatwierdzenia urządzenia\". Użytkownicy z tą rolą będą potrzebowali zatwierdzenia administratora dla nowych urządzeń.",
"approvalsEmptyStatePreviewDescription": "Podgląd: Gdy włączone, oczekujące prośby o sprawdzenie pojawią się tutaj",
"approvalsEmptyStateButtonText": "Zarządzaj rolami"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "É membro de {count, plural, =0 {nenhuma organização} one {uma organização} other {# organizações}}.", "componentsMember": "É membro de {count, plural, =0 {nenhuma organização} one {uma organização} other {# organizações}}.",
"componentsInvalidKey": "Chaves de licença inválidas ou expiradas detectadas. Siga os termos da licença para continuar usando todos os recursos.", "componentsInvalidKey": "Chaves de licença inválidas ou expiradas detectadas. Siga os termos da licença para continuar usando todos os recursos.",
"dismiss": "Rejeitar", "dismiss": "Rejeitar",
"subscriptionViolationMessage": "Você está além dos seus limites para o seu plano atual. Corrija o problema removendo sites, usuários, ou outros recursos para ficar em seu plano.",
"subscriptionViolationViewBilling": "Ver faturamento",
"componentsLicenseViolation": "Violação de Licença: Este servidor está usando sites {usedSites} que excedem o limite licenciado de sites {maxSites} . Siga os termos da licença para continuar usando todos os recursos.", "componentsLicenseViolation": "Violação de Licença: Este servidor está usando sites {usedSites} que excedem o limite licenciado de sites {maxSites} . Siga os termos da licença para continuar usando todos os recursos.",
"componentsSupporterMessage": "Obrigado por apoiar o Pangolin como um {tier}!", "componentsSupporterMessage": "Obrigado por apoiar o Pangolin como um {tier}!",
"inviteErrorNotValid": "Desculpe, mas parece que o convite que está a tentar aceder não foi aceito ou não é mais válido.", "inviteErrorNotValid": "Desculpe, mas parece que o convite que está a tentar aceder não foi aceito ou não é mais válido.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Conectar a Qualquer Rede", "sitesBannerTitle": "Conectar a Qualquer Rede",
"sitesBannerDescription": "Um site é uma conexão a uma rede remota que permite ao Pangolin fornecer acesso a recursos, sejam eles públicos ou privados, a usuários em qualquer lugar. Instale o conector de rede do site (Newt) em qualquer lugar onde você possa executar um binário ou contêiner para estabelecer a conexão.", "sitesBannerDescription": "Um site é uma conexão a uma rede remota que permite ao Pangolin fornecer acesso a recursos, sejam eles públicos ou privados, a usuários em qualquer lugar. Instale o conector de rede do site (Newt) em qualquer lugar onde você possa executar um binário ou contêiner para estabelecer a conexão.",
"sitesBannerButtonText": "Instalar Site", "sitesBannerButtonText": "Instalar Site",
"approvalsBannerTitle": "Aprovar ou negar acesso ao dispositivo",
"approvalsBannerDescription": "Revisar e aprovar ou negar solicitações de acesso ao dispositivo de usuários. Quando as aprovações do dispositivo são necessárias, os usuários devem obter a aprovação do administrador antes que seus dispositivos possam se conectar aos recursos da sua organização.",
"approvalsBannerButtonText": "Saiba mais",
"siteCreate": "Criar site", "siteCreate": "Criar site",
"siteCreateDescription2": "Siga os passos abaixo para criar e conectar um novo site", "siteCreateDescription2": "Siga os passos abaixo para criar e conectar um novo site",
"siteCreateDescription": "Crie um novo site para começar a conectar os recursos", "siteCreateDescription": "Crie um novo site para começar a conectar os recursos",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Pesquisar funções...", "accessRolesSearch": "Pesquisar funções...",
"accessRolesAdd": "Adicionar função", "accessRolesAdd": "Adicionar função",
"accessRoleDelete": "Excluir Papel", "accessRoleDelete": "Excluir Papel",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Gerenciar aprovações",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Visualizar e gerenciar aprovações pendentes para acesso a esta organização",
"description": "Descrição:", "description": "Descrição:",
"inviteTitle": "Convites Abertos", "inviteTitle": "Convites Abertos",
"inviteDescription": "Gerenciar convites para outros usuários participarem da organização", "inviteDescription": "Gerenciar convites para outros usuários participarem da organização",
@@ -452,18 +457,18 @@
"selectDuration": "Selecionar duração", "selectDuration": "Selecionar duração",
"selectResource": "Selecionar Recurso", "selectResource": "Selecionar Recurso",
"filterByResource": "Filtrar por Recurso", "filterByResource": "Filtrar por Recurso",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Selecionar Estado de Aprovação",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Filtrar por estado de aprovação",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Sem aprovações",
"approvalState": "Approval State", "approvalState": "Estado de aprovação",
"approve": "Approve", "approve": "Aprovar",
"approved": "Approved", "approved": "Aceito",
"denied": "Denied", "denied": "Negado",
"deniedApproval": "Denied Approval", "deniedApproval": "Aprovação Negada",
"all": "All", "all": "Todos",
"deny": "Deny", "deny": "Recusar",
"viewDetails": "View Details", "viewDetails": "Visualizar Detalhes",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "solicitou um novo dispositivo",
"resetFilters": "Redefinir filtros", "resetFilters": "Redefinir filtros",
"totalBlocked": "Solicitações bloqueadas pelo Pangolin", "totalBlocked": "Solicitações bloqueadas pelo Pangolin",
"totalRequests": "Total de pedidos", "totalRequests": "Total de pedidos",
@@ -743,28 +748,28 @@
"countries": "Países", "countries": "Países",
"accessRoleCreate": "Criar Função", "accessRoleCreate": "Criar Função",
"accessRoleCreateDescription": "Crie uma nova função para agrupar utilizadores e gerir suas permissões.", "accessRoleCreateDescription": "Crie uma nova função para agrupar utilizadores e gerir suas permissões.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Editar Permissão",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Editar informações do papel.",
"accessRoleCreateSubmit": "Criar Função", "accessRoleCreateSubmit": "Criar Função",
"accessRoleCreated": "Função criada", "accessRoleCreated": "Função criada",
"accessRoleCreatedDescription": "A função foi criada com sucesso.", "accessRoleCreatedDescription": "A função foi criada com sucesso.",
"accessRoleErrorCreate": "Falha ao criar função", "accessRoleErrorCreate": "Falha ao criar função",
"accessRoleErrorCreateDescription": "Ocorreu um erro ao criar a função.", "accessRoleErrorCreateDescription": "Ocorreu um erro ao criar a função.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Atualizar Função",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Função atualizada",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "A função foi atualizada com sucesso.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Aprovação processada",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Definir decisão de solicitação de aprovação para aprovada.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Definir decisão de solicitação de aprovação para negada.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Falha ao atualizar papel",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Ocorreu um erro ao atualizar a função.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Não foi possível processar a aprovação",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Ocorreu um erro ao processar a aprovação.",
"accessRoleErrorNewRequired": "Nova função é necessária", "accessRoleErrorNewRequired": "Nova função é necessária",
"accessRoleErrorRemove": "Falha ao remover função", "accessRoleErrorRemove": "Falha ao remover função",
"accessRoleErrorRemoveDescription": "Ocorreu um erro ao remover a função.", "accessRoleErrorRemoveDescription": "Ocorreu um erro ao remover a função.",
"accessRoleName": "Nome da Função", "accessRoleName": "Nome da Função",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Você está prestes a apagar o papel `{name}. Você não pode desfazer esta ação.",
"accessRoleRemove": "Remover Função", "accessRoleRemove": "Remover Função",
"accessRoleRemoveDescription": "Remover uma função da organização", "accessRoleRemoveDescription": "Remover uma função da organização",
"accessRoleRemoveSubmit": "Remover Função", "accessRoleRemoveSubmit": "Remover Função",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Aumentar contagem de sites", "sitestCountIncrease": "Aumentar contagem de sites",
"idpManage": "Gerir Provedores de Identidade", "idpManage": "Gerir Provedores de Identidade",
"idpManageDescription": "Visualizar e gerir provedores de identidade no sistema", "idpManageDescription": "Visualizar e gerir provedores de identidade no sistema",
"idpGlobalModeBanner": "Provedores de identidade (Pds) por organização estão desabilitados neste servidor. Ele está usando IdPs globais (compartilhados entre todas as organizações). Gerencie IdPs no painel <adminPanelLink>admin</adminPanelLink>. Para habilitar IdPs por organização, edite a configuração do servidor e defina o modo IdP como org. <configDocsLink>Veja a documentação</configDocsLink>. Se quiser continuar usando IdPs globais e fazer isso desaparecer das configurações da organização, defina explicitamente o modo como global na configuração.",
"idpGlobalModeBannerUpgradeRequired": "Os provedores de identidade (IdPs) por organização estão desativados neste servidor. Ele está usando IdPs globais (compartilhados entre todas as organizações). Gerencie os IdPs globais no <adminPanelLink>painel administrativo</adminPanelLink>. Para usar provedores de identidade por organização, você deve atualizar para a edição Enterprise.",
"idpGlobalModeBannerLicenseRequired": "Os provedores de identidade (IdPs) por organização estão desativados neste servidor. Ele está usando IdPs globais (compartilhados entre todas as organizações). Gerencie os IdPs globais no <adminPanelLink>painel administrativo</adminPanelLink>. Para usar provedores de identidade por organização, é necessário uma licença Enterprise.",
"idpDeletedDescription": "Provedor de identidade eliminado com sucesso", "idpDeletedDescription": "Provedor de identidade eliminado com sucesso",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Tem certeza que deseja eliminar permanentemente o provedor de identidade?", "idpQuestionRemove": "Tem certeza que deseja eliminar permanentemente o provedor de identidade?",
@@ -900,7 +908,7 @@
"inviteAlready": "Parece que já foi convidado!", "inviteAlready": "Parece que já foi convidado!",
"inviteAlreadyDescription": "Para aceitar o convite, deve iniciar sessão ou criar uma conta.", "inviteAlreadyDescription": "Para aceitar o convite, deve iniciar sessão ou criar uma conta.",
"signupQuestion": "Já tem uma conta?", "signupQuestion": "Já tem uma conta?",
"login": "Log In", "login": "Iniciar sessão",
"resourceNotFound": "Recurso Não Encontrado", "resourceNotFound": "Recurso Não Encontrado",
"resourceNotFoundDescription": "O recurso que está a tentar aceder não existe.", "resourceNotFoundDescription": "O recurso que está a tentar aceder não existe.",
"pincodeRequirementsLength": "O PIN deve ter exatamente 6 dígitos", "pincodeRequirementsLength": "O PIN deve ter exatamente 6 dígitos",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Esta organização exige que você altere sua senha a cada {maxDays} dias.", "passwordExpiryDescription": "Esta organização exige que você altere sua senha a cada {maxDays} dias.",
"changePasswordNow": "Alterar a senha agora", "changePasswordNow": "Alterar a senha agora",
"pincodeAuth": "Código do Autenticador", "pincodeAuth": "Código do Autenticador",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Enviar código",
"passwordResetSubmit": "Solicitar Redefinição", "passwordResetSubmit": "Solicitar Redefinição",
"passwordResetAlreadyHaveCode": "Inserir Código", "passwordResetAlreadyHaveCode": "Inserir Código",
"passwordResetSmtpRequired": "Por favor, contate o administrador", "passwordResetSmtpRequired": "Por favor, contate o administrador",
"passwordResetSmtpRequiredDescription": "É necessário um código de redefinição de senha para redefinir sua senha. Por favor, contate o administrador para assistência.", "passwordResetSmtpRequiredDescription": "É necessário um código de redefinição de senha para redefinir sua senha. Por favor, contate o administrador para assistência.",
"passwordBack": "Voltar à Palavra-passe", "passwordBack": "Voltar à Palavra-passe",
"loginBack": "Go back to main login page", "loginBack": "Voltar para a página principal de acesso",
"signup": "Registar", "signup": "Registar",
"loginStart": "Inicie sessão para começar", "loginStart": "Inicie sessão para começar",
"idpOidcTokenValidating": "A validar token OIDC", "idpOidcTokenValidating": "A validar token OIDC",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Atualizar Organização IDP", "actionUpdateIdpOrg": "Atualizar Organização IDP",
"actionCreateClient": "Criar Cliente", "actionCreateClient": "Criar Cliente",
"actionDeleteClient": "Excluir Cliente", "actionDeleteClient": "Excluir Cliente",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Arquivar Cliente",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Desarquivar Cliente",
"actionBlockClient": "Block Client", "actionBlockClient": "Bloco do Cliente",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Desbloquear Cliente",
"actionUpdateClient": "Atualizar Cliente", "actionUpdateClient": "Atualizar Cliente",
"actionListClients": "Listar Clientes", "actionListClients": "Listar Clientes",
"actionGetClient": "Obter Cliente", "actionGetClient": "Obter Cliente",
@@ -1164,14 +1172,14 @@
"searchProgress": "Pesquisar...", "searchProgress": "Pesquisar...",
"create": "Criar", "create": "Criar",
"orgs": "Organizações", "orgs": "Organizações",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Ocorreu um erro inesperado. Por favor, tente novamente.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "O login é necessário para seu dispositivo.",
"passwordForgot": "Esqueceu a sua palavra-passe?", "passwordForgot": "Esqueceu a sua palavra-passe?",
"otpAuth": "Autenticação de Dois Fatores", "otpAuth": "Autenticação de Dois Fatores",
"otpAuthDescription": "Insira o código da sua aplicação de autenticação ou um dos seus códigos de backup de uso único.", "otpAuthDescription": "Insira o código da sua aplicação de autenticação ou um dos seus códigos de backup de uso único.",
"otpAuthSubmit": "Submeter Código", "otpAuthSubmit": "Submeter Código",
"idpContinue": "Ou continuar com", "idpContinue": "Ou continuar com",
"otpAuthBack": "Back to Password", "otpAuthBack": "Voltar à Palavra-passe",
"navbar": "Menu de Navegação", "navbar": "Menu de Navegação",
"navbarDescription": "Menu de navegação principal da aplicação", "navbarDescription": "Menu de navegação principal da aplicação",
"navbarDocsLink": "Documentação", "navbarDocsLink": "Documentação",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Geral", "sidebarOverview": "Geral",
"sidebarHome": "Residencial", "sidebarHome": "Residencial",
"sidebarSites": "sites", "sidebarSites": "sites",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Solicitações de aprovação",
"sidebarResources": "Recursos", "sidebarResources": "Recursos",
"sidebarProxyResources": "Público", "sidebarProxyResources": "Público",
"sidebarClientResources": "Privado", "sidebarClientResources": "Privado",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Provedores de identidade", "sidebarIdentityProviders": "Provedores de identidade",
"sidebarLicense": "Tipo:", "sidebarLicense": "Tipo:",
"sidebarClients": "Clientes", "sidebarClients": "Clientes",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Dispositivos do usuário",
"sidebarMachineClients": "Máquinas", "sidebarMachineClients": "Máquinas",
"sidebarDomains": "Domínios", "sidebarDomains": "Domínios",
"sidebarGeneral": "Gerir", "sidebarGeneral": "Gerir",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Ocorreu um erro ao criar a conta de administrador do servidor.", "setupErrorCreateAdmin": "Ocorreu um erro ao criar a conta de administrador do servidor.",
"certificateStatus": "Status do Certificado", "certificateStatus": "Status do Certificado",
"loading": "Carregando", "loading": "Carregando",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Carregando Analytics",
"restart": "Reiniciar", "restart": "Reiniciar",
"domains": "Domínios", "domains": "Domínios",
"domainsDescription": "Criar e gerenciar domínios disponíveis na organização", "domainsDescription": "Criar e gerenciar domínios disponíveis na organização",
@@ -1336,7 +1344,7 @@
"refreshError": "Falha ao atualizar dados", "refreshError": "Falha ao atualizar dados",
"verified": "Verificado", "verified": "Verificado",
"pending": "Pendente", "pending": "Pendente",
"pendingApproval": "Pending Approval", "pendingApproval": "Aprovação pendente",
"sidebarBilling": "Faturamento", "sidebarBilling": "Faturamento",
"billing": "Faturamento", "billing": "Faturamento",
"orgBillingDescription": "Gerenciar informações e assinaturas de cobrança", "orgBillingDescription": "Gerenciar informações e assinaturas de cobrança",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Visão Geral dos Limites de Uso", "billingUsageLimitsOverview": "Visão Geral dos Limites de Uso",
"billingMonitorUsage": "Monitore seu uso em relação aos limites configurados. Se precisar aumentar esses limites, entre em contato conosco support@pangolin.net.", "billingMonitorUsage": "Monitore seu uso em relação aos limites configurados. Se precisar aumentar esses limites, entre em contato conosco support@pangolin.net.",
"billingDataUsage": "Uso de Dados", "billingDataUsage": "Uso de Dados",
"billingOnlineTime": "Tempo Online do Site", "billingSites": "sites",
"billingUsers": "Usuários Ativos", "billingUsers": "Utilizadores",
"billingDomains": "Domínios Ativos", "billingDomains": "Domínios",
"billingRemoteExitNodes": "Nodos Auto-Hospedados Ativos", "billingRemoteExitNodes": "Nós remotos",
"billingNoLimitConfigured": "Nenhum limite configurado", "billingNoLimitConfigured": "Nenhum limite configurado",
"billingEstimatedPeriod": "Período Estimado de Cobrança", "billingEstimatedPeriod": "Período Estimado de Cobrança",
"billingIncludedUsage": "Uso Incluído", "billingIncludedUsage": "Uso Incluído",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Falha ao obter URL do portal", "billingFailedToGetPortalUrl": "Falha ao obter URL do portal",
"billingPortalError": "Erro do Portal", "billingPortalError": "Erro do Portal",
"billingDataUsageInfo": "Você é cobrado por todos os dados transferidos através de seus túneis seguros quando conectado à nuvem. Isso inclui o tráfego de entrada e saída em todos os seus sites. Quando você atingir o seu limite, seus sites desconectarão até que você atualize seu plano ou reduza o uso. Os dados não serão cobrados ao usar os nós.", "billingDataUsageInfo": "Você é cobrado por todos os dados transferidos através de seus túneis seguros quando conectado à nuvem. Isso inclui o tráfego de entrada e saída em todos os seus sites. Quando você atingir o seu limite, seus sites desconectarão até que você atualize seu plano ou reduza o uso. Os dados não serão cobrados ao usar os nós.",
"billingOnlineTimeInfo": "Cobrança de acordo com o tempo em que seus sites permanecem conectados à nuvem. Por exemplo, 44,640 minutos é igual a um site que roda 24/7 para um mês inteiro. Quando você atinge o seu limite, seus sites desconectarão até que você faça o upgrade do seu plano ou reduza o uso. O tempo não é cobrado ao usar nós.", "billingSInfo": "Quantos sites você pode usar",
"billingUsersInfo": "A cobrança é feita por cada usuário na organização. A cobrança é feita diariamente com base no número de contas de usuário ativas na sua organização.", "billingUsersInfo": "Quantos usuários você pode usar",
"billingDomainInfo": "A cobrança é feita por cada domínio da organização. A cobrança é feita diariamente com base no número de contas de domínio ativas na sua organização.", "billingDomainInfo": "Quantos domínios você pode usar",
"billingRemoteExitNodesInfo": "Você é cobrado por cada nó gerenciado na organização. A cobrança é calculada diariamente com base no número de nós gerenciados ativos em sua organização.", "billingRemoteExitNodesInfo": "Quantos nós remotos você pode usar",
"billingLicenseKeys": "Chaves de Licença",
"billingLicenseKeysDescription": "Gerenciar suas subscrições de chave de licença",
"billingLicenseSubscription": "Assinatura de Licença",
"billingInactive": "Inativo",
"billingLicenseItem": "Item de Licença",
"billingQuantity": "Quantidade",
"billingTotal": "total:",
"billingModifyLicenses": "Modificar assinatura de licença",
"domainNotFound": "Domínio Não Encontrado", "domainNotFound": "Domínio Não Encontrado",
"domainNotFoundDescription": "Este recurso está desativado porque o domínio não existe mais em nosso sistema. Defina um novo domínio para este recurso.", "domainNotFoundDescription": "Este recurso está desativado porque o domínio não existe mais em nosso sistema. Defina um novo domínio para este recurso.",
"failed": "Falhou", "failed": "Falhou",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Chave de segurança removida com sucesso", "securityKeyRemoveSuccess": "Chave de segurança removida com sucesso",
"securityKeyRemoveError": "Erro ao remover chave de segurança", "securityKeyRemoveError": "Erro ao remover chave de segurança",
"securityKeyLoadError": "Erro ao carregar chaves de segurança", "securityKeyLoadError": "Erro ao carregar chaves de segurança",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Usar chave de segurança",
"securityKeyAuthError": "Erro ao autenticar com chave de segurança", "securityKeyAuthError": "Erro ao autenticar com chave de segurança",
"securityKeyRecommendation": "Considere registrar outra chave de segurança em um dispositivo diferente para garantir que você não fique bloqueado da sua conta.", "securityKeyRecommendation": "Considere registrar outra chave de segurança em um dispositivo diferente para garantir que você não fique bloqueado da sua conta.",
"registering": "Registrando...", "registering": "Registrando...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Número da porta é obrigatório para recursos não-HTTP", "resourcePortRequired": "Número da porta é obrigatório para recursos não-HTTP",
"resourcePortNotAllowed": "Número da porta não deve ser definido para recursos HTTP", "resourcePortNotAllowed": "Número da porta não deve ser definido para recursos HTTP",
"billingPricingCalculatorLink": "Calculadora de Preços", "billingPricingCalculatorLink": "Calculadora de Preços",
"billingYourPlan": "Seu plano",
"billingViewOrModifyPlan": "Ver ou modificar seu plano atual",
"billingViewPlanDetails": "Ver detalhes do plano",
"billingUsageAndLimits": "Uso e Limites",
"billingViewUsageAndLimits": "Ver os limites do seu plano e o uso atual",
"billingCurrentUsage": "Uso atual",
"billingMaximumLimits": "Limite Máximo",
"billingRemoteNodes": "Nós remotos",
"billingUnlimited": "Ilimitado",
"billingPaidLicenseKeys": "Chaves de licença paga",
"billingManageLicenseSubscription": "Gerencie sua assinatura para as chaves de licenças auto-hospedadas pagas",
"billingCurrentKeys": "Chaves atuais",
"billingModifyCurrentPlan": "Modificar o Plano Atual",
"billingConfirmUpgrade": "Confirmar a atualização",
"billingConfirmDowngrade": "Confirmar downgrade",
"billingConfirmUpgradeDescription": "Você está prestes a atualizar seu plano. Revise os novos limites e preços abaixo.",
"billingConfirmDowngradeDescription": "Você está prestes a fazer o downgrade do seu plano. Revise os novos limites e preços abaixo.",
"billingPlanIncludes": "Plano Inclui",
"billingProcessing": "Processandochar@@0",
"billingConfirmUpgradeButton": "Confirmar a atualização",
"billingConfirmDowngradeButton": "Confirmar downgrade",
"billingLimitViolationWarning": "Uso excede novos limites de plano",
"billingLimitViolationDescription": "Seu uso atual excede os limites deste plano. Após desclassificação, todas as ações serão desabilitadas até que você reduza o uso dentro dos novos limites. Por favor, reveja os recursos abaixo que atualmente estão acima dos limites. Limites de violação:",
"billingFeatureLossWarning": "Aviso de disponibilidade de recursos",
"billingFeatureLossDescription": "Ao fazer o downgrading, recursos não disponíveis no novo plano serão desativados automaticamente. Algumas configurações e configurações podem ser perdidas. Por favor, revise a matriz de preços para entender quais características não estarão mais disponíveis.",
"billingUsageExceedsLimit": "Uso atual ({current}) excede o limite ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Concordo com", "IAgreeToThe": "Concordo com",
"termsOfService": "os termos de serviço", "termsOfService": "os termos de serviço",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Intervalo Saudável", "IntervalSeconds": "Intervalo Saudável",
"timeoutSeconds": "Tempo limite (seg)", "timeoutSeconds": "Tempo limite (seg)",
"timeIsInSeconds": "O tempo está em segundos", "timeIsInSeconds": "O tempo está em segundos",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Exigir aprovação do dispositivo",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Usuários com esta função precisam de novos dispositivos aprovados por um administrador antes que eles possam se conectar e acessar recursos.",
"retryAttempts": "Tentativas de Repetição", "retryAttempts": "Tentativas de Repetição",
"expectedResponseCodes": "Códigos de Resposta Esperados", "expectedResponseCodes": "Códigos de Resposta Esperados",
"expectedResponseCodesDescription": "Código de status HTTP que indica estado saudável. Se deixado em branco, 200-300 é considerado saudável.", "expectedResponseCodesDescription": "Código de status HTTP que indica estado saudável. Se deixado em branco, 200-300 é considerado saudável.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Nenhum recurso interno encontrado.", "resourcesTableNoInternalResourcesFound": "Nenhum recurso interno encontrado.",
"resourcesTableDestination": "Destino", "resourcesTableDestination": "Destino",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Endereço do Pseudônimo",
"resourcesTableAliasAddressInfo": "Este endereço faz parte da sub-rede de utilitários da organização. É usado para resolver registros de alias usando resolução de DNS interno.",
"resourcesTableClients": "Clientes", "resourcesTableClients": "Clientes",
"resourcesTableAndOnlyAccessibleInternally": "e são acessíveis apenas internamente quando conectados com um cliente.", "resourcesTableAndOnlyAccessibleInternally": "e são acessíveis apenas internamente quando conectados com um cliente.",
"resourcesTableNoTargets": "Nenhum alvo", "resourcesTableNoTargets": "Nenhum alvo",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Escolha o seu provedor de identidade para continuar", "orgAuthChooseIdpDescription": "Escolha o seu provedor de identidade para continuar",
"orgAuthNoIdpConfigured": "Esta organização não tem nenhum provedor de identidade configurado. Você pode entrar com a identidade do seu Pangolin.", "orgAuthNoIdpConfigured": "Esta organização não tem nenhum provedor de identidade configurado. Você pode entrar com a identidade do seu Pangolin.",
"orgAuthSignInWithPangolin": "Entrar com o Pangolin", "orgAuthSignInWithPangolin": "Entrar com o Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Fazer login em uma organização",
"orgAuthSelectOrgTitle": "Entrada da Organização", "orgAuthSelectOrgTitle": "Entrada da Organização",
"orgAuthSelectOrgDescription": "Digite seu ID da organização para continuar", "orgAuthSelectOrgDescription": "Digite seu ID da organização para continuar",
"orgAuthOrgIdPlaceholder": "sua-organização", "orgAuthOrgIdPlaceholder": "sua-organização",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Voltar para entrada padrão", "orgAuthBackToSignIn": "Voltar para entrada padrão",
"orgAuthNoAccount": "Não possui uma conta?", "orgAuthNoAccount": "Não possui uma conta?",
"subscriptionRequiredToUse": "Uma assinatura é necessária para usar esse recurso.", "subscriptionRequiredToUse": "Uma assinatura é necessária para usar esse recurso.",
"mustUpgradeToUse": "Você deve atualizar sua assinatura para usar este recurso.",
"subscriptionRequiredTierToUse": "Esta função requer <tierLink>{tier}</tierLink> ou superior.",
"upgradeToTierToUse": "Atualize para <tierLink>{tier}</tierLink> ou superior para usar este recurso.",
"subscriptionTierTier1": "Residencial",
"subscriptionTierTier2": "Equipe",
"subscriptionTierTier3": "Empresas",
"subscriptionTierEnterprise": "Empresa",
"idpDisabled": "Provedores de identidade estão desabilitados.", "idpDisabled": "Provedores de identidade estão desabilitados.",
"orgAuthPageDisabled": "A página de autenticação da organização está desativada.", "orgAuthPageDisabled": "A página de autenticação da organização está desativada.",
"domainRestartedDescription": "Verificação de domínio reiniciado com sucesso", "domainRestartedDescription": "Verificação de domínio reiniciado com sucesso",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Obtenha uma licença",
"description": "Escolha um plano e nos diga como você planeja usar o Pangolin.",
"chooseTier": "Escolha seu plano",
"viewPricingLink": "Veja os preços, recursos e limites",
"tiers": {
"starter": {
"title": "Iniciante",
"description": "Recursos de empresa, 25 usuários, 25 sites e apoio da comunidade."
},
"scale": {
"title": "Escala",
"description": "Recursos de empresa, 50 usuários, 50 sites e apoio prioritário."
}
},
"personalUseOnly": "Apenas uso pessoal (licença gratuita — sem check-out)",
"buttons": {
"continueToCheckout": "Continuar com checkout"
},
"toasts": {
"checkoutError": {
"title": "Erro no check-out",
"description": "Não foi possível iniciar o checkout. Por favor, tente novamente."
}
}
},
"priority": "Prioridade", "priority": "Prioridade",
"priorityDescription": "Rotas de alta prioridade são avaliadas primeiro. Prioridade = 100 significa ordem automática (decisões do sistema). Use outro número para aplicar prioridade manual.", "priorityDescription": "Rotas de alta prioridade são avaliadas primeiro. Prioridade = 100 significa ordem automática (decisões do sistema). Use outro número para aplicar prioridade manual.",
"instanceName": "Nome da Instância", "instanceName": "Nome da Instância",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Fim do ano seguinte", "logRetentionEndOfFollowingYear": "Fim do ano seguinte",
"actionLogsDescription": "Visualizar histórico de ações realizadas nesta organização", "actionLogsDescription": "Visualizar histórico de ações realizadas nesta organização",
"accessLogsDescription": "Ver solicitações de autenticação de recursos nesta organização", "accessLogsDescription": "Ver solicitações de autenticação de recursos nesta organização",
"licenseRequiredToUse": "É necessária uma licença empresarial para usar esse recurso.", "licenseRequiredToUse": "Uma licença <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> é necessária para usar este recurso. Este recurso também está disponível no <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "O <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> é necessário para usar este recurso. Este recurso também está disponível no <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Resolvedor de Certificado", "certResolver": "Resolvedor de Certificado",
"certResolverDescription": "Selecione o resolvedor de certificados para este recurso.", "certResolverDescription": "Selecione o resolvedor de certificados para este recurso.",
"selectCertResolver": "Selecionar solucionador de certificado", "selectCertResolver": "Selecionar solucionador de certificado",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "O código deve ter 9 caracteres (ex.: A1AJ-N5JD)", "deviceCodeInvalidFormat": "O código deve ter 9 caracteres (ex.: A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Código inválido ou expirado", "deviceCodeInvalidOrExpired": "Código inválido ou expirado",
"deviceCodeVerifyFailed": "Falha ao verificar o código do dispositivo", "deviceCodeVerifyFailed": "Falha ao verificar o código do dispositivo",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Validando código do dispositivo...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Verificando autorização do dispositivo...",
"signedInAs": "Sessão iniciada como", "signedInAs": "Sessão iniciada como",
"deviceCodeEnterPrompt": "Digite o código exibido no dispositivo", "deviceCodeEnterPrompt": "Digite o código exibido no dispositivo",
"continue": "Continuar", "continue": "Continuar",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Acesso a todas as organizações que sua conta tem acesso a", "deviceOrganizationsAccess": "Acesso a todas as organizações que sua conta tem acesso a",
"deviceAuthorize": "Autorizar {applicationName}", "deviceAuthorize": "Autorizar {applicationName}",
"deviceConnected": "Dispositivo Conectado!", "deviceConnected": "Dispositivo Conectado!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "O dispositivo está autorizado a acessar sua conta. Por favor, retorne ao aplicativo cliente.",
"pangolinCloud": "Nuvem do Pangolin", "pangolinCloud": "Nuvem do Pangolin",
"viewDevices": "Ver Dispositivos", "viewDevices": "Ver Dispositivos",
"viewDevicesDescription": "Gerencie seus dispositivos conectados", "viewDevicesDescription": "Gerencie seus dispositivos conectados",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Não é você? Use uma conta diferente.", "deviceLoginUseDifferentAccount": "Não é você? Use uma conta diferente.",
"deviceLoginDeviceRequestingAccessToAccount": "Um dispositivo está solicitando acesso a essa conta.", "deviceLoginDeviceRequestingAccessToAccount": "Um dispositivo está solicitando acesso a essa conta.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Selecione um método de autenticação para continuar.",
"noData": "Nenhum dado encontrado", "noData": "Nenhum dado encontrado",
"machineClients": "Clientes de máquina", "machineClients": "Clientes de máquina",
"install": "Instale", "install": "Instale",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Estamos enfrentando dificuldades técnicas no momento. Por favor, volte em breve.", "maintenanceScreenMessage": "Estamos enfrentando dificuldades técnicas no momento. Por favor, volte em breve.",
"maintenanceScreenEstimatedCompletion": "Conclusão Estimada:", "maintenanceScreenEstimatedCompletion": "Conclusão Estimada:",
"createInternalResourceDialogDestinationRequired": "Destino é obrigatório", "createInternalResourceDialogDestinationRequired": "Destino é obrigatório",
"available": "Available", "available": "Disponível",
"archived": "Archived", "archived": "Arquivado",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Nenhum dispositivo arquivado encontrado",
"deviceArchived": "Device archived", "deviceArchived": "Dispositivo arquivado",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "O dispositivo foi arquivado com sucesso.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Erro ao arquivar dispositivo",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Falha ao arquivar dispositivo",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Tem certeza que deseja arquivar este dispositivo?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "O dispositivo será arquivado e removido da sua lista de dispositivos ativos.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Arquivar dispositivo",
"archiveDevice": "Archive Device", "archiveDevice": "Arquivar dispositivo",
"archive": "Archive", "archive": "Arquivo",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Dispositivo desarquivado",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "O dispositivo foi desarquivado com sucesso.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Erro ao desarquivar dispositivo",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Falha ao desarquivar dispositivo",
"unarchive": "Unarchive", "unarchive": "Desarquivar",
"archiveClient": "Archive Client", "archiveClient": "Arquivar Cliente",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Tem certeza que deseja arquivar este cliente?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "O cliente será arquivado e removido da sua lista de clientes ativos.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Arquivar Cliente",
"blockClient": "Block Client", "blockClient": "Bloco do Cliente",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Tem certeza que deseja bloquear este cliente?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "O dispositivo será forçado a desconectar se estiver conectado. Você pode desbloquear o dispositivo mais tarde.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Bloco do Cliente",
"active": "Active", "active": "ativo",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Usuário ou Email",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Selecione sua organização",
"signInTo": "Log in in to", "signInTo": "Iniciar sessão em",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Continuar com a senha",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Nenhum método de autenticação disponível para esta organização.",
"enterPassword": "Enter your password", "enterPassword": "Digite sua senha",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Insira o código do seu aplicativo autenticador",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Por favor, utilize sua chave de segurança para entrar.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Precisa usar uma conta diferente?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Ao clicar nos botões abaixo, você reconhece que leu, entende e concorda com os <termsOfService>Termos de Serviço</termsOfService> e a <privacyPolicy>Política de Privacidade</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Termos de Serviço",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Política de Privacidade",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Nenhum usuário encontrado com este nome de usuário.",
"verify": "Verify", "verify": "Verificar",
"signIn": "Sign In", "signIn": "Iniciar sessão",
"forgotPassword": "Forgot password?", "forgotPassword": "Esqueceu a senha?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Se você já fez login antes, você pode digitar seu nome de usuário ou e-mail acima para autenticar com o provedor de identidade da sua organização. É mais fácil!",
"continueAnyway": "Continue anyway", "continueAnyway": "Continuar mesmo assim",
"dontShowAgain": "Don't show again", "dontShowAgain": "Não mostrar novamente",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Você sabia?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Tentando fazer login?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Você está tentando entrar através do provedor de identidade da sua organização?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Faça login ou inscreva-se com sua organização em vez disso",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Use uma Conta Diferente",
"logIn": "Log In", "logIn": "Iniciar sessão",
"deviceInformation": "Device Information", "deviceInformation": "Informações do dispositivo",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Informações sobre o dispositivo e o agente",
"platform": "Platform", "deviceSecurity": "Segurança do dispositivo",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Informações sobre postagem de segurança",
"windowsVersion": "Windows Version", "platform": "Plataforma",
"iosVersion": "iOS Version", "macosVersion": "Versão do macOS",
"androidVersion": "Android Version", "windowsVersion": "Versão do Windows",
"osVersion": "OS Version", "iosVersion": "Versão para iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Versão do Android",
"deviceModel": "Device Model", "osVersion": "Versão do SO",
"serialNumber": "Serial Number", "kernelVersion": "Versão do Kernel",
"deviceModel": "Modelo do dispositivo",
"serialNumber": "Número de Série",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Visto primeiro",
"lastSeen": "Last Seen", "lastSeen": "Visto por último",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biometria habilitada",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Disco criptografado",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Firewall habilitado",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Atualizações Automáticas Habilitadas",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM disponível",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivírus habilitado",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Proteção da Integridade do Sistema (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Modo Furtivo do Firewall",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "AppArmor",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Ver informações e configurações do dispositivo",
"devicePendingApprovalDescription": "Este dispositivo está aguardando aprovação",
"deviceBlockedDescription": "Este dispositivo está bloqueado no momento. Ele não será capaz de se conectar a qualquer recurso a menos que seja desbloqueado.",
"unblockClient": "Desbloquear Cliente",
"unblockClientDescription": "O dispositivo foi desbloqueado",
"unarchiveClient": "Desarquivar Cliente",
"unarchiveClientDescription": "O dispositivo foi desarquivado",
"block": "Bloquear",
"unblock": "Desbloquear",
"deviceActions": "Ações do dispositivo",
"deviceActionsDescription": "Gerenciar status e acesso do dispositivo",
"devicePendingApprovalBannerDescription": "Este dispositivo está pendente de aprovação. Não será possível conectar-se a recursos até ser aprovado.",
"connected": "Conectado",
"disconnected": "Desconectado",
"approvalsEmptyStateTitle": "Aprovações do dispositivo não habilitado",
"approvalsEmptyStateDescription": "Habilitar aprovações do dispositivo para cargos que exigem aprovação do administrador antes que os usuários possam conectar novos dispositivos.",
"approvalsEmptyStateStep1Title": "Ir para Funções",
"approvalsEmptyStateStep1Description": "Navegue até as configurações dos papéis da sua organização para configurar as aprovações de dispositivo.",
"approvalsEmptyStateStep2Title": "Habilitar Aprovações do Dispositivo",
"approvalsEmptyStateStep2Description": "Editar uma função e habilitar a opção 'Exigir aprovação de dispositivos'. Usuários com essa função precisarão de aprovação de administrador para novos dispositivos.",
"approvalsEmptyStatePreviewDescription": "Pré-visualização: Quando ativado, solicitações de dispositivo pendentes aparecerão aqui para revisão",
"approvalsEmptyStateButtonText": "Gerir Funções"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "Вы состоите в {count, plural, =0 {0 организациях} one {# организации} few {# организациях} many {# организациях} other {# организациях}}.", "componentsMember": "Вы состоите в {count, plural, =0 {0 организациях} one {# организации} few {# организациях} many {# организациях} other {# организациях}}.",
"componentsInvalidKey": "Обнаружены недействительные или просроченные лицензионные ключи. Соблюдайте условия лицензии для использования всех функций.", "componentsInvalidKey": "Обнаружены недействительные или просроченные лицензионные ключи. Соблюдайте условия лицензии для использования всех функций.",
"dismiss": "Отменить", "dismiss": "Отменить",
"subscriptionViolationMessage": "Вы превысили лимиты для вашего текущего плана. Исправьте проблему, удалив сайты, пользователей или другие ресурсы, чтобы остаться в пределах вашего плана.",
"subscriptionViolationViewBilling": "Просмотр биллинга",
"componentsLicenseViolation": "Нарушение лицензии: Сервер использует {usedSites} сайтов, что превышает лицензионный лимит в {maxSites} сайтов. Соблюдайте условия лицензии для использования всех функций.", "componentsLicenseViolation": "Нарушение лицензии: Сервер использует {usedSites} сайтов, что превышает лицензионный лимит в {maxSites} сайтов. Соблюдайте условия лицензии для использования всех функций.",
"componentsSupporterMessage": "Спасибо за поддержку Pangolin в качестве {tier}!", "componentsSupporterMessage": "Спасибо за поддержку Pangolin в качестве {tier}!",
"inviteErrorNotValid": "Извините, но это приглашение не было принято или срок его действия истёк.", "inviteErrorNotValid": "Извините, но это приглашение не было принято или срок его действия истёк.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Подключить любую сеть", "sitesBannerTitle": "Подключить любую сеть",
"sitesBannerDescription": "Сайт — это соединение с удаленной сетью, которое позволяет Pangolin предоставлять доступ к ресурсам, будь они общедоступными или частными, пользователям в любом месте. Установите сетевой коннектор сайта (Newt) там, где можно запустить исполняемый файл или контейнер, чтобы установить соединение.", "sitesBannerDescription": "Сайт — это соединение с удаленной сетью, которое позволяет Pangolin предоставлять доступ к ресурсам, будь они общедоступными или частными, пользователям в любом месте. Установите сетевой коннектор сайта (Newt) там, где можно запустить исполняемый файл или контейнер, чтобы установить соединение.",
"sitesBannerButtonText": "Установить сайт", "sitesBannerButtonText": "Установить сайт",
"approvalsBannerTitle": "Одобрить или запретить доступ к устройству",
"approvalsBannerDescription": "Просмотрите и подтвердите или отклоните запросы на доступ к устройству от пользователей. Когда требуется подтверждение устройства, пользователи должны получить одобрение администратора, прежде чем их устройства смогут подключиться к ресурсам вашей организации.",
"approvalsBannerButtonText": "Узнать больше",
"siteCreate": "Создать сайт", "siteCreate": "Создать сайт",
"siteCreateDescription2": "Следуйте инструкциям ниже для создания и подключения нового сайта", "siteCreateDescription2": "Следуйте инструкциям ниже для создания и подключения нового сайта",
"siteCreateDescription": "Создайте новый сайт для начала подключения ресурсов", "siteCreateDescription": "Создайте новый сайт для начала подключения ресурсов",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Поиск ролей...", "accessRolesSearch": "Поиск ролей...",
"accessRolesAdd": "Добавить роль", "accessRolesAdd": "Добавить роль",
"accessRoleDelete": "Удалить роль", "accessRoleDelete": "Удалить роль",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Управление утверждениями",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Просмотр и управление утверждениями в ожидании доступа к этой организации",
"description": "Описание", "description": "Описание",
"inviteTitle": "Открытые приглашения", "inviteTitle": "Открытые приглашения",
"inviteDescription": "Управление приглашениями для присоединения других пользователей к организации", "inviteDescription": "Управление приглашениями для присоединения других пользователей к организации",
@@ -452,18 +457,18 @@
"selectDuration": "Укажите срок действия", "selectDuration": "Укажите срок действия",
"selectResource": "Выберите ресурс", "selectResource": "Выберите ресурс",
"filterByResource": "Фильтровать по ресурсам", "filterByResource": "Фильтровать по ресурсам",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Выберите состояние одобрения",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Фильтр по состоянию утверждения",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Нет утверждений",
"approvalState": "Approval State", "approvalState": "Состояние одобрения",
"approve": "Approve", "approve": "Одобрить",
"approved": "Approved", "approved": "Одобрено",
"denied": "Denied", "denied": "Отказано",
"deniedApproval": "Denied Approval", "deniedApproval": "Отказано в одобрении",
"all": "All", "all": "Все",
"deny": "Deny", "deny": "Запретить",
"viewDetails": "View Details", "viewDetails": "Детали",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "запросил новое устройство",
"resetFilters": "Сбросить фильтры", "resetFilters": "Сбросить фильтры",
"totalBlocked": "Запросы заблокированы Панголином", "totalBlocked": "Запросы заблокированы Панголином",
"totalRequests": "Всего запросов", "totalRequests": "Всего запросов",
@@ -743,28 +748,28 @@
"countries": "Страны", "countries": "Страны",
"accessRoleCreate": "Создание роли", "accessRoleCreate": "Создание роли",
"accessRoleCreateDescription": "Создайте новую роль для группы пользователей и выдавайте им разрешения.", "accessRoleCreateDescription": "Создайте новую роль для группы пользователей и выдавайте им разрешения.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Изменить роль",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Редактировать информацию о роли.",
"accessRoleCreateSubmit": "Создать роль", "accessRoleCreateSubmit": "Создать роль",
"accessRoleCreated": "Роль создана", "accessRoleCreated": "Роль создана",
"accessRoleCreatedDescription": "Роль была успешно создана.", "accessRoleCreatedDescription": "Роль была успешно создана.",
"accessRoleErrorCreate": "Не удалось создать роль", "accessRoleErrorCreate": "Не удалось создать роль",
"accessRoleErrorCreateDescription": "Произошла ошибка при создании роли.", "accessRoleErrorCreateDescription": "Произошла ошибка при создании роли.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Обновить роль",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Роль обновлена",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Роль была успешно обновлена.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Выполнено утверждение",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Принять решение об утверждении запроса.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Отказано в запросе об утверждении.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Не удалось обновить роль",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Произошла ошибка при обновлении роли.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Не удалось обработать подтверждение",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Произошла ошибка при обработке одобрения.",
"accessRoleErrorNewRequired": "Новая роль обязательна", "accessRoleErrorNewRequired": "Новая роль обязательна",
"accessRoleErrorRemove": "Не удалось удалить роль", "accessRoleErrorRemove": "Не удалось удалить роль",
"accessRoleErrorRemoveDescription": "Произошла ошибка при удалении роли.", "accessRoleErrorRemoveDescription": "Произошла ошибка при удалении роли.",
"accessRoleName": "Название роли", "accessRoleName": "Название роли",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "Вы собираетесь удалить `{name}` роль. Это действие нельзя отменить.",
"accessRoleRemove": "Удалить роль", "accessRoleRemove": "Удалить роль",
"accessRoleRemoveDescription": "Удалить роль из организации", "accessRoleRemoveDescription": "Удалить роль из организации",
"accessRoleRemoveSubmit": "Удалить роль", "accessRoleRemoveSubmit": "Удалить роль",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Увеличить количество сайтов", "sitestCountIncrease": "Увеличить количество сайтов",
"idpManage": "Управление поставщиками удостоверений", "idpManage": "Управление поставщиками удостоверений",
"idpManageDescription": "Просмотр и управление поставщиками удостоверений в системе", "idpManageDescription": "Просмотр и управление поставщиками удостоверений в системе",
"idpGlobalModeBanner": "Поставщики удостоверений (IdP) для каждой организации отключены на этом сервере. Используются глобальные IdP (общие для всех организаций). Управляйте глобальными IdP в <adminPanelLink>админ-панели</adminPanelLink>. Чтобы включить IdP для каждой организации, отредактируйте конфигурацию сервера и установите режим IdP в org. <configDocsLink>См. документацию</configDocsLink>. Если вы хотите продолжать использовать глобальные IdP и скрыть это из настроек организации, явно установите режим в глобальном конфиге.",
"idpGlobalModeBannerUpgradeRequired": "Поставщики удостоверений (IdP) для каждой организации отключены на этом сервере. Используются глобальные IdP (общие для всех организаций). Управляйте глобальными IdP в <adminPanelLink>админ-панели</adminPanelLink>. Чтобы использовать поставщиков удостоверений для каждой организации, необходимо обновить систему до версии Enterprise.",
"idpGlobalModeBannerLicenseRequired": "Поставщики удостоверений (IdP) для каждой организации отключены на этом сервере. Используются глобальные IdP (общие для всех организаций). Управляйте глобальными IdP в <adminPanelLink>админ-панели</adminPanelLink>. Для использования поставщиков удостоверений на организацию требуется лицензия Enterprise.",
"idpDeletedDescription": "Поставщик удостоверений успешно удалён", "idpDeletedDescription": "Поставщик удостоверений успешно удалён",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Вы уверены, что хотите навсегда удалить поставщика удостоверений?", "idpQuestionRemove": "Вы уверены, что хотите навсегда удалить поставщика удостоверений?",
@@ -900,7 +908,7 @@
"inviteAlready": "Похоже, вы были приглашены!", "inviteAlready": "Похоже, вы были приглашены!",
"inviteAlreadyDescription": "Чтобы принять приглашение, вы должны войти или создать учётную запись.", "inviteAlreadyDescription": "Чтобы принять приглашение, вы должны войти или создать учётную запись.",
"signupQuestion": "Уже есть учётная запись?", "signupQuestion": "Уже есть учётная запись?",
"login": "Log In", "login": "Войти",
"resourceNotFound": "Ресурс не найден", "resourceNotFound": "Ресурс не найден",
"resourceNotFoundDescription": "Ресурс, к которому вы пытаетесь получить доступ, не существует.", "resourceNotFoundDescription": "Ресурс, к которому вы пытаетесь получить доступ, не существует.",
"pincodeRequirementsLength": "PIN должен состоять ровно из 6 цифр", "pincodeRequirementsLength": "PIN должен состоять ровно из 6 цифр",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Эта организация требует смены пароля каждые {maxDays} дней.", "passwordExpiryDescription": "Эта организация требует смены пароля каждые {maxDays} дней.",
"changePasswordNow": "Изменить пароль сейчас", "changePasswordNow": "Изменить пароль сейчас",
"pincodeAuth": "Код аутентификатора", "pincodeAuth": "Код аутентификатора",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Отправить код",
"passwordResetSubmit": "Запросить сброс", "passwordResetSubmit": "Запросить сброс",
"passwordResetAlreadyHaveCode": "Введите код", "passwordResetAlreadyHaveCode": "Введите код",
"passwordResetSmtpRequired": "Пожалуйста, обратитесь к администратору", "passwordResetSmtpRequired": "Пожалуйста, обратитесь к администратору",
"passwordResetSmtpRequiredDescription": "Для сброса пароля необходим код сброса пароля. Обратитесь к администратору за помощью.", "passwordResetSmtpRequiredDescription": "Для сброса пароля необходим код сброса пароля. Обратитесь к администратору за помощью.",
"passwordBack": "Назад к паролю", "passwordBack": "Назад к паролю",
"loginBack": "Go back to main login page", "loginBack": "Вернуться на главную страницу входа",
"signup": "Регистрация", "signup": "Регистрация",
"loginStart": "Войдите для начала работы", "loginStart": "Войдите для начала работы",
"idpOidcTokenValidating": "Проверка OIDC токена", "idpOidcTokenValidating": "Проверка OIDC токена",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Обновить организацию IDP", "actionUpdateIdpOrg": "Обновить организацию IDP",
"actionCreateClient": "Создать Клиента", "actionCreateClient": "Создать Клиента",
"actionDeleteClient": "Удалить Клиента", "actionDeleteClient": "Удалить Клиента",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "Архивировать клиента",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "Разархивировать клиента",
"actionBlockClient": "Block Client", "actionBlockClient": "Блокировать клиента",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "Разблокировать клиента",
"actionUpdateClient": "Обновить Клиента", "actionUpdateClient": "Обновить Клиента",
"actionListClients": "Список Клиентов", "actionListClients": "Список Клиентов",
"actionGetClient": "Получить Клиента", "actionGetClient": "Получить Клиента",
@@ -1164,14 +1172,14 @@
"searchProgress": "Поиск...", "searchProgress": "Поиск...",
"create": "Создать", "create": "Создать",
"orgs": "Организации", "orgs": "Организации",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Логин необходим для вашего устройства.",
"passwordForgot": "Забыли пароль?", "passwordForgot": "Забыли пароль?",
"otpAuth": "Двухфакторная аутентификация", "otpAuth": "Двухфакторная аутентификация",
"otpAuthDescription": "Введите код из вашего приложения-аутентификатора или один из ваших одноразовых резервных кодов.", "otpAuthDescription": "Введите код из вашего приложения-аутентификатора или один из ваших одноразовых резервных кодов.",
"otpAuthSubmit": "Отправить код", "otpAuthSubmit": "Отправить код",
"idpContinue": "Или продолжить с", "idpContinue": "Или продолжить с",
"otpAuthBack": "Back to Password", "otpAuthBack": "Назад к паролю",
"navbar": "Навигационное меню", "navbar": "Навигационное меню",
"navbarDescription": "Главное навигационное меню приложения", "navbarDescription": "Главное навигационное меню приложения",
"navbarDocsLink": "Документация", "navbarDocsLink": "Документация",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Обзор", "sidebarOverview": "Обзор",
"sidebarHome": "Главная", "sidebarHome": "Главная",
"sidebarSites": "Сайты", "sidebarSites": "Сайты",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Запросы на утверждение",
"sidebarResources": "Ресурсы", "sidebarResources": "Ресурсы",
"sidebarProxyResources": "Публичный", "sidebarProxyResources": "Публичный",
"sidebarClientResources": "Приватный", "sidebarClientResources": "Приватный",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Поставщики удостоверений", "sidebarIdentityProviders": "Поставщики удостоверений",
"sidebarLicense": "Лицензия", "sidebarLicense": "Лицензия",
"sidebarClients": "Клиенты", "sidebarClients": "Клиенты",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Устройства пользователя",
"sidebarMachineClients": "Машины", "sidebarMachineClients": "Машины",
"sidebarDomains": "Домены", "sidebarDomains": "Домены",
"sidebarGeneral": "Управление", "sidebarGeneral": "Управление",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Произошла ошибка при создании учётной записи администратора сервера.", "setupErrorCreateAdmin": "Произошла ошибка при создании учётной записи администратора сервера.",
"certificateStatus": "Статус сертификата", "certificateStatus": "Статус сертификата",
"loading": "Загрузка", "loading": "Загрузка",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Загрузка аналитики",
"restart": "Перезагрузка", "restart": "Перезагрузка",
"domains": "Домены", "domains": "Домены",
"domainsDescription": "Создание и управление доменами, доступными в организации", "domainsDescription": "Создание и управление доменами, доступными в организации",
@@ -1336,7 +1344,7 @@
"refreshError": "Не удалось обновить данные", "refreshError": "Не удалось обновить данные",
"verified": "Подтверждено", "verified": "Подтверждено",
"pending": "В ожидании", "pending": "В ожидании",
"pendingApproval": "Pending Approval", "pendingApproval": "Ожидает утверждения",
"sidebarBilling": "Выставление счетов", "sidebarBilling": "Выставление счетов",
"billing": "Выставление счетов", "billing": "Выставление счетов",
"orgBillingDescription": "Управление платежной информацией и подписками", "orgBillingDescription": "Управление платежной информацией и подписками",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Обзор лимитов использования", "billingUsageLimitsOverview": "Обзор лимитов использования",
"billingMonitorUsage": "Контролируйте использование в соответствии с установленными лимитами. Если вам требуется увеличение лимитов, пожалуйста, свяжитесь с нами support@pangolin.net.", "billingMonitorUsage": "Контролируйте использование в соответствии с установленными лимитами. Если вам требуется увеличение лимитов, пожалуйста, свяжитесь с нами support@pangolin.net.",
"billingDataUsage": "Использование данных", "billingDataUsage": "Использование данных",
"billingOnlineTime": "Время работы сайта", "billingSites": "Сайты",
"billingUsers": "Активные пользователи", "billingUsers": "Пользователи",
"billingDomains": "Активные домены", "billingDomains": "Домены",
"billingRemoteExitNodes": "Активные самоуправляемые узлы", "billingRemoteExitNodes": "Удаленные узлы",
"billingNoLimitConfigured": "Лимит не установлен", "billingNoLimitConfigured": "Лимит не установлен",
"billingEstimatedPeriod": "Предполагаемый период выставления счетов", "billingEstimatedPeriod": "Предполагаемый период выставления счетов",
"billingIncludedUsage": "Включенное использование", "billingIncludedUsage": "Включенное использование",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Не удалось получить URL-адрес портала", "billingFailedToGetPortalUrl": "Не удалось получить URL-адрес портала",
"billingPortalError": "Ошибка портала", "billingPortalError": "Ошибка портала",
"billingDataUsageInfo": "Вы несете ответственность за все данные, переданные через безопасные туннели при подключении к облаку. Это включает как входящий, так и исходящий трафик на всех ваших сайтах. При достижении лимита ваши сайты будут отключаться до тех пор, пока вы не обновите план или не уменьшите его использование. При использовании узлов не взимается плата.", "billingDataUsageInfo": "Вы несете ответственность за все данные, переданные через безопасные туннели при подключении к облаку. Это включает как входящий, так и исходящий трафик на всех ваших сайтах. При достижении лимита ваши сайты будут отключаться до тех пор, пока вы не обновите план или не уменьшите его использование. При использовании узлов не взимается плата.",
"billingOnlineTimeInfo": "Вы тарифицируете на то, как долго ваши сайты будут подключены к облаку. Например, 44 640 минут равны одному сайту, работающему круглосуточно за весь месяц. Когда вы достигните лимита, ваши сайты будут отключаться до тех пор, пока вы не обновите тарифный план или не сократите нагрузку. При использовании узлов не тарифицируется.", "billingSInfo": "Сколько сайтов вы можете использовать",
"billingUsersInfo": "Вы оплачиваете за каждого пользователя в организации. Платеж рассчитывается ежедневно в зависимости от количества активных учетных записей в вашем органе.", "billingUsersInfo": "Сколько пользователей вы можете использовать",
"billingDomainInfo": "Вы платите за каждый домен в организации. Платеж рассчитывается ежедневно в зависимости от количества активных доменных аккаунтов в вашем органе.", "billingDomainInfo": "Сколько доменов вы можете использовать",
"billingRemoteExitNodesInfo": "Вы платите за каждый управляемый узел организации. Платёж рассчитывается ежедневно на основе количества активных управляемых узлов в вашем органе.", "billingRemoteExitNodesInfo": "Сколько удаленных узлов вы можете использовать",
"billingLicenseKeys": "Лицензионные ключи",
"billingLicenseKeysDescription": "Управление подписками на лицензионные ключи",
"billingLicenseSubscription": "Лицензионное соглашение",
"billingInactive": "Неактивный",
"billingLicenseItem": "Элемент лицензии",
"billingQuantity": "Количество",
"billingTotal": "итого",
"billingModifyLicenses": "Изменить лицензию подписки",
"domainNotFound": "Домен не найден", "domainNotFound": "Домен не найден",
"domainNotFoundDescription": "Этот ресурс отключен, так как домен больше не существует в нашей системе. Пожалуйста, установите новый домен для этого ресурса.", "domainNotFoundDescription": "Этот ресурс отключен, так как домен больше не существует в нашей системе. Пожалуйста, установите новый домен для этого ресурса.",
"failed": "Ошибка", "failed": "Ошибка",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Ключ безопасности успешно удален", "securityKeyRemoveSuccess": "Ключ безопасности успешно удален",
"securityKeyRemoveError": "Не удалось удалить ключ безопасности", "securityKeyRemoveError": "Не удалось удалить ключ безопасности",
"securityKeyLoadError": "Не удалось загрузить ключи безопасности", "securityKeyLoadError": "Не удалось загрузить ключи безопасности",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Использовать ключ безопасности",
"securityKeyAuthError": "Не удалось аутентифицироваться с ключом безопасности", "securityKeyAuthError": "Не удалось аутентифицироваться с ключом безопасности",
"securityKeyRecommendation": "Зарегистрируйте резервный ключ безопасности на другом устройстве, чтобы всегда иметь доступ к вашему аккаунту.", "securityKeyRecommendation": "Зарегистрируйте резервный ключ безопасности на другом устройстве, чтобы всегда иметь доступ к вашему аккаунту.",
"registering": "Регистрация...", "registering": "Регистрация...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "Номер порта необходим для не-HTTP ресурсов", "resourcePortRequired": "Номер порта необходим для не-HTTP ресурсов",
"resourcePortNotAllowed": "Номер порта не должен быть установлен для HTTP ресурсов", "resourcePortNotAllowed": "Номер порта не должен быть установлен для HTTP ресурсов",
"billingPricingCalculatorLink": "Калькулятор расценок", "billingPricingCalculatorLink": "Калькулятор расценок",
"billingYourPlan": "Ваш план",
"billingViewOrModifyPlan": "Просмотреть или изменить ваш текущий тариф",
"billingViewPlanDetails": "Подробности плана",
"billingUsageAndLimits": "Использование и ограничения",
"billingViewUsageAndLimits": "Просмотр лимитов и текущего использования вашего плана",
"billingCurrentUsage": "Текущее использование",
"billingMaximumLimits": "Максимальные ограничения",
"billingRemoteNodes": "Удаленные узлы",
"billingUnlimited": "Неограниченный",
"billingPaidLicenseKeys": "Платные лицензионные ключи",
"billingManageLicenseSubscription": "Управление подпиской на платные лицензионные ключи собственного хостинга",
"billingCurrentKeys": "Текущие ключи",
"billingModifyCurrentPlan": "Изменить текущий план",
"billingConfirmUpgrade": "Подтвердить обновление",
"billingConfirmDowngrade": "Подтверждение понижения",
"billingConfirmUpgradeDescription": "Вы собираетесь обновить тарифный план. Проверьте новые лимиты и цены ниже.",
"billingConfirmDowngradeDescription": "Вы собираетесь понизить тарифный план. Проверьте новые ограничения и цены ниже.",
"billingPlanIncludes": "Включает план",
"billingProcessing": "Обработка...",
"billingConfirmUpgradeButton": "Подтвердить обновление",
"billingConfirmDowngradeButton": "Подтверждение понижения",
"billingLimitViolationWarning": "Превышено количество новых лимитов плана",
"billingLimitViolationDescription": "Ваше текущее использование превышает лимиты этого плана. После понижения значения все действия будут отключены до уменьшения использования в пределах новых лимитов. Пожалуйста, ознакомьтесь с функциями, которые в настоящее время превышают лимиты. Ограничения:",
"billingFeatureLossWarning": "Уведомление о доступности функций",
"billingFeatureLossDescription": "При переходе на другой тарифный план функции не будут автоматически отключены. Некоторые настройки и конфигурации могут быть потеряны. Пожалуйста, ознакомьтесь с матрицей ценообразования, чтобы понять, какие функции больше не будут доступны.",
"billingUsageExceedsLimit": "Текущее использование ({current}) превышает предел ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Я согласен с", "IAgreeToThe": "Я согласен с",
"termsOfService": "условия использования", "termsOfService": "условия использования",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Интервал здоровых состояний", "IntervalSeconds": "Интервал здоровых состояний",
"timeoutSeconds": "Таймаут (сек)", "timeoutSeconds": "Таймаут (сек)",
"timeIsInSeconds": "Время указано в секундах", "timeIsInSeconds": "Время указано в секундах",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Требовать подтверждения устройства",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Пользователям с этой ролью нужны новые устройства, одобренные администратором, прежде чем они смогут подключаться и получать доступ к ресурсам.",
"retryAttempts": "Количество попыток повторного запроса", "retryAttempts": "Количество попыток повторного запроса",
"expectedResponseCodes": "Ожидаемые коды ответов", "expectedResponseCodes": "Ожидаемые коды ответов",
"expectedResponseCodesDescription": "HTTP-код состояния, указывающий на здоровое состояние. Если оставить пустым, 200-300 считается здоровым.", "expectedResponseCodesDescription": "HTTP-код состояния, указывающий на здоровое состояние. Если оставить пустым, 200-300 считается здоровым.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Внутренних ресурсов не найдено.", "resourcesTableNoInternalResourcesFound": "Внутренних ресурсов не найдено.",
"resourcesTableDestination": "Пункт назначения", "resourcesTableDestination": "Пункт назначения",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "Псевдоним адреса",
"resourcesTableAliasAddressInfo": "Этот адрес является частью вспомогательной подсети организации. Он используется для разрешения псевдонимов с использованием внутреннего разрешения DNS.",
"resourcesTableClients": "Клиенты", "resourcesTableClients": "Клиенты",
"resourcesTableAndOnlyAccessibleInternally": "и доступны только внутренне при подключении с клиентом.", "resourcesTableAndOnlyAccessibleInternally": "и доступны только внутренне при подключении с клиентом.",
"resourcesTableNoTargets": "Нет ярлыков", "resourcesTableNoTargets": "Нет ярлыков",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Выберите своего поставщика удостоверений личности для продолжения", "orgAuthChooseIdpDescription": "Выберите своего поставщика удостоверений личности для продолжения",
"orgAuthNoIdpConfigured": "Эта организация не имеет настроенных поставщиков идентификационных данных. Вместо этого вы можете войти в свой Pangolin.", "orgAuthNoIdpConfigured": "Эта организация не имеет настроенных поставщиков идентификационных данных. Вместо этого вы можете войти в свой Pangolin.",
"orgAuthSignInWithPangolin": "Войти через Pangolin", "orgAuthSignInWithPangolin": "Войти через Pangolin",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Войти в организацию",
"orgAuthSelectOrgTitle": "Вход в организацию", "orgAuthSelectOrgTitle": "Вход в организацию",
"orgAuthSelectOrgDescription": "Введите ID вашей организации, чтобы продолжить", "orgAuthSelectOrgDescription": "Введите ID вашей организации, чтобы продолжить",
"orgAuthOrgIdPlaceholder": "ваша-организация", "orgAuthOrgIdPlaceholder": "ваша-организация",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Вернуться к стандартному входу", "orgAuthBackToSignIn": "Вернуться к стандартному входу",
"orgAuthNoAccount": "Нет учётной записи?", "orgAuthNoAccount": "Нет учётной записи?",
"subscriptionRequiredToUse": "Для использования этой функции требуется подписка.", "subscriptionRequiredToUse": "Для использования этой функции требуется подписка.",
"mustUpgradeToUse": "Вы должны обновить подписку, чтобы использовать эту функцию.",
"subscriptionRequiredTierToUse": "Эта функция требует <tierLink>{tier}</tierLink> или выше.",
"upgradeToTierToUse": "Обновитесь до <tierLink>{tier}</tierLink> или выше, чтобы использовать эту функцию.",
"subscriptionTierTier1": "Главная",
"subscriptionTierTier2": "Команда",
"subscriptionTierTier3": "Бизнес",
"subscriptionTierEnterprise": "Предприятие",
"idpDisabled": "Провайдеры идентификации отключены.", "idpDisabled": "Провайдеры идентификации отключены.",
"orgAuthPageDisabled": "Страница авторизации организации отключена.", "orgAuthPageDisabled": "Страница авторизации организации отключена.",
"domainRestartedDescription": "Проверка домена успешно перезапущена", "domainRestartedDescription": "Проверка домена успешно перезапущена",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Получить лицензию",
"description": "Выберите план и расскажите нам, как вы планируете использовать Панголин.",
"chooseTier": "Выберите ваш план",
"viewPricingLink": "Смотрите цены, возможности и ограничения",
"tiers": {
"starter": {
"title": "Старт",
"description": "Функции предприятия, 25 пользователей, 25 сайтов, и поддержка сообщества."
},
"scale": {
"title": "Масштаб",
"description": "Функции предприятия, 50 пользователей, 50 сайтов, а также приоритетная поддержка."
}
},
"personalUseOnly": "Только для личного пользования (бесплатная лицензия — без оформления)",
"buttons": {
"continueToCheckout": "Продолжить оформление заказа"
},
"toasts": {
"checkoutError": {
"title": "Ошибка оформления заказа",
"description": "Не удалось начать оформление заказа. Пожалуйста, попробуйте еще раз."
}
}
},
"priority": "Приоритет", "priority": "Приоритет",
"priorityDescription": "Маршруты с более высоким приоритетом оцениваются первым. Приоритет = 100 означает автоматическое упорядочение (решение системы). Используйте другой номер для обеспечения ручного приоритета.", "priorityDescription": "Маршруты с более высоким приоритетом оцениваются первым. Приоритет = 100 означает автоматическое упорядочение (решение системы). Используйте другой номер для обеспечения ручного приоритета.",
"instanceName": "Имя экземпляра", "instanceName": "Имя экземпляра",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Конец следующего года", "logRetentionEndOfFollowingYear": "Конец следующего года",
"actionLogsDescription": "Просмотр истории действий, выполненных в этой организации", "actionLogsDescription": "Просмотр истории действий, выполненных в этой организации",
"accessLogsDescription": "Просмотр запросов авторизации доступа к ресурсам этой организации", "accessLogsDescription": "Просмотр запросов авторизации доступа к ресурсам этой организации",
"licenseRequiredToUse": "Для использования этой функции требуется лицензия предприятия.", "licenseRequiredToUse": "Лицензия на <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> требуется для использования этой функции. Эта функция также доступна в <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"ossEnterpriseEditionRequired": "Для использования этой функции требуется <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink>. Эта функция также доступна в <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>.",
"certResolver": "Резольвер сертификата", "certResolver": "Резольвер сертификата",
"certResolverDescription": "Выберите резолвер сертификата, который будет использоваться для этого ресурса.", "certResolverDescription": "Выберите резолвер сертификата, который будет использоваться для этого ресурса.",
"selectCertResolver": "Выберите резолвер сертификата", "selectCertResolver": "Выберите резолвер сертификата",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Код должен быть 9 символов (например, A1AJ-N5JD)", "deviceCodeInvalidFormat": "Код должен быть 9 символов (например, A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Неверный или просроченный код", "deviceCodeInvalidOrExpired": "Неверный или просроченный код",
"deviceCodeVerifyFailed": "Не удалось проверить код устройства", "deviceCodeVerifyFailed": "Не удалось проверить код устройства",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Проверка кода устройства...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Проверка авторизации устройства...",
"signedInAs": "Вы вошли как", "signedInAs": "Вы вошли как",
"deviceCodeEnterPrompt": "Введите код, отображаемый на устройстве", "deviceCodeEnterPrompt": "Введите код, отображаемый на устройстве",
"continue": "Продолжить", "continue": "Продолжить",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Доступ ко всем организациям, к которым ваш аккаунт имеет доступ", "deviceOrganizationsAccess": "Доступ ко всем организациям, к которым ваш аккаунт имеет доступ",
"deviceAuthorize": "Авторизовать {applicationName}", "deviceAuthorize": "Авторизовать {applicationName}",
"deviceConnected": "Устройство подключено!", "deviceConnected": "Устройство подключено!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Устройство авторизовано для доступа к вашей учетной записи. Вернитесь в клиентское приложение.",
"pangolinCloud": "Облако Панголина", "pangolinCloud": "Облако Панголина",
"viewDevices": "Просмотр устройств", "viewDevices": "Просмотр устройств",
"viewDevicesDescription": "Управление подключенными устройствами", "viewDevicesDescription": "Управление подключенными устройствами",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "Не вы? Используйте другую учетную запись.", "deviceLoginUseDifferentAccount": "Не вы? Используйте другую учетную запись.",
"deviceLoginDeviceRequestingAccessToAccount": "Устройство запрашивает доступ к этой учетной записи.", "deviceLoginDeviceRequestingAccessToAccount": "Устройство запрашивает доступ к этой учетной записи.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Выберите метод аутентификации для продолжения.",
"noData": "Нет данных", "noData": "Нет данных",
"machineClients": "Машинные клиенты", "machineClients": "Машинные клиенты",
"install": "Установить", "install": "Установить",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "В настоящее время мы испытываем технические трудности. Пожалуйста, зайдите позже.", "maintenanceScreenMessage": "В настоящее время мы испытываем технические трудности. Пожалуйста, зайдите позже.",
"maintenanceScreenEstimatedCompletion": "Предполагаемое завершение:", "maintenanceScreenEstimatedCompletion": "Предполагаемое завершение:",
"createInternalResourceDialogDestinationRequired": "Укажите адрес назначения. Это может быть имя хоста или IP-адрес.", "createInternalResourceDialogDestinationRequired": "Укажите адрес назначения. Это может быть имя хоста или IP-адрес.",
"available": "Available", "available": "Доступно",
"archived": "Archived", "archived": "Архивировано",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Архивные устройства не найдены",
"deviceArchived": "Device archived", "deviceArchived": "Устройство архивировано",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Устройство успешно архивировано.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Ошибка архивирования устройства",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Не удалось архивировать устройство",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Вы уверены, что хотите архивировать это устройство?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Устройство будет архивировано и удалено из вашего списка активных устройств.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Архивировать устройство",
"archiveDevice": "Archive Device", "archiveDevice": "Архивировать устройство",
"archive": "Archive", "archive": "Архивировать",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Устройство разархивировано",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Устройство было успешно разархивировано.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Ошибка разархивирования устройства",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Не удалось распаковать устройство",
"unarchive": "Unarchive", "unarchive": "Разархивировать",
"archiveClient": "Archive Client", "archiveClient": "Архивировать клиента",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Вы уверены, что хотите архивировать этого клиента?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "Клиент будет архивирован и удален из вашего активного списка клиентов.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "Архивировать клиента",
"blockClient": "Block Client", "blockClient": "Блокировать клиента",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Вы уверены, что хотите заблокировать этого клиента?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Устройство будет вынуждено отключиться, если подключено в данный момент. Вы можете разблокировать устройство позже.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "Блокировать клиента",
"active": "Active", "active": "Активный",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Имя пользователя или Email",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Выберите вашу организацию",
"signInTo": "Log in in to", "signInTo": "Войти в",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Продолжить с паролем",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Методы аутентификации для этой организации недоступны.",
"enterPassword": "Enter your password", "enterPassword": "Введите ваш пароль",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Введите код из вашего приложения-аутентификатора",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Пожалуйста, используйте ваш защитный ключ для входа.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Нужно использовать другой аккаунт?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Нажимая на кнопки ниже, вы подтверждаете, что прочитали, поняли и согласны с <termsOfService>Условиями использования</termsOfService> и <privacyPolicy>Политикой конфиденциальности</privacyPolicy>.",
"termsOfService": "Terms of Service", "termsOfService": "Условия предоставления услуг",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Политика конфиденциальности",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Пользователь с таким именем пользователя не найден.",
"verify": "Verify", "verify": "Подтвердить",
"signIn": "Sign In", "signIn": "Войти",
"forgotPassword": "Forgot password?", "forgotPassword": "Забыли пароль?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Если вы вошли в систему ранее, вы можете ввести имя пользователя или адрес электронной почты, чтобы войти в систему с поставщиком идентификации вашей организации. Это проще!",
"continueAnyway": "Continue anyway", "continueAnyway": "Все равно продолжить",
"dontShowAgain": "Don't show again", "dontShowAgain": "Больше не показывать",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Знаете ли вы?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Пытаетесь войти?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Вы пытаетесь войти через оператора идентификации вашей организации?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Войдите или зарегистрируйтесь через вашу организацию",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Использовать другую учетную запись",
"logIn": "Log In", "logIn": "Войти",
"deviceInformation": "Device Information", "deviceInformation": "Информация об устройстве",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Информация о устройстве и агенте",
"platform": "Platform", "deviceSecurity": "Безопасность устройства",
"macosVersion": "macOS Version", "deviceSecurityDescription": "Информация о позе безопасности устройства",
"windowsVersion": "Windows Version", "platform": "Платформа",
"iosVersion": "iOS Version", "macosVersion": "Версия macOS",
"androidVersion": "Android Version", "windowsVersion": "Версия Windows",
"osVersion": "OS Version", "iosVersion": "Версия iOS",
"kernelVersion": "Kernel Version", "androidVersion": "Версия Android",
"deviceModel": "Device Model", "osVersion": "Версия ОС",
"serialNumber": "Serial Number", "kernelVersion": "Версия ядра",
"deviceModel": "Модель устройства",
"serialNumber": "Серийный номер",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "Первый раз виден",
"lastSeen": "Last Seen", "lastSeen": "Последнее посещение",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Включены биометрические данные",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Диск зашифрован",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Брандмауэр включен",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Автоматические обновления включены",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "Доступно TPM",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Антивирус включен",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Защита целостности системы (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Стилс-режим брандмауэра",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "Броня",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Просмотр информации и настроек устройства",
"devicePendingApprovalDescription": "Это устройство ожидает одобрения",
"deviceBlockedDescription": "Это устройство заблокировано. Оно не сможет подключаться к ресурсам, если не разблокировано.",
"unblockClient": "Разблокировать клиента",
"unblockClientDescription": "Устройство разблокировано",
"unarchiveClient": "Разархивировать клиента",
"unarchiveClientDescription": "Устройство было разархивировано",
"block": "Блок",
"unblock": "Разблокировать",
"deviceActions": "Действия устройства",
"deviceActionsDescription": "Управление статусом устройства и доступом",
"devicePendingApprovalBannerDescription": "Это устройство ожидает одобрения. Он не сможет подключиться к ресурсам до утверждения.",
"connected": "Подключено",
"disconnected": "Отключено",
"approvalsEmptyStateTitle": "Утверждения устройства не включены",
"approvalsEmptyStateDescription": "Включите одобрение ролей для того, чтобы пользователи могли подключать новые устройства.",
"approvalsEmptyStateStep1Title": "Перейти к ролям",
"approvalsEmptyStateStep1Description": "Перейдите в настройки ролей вашей организации для настройки утверждений устройств.",
"approvalsEmptyStateStep2Title": "Включить утверждения устройства",
"approvalsEmptyStateStep2Description": "Редактировать роль и включить опцию 'Требовать утверждения устройств'. Пользователям с этой ролью потребуется подтверждение администратора для новых устройств.",
"approvalsEmptyStatePreviewDescription": "Предпросмотр: Если включено, ожидающие запросы на устройство появятся здесь для проверки",
"approvalsEmptyStateButtonText": "Управление ролями"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "{count, plural, =0 {hiçbir organizasyon} one {bir organizasyon} other {# organizasyon}} üyesisiniz.", "componentsMember": "{count, plural, =0 {hiçbir organizasyon} one {bir organizasyon} other {# organizasyon}} üyesisiniz.",
"componentsInvalidKey": "Geçersiz veya süresi dolmuş lisans anahtarları tespit edildi. Tüm özellikleri kullanmaya devam etmek için lisans koşullarına uyun.", "componentsInvalidKey": "Geçersiz veya süresi dolmuş lisans anahtarları tespit edildi. Tüm özellikleri kullanmaya devam etmek için lisans koşullarına uyun.",
"dismiss": "Kapat", "dismiss": "Kapat",
"subscriptionViolationMessage": "Geçerli planınız için limitlerinizi aştınız. Planınız dahilinde kalmak için siteleri, kullanıcıları veya diğer kaynakları kaldırarak sorunu düzeltin.",
"subscriptionViolationViewBilling": "Faturalamayı görüntüle",
"componentsLicenseViolation": "Lisans İhlali: Bu sunucu, lisanslı sınırı olan {maxSites} sitesini aşarak {usedSites} site kullanmaktadır. Tüm özellikleri kullanmaya devam etmek için lisans koşullarına uyun.", "componentsLicenseViolation": "Lisans İhlali: Bu sunucu, lisanslı sınırı olan {maxSites} sitesini aşarak {usedSites} site kullanmaktadır. Tüm özellikleri kullanmaya devam etmek için lisans koşullarına uyun.",
"componentsSupporterMessage": "Pangolin'e {tier} olarak destek olduğunuz için teşekkür ederiz!", "componentsSupporterMessage": "Pangolin'e {tier} olarak destek olduğunuz için teşekkür ederiz!",
"inviteErrorNotValid": "Üzgünüz, ancak erişmeye çalıştığınız davet kabul edilmemiş veya artık geçerli değil gibi görünüyor.", "inviteErrorNotValid": "Üzgünüz, ancak erişmeye çalıştığınız davet kabul edilmemiş veya artık geçerli değil gibi görünüyor.",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "Herhangi Bir Ağa Bağlan", "sitesBannerTitle": "Herhangi Bir Ağa Bağlan",
"sitesBannerDescription": "Bir site, Pangolin'in kullanıcılara, halka açık veya özel kaynaklara, her yerden erişim sağlamak için uzak bir ağa bağlantı sunmasıdır. Site ağı bağlantısını (Newt) çalıştırabileceğiniz her yere kurarak bağlantıyı kurunuz.", "sitesBannerDescription": "Bir site, Pangolin'in kullanıcılara, halka açık veya özel kaynaklara, her yerden erişim sağlamak için uzak bir ağa bağlantı sunmasıdır. Site ağı bağlantısını (Newt) çalıştırabileceğiniz her yere kurarak bağlantıyı kurunuz.",
"sitesBannerButtonText": "Site Kur", "sitesBannerButtonText": "Site Kur",
"approvalsBannerTitle": "Cihaz Erişimini Onayla veya Reddet",
"approvalsBannerDescription": "Kullanıcılardan gelen cihaz erişim isteklerini gözden geçirin ve onaylayın veya reddedin. Cihaz onaylarının gerekli olduğu durumlarda, kullanıcıların cihazlarının kuruluşunuzun kaynaklarına bağlanabilmesi için yönetici onayı alması gerekecektir.",
"approvalsBannerButtonText": "Daha fazla bilgi",
"siteCreate": "Site Oluştur", "siteCreate": "Site Oluştur",
"siteCreateDescription2": "Yeni bir site oluşturup bağlanmak için aşağıdaki adımları izleyin", "siteCreateDescription2": "Yeni bir site oluşturup bağlanmak için aşağıdaki adımları izleyin",
"siteCreateDescription": "Kaynaklarınızı bağlamaya başlamak için yeni bir site oluşturun", "siteCreateDescription": "Kaynaklarınızı bağlamaya başlamak için yeni bir site oluşturun",
@@ -257,8 +262,8 @@
"accessRolesSearch": "Rolleri ara...", "accessRolesSearch": "Rolleri ara...",
"accessRolesAdd": "Rol Ekle", "accessRolesAdd": "Rol Ekle",
"accessRoleDelete": "Rolü Sil", "accessRoleDelete": "Rolü Sil",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "Onayları Yönet",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "Bu kuruluşa erişim için bekleyen onayları görüntüleyin ve yönetin",
"description": "Açıklama", "description": "Açıklama",
"inviteTitle": "Açık Davetiyeler", "inviteTitle": "Açık Davetiyeler",
"inviteDescription": "Organizasyona katılmak için diğer kullanıcılar için davetleri yönetin", "inviteDescription": "Organizasyona katılmak için diğer kullanıcılar için davetleri yönetin",
@@ -452,18 +457,18 @@
"selectDuration": "Süreyi seçin", "selectDuration": "Süreyi seçin",
"selectResource": "Kaynak Seçin", "selectResource": "Kaynak Seçin",
"filterByResource": "Kaynağa Göre Filtrele", "filterByResource": "Kaynağa Göre Filtrele",
"selectApprovalState": "Select Approval State", "selectApprovalState": "Onay Durumunu Seçin",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "Onay Durumuna Göre Filtrele",
"approvalListEmpty": "No approvals", "approvalListEmpty": "Onay yok",
"approvalState": "Approval State", "approvalState": "Onay Durumu",
"approve": "Approve", "approve": "Onayla",
"approved": "Approved", "approved": "Onaylandı",
"denied": "Denied", "denied": "Reddedildi",
"deniedApproval": "Denied Approval", "deniedApproval": "Reddedilen Onay",
"all": "All", "all": "Tümü",
"deny": "Deny", "deny": "Reddet",
"viewDetails": "View Details", "viewDetails": "Ayrıntıları Gör",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "yeni bir cihaz talep etti",
"resetFilters": "Filtreleri Sıfırla", "resetFilters": "Filtreleri Sıfırla",
"totalBlocked": "Pangolin Tarafından Engellenen İstekler", "totalBlocked": "Pangolin Tarafından Engellenen İstekler",
"totalRequests": "Toplam İstekler", "totalRequests": "Toplam İstekler",
@@ -743,28 +748,28 @@
"countries": "Ülkeler", "countries": "Ülkeler",
"accessRoleCreate": "Rol Oluştur", "accessRoleCreate": "Rol Oluştur",
"accessRoleCreateDescription": "Kullanıcıları gruplamak ve izinlerini yönetmek için yeni bir rol oluşturun.", "accessRoleCreateDescription": "Kullanıcıları gruplamak ve izinlerini yönetmek için yeni bir rol oluşturun.",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "Rol Düzenle",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "Rol bilgilerini düzenleyin.",
"accessRoleCreateSubmit": "Rol Oluştur", "accessRoleCreateSubmit": "Rol Oluştur",
"accessRoleCreated": "Rol oluşturuldu", "accessRoleCreated": "Rol oluşturuldu",
"accessRoleCreatedDescription": "Rol başarıyla oluşturuldu.", "accessRoleCreatedDescription": "Rol başarıyla oluşturuldu.",
"accessRoleErrorCreate": "Rol oluşturulamadı", "accessRoleErrorCreate": "Rol oluşturulamadı",
"accessRoleErrorCreateDescription": "Rol oluşturulurken bir hata oluştu.", "accessRoleErrorCreateDescription": "Rol oluşturulurken bir hata oluştu.",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "Rolü Güncelle",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "Rol güncellendi",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "Rol başarıyla güncellendi.",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "Onay işlendi",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "Onay İsteği kararını onaylandı olarak ayarlayın.",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "Onay İsteği kararını reddedildi olarak ayarlayın.",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "Rol güncellenemedi",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "Rol güncellenirken bir hata oluştu.",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "Onay işlenemedi",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "Onay işlenirken bir hata oluştu.",
"accessRoleErrorNewRequired": "Yeni rol gerekli", "accessRoleErrorNewRequired": "Yeni rol gerekli",
"accessRoleErrorRemove": "Rol kaldırılamadı", "accessRoleErrorRemove": "Rol kaldırılamadı",
"accessRoleErrorRemoveDescription": "Rol kaldırılırken bir hata oluştu.", "accessRoleErrorRemoveDescription": "Rol kaldırılırken bir hata oluştu.",
"accessRoleName": "Rol Adı", "accessRoleName": "Rol Adı",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "{name} rolünü silmek üzeresiniz. Bu eylemi geri alamazsınız.",
"accessRoleRemove": "Rolü Kaldır", "accessRoleRemove": "Rolü Kaldır",
"accessRoleRemoveDescription": "Kuruluştan bir rol kaldır", "accessRoleRemoveDescription": "Kuruluştan bir rol kaldır",
"accessRoleRemoveSubmit": "Rolü Kaldır", "accessRoleRemoveSubmit": "Rolü Kaldır",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "Site sayısını artır", "sitestCountIncrease": "Site sayısını artır",
"idpManage": "Kimlik Sağlayıcılarını Yönet", "idpManage": "Kimlik Sağlayıcılarını Yönet",
"idpManageDescription": "Sistem içindeki kimlik sağlayıcıları görün ve yönetin", "idpManageDescription": "Sistem içindeki kimlik sağlayıcıları görün ve yönetin",
"idpGlobalModeBanner": "Bu sunucuda örgüt başına kimlik sağlayıcılar (IdP'ler) devre dışı bırakılmıştır. Tüm örgütler arasında paylaşılan küresel IdP'leri kullanıyor. Küresel IdP'leri <adminPanelLink> yönetici panelinde </adminPanelLink>yönetin. Örgüt başına IdP'leri etkinleştirmek için, sunucu yapılandırmasını düzenleyin ve IdP modunu 'org' olarak ayarlayın. <configDocsLink> Belgeleri inceleyin </configDocsLink>. Küresel IdP'leri kullanmaya devam etmek istiyorsanız ve bunun örgüt ayarlarından kaybolmasını istiyorsanız, yapılandırmada modu otomatik olarak 'global' olarak ayarlayın.",
"idpGlobalModeBannerUpgradeRequired": "Bu sunucuda örgüt başına kimlik sağlayıcılar (IdP'ler) devre dışı bırakılmıştır. Tüm örgütler arasında paylaşılan küresel IdP'leri kullanıyor. Küresel IdP'leri <adminPanelLink> yönetici panelinde </adminPanelLink>yönetin. Örgüt başına kimlik sağlayıcılar kullanmak için, Enterprise sürümüne yükseltmeniz gerekmektedir.",
"idpGlobalModeBannerLicenseRequired": "Bu sunucuda örgüt başına kimlik sağlayıcılar (IdP'ler) devre dışı bırakılmıştır. Tüm örgütler arasında paylaşılan küresel IdP'leri kullanıyor. Küresel IdP'leri <adminPanelLink> yönetici panelinde </adminPanelLink>yönetin. Örgüt başına kimlik sağlayıcılar kullanmak için Enterprise lisansı gereklidir.",
"idpDeletedDescription": "Kimlik sağlayıcı başarıyla silindi", "idpDeletedDescription": "Kimlik sağlayıcı başarıyla silindi",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Kimlik sağlayıcısını kalıcı olarak silmek istediğinizden emin misiniz?", "idpQuestionRemove": "Kimlik sağlayıcısını kalıcı olarak silmek istediğinizden emin misiniz?",
@@ -900,7 +908,7 @@
"inviteAlready": "Davetiye gönderilmiş gibi görünüyor!", "inviteAlready": "Davetiye gönderilmiş gibi görünüyor!",
"inviteAlreadyDescription": "Daveti kabul etmek için giriş yapmalı veya bir hesap oluşturmalısınız.", "inviteAlreadyDescription": "Daveti kabul etmek için giriş yapmalı veya bir hesap oluşturmalısınız.",
"signupQuestion": "Zaten bir hesabınız var mı?", "signupQuestion": "Zaten bir hesabınız var mı?",
"login": "Log In", "login": "Giriş Yap",
"resourceNotFound": "No resources found", "resourceNotFound": "No resources found",
"resourceNotFoundDescription": "Erişmeye çalıştığınız kaynak mevcut değil.", "resourceNotFoundDescription": "Erişmeye çalıştığınız kaynak mevcut değil.",
"pincodeRequirementsLength": "PIN kesinlikle 6 haneli olmalıdır", "pincodeRequirementsLength": "PIN kesinlikle 6 haneli olmalıdır",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "Bu kuruluş, parolanızı {maxDays} günde bir değiştirmenizi gerektirir.", "passwordExpiryDescription": "Bu kuruluş, parolanızı {maxDays} günde bir değiştirmenizi gerektirir.",
"changePasswordNow": "Şifrenizi Şimdi Değiştirin", "changePasswordNow": "Şifrenizi Şimdi Değiştirin",
"pincodeAuth": "Kimlik Doğrulama Kodu", "pincodeAuth": "Kimlik Doğrulama Kodu",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "Kodu Gönder",
"passwordResetSubmit": "Sıfırlama İsteği", "passwordResetSubmit": "Sıfırlama İsteği",
"passwordResetAlreadyHaveCode": "Kodu Girin", "passwordResetAlreadyHaveCode": "Kodu Girin",
"passwordResetSmtpRequired": "Yönetici ile iletişime geçin", "passwordResetSmtpRequired": "Yönetici ile iletişime geçin",
"passwordResetSmtpRequiredDescription": "Parolanızı sıfırlamak için bir parola sıfırlama kodu gereklidir. Yardım için yönetici ile iletişime geçin.", "passwordResetSmtpRequiredDescription": "Parolanızı sıfırlamak için bir parola sıfırlama kodu gereklidir. Yardım için yönetici ile iletişime geçin.",
"passwordBack": "Şifreye Geri Dön", "passwordBack": "Şifreye Geri Dön",
"loginBack": "Go back to main login page", "loginBack": "Ana oturum açma sayfasına geri dön",
"signup": "Kaydol", "signup": "Kaydol",
"loginStart": "Başlamak için giriş yapın", "loginStart": "Başlamak için giriş yapın",
"idpOidcTokenValidating": "OIDC token'ı doğrulanıyor", "idpOidcTokenValidating": "OIDC token'ı doğrulanıyor",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "Kimlik Sağlayıcı Organizasyonu Güncelle", "actionUpdateIdpOrg": "Kimlik Sağlayıcı Organizasyonu Güncelle",
"actionCreateClient": "Müşteri Oluştur", "actionCreateClient": "Müşteri Oluştur",
"actionDeleteClient": "Müşteri Sil", "actionDeleteClient": "Müşteri Sil",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "İstemci Arşivle",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "İstemci Arşivini Kaldır",
"actionBlockClient": "Block Client", "actionBlockClient": "İstemci Engelle",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "İstemci Engelini Kaldır",
"actionUpdateClient": "Müşteri Güncelle", "actionUpdateClient": "Müşteri Güncelle",
"actionListClients": "Müşterileri Listele", "actionListClients": "Müşterileri Listele",
"actionGetClient": "Müşteriyi Al", "actionGetClient": "Müşteriyi Al",
@@ -1164,14 +1172,14 @@
"searchProgress": "Ara...", "searchProgress": "Ara...",
"create": "Oluştur", "create": "Oluştur",
"orgs": "Organizasyonlar", "orgs": "Organizasyonlar",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin.",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "Cihazınız için oturum açmanız gerekiyor.",
"passwordForgot": "Şifrenizi mi unuttunuz?", "passwordForgot": "Şifrenizi mi unuttunuz?",
"otpAuth": "İki Faktörlü Kimlik Doğrulama", "otpAuth": "İki Faktörlü Kimlik Doğrulama",
"otpAuthDescription": "Authenticator uygulamanızdan veya tek kullanımlık yedek kodlarınızdan birini girin.", "otpAuthDescription": "Authenticator uygulamanızdan veya tek kullanımlık yedek kodlarınızdan birini girin.",
"otpAuthSubmit": "Kodu Gönder", "otpAuthSubmit": "Kodu Gönder",
"idpContinue": "Veya devam et:", "idpContinue": "Veya devam et:",
"otpAuthBack": "Back to Password", "otpAuthBack": "Şifreye Geri Dön",
"navbar": "Navigasyon Menüsü", "navbar": "Navigasyon Menüsü",
"navbarDescription": "Uygulamanın ana navigasyon menüsü", "navbarDescription": "Uygulamanın ana navigasyon menüsü",
"navbarDocsLink": "Dokümantasyon", "navbarDocsLink": "Dokümantasyon",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "Genel Bakış", "sidebarOverview": "Genel Bakış",
"sidebarHome": "Ana Sayfa", "sidebarHome": "Ana Sayfa",
"sidebarSites": "Siteler", "sidebarSites": "Siteler",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "Onay Talepleri",
"sidebarResources": "Kaynaklar", "sidebarResources": "Kaynaklar",
"sidebarProxyResources": "Herkese Açık", "sidebarProxyResources": "Herkese Açık",
"sidebarClientResources": "Özel", "sidebarClientResources": "Özel",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "Kimlik Sağlayıcılar", "sidebarIdentityProviders": "Kimlik Sağlayıcılar",
"sidebarLicense": "Lisans", "sidebarLicense": "Lisans",
"sidebarClients": "İstemciler", "sidebarClients": "İstemciler",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "Kullanıcı Cihazları",
"sidebarMachineClients": "Makineler", "sidebarMachineClients": "Makineler",
"sidebarDomains": "Alan Adları", "sidebarDomains": "Alan Adları",
"sidebarGeneral": "Yönet", "sidebarGeneral": "Yönet",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "Sunucu yönetici hesabı oluşturulurken bir hata oluştu.", "setupErrorCreateAdmin": "Sunucu yönetici hesabı oluşturulurken bir hata oluştu.",
"certificateStatus": "Sertifika Durumu", "certificateStatus": "Sertifika Durumu",
"loading": "Yükleniyor", "loading": "Yükleniyor",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "Analiz Yükleniyor",
"restart": "Yeniden Başlat", "restart": "Yeniden Başlat",
"domains": "Alan Adları", "domains": "Alan Adları",
"domainsDescription": "Organizasyonda kullanılabilir alan adlarını oluşturun ve yönetin", "domainsDescription": "Organizasyonda kullanılabilir alan adlarını oluşturun ve yönetin",
@@ -1336,7 +1344,7 @@
"refreshError": "Veriler yenilenemedi", "refreshError": "Veriler yenilenemedi",
"verified": "Doğrulandı", "verified": "Doğrulandı",
"pending": "Beklemede", "pending": "Beklemede",
"pendingApproval": "Pending Approval", "pendingApproval": "Bekleyen Onay",
"sidebarBilling": "Faturalama", "sidebarBilling": "Faturalama",
"billing": "Faturalama", "billing": "Faturalama",
"orgBillingDescription": "Fatura bilgilerinizi ve aboneliklerinizi yönetin", "orgBillingDescription": "Fatura bilgilerinizi ve aboneliklerinizi yönetin",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "Kullanım Limitleri Genel Görünümü", "billingUsageLimitsOverview": "Kullanım Limitleri Genel Görünümü",
"billingMonitorUsage": "Kullanımınızı yapılandırılmış limitlerle karşılaştırın. Limitlerin artırılmasına ihtiyacınız varsa, lütfen support@pangolin.net adresinden bizimle iletişime geçin.", "billingMonitorUsage": "Kullanımınızı yapılandırılmış limitlerle karşılaştırın. Limitlerin artırılmasına ihtiyacınız varsa, lütfen support@pangolin.net adresinden bizimle iletişime geçin.",
"billingDataUsage": "Veri Kullanımı", "billingDataUsage": "Veri Kullanımı",
"billingOnlineTime": "Site Çevrimiçi Süresi", "billingSites": "Siteler",
"billingUsers": "Aktif Kullanıcılar", "billingUsers": "Kullanıcılar",
"billingDomains": "Aktif Alanlar", "billingDomains": "Alan Adları",
"billingRemoteExitNodes": "Aktif Öz-Host Düğümleri", "billingRemoteExitNodes": "Uzak Düğümler",
"billingNoLimitConfigured": "Hiçbir limit yapılandırılmadı", "billingNoLimitConfigured": "Hiçbir limit yapılandırılmadı",
"billingEstimatedPeriod": "Tahmini Fatura Dönemi", "billingEstimatedPeriod": "Tahmini Fatura Dönemi",
"billingIncludedUsage": "Dahil Kullanım", "billingIncludedUsage": "Dahil Kullanım",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "Portal URL'si alınamadı", "billingFailedToGetPortalUrl": "Portal URL'si alınamadı",
"billingPortalError": "Portal Hatası", "billingPortalError": "Portal Hatası",
"billingDataUsageInfo": "Buluta bağlandığınızda, güvenli tünellerinizden aktarılan tüm verilerden ücret alınırsınız. Bu, tüm sitelerinizdeki gelen ve giden trafiği içerir. Limitinize ulaştığınızda, planınızı yükseltmeli veya kullanımı azaltmalısınız, aksi takdirde siteleriniz bağlantıyı keser. Düğümler kullanırken verilerden ücret alınmaz.", "billingDataUsageInfo": "Buluta bağlandığınızda, güvenli tünellerinizden aktarılan tüm verilerden ücret alınırsınız. Bu, tüm sitelerinizdeki gelen ve giden trafiği içerir. Limitinize ulaştığınızda, planınızı yükseltmeli veya kullanımı azaltmalısınız, aksi takdirde siteleriniz bağlantıyı keser. Düğümler kullanırken verilerden ücret alınmaz.",
"billingOnlineTimeInfo": "Sitelerinizin buluta ne kadar süre bağlı kaldığına göre ücretlendirilirsiniz. Örneğin, 44,640 dakika, bir sitenin 24/7 boyunca tam bir ay boyunca çalışması anlamına gelir. Limitinize ulaştığınızda, planınızı yükseltmeyip kullanımı azaltmazsanız siteleriniz bağlantıyı keser. Düğümler kullanırken zamandan ücret alınmaz.", "billingSInfo": "Kaç tane site kullanabileceğiniz",
"billingUsersInfo": "Kuruluşunuzdaki her kullanıcı için ücretlendirilirsiniz. Faturalandırma, organizasyonunuza kayıtlı aktif kullanıcı hesaplarının sayısına göre günlük olarak hesaplanır.", "billingUsersInfo": "Kaç tane kullanıcı kullanabileceğiniz",
"billingDomainInfo": "Kuruluşunuzdaki her alan adı için ücretlendirilirsiniz. Faturalandırma, organizasyonunuza kayıtlı aktif alan adları hesaplarının sayısına göre günlük olarak hesaplanır.", "billingDomainInfo": "Kaç tane alan adı kullanabileceğiniz",
"billingRemoteExitNodesInfo": "Kuruluşunuzdaki her yönetilen Düğüm için ücretlendirilirsiniz. Faturalandırma, organizasyonunuza kayıtlı aktif yönetilen Düğümler sayısına göre günlük olarak hesaplanır.", "billingRemoteExitNodesInfo": "Kaç tane uzaktan düğüm kullanabileceğiniz",
"billingLicenseKeys": "Lisans Anahtarları",
"billingLicenseKeysDescription": "Lisans anahtarı aboneliklerinizi yönetin",
"billingLicenseSubscription": "Lisans Aboneliği",
"billingInactive": "Pasif",
"billingLicenseItem": "Lisans Öğesi",
"billingQuantity": "Miktar",
"billingTotal": "toplam",
"billingModifyLicenses": "Lisans Aboneliğini Düzenle",
"domainNotFound": "Alan Adı Bulunamadı", "domainNotFound": "Alan Adı Bulunamadı",
"domainNotFoundDescription": "Bu kaynak devre dışıdır çünkü alan adı sistemimizde artık mevcut değil. Bu kaynak için yeni bir alan adı belirleyin.", "domainNotFoundDescription": "Bu kaynak devre dışıdır çünkü alan adı sistemimizde artık mevcut değil. Bu kaynak için yeni bir alan adı belirleyin.",
"failed": "Başarısız", "failed": "Başarısız",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "Güvenlik anahtarı başarıyla kaldırıldı", "securityKeyRemoveSuccess": "Güvenlik anahtarı başarıyla kaldırıldı",
"securityKeyRemoveError": "Güvenlik anahtarı kaldırılırken hata oluştu", "securityKeyRemoveError": "Güvenlik anahtarı kaldırılırken hata oluştu",
"securityKeyLoadError": "Güvenlik anahtarları yüklenirken hata oluştu", "securityKeyLoadError": "Güvenlik anahtarları yüklenirken hata oluştu",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "Güvenlik Anahtarı Kullan",
"securityKeyAuthError": "Güvenlik anahtarı ile kimlik doğrulama başarısız oldu", "securityKeyAuthError": "Güvenlik anahtarı ile kimlik doğrulama başarısız oldu",
"securityKeyRecommendation": "Hesabınızdan kilitlenmediğinizden emin olmak için farklı bir cihazda başka bir güvenlik anahtarı kaydetmeyi düşünün.", "securityKeyRecommendation": "Hesabınızdan kilitlenmediğinizden emin olmak için farklı bir cihazda başka bir güvenlik anahtarı kaydetmeyi düşünün.",
"registering": "Kaydediliyor...", "registering": "Kaydediliyor...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "HTTP dışı kaynaklar için bağlantı noktası numarası gereklidir", "resourcePortRequired": "HTTP dışı kaynaklar için bağlantı noktası numarası gereklidir",
"resourcePortNotAllowed": "HTTP kaynakları için bağlantı noktası numarası ayarlanmamalı", "resourcePortNotAllowed": "HTTP kaynakları için bağlantı noktası numarası ayarlanmamalı",
"billingPricingCalculatorLink": "Fiyat Hesaplayıcı", "billingPricingCalculatorLink": "Fiyat Hesaplayıcı",
"billingYourPlan": "Planınız",
"billingViewOrModifyPlan": "Mevcut planınızı görüntüleyin veya düzenleyin",
"billingViewPlanDetails": "Plan Detaylarını Görüntüle",
"billingUsageAndLimits": "Kullanım ve Sınırlar",
"billingViewUsageAndLimits": "Planınızın limitlerini ve mevcut kullanım durumunu görüntüleyin",
"billingCurrentUsage": "Mevcut Kullanım",
"billingMaximumLimits": "Maksimum Sınırlar",
"billingRemoteNodes": "Uzak Düğümler",
"billingUnlimited": "Sınırsız",
"billingPaidLicenseKeys": "Ücretli Lisans Anahtarları",
"billingManageLicenseSubscription": "Kendi barındırdığınız ücretli lisans anahtarları için aboneliğinizi yönetin",
"billingCurrentKeys": "Mevcut Anahtarlar",
"billingModifyCurrentPlan": "Mevcut Planı Düzenle",
"billingConfirmUpgrade": "Yükseltmeyi Onayla",
"billingConfirmDowngrade": "Düşürmeyi Onayla",
"billingConfirmUpgradeDescription": "Planınızı yükseltmek üzeresiniz. Yeni limitleri ve fiyatları aşağıda inceleyin.",
"billingConfirmDowngradeDescription": "Planınızı düşürmek üzeresiniz. Yeni limitleri ve fiyatları aşağıda inceleyin.",
"billingPlanIncludes": "Plan İçerikleri",
"billingProcessing": "İşleniyor...",
"billingConfirmUpgradeButton": "Yükseltmeyi Onayla",
"billingConfirmDowngradeButton": "Düşürmeyi Onayla",
"billingLimitViolationWarning": "Kullanım Yeni Plan Sınırlarını Aşıyor",
"billingLimitViolationDescription": "Mevcut kullanımınız bu planın sınırlarını aşıyor. Düzeltmelerden sonra, yeni sınırlar içinde kalana kadar tüm işlemler devre dışı bırakılacak. Lütfen şu anda limitlerin üzerinde olan özellikleri inceleyin. İhlal edilen sınırlar:",
"billingFeatureLossWarning": "Özellik Kullanılabilirlik Bildirimi",
"billingFeatureLossDescription": "Plan düşürüldüğünde, yeni planda mevcut olmayan özellikler otomatik olarak devre dışı bırakılacaktır. Bazı ayarlar ve yapılar kaybolabilir. Hangi özelliklerin artık mevcut olmayacağını anlamak için fiyat tablosunu inceleyiniz.",
"billingUsageExceedsLimit": "Mevcut kullanım ({current}) limitleri ({limit}) aşıyor",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "Kabul ediyorum", "IAgreeToThe": "Kabul ediyorum",
"termsOfService": "hizmet şartları", "termsOfService": "hizmet şartları",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "Sağlıklı Aralık", "IntervalSeconds": "Sağlıklı Aralık",
"timeoutSeconds": "Zaman Aşımı (saniye)", "timeoutSeconds": "Zaman Aşımı (saniye)",
"timeIsInSeconds": "Zaman saniye cinsindendir", "timeIsInSeconds": "Zaman saniye cinsindendir",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "Cihaz Onaylarını Gerektir",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "Bu role sahip kullanıcıların yeni cihazlarının bağlanabilmesi ve kaynaklara erişebilmesi için bir yönetici tarafından onaylanması gerekiyor.",
"retryAttempts": "Tekrar Deneme Girişimleri", "retryAttempts": "Tekrar Deneme Girişimleri",
"expectedResponseCodes": "Beklenen Yanıt Kodları", "expectedResponseCodes": "Beklenen Yanıt Kodları",
"expectedResponseCodesDescription": "Sağlıklı durumu gösteren HTTP durum kodu. Boş bırakılırsa, 200-300 arası sağlıklı kabul edilir.", "expectedResponseCodesDescription": "Sağlıklı durumu gösteren HTTP durum kodu. Boş bırakılırsa, 200-300 arası sağlıklı kabul edilir.",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "Hiçbir dahili kaynak bulunamadı.", "resourcesTableNoInternalResourcesFound": "Hiçbir dahili kaynak bulunamadı.",
"resourcesTableDestination": "Hedef", "resourcesTableDestination": "Hedef",
"resourcesTableAlias": "Takma Ad", "resourcesTableAlias": "Takma Ad",
"resourcesTableAliasAddress": "Alias Adresi",
"resourcesTableAliasAddressInfo": "Bu adres, kuruluşun yardımcı ağ alt bantının bir parçasıdır. Alias kayıtlarını çözümlemek için dahili DNS çözümlemesi kullanılır.",
"resourcesTableClients": "İstemciler", "resourcesTableClients": "İstemciler",
"resourcesTableAndOnlyAccessibleInternally": "veyalnızca bir istemci ile bağlandığında dahili olarak erişilebilir.", "resourcesTableAndOnlyAccessibleInternally": "veyalnızca bir istemci ile bağlandığında dahili olarak erişilebilir.",
"resourcesTableNoTargets": "Hedef yok", "resourcesTableNoTargets": "Hedef yok",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "Devam etmek için kimlik sağlayıcınızı seçin", "orgAuthChooseIdpDescription": "Devam etmek için kimlik sağlayıcınızı seçin",
"orgAuthNoIdpConfigured": "Bu kuruluşta yapılandırılmış kimlik sağlayıcı yok. Bunun yerine Pangolin kimliğinizle giriş yapabilirsiniz.", "orgAuthNoIdpConfigured": "Bu kuruluşta yapılandırılmış kimlik sağlayıcı yok. Bunun yerine Pangolin kimliğinizle giriş yapabilirsiniz.",
"orgAuthSignInWithPangolin": "Pangolin ile Giriş Yap", "orgAuthSignInWithPangolin": "Pangolin ile Giriş Yap",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "Bir kuruluşa giriş yapın",
"orgAuthSelectOrgTitle": "Kuruluş Giriş", "orgAuthSelectOrgTitle": "Kuruluş Giriş",
"orgAuthSelectOrgDescription": "Devam etmek için kuruluş kimliğinizi girin", "orgAuthSelectOrgDescription": "Devam etmek için kuruluş kimliğinizi girin",
"orgAuthOrgIdPlaceholder": "kuruluşunuz", "orgAuthOrgIdPlaceholder": "kuruluşunuz",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "Standart girişe geri dön", "orgAuthBackToSignIn": "Standart girişe geri dön",
"orgAuthNoAccount": "Hesabınız yok mu?", "orgAuthNoAccount": "Hesabınız yok mu?",
"subscriptionRequiredToUse": "Bu özelliği kullanmak için abonelik gerekmektedir.", "subscriptionRequiredToUse": "Bu özelliği kullanmak için abonelik gerekmektedir.",
"mustUpgradeToUse": "Bu özelliği kullanmak için aboneliğinizi yükseltmelisiniz.",
"subscriptionRequiredTierToUse": "Bu özellik <tierLink>{tier}</tierLink> veya daha üstünü gerektirir.",
"upgradeToTierToUse": "Bu özelliği kullanmak için <tierLink>{tier}</tierLink> veya daha üst bir seviyeye yükseltin.",
"subscriptionTierTier1": "Ana Sayfa",
"subscriptionTierTier2": "Takım",
"subscriptionTierTier3": "İşletme",
"subscriptionTierEnterprise": "Kurumsal",
"idpDisabled": "Kimlik sağlayıcılar devre dışı bırakılmıştır.", "idpDisabled": "Kimlik sağlayıcılar devre dışı bırakılmıştır.",
"orgAuthPageDisabled": "Kuruluş kimlik doğrulama sayfası devre dışı bırakılmıştır.", "orgAuthPageDisabled": "Kuruluş kimlik doğrulama sayfası devre dışı bırakılmıştır.",
"domainRestartedDescription": "Alan doğrulaması başarıyla yeniden başlatıldı", "domainRestartedDescription": "Alan doğrulaması başarıyla yeniden başlatıldı",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "Bir lisans alın",
"description": "Bir plan seçin ve Pangolin'i nasıl kullanmayı planladığınızı anlatın.",
"chooseTier": "Planınızı seçin",
"viewPricingLink": "Fiyatları, özellikleri ve limitleri görüntüleyin",
"tiers": {
"starter": {
"title": "Başlangıç",
"description": "Kurumsal özellikler, 25 kullanıcı, 25 site ve topluluk desteği."
},
"scale": {
"title": "Ölçek",
"description": "Kurumsal özellikler, 50 kullanıcı, 50 site ve öncelikli destek."
}
},
"personalUseOnly": "Yalnızca kişisel kullanım (ücretsiz lisans — ödeme yapılmaz)",
"buttons": {
"continueToCheckout": "Ödemeye Devam Et"
},
"toasts": {
"checkoutError": {
"title": "Ödeme Hatası",
"description": "Ödeme işlemi başlatılamadı. Lütfen tekrar deneyin."
}
}
},
"priority": "Öncelik", "priority": "Öncelik",
"priorityDescription": "Daha yüksek öncelikli rotalar önce değerlendirilir. Öncelik = 100, otomatik sıralama anlamına gelir (sistem karar verir). Manuel öncelik uygulamak için başka bir numara kullanın.", "priorityDescription": "Daha yüksek öncelikli rotalar önce değerlendirilir. Öncelik = 100, otomatik sıralama anlamına gelir (sistem karar verir). Manuel öncelik uygulamak için başka bir numara kullanın.",
"instanceName": "Örnek İsmi", "instanceName": "Örnek İsmi",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "Bir sonraki yılın sonu", "logRetentionEndOfFollowingYear": "Bir sonraki yılın sonu",
"actionLogsDescription": "Bu organizasyondaki eylemler geçmişini görüntüleyin", "actionLogsDescription": "Bu organizasyondaki eylemler geçmişini görüntüleyin",
"accessLogsDescription": "Bu organizasyondaki kaynaklar için erişim kimlik doğrulama isteklerini görüntüleyin", "accessLogsDescription": "Bu organizasyondaki kaynaklar için erişim kimlik doğrulama isteklerini görüntüleyin",
"licenseRequiredToUse": "Bu özelliği kullanmak için bir kurumsal lisans gereklidir.", "licenseRequiredToUse": "Bu özelliği kullanmak için bir <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> lisansı gereklidir. Bu özellik ayrıca <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>'da da mevcuttur.",
"ossEnterpriseEditionRequired": "Bu özelliği kullanmak için <enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> gereklidir. Bu özellik ayrıca <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink>'da da mevcuttur.",
"certResolver": "Sertifika Çözücü", "certResolver": "Sertifika Çözücü",
"certResolverDescription": "Bu kaynak için kullanılacak sertifika çözücüsünü seçin.", "certResolverDescription": "Bu kaynak için kullanılacak sertifika çözücüsünü seçin.",
"selectCertResolver": "Sertifika Çözücü Seçin", "selectCertResolver": "Sertifika Çözücü Seçin",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "Kod 9 karakter olmalı (ör. A1AJ-N5JD)", "deviceCodeInvalidFormat": "Kod 9 karakter olmalı (ör. A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "Geçersiz veya süresi dolmuş kod", "deviceCodeInvalidOrExpired": "Geçersiz veya süresi dolmuş kod",
"deviceCodeVerifyFailed": "Cihaz kodu doğrulanamadı", "deviceCodeVerifyFailed": "Cihaz kodu doğrulanamadı",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "Cihaz kodu doğrulanıyor...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "Cihaz yetkilendirme doğrulanıyor...",
"signedInAs": "Olarak giriş yapıldı", "signedInAs": "Olarak giriş yapıldı",
"deviceCodeEnterPrompt": "Cihazda gösterilen kodu girin", "deviceCodeEnterPrompt": "Cihazda gösterilen kodu girin",
"continue": "Devam Et", "continue": "Devam Et",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "Hesabınızın erişim hakkına sahip olduğu tüm organizasyonlara erişim", "deviceOrganizationsAccess": "Hesabınızın erişim hakkına sahip olduğu tüm organizasyonlara erişim",
"deviceAuthorize": "{uygulamaAdi} yetkilendir", "deviceAuthorize": "{uygulamaAdi} yetkilendir",
"deviceConnected": "Cihaz Bağlandı!", "deviceConnected": "Cihaz Bağlandı!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "Cihaz hesabınıza erişim yetkisine sahiptir. Lütfen istemci uygulamasına geri dönün.",
"pangolinCloud": "Pangolin Cloud", "pangolinCloud": "Pangolin Cloud",
"viewDevices": "Cihazları Görüntüle", "viewDevices": "Cihazları Görüntüle",
"viewDevicesDescription": "Bağlantılı cihazlarınızı yönetin", "viewDevicesDescription": "Bağlantılı cihazlarınızı yönetin",
@@ -2343,7 +2421,7 @@
"identifier": "Tanımlayıcı", "identifier": "Tanımlayıcı",
"deviceLoginUseDifferentAccount": "Siz değil misiniz? Farklı bir hesap kullanın.", "deviceLoginUseDifferentAccount": "Siz değil misiniz? Farklı bir hesap kullanın.",
"deviceLoginDeviceRequestingAccessToAccount": "Bir cihaz bu hesaba erişim talep ediyor.", "deviceLoginDeviceRequestingAccessToAccount": "Bir cihaz bu hesaba erişim talep ediyor.",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "Devam etmek için bir kimlik doğrulama yöntemi seçin.",
"noData": "Veri Yok", "noData": "Veri Yok",
"machineClients": "Makine İstemcileri", "machineClients": "Makine İstemcileri",
"install": "Yükle", "install": "Yükle",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "Şu anda teknik zorluklar yaşıyoruz. Lütfen yakında tekrar kontrol edin.", "maintenanceScreenMessage": "Şu anda teknik zorluklar yaşıyoruz. Lütfen yakında tekrar kontrol edin.",
"maintenanceScreenEstimatedCompletion": "Tahmini Tamamlama:", "maintenanceScreenEstimatedCompletion": "Tahmini Tamamlama:",
"createInternalResourceDialogDestinationRequired": "Hedef gereklidir", "createInternalResourceDialogDestinationRequired": "Hedef gereklidir",
"available": "Available", "available": "Mevcut",
"archived": "Archived", "archived": "Arşivlenmiş",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "Arşivlenmiş cihaz bulunamadı",
"deviceArchived": "Device archived", "deviceArchived": "Cihaz arşivlendi",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "Cihaz başarıyla arşivlendi.",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "Cihaz arşivleme hatası",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "Cihaz arşivlenemedi",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "Bu cihazı arşivlemek istediğinizden emin misiniz?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "Cihaz arşivlenecek ve aktif cihazlar listenizden kaldırılacak.",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "Cihaz Arşivle",
"archiveDevice": "Archive Device", "archiveDevice": "Cihaz Arşivle",
"archive": "Archive", "archive": "Arşivle",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "Cihaz arşivden çıkarıldı",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "Cihaz başarıyla arşivden çıkarıldı.",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "Cihaz arşivden çıkartılamadı",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "Cihaz arşivden çıkarılamadı",
"unarchive": "Unarchive", "unarchive": "Arşivden Çıkart",
"archiveClient": "Archive Client", "archiveClient": "İstemci Arşivle",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "Bu istemciyi arşivlemek istediğinizden emin misiniz?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "İstemci arşivlenecek ve aktif istemciler listenizden çıkarılacak.",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "İstemci Arşivle",
"blockClient": "Block Client", "blockClient": "İstemci Engelle",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "Bu istemciyi engellemek istediğinizden emin misiniz?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "Cihaz şu anda bağlıysa bağlantısı kesilecek. Cihazı daha sonra engelini kaldırabilirsiniz.",
"blockClientConfirm": "Block Client", "blockClientConfirm": "İstemci Engelle",
"active": "Active", "active": "Aktif",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "Kullanıcı adı veya E-posta",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "Kuruluşunuzu seçin",
"signInTo": "Log in in to", "signInTo": "Giriş yapın",
"signInWithPassword": "Continue with Password", "signInWithPassword": "Şifre ile Devam Et",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "Bu kuruluş için kullanılabilir kimlik doğrulama yöntemleri yok.",
"enterPassword": "Enter your password", "enterPassword": "Şifrenizi girin",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "Authenticator uygulamanızdan kodu girin",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "Giriş yapmak için güvenlik anahtarınızı kullanın.",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "Farklı bir hesap kullanmanız mı gerekiyor?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "Aşağıdaki butonlara tıklayarak, <termsOfService>Hizmet Şartları</termsOfService> ve <privacyPolicy>Gizlilik Politikası</privacyPolicy> metinlerini okuduğunuzu ve anladığınızı kabul etmektesiniz.",
"termsOfService": "Terms of Service", "termsOfService": "Hizmet Şartları",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "Gizlilik Politikası",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "Bu kullanıcı adıyla eşleşen kullanıcı bulunamadı.",
"verify": "Verify", "verify": "Doğrula",
"signIn": "Sign In", "signIn": "Giriş Yap",
"forgotPassword": "Forgot password?", "forgotPassword": "Şifreni mi unuttun?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "Daha önce giriş yaptıysanız, yukarıda kullanıcı adınızı veya e-posta adresinizi girerek kuruluşunuzun kimlik sağlayıcısıyla kimlik doğrulaması yapabilirsiniz. Daha kolay!",
"continueAnyway": "Continue anyway", "continueAnyway": "Yine de devam et",
"dontShowAgain": "Don't show again", "dontShowAgain": "Tekrar gösterme",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "Biliyor muydunuz?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "Giriş yapmaya mı çalışıyorsunuz?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "Kuruluşunuzun kimlik sağlayıcısı aracılığıyla giriş yapmaya mı çalışıyorsunuz?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "Bunun yerine kuruluşunuzla giriş yapın veya kaydolun",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "Farklı Bir Hesap Kullan",
"logIn": "Log In", "logIn": "Giriş Yap",
"deviceInformation": "Device Information", "deviceInformation": "Cihaz Bilgisi",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "Cihaz ve temsilci hakkında bilgi",
"deviceSecurity": "Cihaz Güvenliği",
"deviceSecurityDescription": "Cihaz güvenliği durumu bilgisi",
"platform": "Platform", "platform": "Platform",
"macosVersion": "macOS Version", "macosVersion": "macOS Sürümü",
"windowsVersion": "Windows Version", "windowsVersion": "Windows Sürümü",
"iosVersion": "iOS Version", "iosVersion": "iOS Sürümü",
"androidVersion": "Android Version", "androidVersion": "Android Sürümü",
"osVersion": "OS Version", "osVersion": "İşletim Sistemi Sürümü",
"kernelVersion": "Kernel Version", "kernelVersion": "Çekirdek Sürümü",
"deviceModel": "Device Model", "deviceModel": "Cihaz Modeli",
"serialNumber": "Serial Number", "serialNumber": "Seri Numarası",
"hostname": "Hostname", "hostname": "Ana Makine Adı",
"firstSeen": "First Seen", "firstSeen": "İlk Görüldü",
"lastSeen": "Last Seen", "lastSeen": "Son Görüldü",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "Biyometri Etkin",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "Disk Şifrelenmiş",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "Güvenlik Duvarı Etkin",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "Otomatik Güncellemeler Etkin",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM Mevcut",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "Antivirüs Etkinleştirildi",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "Sistem Bütünlüğü Koruması (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "Güvenlik Duvarı Gizlilik Modu",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "AppArmor",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "Cihaz bilgilerini ve ayarlarını görüntüleyin",
"devicePendingApprovalDescription": "Bu cihaz onay bekliyor",
"deviceBlockedDescription": "Bu cihaz şu anda engellidir. Engeli kaldırılmadığı sürece hiçbir kaynağa bağlanamayacaktır.",
"unblockClient": "İstemci Engeli Kaldır",
"unblockClientDescription": "Cihazın engeli kaldırıldı",
"unarchiveClient": "İstemci Arşivini Kaldır",
"unarchiveClientDescription": "Cihaz arşivden çıkarıldı",
"block": "Engelle",
"unblock": "Engelini Kaldır",
"deviceActions": "Cihaz İşlemleri",
"deviceActionsDescription": "Cihaz durumu ve erişimini yönetin",
"devicePendingApprovalBannerDescription": "Bu cihaz onay bekliyor. Onaylanana kadar kaynaklara bağlanamayacak.",
"connected": "Bağlandı",
"disconnected": "Bağlantı Kesildi",
"approvalsEmptyStateTitle": "Cihaz Onayları Etkin Değil",
"approvalsEmptyStateDescription": "Kullanıcıların yeni cihazlara bağlanabilmeleri için yönetici onayı gerektiren rol cihaz onaylarını etkinleştirin.",
"approvalsEmptyStateStep1Title": "Rollere Git",
"approvalsEmptyStateStep1Description": "Cihaz onaylarını yapılandırmak için kuruluşunuzun rol ayarlarına gidin.",
"approvalsEmptyStateStep2Title": "Cihaz Onaylarını Etkinleştir",
"approvalsEmptyStateStep2Description": "Bir rolü düzenleyin ve 'Cihaz Onaylarını Gerektir' seçeneğini etkinleştirin. Bu role sahip kullanıcıların yeni cihazlar için yönetici onayına ihtiyacı olacaktır.",
"approvalsEmptyStatePreviewDescription": "Önizleme: Etkinleştirildiğinde, bekleyen cihaz talepleri incelenmek üzere burada görünecektir.",
"approvalsEmptyStateButtonText": "Rolleri Yönet"
} }
+235 -134
View File
@@ -18,6 +18,8 @@
"componentsMember": "您属于{count, plural, =0 {没有组织} one {一个组织} other {# 个组织}}。", "componentsMember": "您属于{count, plural, =0 {没有组织} one {一个组织} other {# 个组织}}。",
"componentsInvalidKey": "检测到无效或过期的许可证密钥。按照许可证条款操作以继续使用所有功能。", "componentsInvalidKey": "检测到无效或过期的许可证密钥。按照许可证条款操作以继续使用所有功能。",
"dismiss": "忽略", "dismiss": "忽略",
"subscriptionViolationMessage": "您的当前计划超出了您的限制。通过移除站点、用户或其他资源以保持在您的计划范围内来纠正问题。",
"subscriptionViolationViewBilling": "查看计费",
"componentsLicenseViolation": "许可证超限:该服务器使用了 {usedSites} 个站点,已超过授权的 {maxSites} 个。请遵守许可证条款以继续使用全部功能。", "componentsLicenseViolation": "许可证超限:该服务器使用了 {usedSites} 个站点,已超过授权的 {maxSites} 个。请遵守许可证条款以继续使用全部功能。",
"componentsSupporterMessage": "感谢您的支持!您现在是 Pangolin 的 {tier} 用户。", "componentsSupporterMessage": "感谢您的支持!您现在是 Pangolin 的 {tier} 用户。",
"inviteErrorNotValid": "很抱歉,但看起来你试图访问的邀请尚未被接受或不再有效。", "inviteErrorNotValid": "很抱歉,但看起来你试图访问的邀请尚未被接受或不再有效。",
@@ -56,6 +58,9 @@
"sitesBannerTitle": "连接任何网络", "sitesBannerTitle": "连接任何网络",
"sitesBannerDescription": "站点是连接到远程网络的链接,允许Pangolin为用户提供资源访问,无论是公共还是私人。可以在任何可以运行二进制文件或容器的地方安装站点网络连接器(Newt)以建立连接。", "sitesBannerDescription": "站点是连接到远程网络的链接,允许Pangolin为用户提供资源访问,无论是公共还是私人。可以在任何可以运行二进制文件或容器的地方安装站点网络连接器(Newt)以建立连接。",
"sitesBannerButtonText": "安装站点", "sitesBannerButtonText": "安装站点",
"approvalsBannerTitle": "批准或拒绝设备访问",
"approvalsBannerDescription": "审核、批准或拒绝用户的设备访问请求。 当需要设备批准时,用户必须先获得管理员批准,然后他们的设备才能连接到您的组织资源。",
"approvalsBannerButtonText": "了解更多",
"siteCreate": "创建站点", "siteCreate": "创建站点",
"siteCreateDescription2": "按照下面的步骤创建和连接一个新站点", "siteCreateDescription2": "按照下面的步骤创建和连接一个新站点",
"siteCreateDescription": "创建一个新站点开始连接资源", "siteCreateDescription": "创建一个新站点开始连接资源",
@@ -257,8 +262,8 @@
"accessRolesSearch": "搜索角色...", "accessRolesSearch": "搜索角色...",
"accessRolesAdd": "添加角色", "accessRolesAdd": "添加角色",
"accessRoleDelete": "删除角色", "accessRoleDelete": "删除角色",
"accessApprovalsManage": "Manage Approvals", "accessApprovalsManage": "管理批准",
"accessApprovalsDescription": "Manage approval requests in the organization", "accessApprovalsDescription": "查看和管理待审批的组织访问权限",
"description": "描述", "description": "描述",
"inviteTitle": "打开邀请", "inviteTitle": "打开邀请",
"inviteDescription": "管理其他用户加入机构的邀请", "inviteDescription": "管理其他用户加入机构的邀请",
@@ -452,18 +457,18 @@
"selectDuration": "选择持续时间", "selectDuration": "选择持续时间",
"selectResource": "选择资源", "selectResource": "选择资源",
"filterByResource": "按资源过滤", "filterByResource": "按资源过滤",
"selectApprovalState": "Select Approval State", "selectApprovalState": "选择审批状态",
"filterByApprovalState": "Filter By Approval State", "filterByApprovalState": "按批准状态过滤",
"approvalListEmpty": "No approvals", "approvalListEmpty": "无批准",
"approvalState": "Approval State", "approvalState": "审批状态",
"approve": "Approve", "approve": "批准",
"approved": "Approved", "approved": "已批准",
"denied": "Denied", "denied": "被拒绝",
"deniedApproval": "Denied Approval", "deniedApproval": "拒绝批准",
"all": "All", "all": "所有",
"deny": "Deny", "deny": "拒绝",
"viewDetails": "View Details", "viewDetails": "查看详情",
"requestingNewDeviceApproval": "requested a new device", "requestingNewDeviceApproval": "请求了一个新设备",
"resetFilters": "重置过滤器", "resetFilters": "重置过滤器",
"totalBlocked": "被Pangolin阻止的请求", "totalBlocked": "被Pangolin阻止的请求",
"totalRequests": "总请求", "totalRequests": "总请求",
@@ -743,28 +748,28 @@
"countries": "国家", "countries": "国家",
"accessRoleCreate": "创建角色", "accessRoleCreate": "创建角色",
"accessRoleCreateDescription": "创建一个新角色来分组用户并管理他们的权限。", "accessRoleCreateDescription": "创建一个新角色来分组用户并管理他们的权限。",
"accessRoleEdit": "Edit Role", "accessRoleEdit": "编辑角色",
"accessRoleEditDescription": "Edit role information.", "accessRoleEditDescription": "编辑角色信息。",
"accessRoleCreateSubmit": "创建角色", "accessRoleCreateSubmit": "创建角色",
"accessRoleCreated": "角色已创建", "accessRoleCreated": "角色已创建",
"accessRoleCreatedDescription": "角色已成功创建。", "accessRoleCreatedDescription": "角色已成功创建。",
"accessRoleErrorCreate": "创建角色失败", "accessRoleErrorCreate": "创建角色失败",
"accessRoleErrorCreateDescription": "创建角色时出错。", "accessRoleErrorCreateDescription": "创建角色时出错。",
"accessRoleUpdateSubmit": "Update Role", "accessRoleUpdateSubmit": "更新角色",
"accessRoleUpdated": "Role updated", "accessRoleUpdated": "角色已更新",
"accessRoleUpdatedDescription": "The role has been successfully updated.", "accessRoleUpdatedDescription": "角色已成功更新。",
"accessApprovalUpdated": "Approval processed", "accessApprovalUpdated": "审批已处理",
"accessApprovalApprovedDescription": "Set Approval Request decision to approved.", "accessApprovalApprovedDescription": "将审批请求决定设置为已批准。",
"accessApprovalDeniedDescription": "Set Approval Request decision to denied.", "accessApprovalDeniedDescription": "设置审批请求决定被拒绝。",
"accessRoleErrorUpdate": "Failed to update role", "accessRoleErrorUpdate": "更新角色失败",
"accessRoleErrorUpdateDescription": "An error occurred while updating the role.", "accessRoleErrorUpdateDescription": "更新角色时出错。",
"accessApprovalErrorUpdate": "Failed to process approval", "accessApprovalErrorUpdate": "处理审核失败",
"accessApprovalErrorUpdateDescription": "An error occurred while processing the approval.", "accessApprovalErrorUpdateDescription": "处理批准时出错。",
"accessRoleErrorNewRequired": "需要新角色", "accessRoleErrorNewRequired": "需要新角色",
"accessRoleErrorRemove": "删除角色失败", "accessRoleErrorRemove": "删除角色失败",
"accessRoleErrorRemoveDescription": "删除角色时出错。", "accessRoleErrorRemoveDescription": "删除角色时出错。",
"accessRoleName": "角色名称", "accessRoleName": "角色名称",
"accessRoleQuestionRemove": "You're about to delete the `{name}` role. You cannot undo this action.", "accessRoleQuestionRemove": "您即将删除 `{name}` 角色。此操作无法撤销。",
"accessRoleRemove": "删除角色", "accessRoleRemove": "删除角色",
"accessRoleRemoveDescription": "从组织中删除角色", "accessRoleRemoveDescription": "从组织中删除角色",
"accessRoleRemoveSubmit": "删除角色", "accessRoleRemoveSubmit": "删除角色",
@@ -786,6 +791,9 @@
"sitestCountIncrease": "增加站点数量", "sitestCountIncrease": "增加站点数量",
"idpManage": "管理身份提供商", "idpManage": "管理身份提供商",
"idpManageDescription": "查看和管理系统中的身份提供商", "idpManageDescription": "查看和管理系统中的身份提供商",
"idpGlobalModeBanner": "此服务器上禁用了每个组织的身份提供商(Idps)。 它正在使用全局IdP(所有组织共享)。在 <adminPanelLink>管理面板</adminPanelLink>中管理全局IdP。 要启用每个组织的 IdP,请编辑服务器配置并将 IdP 模式设置为 org。 <configDocsLink>请参阅文档</configDocsLink>。 如果您想要继续使用全局IdP并使其从组织设置中消失,请在配置中将模式设置为全局模式。",
"idpGlobalModeBannerUpgradeRequired": "此服务器上禁用了每个组织的身份提供商(Idps)。它正在使用全局身份提供商(所有组织共享)。 在 <adminPanelLink>管理面板</adminPanelLink>管理全局身份。要使用每个组织的身份提供者,您必须升级到企业版本。",
"idpGlobalModeBannerLicenseRequired": "此服务器上禁用了每个组织的身份提供商(Idps)。它正在使用全局身份提供商(所有组织共享)。 在 <adminPanelLink>管理面板</adminPanelLink>管理全局身份。要使用每个组织的身份提供者,需要企业许可证。",
"idpDeletedDescription": "身份提供商删除成功", "idpDeletedDescription": "身份提供商删除成功",
"idpOidc": "OAuth2/OIDC", "idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "您确定要永久删除身份提供者吗?", "idpQuestionRemove": "您确定要永久删除身份提供者吗?",
@@ -900,7 +908,7 @@
"inviteAlready": "看起来您已被邀请!", "inviteAlready": "看起来您已被邀请!",
"inviteAlreadyDescription": "要接受邀请,您必须登录或创建一个帐户。", "inviteAlreadyDescription": "要接受邀请,您必须登录或创建一个帐户。",
"signupQuestion": "已经有一个帐户?", "signupQuestion": "已经有一个帐户?",
"login": "Log In", "login": "登录",
"resourceNotFound": "找不到资源", "resourceNotFound": "找不到资源",
"resourceNotFoundDescription": "您要访问的资源不存在。", "resourceNotFoundDescription": "您要访问的资源不存在。",
"pincodeRequirementsLength": "PIN码必须是6位数字", "pincodeRequirementsLength": "PIN码必须是6位数字",
@@ -980,13 +988,13 @@
"passwordExpiryDescription": "该机构要求您每 {maxDays} 天更改一次密码。", "passwordExpiryDescription": "该机构要求您每 {maxDays} 天更改一次密码。",
"changePasswordNow": "现在更改密码", "changePasswordNow": "现在更改密码",
"pincodeAuth": "验证器代码", "pincodeAuth": "验证器代码",
"pincodeSubmit2": "Submit code", "pincodeSubmit2": "提交代码",
"passwordResetSubmit": "请求重置", "passwordResetSubmit": "请求重置",
"passwordResetAlreadyHaveCode": "输入代码", "passwordResetAlreadyHaveCode": "输入代码",
"passwordResetSmtpRequired": "请联系您的管理员", "passwordResetSmtpRequired": "请联系您的管理员",
"passwordResetSmtpRequiredDescription": "需要密码重置密码。请联系您的管理员寻求帮助。", "passwordResetSmtpRequiredDescription": "需要密码重置密码。请联系您的管理员寻求帮助。",
"passwordBack": "回到密码", "passwordBack": "回到密码",
"loginBack": "Go back to main login page", "loginBack": "返回主登录页面",
"signup": "注册", "signup": "注册",
"loginStart": "登录以开始", "loginStart": "登录以开始",
"idpOidcTokenValidating": "正在验证 OIDC 令牌", "idpOidcTokenValidating": "正在验证 OIDC 令牌",
@@ -1144,10 +1152,10 @@
"actionUpdateIdpOrg": "更新 IDP组织", "actionUpdateIdpOrg": "更新 IDP组织",
"actionCreateClient": "创建客户端", "actionCreateClient": "创建客户端",
"actionDeleteClient": "删除客户端", "actionDeleteClient": "删除客户端",
"actionArchiveClient": "Archive Client", "actionArchiveClient": "归档客户端",
"actionUnarchiveClient": "Unarchive Client", "actionUnarchiveClient": "取消归档客户端",
"actionBlockClient": "Block Client", "actionBlockClient": "屏蔽客户端",
"actionUnblockClient": "Unblock Client", "actionUnblockClient": "解除屏蔽客户端",
"actionUpdateClient": "更新客户端", "actionUpdateClient": "更新客户端",
"actionListClients": "列出客户端", "actionListClients": "列出客户端",
"actionGetClient": "获取客户端", "actionGetClient": "获取客户端",
@@ -1164,14 +1172,14 @@
"searchProgress": "搜索中...", "searchProgress": "搜索中...",
"create": "创建", "create": "创建",
"orgs": "组织", "orgs": "组织",
"loginError": "An unexpected error occurred. Please try again.", "loginError": "发生意外错误。请重试。",
"loginRequiredForDevice": "Login is required for your device.", "loginRequiredForDevice": "您的设备需要登录。",
"passwordForgot": "忘记密码?", "passwordForgot": "忘记密码?",
"otpAuth": "两步验证", "otpAuth": "两步验证",
"otpAuthDescription": "从您的身份验证程序中输入代码或您的单次备份代码。", "otpAuthDescription": "从您的身份验证程序中输入代码或您的单次备份代码。",
"otpAuthSubmit": "提交代码", "otpAuthSubmit": "提交代码",
"idpContinue": "或者继续", "idpContinue": "或者继续",
"otpAuthBack": "Back to Password", "otpAuthBack": "回到密码",
"navbar": "导航菜单", "navbar": "导航菜单",
"navbarDescription": "应用程序的主导航菜单", "navbarDescription": "应用程序的主导航菜单",
"navbarDocsLink": "文件", "navbarDocsLink": "文件",
@@ -1219,7 +1227,7 @@
"sidebarOverview": "概览", "sidebarOverview": "概览",
"sidebarHome": "首页", "sidebarHome": "首页",
"sidebarSites": "站点", "sidebarSites": "站点",
"sidebarApprovals": "Approval Requests", "sidebarApprovals": "审批请求",
"sidebarResources": "资源", "sidebarResources": "资源",
"sidebarProxyResources": "公开的", "sidebarProxyResources": "公开的",
"sidebarClientResources": "非公开的", "sidebarClientResources": "非公开的",
@@ -1236,7 +1244,7 @@
"sidebarIdentityProviders": "身份提供商", "sidebarIdentityProviders": "身份提供商",
"sidebarLicense": "证书", "sidebarLicense": "证书",
"sidebarClients": "客户端", "sidebarClients": "客户端",
"sidebarUserDevices": "User Devices", "sidebarUserDevices": "用户设备",
"sidebarMachineClients": "机", "sidebarMachineClients": "机",
"sidebarDomains": "域", "sidebarDomains": "域",
"sidebarGeneral": "管理", "sidebarGeneral": "管理",
@@ -1308,7 +1316,7 @@
"setupErrorCreateAdmin": "创建服务器管理员账户时发生错误。", "setupErrorCreateAdmin": "创建服务器管理员账户时发生错误。",
"certificateStatus": "证书状态", "certificateStatus": "证书状态",
"loading": "加载中", "loading": "加载中",
"loadingAnalytics": "Loading Analytics", "loadingAnalytics": "加载分析",
"restart": "重启", "restart": "重启",
"domains": "域", "domains": "域",
"domainsDescription": "创建和管理组织中可用的域", "domainsDescription": "创建和管理组织中可用的域",
@@ -1336,7 +1344,7 @@
"refreshError": "刷新数据失败", "refreshError": "刷新数据失败",
"verified": "已验证", "verified": "已验证",
"pending": "待定", "pending": "待定",
"pendingApproval": "Pending Approval", "pendingApproval": "等待批准",
"sidebarBilling": "计费", "sidebarBilling": "计费",
"billing": "计费", "billing": "计费",
"orgBillingDescription": "管理账单信息和订阅", "orgBillingDescription": "管理账单信息和订阅",
@@ -1401,10 +1409,10 @@
"billingUsageLimitsOverview": "使用限制概览", "billingUsageLimitsOverview": "使用限制概览",
"billingMonitorUsage": "监控您的使用情况以对比已配置的限制。如需提高限制请联系我们 support@pangolin.net。", "billingMonitorUsage": "监控您的使用情况以对比已配置的限制。如需提高限制请联系我们 support@pangolin.net。",
"billingDataUsage": "数据使用情况", "billingDataUsage": "数据使用情况",
"billingOnlineTime": "站点在线时间", "billingSites": "站点",
"billingUsers": "活跃用户", "billingUsers": "用户",
"billingDomains": "活跃域", "billingDomains": "域",
"billingRemoteExitNodes": "活跃自托管节点", "billingRemoteExitNodes": "远程节点",
"billingNoLimitConfigured": "未配置限制", "billingNoLimitConfigured": "未配置限制",
"billingEstimatedPeriod": "估计结算周期", "billingEstimatedPeriod": "估计结算周期",
"billingIncludedUsage": "包含的使用量", "billingIncludedUsage": "包含的使用量",
@@ -1429,10 +1437,18 @@
"billingFailedToGetPortalUrl": "无法获取门户网址", "billingFailedToGetPortalUrl": "无法获取门户网址",
"billingPortalError": "门户错误", "billingPortalError": "门户错误",
"billingDataUsageInfo": "当连接到云端时,您将为通过安全隧道传输的所有数据收取费用。 这包括您所有站点的进出流量。 当您达到上限时,您的站点将断开连接,直到您升级计划或减少使用。使用节点时不收取数据。", "billingDataUsageInfo": "当连接到云端时,您将为通过安全隧道传输的所有数据收取费用。 这包括您所有站点的进出流量。 当您达到上限时,您的站点将断开连接,直到您升级计划或减少使用。使用节点时不收取数据。",
"billingOnlineTimeInfo": "您要根据您的网站连接到云端的时间长短收取费用。 例如,44,640分钟等于一个24/7全月运行的网站。 当您达到上限时,您的站点将断开连接,直到您升级计划或减少使用。使用节点时不收取费用。", "billingSInfo": "您可以使用多少站点",
"billingUsersInfo": "您为组织中的每个用户收取费用。每日计费是根据您组织中活跃用户帐户的数量计算的。", "billingUsersInfo": "您可以使用多少用户",
"billingDomainInfo": "您在组织中的每个域都要收取费用。每日计费是根据您组织中的活动域帐户数计算的。", "billingDomainInfo": "您可以使用多少域",
"billingRemoteExitNodesInfo": "您为组织中的每个管理节点收取费用。计费是每日根据您组织中活跃的管理节点数计算的。", "billingRemoteExitNodesInfo": "您可以使用多少远程节点",
"billingLicenseKeys": "许可证密钥",
"billingLicenseKeysDescription": "管理您的许可证密钥订阅",
"billingLicenseSubscription": "许可订阅",
"billingInactive": "未激活",
"billingLicenseItem": "许可证项目",
"billingQuantity": "数量",
"billingTotal": "总计",
"billingModifyLicenses": "修改许可订阅",
"domainNotFound": "域未找到", "domainNotFound": "域未找到",
"domainNotFoundDescription": "此资源已禁用,因为该域不再在我们的系统中存在。请为此资源设置一个新域。", "domainNotFoundDescription": "此资源已禁用,因为该域不再在我们的系统中存在。请为此资源设置一个新域。",
"failed": "失败", "failed": "失败",
@@ -1453,7 +1469,7 @@
"securityKeyRemoveSuccess": "安全密钥删除成功", "securityKeyRemoveSuccess": "安全密钥删除成功",
"securityKeyRemoveError": "删除安全密钥失败", "securityKeyRemoveError": "删除安全密钥失败",
"securityKeyLoadError": "加载安全密钥失败", "securityKeyLoadError": "加载安全密钥失败",
"securityKeyLogin": "Use Security Key", "securityKeyLogin": "使用安全密钥",
"securityKeyAuthError": "使用安全密钥认证失败", "securityKeyAuthError": "使用安全密钥认证失败",
"securityKeyRecommendation": "考虑在其他设备上注册另一个安全密钥,以确保不会被锁定在您的账户之外。", "securityKeyRecommendation": "考虑在其他设备上注册另一个安全密钥,以确保不会被锁定在您的账户之外。",
"registering": "注册中...", "registering": "注册中...",
@@ -1509,6 +1525,32 @@
"resourcePortRequired": "非 HTTP 资源必须输入端口号", "resourcePortRequired": "非 HTTP 资源必须输入端口号",
"resourcePortNotAllowed": "HTTP 资源不应设置端口号", "resourcePortNotAllowed": "HTTP 资源不应设置端口号",
"billingPricingCalculatorLink": "价格计算器", "billingPricingCalculatorLink": "价格计算器",
"billingYourPlan": "您的计划",
"billingViewOrModifyPlan": "查看或修改您当前的计划",
"billingViewPlanDetails": "查看计划详细信息",
"billingUsageAndLimits": "用法和限制",
"billingViewUsageAndLimits": "查看您的计划限制和当前使用情况",
"billingCurrentUsage": "当前使用情况",
"billingMaximumLimits": "最大限制",
"billingRemoteNodes": "远程节点",
"billingUnlimited": "无限制",
"billingPaidLicenseKeys": "付费许可证密钥",
"billingManageLicenseSubscription": "管理您对付费的自托管许可证密钥的订阅",
"billingCurrentKeys": "当前密钥",
"billingModifyCurrentPlan": "修改当前计划",
"billingConfirmUpgrade": "确认升级",
"billingConfirmDowngrade": "确认降级",
"billingConfirmUpgradeDescription": "您即将升级您的计划。请检查下面的新限额和定价。",
"billingConfirmDowngradeDescription": "您即将降级计划。请检查下面的新限额和定价。",
"billingPlanIncludes": "计划包含",
"billingProcessing": "正在处理...",
"billingConfirmUpgradeButton": "确认升级",
"billingConfirmDowngradeButton": "确认降级",
"billingLimitViolationWarning": "超出新计划限制",
"billingLimitViolationDescription": "您当前的使用量超过了此计划的限制。降级后,所有操作都将被禁用,直到您在新的限制范围内减少使用量。 请查看以下当前超出限制的特性:",
"billingFeatureLossWarning": "功能可用通知",
"billingFeatureLossDescription": "如果降级,新计划中不可用的功能将被自动禁用。一些设置和配置可能会丢失。 请查看定价矩阵以了解哪些功能将不再可用。",
"billingUsageExceedsLimit": "当前使用量 ({current}) 超出限制 ({limit})",
"signUpTerms": { "signUpTerms": {
"IAgreeToThe": "我同意", "IAgreeToThe": "我同意",
"termsOfService": "服务条款", "termsOfService": "服务条款",
@@ -1580,8 +1622,8 @@
"IntervalSeconds": "正常间隔", "IntervalSeconds": "正常间隔",
"timeoutSeconds": "超时(秒)", "timeoutSeconds": "超时(秒)",
"timeIsInSeconds": "时间以秒为单位", "timeIsInSeconds": "时间以秒为单位",
"requireDeviceApproval": "Require Device Approvals", "requireDeviceApproval": "需要设备批准",
"requireDeviceApprovalDescription": "Users with this role need new devices approved by an admin before they can connect and access resources.", "requireDeviceApprovalDescription": "具有此角色的用户需要管理员批准的新设备才能连接和访问资源。",
"retryAttempts": "重试次数", "retryAttempts": "重试次数",
"expectedResponseCodes": "期望响应代码", "expectedResponseCodes": "期望响应代码",
"expectedResponseCodesDescription": "HTTP 状态码表示健康状态。如留空,200-300 被视为健康。", "expectedResponseCodesDescription": "HTTP 状态码表示健康状态。如留空,200-300 被视为健康。",
@@ -1622,6 +1664,8 @@
"resourcesTableNoInternalResourcesFound": "未找到内部资源。", "resourcesTableNoInternalResourcesFound": "未找到内部资源。",
"resourcesTableDestination": "目标", "resourcesTableDestination": "目标",
"resourcesTableAlias": "Alias", "resourcesTableAlias": "Alias",
"resourcesTableAliasAddress": "别名地址",
"resourcesTableAliasAddressInfo": "此地址是组织实用子网的一部分。它用来使用内部DNS解析来解析别名记录。",
"resourcesTableClients": "客户端", "resourcesTableClients": "客户端",
"resourcesTableAndOnlyAccessibleInternally": "且仅在与客户端连接时可内部访问。", "resourcesTableAndOnlyAccessibleInternally": "且仅在与客户端连接时可内部访问。",
"resourcesTableNoTargets": "没有目标", "resourcesTableNoTargets": "没有目标",
@@ -1911,7 +1955,7 @@
"orgAuthChooseIdpDescription": "选择您的身份提供商以继续", "orgAuthChooseIdpDescription": "选择您的身份提供商以继续",
"orgAuthNoIdpConfigured": "此机构没有配置任何身份提供者。您可以使用您的 Pangolin 身份登录。", "orgAuthNoIdpConfigured": "此机构没有配置任何身份提供者。您可以使用您的 Pangolin 身份登录。",
"orgAuthSignInWithPangolin": "使用 Pangolin 登录", "orgAuthSignInWithPangolin": "使用 Pangolin 登录",
"orgAuthSignInToOrg": "Sign in to an organization", "orgAuthSignInToOrg": "登录到组织",
"orgAuthSelectOrgTitle": "组织登录", "orgAuthSelectOrgTitle": "组织登录",
"orgAuthSelectOrgDescription": "输入您的组织ID以继续", "orgAuthSelectOrgDescription": "输入您的组织ID以继续",
"orgAuthOrgIdPlaceholder": "您的组织", "orgAuthOrgIdPlaceholder": "您的组织",
@@ -1921,6 +1965,13 @@
"orgAuthBackToSignIn": "返回标准登录", "orgAuthBackToSignIn": "返回标准登录",
"orgAuthNoAccount": "没有账户?", "orgAuthNoAccount": "没有账户?",
"subscriptionRequiredToUse": "需要订阅才能使用此功能。", "subscriptionRequiredToUse": "需要订阅才能使用此功能。",
"mustUpgradeToUse": "您必须升级您的订阅才能使用此功能。",
"subscriptionRequiredTierToUse": "此功能需要 <tierLink>{tier}</tierLink> 或更高级别。",
"upgradeToTierToUse": "升级到 <tierLink>{tier}</tierLink> 或更高级别以使用此功能。",
"subscriptionTierTier1": "首页",
"subscriptionTierTier2": "团队",
"subscriptionTierTier3": "业务",
"subscriptionTierEnterprise": "企业",
"idpDisabled": "身份提供者已禁用。", "idpDisabled": "身份提供者已禁用。",
"orgAuthPageDisabled": "组织认证页面已禁用。", "orgAuthPageDisabled": "组织认证页面已禁用。",
"domainRestartedDescription": "域验证重新启动成功", "domainRestartedDescription": "域验证重新启动成功",
@@ -2108,6 +2159,32 @@
} }
} }
}, },
"newPricingLicenseForm": {
"title": "获取许可证",
"description": "选择一个计划,告诉我们你计划如何使用 Pangolin。",
"chooseTier": "选择您的计划",
"viewPricingLink": "查看价格、特征和限制",
"tiers": {
"starter": {
"title": "启动器",
"description": "企业特征,25个用户,25个站点和社区支持。"
},
"scale": {
"title": "缩放比例",
"description": "企业特征、50个用户、50个站点和优先支持。"
}
},
"personalUseOnly": "仅供个人使用 (免费许可证-无签出)",
"buttons": {
"continueToCheckout": "继续签出"
},
"toasts": {
"checkoutError": {
"title": "签出错误",
"description": "无法启动结帐。请重试。"
}
}
},
"priority": "优先权", "priority": "优先权",
"priorityDescription": "先评估更高优先级线路。优先级 = 100意味着自动排序(系统决定). 使用另一个数字强制执行手动优先级。", "priorityDescription": "先评估更高优先级线路。优先级 = 100意味着自动排序(系统决定). 使用另一个数字强制执行手动优先级。",
"instanceName": "实例名称", "instanceName": "实例名称",
@@ -2206,7 +2283,8 @@
"logRetentionEndOfFollowingYear": "下一年结束", "logRetentionEndOfFollowingYear": "下一年结束",
"actionLogsDescription": "查看此机构执行的操作历史", "actionLogsDescription": "查看此机构执行的操作历史",
"accessLogsDescription": "查看此机构资源的访问认证请求", "accessLogsDescription": "查看此机构资源的访问认证请求",
"licenseRequiredToUse": "需要企业许可才能使用此功能。", "licenseRequiredToUse": "需要 <enterpriseLicenseLink>Enterprise Edition</enterpriseLicenseLink> 许可才能使用此功能。此功能也可在 <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink> 中使用。",
"ossEnterpriseEditionRequired": "<enterpriseEditionLink>Enterprise Edition</enterpriseEditionLink> 需要使用此功能。此功能也可在 <pangolinCloudLink>Pangolin Cloud</pangolinCloudLink> 中使用。",
"certResolver": "证书解决器", "certResolver": "证书解决器",
"certResolverDescription": "选择用于此资源的证书解析器。", "certResolverDescription": "选择用于此资源的证书解析器。",
"selectCertResolver": "选择证书解析", "selectCertResolver": "选择证书解析",
@@ -2267,8 +2345,8 @@
"deviceCodeInvalidFormat": "代码必须是9个字符(如A1AJ-N5JD)", "deviceCodeInvalidFormat": "代码必须是9个字符(如A1AJ-N5JD)",
"deviceCodeInvalidOrExpired": "无效或过期的代码", "deviceCodeInvalidOrExpired": "无效或过期的代码",
"deviceCodeVerifyFailed": "验证设备代码失败", "deviceCodeVerifyFailed": "验证设备代码失败",
"deviceCodeValidating": "Validating device code...", "deviceCodeValidating": "正在验证设备代码...",
"deviceCodeVerifying": "Verifying device authorization...", "deviceCodeVerifying": "正在验证设备授权...",
"signedInAs": "登录为", "signedInAs": "登录为",
"deviceCodeEnterPrompt": "输入设备上显示的代码", "deviceCodeEnterPrompt": "输入设备上显示的代码",
"continue": "继续", "continue": "继续",
@@ -2281,7 +2359,7 @@
"deviceOrganizationsAccess": "访问您的帐户拥有访问权限的所有组织", "deviceOrganizationsAccess": "访问您的帐户拥有访问权限的所有组织",
"deviceAuthorize": "授权{applicationName}", "deviceAuthorize": "授权{applicationName}",
"deviceConnected": "设备已连接!", "deviceConnected": "设备已连接!",
"deviceAuthorizedMessage": "Device is authorized to access your account. Please return to the client application.", "deviceAuthorizedMessage": "设备被授权访问您的帐户。请返回客户端应用程序。",
"pangolinCloud": "邦戈林云", "pangolinCloud": "邦戈林云",
"viewDevices": "查看设备", "viewDevices": "查看设备",
"viewDevicesDescription": "管理您已连接的设备", "viewDevicesDescription": "管理您已连接的设备",
@@ -2343,7 +2421,7 @@
"identifier": "Identifier", "identifier": "Identifier",
"deviceLoginUseDifferentAccount": "不是你?使用一个不同的帐户。", "deviceLoginUseDifferentAccount": "不是你?使用一个不同的帐户。",
"deviceLoginDeviceRequestingAccessToAccount": "设备正在请求访问此帐户。", "deviceLoginDeviceRequestingAccessToAccount": "设备正在请求访问此帐户。",
"loginSelectAuthenticationMethod": "Select an authentication method to continue.", "loginSelectAuthenticationMethod": "选择要继续的身份验证方法。",
"noData": "无数据", "noData": "无数据",
"machineClients": "机器客户端", "machineClients": "机器客户端",
"install": "安装", "install": "安装",
@@ -2433,81 +2511,104 @@
"maintenanceScreenMessage": "我们目前遇到技术问题。 请稍后再回来查看。", "maintenanceScreenMessage": "我们目前遇到技术问题。 请稍后再回来查看。",
"maintenanceScreenEstimatedCompletion": "预计完成时间:", "maintenanceScreenEstimatedCompletion": "预计完成时间:",
"createInternalResourceDialogDestinationRequired": "需要目标地址", "createInternalResourceDialogDestinationRequired": "需要目标地址",
"available": "Available", "available": "可用",
"archived": "Archived", "archived": "已存档",
"noArchivedDevices": "No archived devices found", "noArchivedDevices": "未找到存档设备",
"deviceArchived": "Device archived", "deviceArchived": "设备已存档",
"deviceArchivedDescription": "The device has been successfully archived.", "deviceArchivedDescription": "设备已成功归档。",
"errorArchivingDevice": "Error archiving device", "errorArchivingDevice": "错误存档设备",
"failedToArchiveDevice": "Failed to archive device", "failedToArchiveDevice": "归档设备失败",
"deviceQuestionArchive": "Are you sure you want to archive this device?", "deviceQuestionArchive": "您确定要存档此设备吗?",
"deviceMessageArchive": "The device will be archived and removed from your active devices list.", "deviceMessageArchive": "设备将被存档并从活动设备列表中删除。",
"deviceArchiveConfirm": "Archive Device", "deviceArchiveConfirm": "归档设备",
"archiveDevice": "Archive Device", "archiveDevice": "归档设备",
"archive": "Archive", "archive": "存档",
"deviceUnarchived": "Device unarchived", "deviceUnarchived": "设备未存档",
"deviceUnarchivedDescription": "The device has been successfully unarchived.", "deviceUnarchivedDescription": "设备已成功解除归档。",
"errorUnarchivingDevice": "Error unarchiving device", "errorUnarchivingDevice": "卸载设备时出错",
"failedToUnarchiveDevice": "Failed to unarchive device", "failedToUnarchiveDevice": "取消归档设备失败",
"unarchive": "Unarchive", "unarchive": "取消存档",
"archiveClient": "Archive Client", "archiveClient": "归档客户端",
"archiveClientQuestion": "Are you sure you want to archive this client?", "archiveClientQuestion": "您确定要存档此客户端吗?",
"archiveClientMessage": "The client will be archived and removed from your active clients list.", "archiveClientMessage": "客户端将被存档并从您活跃的客户端列表中删除。",
"archiveClientConfirm": "Archive Client", "archiveClientConfirm": "归档客户端",
"blockClient": "Block Client", "blockClient": "屏蔽客户端",
"blockClientQuestion": "Are you sure you want to block this client?", "blockClientQuestion": "您确定要屏蔽此客户端?",
"blockClientMessage": "The device will be forced to disconnect if currently connected. You can unblock the device later.", "blockClientMessage": "如果当前连接,设备将被迫断开连接。您可以稍后取消屏蔽设备。",
"blockClientConfirm": "Block Client", "blockClientConfirm": "屏蔽客户端",
"active": "Active", "active": "已启用",
"usernameOrEmail": "Username or Email", "usernameOrEmail": "用户名或电子邮件",
"selectYourOrganization": "Select your organization", "selectYourOrganization": "选择您的组织",
"signInTo": "Log in in to", "signInTo": "登录到",
"signInWithPassword": "Continue with Password", "signInWithPassword": "使用密码继续",
"noAuthMethodsAvailable": "No authentication methods available for this organization.", "noAuthMethodsAvailable": "该组织没有可用的身份验证方法。",
"enterPassword": "Enter your password", "enterPassword": "输入您的密码",
"enterMfaCode": "Enter the code from your authenticator app", "enterMfaCode": "从您的身份验证程序中输入代码",
"securityKeyRequired": "Please use your security key to sign in.", "securityKeyRequired": "请使用您的安全密钥登录。",
"needToUseAnotherAccount": "Need to use a different account?", "needToUseAnotherAccount": "需要使用不同的帐户?",
"loginLegalDisclaimer": "By clicking the buttons below, you acknowledge you have read, understand, and agree to the <termsOfService>Terms of Service</termsOfService> and <privacyPolicy>Privacy Policy</privacyPolicy>.", "loginLegalDisclaimer": "点击下面的按钮,您确认您已经阅读了,理解, 并同意 <termsOfService>服务条款</termsOfService> <privacyPolicy>隐私政策</privacyPolicy>",
"termsOfService": "Terms of Service", "termsOfService": "服务条款",
"privacyPolicy": "Privacy Policy", "privacyPolicy": "隐私政策",
"userNotFoundWithUsername": "No user found with that username.", "userNotFoundWithUsername": "找不到该用户名。",
"verify": "Verify", "verify": "验证",
"signIn": "Sign In", "signIn": "登录",
"forgotPassword": "Forgot password?", "forgotPassword": "忘记密码?",
"orgSignInTip": "If you've logged in before, you can enter your username or email above to authenticate with your organization's identity provider instead. It's easier!", "orgSignInTip": "如果您以前已经登录,您可以在上面输入您的用户名或电子邮件来验证您的组织身份提供者。这很容易!",
"continueAnyway": "Continue anyway", "continueAnyway": "仍然继续",
"dontShowAgain": "Don't show again", "dontShowAgain": "不再显示",
"orgSignInNotice": "Did you know?", "orgSignInNotice": "您知道吗?",
"signupOrgNotice": "Trying to sign in?", "signupOrgNotice": "试图登录?",
"signupOrgTip": "Are you trying to sign in through your organization's identity provider?", "signupOrgTip": "您是否试图通过您的组织的身份提供者登录?",
"signupOrgLink": "Sign in or sign up with your organization instead", "signupOrgLink": "使用您的组织登录或注册",
"verifyEmailLogInWithDifferentAccount": "Use a Different Account", "verifyEmailLogInWithDifferentAccount": "使用不同的帐户",
"logIn": "Log In", "logIn": "登录",
"deviceInformation": "Device Information", "deviceInformation": "设备信息",
"deviceInformationDescription": "Information about the device and agent", "deviceInformationDescription": "关于设备和代理的信息",
"platform": "Platform", "deviceSecurity": "设备安全",
"macosVersion": "macOS Version", "deviceSecurityDescription": "设备安全态势信息",
"windowsVersion": "Windows Version", "platform": "平台",
"iosVersion": "iOS Version", "macosVersion": "macOS 版本",
"androidVersion": "Android Version", "windowsVersion": "Windows 版本",
"osVersion": "OS Version", "iosVersion": "iOS 版本",
"kernelVersion": "Kernel Version", "androidVersion": "Android 版本",
"deviceModel": "Device Model", "osVersion": "操作系统版本",
"serialNumber": "Serial Number", "kernelVersion": "内核版本",
"deviceModel": "设备模型",
"serialNumber": "序列号",
"hostname": "Hostname", "hostname": "Hostname",
"firstSeen": "First Seen", "firstSeen": "第一次查看",
"lastSeen": "Last Seen", "lastSeen": "上次查看时间",
"deviceSettingsDescription": "View device information and settings", "biometricsEnabled": "生物计已启用",
"devicePendingApprovalDescription": "This device is waiting for approval", "diskEncrypted": "磁盘加密",
"deviceBlockedDescription": "This device is currently blocked. It won't be able to connect to any resources unless unblocked.", "firewallEnabled": "防火墙已启用",
"unblockClient": "Unblock Client", "autoUpdatesEnabled": "启用自动更新",
"unblockClientDescription": "The device has been unblocked", "tpmAvailable": "TPM 可用",
"unarchiveClient": "Unarchive Client", "windowsAntivirusEnabled": "抗病毒已启用",
"unarchiveClientDescription": "The device has been unarchived", "macosSipEnabled": "系统完整性保护 (SIP)",
"block": "Block", "macosGatekeeperEnabled": "Gatekeeper",
"unblock": "Unblock", "macosFirewallStealthMode": "防火墙隐形模式",
"deviceActions": "Device Actions", "linuxAppArmorEnabled": "AppArmor",
"deviceActionsDescription": "Manage device status and access", "linuxSELinuxEnabled": "SELinux",
"devicePendingApprovalBannerDescription": "This device is pending approval. It won't be able to connect to resources until approved." "deviceSettingsDescription": "查看设备信息和设置",
"devicePendingApprovalDescription": "此设备正在等待批准",
"deviceBlockedDescription": "此设备目前已被屏蔽。除非解除屏蔽,否则无法连接到任何资源。",
"unblockClient": "解除屏蔽客户端",
"unblockClientDescription": "设备已解除阻止",
"unarchiveClient": "取消归档客户端",
"unarchiveClientDescription": "设备已被取消存档",
"block": "封禁",
"unblock": "取消屏蔽",
"deviceActions": "设备操作",
"deviceActionsDescription": "管理设备状态和访问权限",
"devicePendingApprovalBannerDescription": "此设备正在等待批准。在批准之前,它将无法连接到资源。",
"connected": "已连接",
"disconnected": "断开连接",
"approvalsEmptyStateTitle": "设备批准未启用",
"approvalsEmptyStateDescription": "在用户连接新设备之前,允许设备批准角色,需要管理员批准。",
"approvalsEmptyStateStep1Title": "转到角色",
"approvalsEmptyStateStep1Description": "导航到您组织的角色设置来配置设备批准。",
"approvalsEmptyStateStep2Title": "启用设备批准",
"approvalsEmptyStateStep2Description": "编辑角色并启用“需要设备审批”选项。具有此角色的用户需要管理员批准新设备。",
"approvalsEmptyStatePreviewDescription": "预览:如果启用,待处理设备请求将出现在这里供审核",
"approvalsEmptyStateButtonText": "管理角色"
} }
+2392 -2095
View File
File diff suppressed because it is too large Load Diff
+850 -3048
View File
File diff suppressed because it is too large Load Diff
+24 -29
View File
@@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"description": "Tunneled Reverse Proxy Management Server with Identity and Access Control and Dashboard UI", "description": "Identity-aware VPN and proxy for remote access to anything, anywhere and Dashboard UI",
"homepage": "https://github.com/fosrl/pangolin", "homepage": "https://github.com/fosrl/pangolin",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -12,30 +12,32 @@
"license": "SEE LICENSE IN LICENSE AND README.md", "license": "SEE LICENSE IN LICENSE AND README.md",
"scripts": { "scripts": {
"dev": "NODE_ENV=development ENVIRONMENT=dev tsx watch server/index.ts", "dev": "NODE_ENV=development ENVIRONMENT=dev tsx watch server/index.ts",
"dev:check": "npx tsc --noEmit && npm run format:check",
"dev:setup": "cp config/config.example.yml config/config.yml && npm run set:oss && npm run set:sqlite && npm run db:generate && npm run db:sqlite:push",
"db:pg:generate": "drizzle-kit generate --config=./drizzle.pg.config.ts", "db:pg:generate": "drizzle-kit generate --config=./drizzle.pg.config.ts",
"db:sqlite:generate": "drizzle-kit generate --config=./drizzle.sqlite.config.ts", "db:sqlite:generate": "drizzle-kit generate --config=./drizzle.sqlite.config.ts",
"db:pg:push": "npx tsx server/db/pg/migrate.ts", "db:pg:push": "npx tsx server/db/pg/migrate.ts",
"db:sqlite:push": "npx tsx server/db/sqlite/migrate.ts", "db:sqlite:push": "npx tsx server/db/sqlite/migrate.ts",
"db:sqlite:studio": "drizzle-kit studio --config=./drizzle.sqlite.config.ts",
"db:pg:studio": "drizzle-kit studio --config=./drizzle.pg.config.ts", "db:pg:studio": "drizzle-kit studio --config=./drizzle.pg.config.ts",
"db:sqlite:studio": "drizzle-kit studio --config=./drizzle.sqlite.config.ts",
"db:clear-migrations": "rm -rf server/migrations", "db:clear-migrations": "rm -rf server/migrations",
"set:oss": "echo 'export const build = \"oss\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.oss.json tsconfig.json", "set:oss": "echo 'export const build = \"oss\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.oss.json tsconfig.json",
"set:saas": "echo 'export const build = \"saas\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.saas.json tsconfig.json", "set:saas": "echo 'export const build = \"saas\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.saas.json tsconfig.json",
"set:enterprise": "echo 'export const build = \"enterprise\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.enterprise.json tsconfig.json", "set:enterprise": "echo 'export const build = \"enterprise\" as \"saas\" | \"enterprise\" | \"oss\";' > server/build.ts && cp tsconfig.enterprise.json tsconfig.json",
"set:sqlite": "echo 'export * from \"./sqlite\";\nexport const driver: \"pg\" | \"sqlite\" = \"sqlite\";' > server/db/index.ts", "set:sqlite": "echo 'export * from \"./sqlite\";\nexport const driver: \"pg\" | \"sqlite\" = \"sqlite\";' > server/db/index.ts && cp drizzle.sqlite.config.ts drizzle.config.ts && cp server/setup/migrationsSqlite.ts server/setup/migrations.ts",
"set:pg": "echo 'export * from \"./pg\";\nexport const driver: \"pg\" | \"sqlite\" = \"pg\";' > server/db/index.ts", "set:pg": "echo 'export * from \"./pg\";\nexport const driver: \"pg\" | \"sqlite\" = \"pg\";' > server/db/index.ts && cp drizzle.pg.config.ts drizzle.config.ts && cp server/setup/migrationsPg.ts server/setup/migrations.ts",
"next:build": "next build", "build:next": "next build",
"build:sqlite": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrationsSqlite.ts -o dist/migrations.mjs", "build": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrations.ts -o dist/migrations.mjs",
"build:pg": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrationsPg.ts -o dist/migrations.mjs",
"start": "ENVIRONMENT=prod node dist/migrations.mjs && ENVIRONMENT=prod NODE_ENV=development node --enable-source-maps dist/server.mjs", "start": "ENVIRONMENT=prod node dist/migrations.mjs && ENVIRONMENT=prod NODE_ENV=development node --enable-source-maps dist/server.mjs",
"email": "email dev --dir server/emails/templates --port 3005", "email": "email dev --dir server/emails/templates --port 3005",
"build:cli": "node esbuild.mjs -e cli/index.ts -o dist/cli.mjs", "build:cli": "node esbuild.mjs -e cli/index.ts -o dist/cli.mjs",
"format:check": "prettier --check .",
"format": "prettier --write ." "format": "prettier --write ."
}, },
"dependencies": { "dependencies": {
"@asteasolutions/zod-to-openapi": "8.2.0", "@asteasolutions/zod-to-openapi": "8.4.0",
"@aws-sdk/client-s3": "3.955.0", "@aws-sdk/client-s3": "3.971.0",
"@faker-js/faker": "10.1.0", "@faker-js/faker": "10.2.0",
"@headlessui/react": "2.2.9", "@headlessui/react": "2.2.9",
"@hookform/resolvers": "5.2.2", "@hookform/resolvers": "5.2.2",
"@monaco-editor/react": "4.7.0", "@monaco-editor/react": "4.7.0",
@@ -75,9 +77,7 @@
"class-variance-authority": "0.7.1", "class-variance-authority": "0.7.1",
"clsx": "2.1.1", "clsx": "2.1.1",
"cmdk": "1.1.1", "cmdk": "1.1.1",
"cookie": "1.1.1",
"cookie-parser": "1.4.7", "cookie-parser": "1.4.7",
"cookies": "0.9.1",
"cors": "2.8.5", "cors": "2.8.5",
"crypto-js": "4.2.0", "crypto-js": "4.2.0",
"d3": "7.9.0", "d3": "7.9.0",
@@ -90,9 +90,8 @@
"glob": "13.0.0", "glob": "13.0.0",
"helmet": "8.1.0", "helmet": "8.1.0",
"http-errors": "2.0.1", "http-errors": "2.0.1",
"i": "0.3.7",
"input-otp": "1.4.2", "input-otp": "1.4.2",
"ioredis": "5.8.2", "ioredis": "5.9.2",
"jmespath": "0.16.0", "jmespath": "0.16.0",
"js-yaml": "4.1.1", "js-yaml": "4.1.1",
"jsonwebtoken": "9.0.3", "jsonwebtoken": "9.0.3",
@@ -100,30 +99,26 @@
"maxmind": "5.0.1", "maxmind": "5.0.1",
"moment": "2.30.1", "moment": "2.30.1",
"next": "15.5.9", "next": "15.5.9",
"next-intl": "4.6.1", "next-intl": "4.7.0",
"next-themes": "0.4.6", "next-themes": "0.4.6",
"nextjs-toploader": "3.9.17", "nextjs-toploader": "3.9.17",
"node-cache": "5.1.2", "node-cache": "5.1.2",
"node-fetch": "3.3.2",
"nodemailer": "7.0.11", "nodemailer": "7.0.11",
"npm": "11.7.0",
"nprogress": "0.2.0",
"oslo": "1.2.1", "oslo": "1.2.1",
"pg": "8.16.3", "pg": "8.17.1",
"posthog-node": "5.17.4", "posthog-node": "5.23.0",
"qrcode.react": "4.2.0", "qrcode.react": "4.2.0",
"react": "19.2.3", "react": "19.2.3",
"react-day-picker": "9.13.0", "react-day-picker": "9.13.0",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"react-easy-sort": "1.8.0", "react-easy-sort": "1.8.0",
"react-hook-form": "7.68.0", "react-hook-form": "7.71.1",
"react-icons": "5.5.0", "react-icons": "5.5.0",
"rebuild": "0.1.2",
"recharts": "2.15.4", "recharts": "2.15.4",
"reodotdev": "1.0.0", "reodotdev": "1.0.0",
"resend": "6.6.0", "resend": "6.8.0",
"semver": "7.7.3", "semver": "7.7.3",
"stripe": "20.1.0", "stripe": "20.2.0",
"swagger-ui-express": "5.0.1", "swagger-ui-express": "5.0.1",
"tailwind-merge": "3.4.0", "tailwind-merge": "3.4.0",
"topojson-client": "3.1.0", "topojson-client": "3.1.0",
@@ -133,10 +128,10 @@
"visionscarto-world-atlas": "1.0.0", "visionscarto-world-atlas": "1.0.0",
"winston": "3.19.0", "winston": "3.19.0",
"winston-daily-rotate-file": "5.0.0", "winston-daily-rotate-file": "5.0.0",
"ws": "8.18.3", "ws": "8.19.0",
"yaml": "2.8.2", "yaml": "2.8.2",
"yargs": "18.0.0", "yargs": "18.0.0",
"zod": "4.2.1", "zod": "4.3.5",
"zod-validation-error": "5.0.0" "zod-validation-error": "5.0.0"
}, },
"devDependencies": { "devDependencies": {
@@ -170,12 +165,12 @@
"esbuild": "0.27.2", "esbuild": "0.27.2",
"esbuild-node-externals": "1.20.1", "esbuild-node-externals": "1.20.1",
"postcss": "8.5.6", "postcss": "8.5.6",
"prettier": "3.7.4", "prettier": "3.8.0",
"react-email": "5.0.7", "react-email": "5.2.5",
"tailwindcss": "4.1.18", "tailwindcss": "4.1.18",
"tsc-alias": "1.8.16", "tsc-alias": "1.8.16",
"tsx": "4.21.0", "tsx": "4.21.0",
"typescript": "5.9.3", "typescript": "5.9.3",
"typescript-eslint": "8.49.0" "typescript-eslint": "8.53.1"
} }
} }
+7 -1
View File
@@ -78,6 +78,10 @@ export enum ActionsEnum {
updateSiteResource = "updateSiteResource", updateSiteResource = "updateSiteResource",
createClient = "createClient", createClient = "createClient",
deleteClient = "deleteClient", deleteClient = "deleteClient",
archiveClient = "archiveClient",
unarchiveClient = "unarchiveClient",
blockClient = "blockClient",
unblockClient = "unblockClient",
updateClient = "updateClient", updateClient = "updateClient",
listClients = "listClients", listClients = "listClients",
getClient = "getClient", getClient = "getClient",
@@ -125,7 +129,9 @@ export enum ActionsEnum {
getBlueprint = "getBlueprint", getBlueprint = "getBlueprint",
applyBlueprint = "applyBlueprint", applyBlueprint = "applyBlueprint",
viewLogs = "viewLogs", viewLogs = "viewLogs",
exportLogs = "exportLogs" exportLogs = "exportLogs",
listApprovals = "listApprovals",
updateApprovals = "updateApprovals"
} }
export async function checkUserActionPermission( export async function checkUserActionPermission(
+150
View File
@@ -0,0 +1,150 @@
{
"iPad1,1": "iPad",
"iPad2,1": "iPad 2",
"iPad2,2": "iPad 2",
"iPad2,3": "iPad 2",
"iPad2,4": "iPad 2",
"iPad3,1": "iPad 3rd Gen",
"iPad3,3": "iPad 3rd Gen",
"iPad3,2": "iPad 3rd Gen",
"iPad3,4": "iPad 4th Gen",
"iPad3,5": "iPad 4th Gen",
"iPad3,6": "iPad 4th Gen",
"iPad6,11": "iPad 9.7 5th Gen",
"iPad6,12": "iPad 9.7 5th Gen",
"iPad7,5": "iPad 9.7 6th Gen",
"iPad7,6": "iPad 9.7 6th Gen",
"iPad7,11": "iPad 10.2 7th Gen",
"iPad7,12": "iPad 10.2 7th Gen",
"iPad11,6": "iPad 10.2 8th Gen",
"iPad11,7": "iPad 10.2 8th Gen",
"iPad12,1": "iPad 10.2 9th Gen",
"iPad12,2": "iPad 10.2 9th Gen",
"iPad13,18": "iPad 10.9 10th Gen",
"iPad13,19": "iPad 10.9 10th Gen",
"iPad4,1": "iPad Air",
"iPad4,2": "iPad Air",
"iPad4,3": "iPad Air",
"iPad5,3": "iPad Air 2",
"iPad5,4": "iPad Air 2",
"iPad11,3": "iPad Air 3rd Gen",
"iPad11,4": "iPad Air 3rd Gen",
"iPad13,1": "iPad Air 4th Gen",
"iPad13,2": "iPad Air 4th Gen",
"iPad13,16": "iPad Air 5th Gen",
"iPad13,17": "iPad Air 5th Gen",
"iPad14,8": "iPad Air M2 11",
"iPad14,9": "iPad Air M2 11",
"iPad14,10": "iPad Air M2 13",
"iPad14,11": "iPad Air M2 13",
"iPad2,5": "iPad mini",
"iPad2,6": "iPad mini",
"iPad2,7": "iPad mini",
"iPad4,4": "iPad mini 2",
"iPad4,5": "iPad mini 2",
"iPad4,6": "iPad mini 2",
"iPad4,7": "iPad mini 3",
"iPad4,8": "iPad mini 3",
"iPad4,9": "iPad mini 3",
"iPad5,1": "iPad mini 4",
"iPad5,2": "iPad mini 4",
"iPad11,1": "iPad mini 5th Gen",
"iPad11,2": "iPad mini 5th Gen",
"iPad14,1": "iPad mini 6th Gen",
"iPad14,2": "iPad mini 6th Gen",
"iPad6,7": "iPad Pro 12.9",
"iPad6,8": "iPad Pro 12.9",
"iPad6,3": "iPad Pro 9.7",
"iPad6,4": "iPad Pro 9.7",
"iPad7,3": "iPad Pro 10.5",
"iPad7,4": "iPad Pro 10.5",
"iPad7,1": "iPad Pro 12.9",
"iPad7,2": "iPad Pro 12.9",
"iPad8,1": "iPad Pro 11",
"iPad8,2": "iPad Pro 11",
"iPad8,3": "iPad Pro 11",
"iPad8,4": "iPad Pro 11",
"iPad8,5": "iPad Pro 12.9",
"iPad8,6": "iPad Pro 12.9",
"iPad8,7": "iPad Pro 12.9",
"iPad8,8": "iPad Pro 12.9",
"iPad8,9": "iPad Pro 11",
"iPad8,10": "iPad Pro 11",
"iPad8,11": "iPad Pro 12.9",
"iPad8,12": "iPad Pro 12.9",
"iPad13,4": "iPad Pro 11",
"iPad13,5": "iPad Pro 11",
"iPad13,6": "iPad Pro 11",
"iPad13,7": "iPad Pro 11",
"iPad13,8": "iPad Pro 12.9",
"iPad13,9": "iPad Pro 12.9",
"iPad13,10": "iPad Pro 12.9",
"iPad13,11": "iPad Pro 12.9",
"iPad14,3": "iPad Pro 11",
"iPad14,4": "iPad Pro 11",
"iPad14,5": "iPad Pro 12.9",
"iPad14,6": "iPad Pro 12.9",
"iPad16,3": "iPad Pro M4 11",
"iPad16,4": "iPad Pro M4 11",
"iPad16,5": "iPad Pro M4 13",
"iPad16,6": "iPad Pro M4 13",
"iPhone1,1": "iPhone",
"iPhone1,2": "iPhone 3G",
"iPhone2,1": "iPhone 3GS",
"iPhone3,1": "iPhone 4",
"iPhone3,2": "iPhone 4",
"iPhone3,3": "iPhone 4",
"iPhone4,1": "iPhone 4S",
"iPhone5,1": "iPhone 5",
"iPhone5,2": "iPhone 5",
"iPhone5,3": "iPhone 5c",
"iPhone5,4": "iPhone 5c",
"iPhone6,1": "iPhone 5s",
"iPhone6,2": "iPhone 5s",
"iPhone7,2": "iPhone 6",
"iPhone7,1": "iPhone 6 Plus",
"iPhone8,1": "iPhone 6s",
"iPhone8,2": "iPhone 6s Plus",
"iPhone8,4": "iPhone SE",
"iPhone9,1": "iPhone 7",
"iPhone9,3": "iPhone 7",
"iPhone9,2": "iPhone 7 Plus",
"iPhone9,4": "iPhone 7 Plus",
"iPhone10,1": "iPhone 8",
"iPhone10,4": "iPhone 8",
"iPhone10,2": "iPhone 8 Plus",
"iPhone10,5": "iPhone 8 Plus",
"iPhone10,3": "iPhone X",
"iPhone10,6": "iPhone X",
"iPhone11,2": "iPhone Xs",
"iPhone11,6": "iPhone Xs Max",
"iPhone11,8": "iPhone XR",
"iPhone12,1": "iPhone 11",
"iPhone12,3": "iPhone 11 Pro",
"iPhone12,5": "iPhone 11 Pro Max",
"iPhone12,8": "iPhone SE",
"iPhone13,1": "iPhone 12 mini",
"iPhone13,2": "iPhone 12",
"iPhone13,3": "iPhone 12 Pro",
"iPhone13,4": "iPhone 12 Pro Max",
"iPhone14,4": "iPhone 13 mini",
"iPhone14,5": "iPhone 13",
"iPhone14,2": "iPhone 13 Pro",
"iPhone14,3": "iPhone 13 Pro Max",
"iPhone14,6": "iPhone SE",
"iPhone14,7": "iPhone 14",
"iPhone14,8": "iPhone 14 Plus",
"iPhone15,2": "iPhone 14 Pro",
"iPhone15,3": "iPhone 14 Pro Max",
"iPhone15,4": "iPhone 15",
"iPhone15,5": "iPhone 15 Plus",
"iPhone16,1": "iPhone 15 Pro",
"iPhone16,2": "iPhone 15 Pro Max",
"iPod1,1": "iPod touch Original",
"iPod2,1": "iPod touch 2nd",
"iPod3,1": "iPod touch 3rd Gen",
"iPod4,1": "iPod touch 4th",
"iPod5,1": "iPod touch 5th",
"iPod7,1": "iPod touch 6th Gen",
"iPod9,1": "iPod touch 7th Gen"
}
+201
View File
@@ -0,0 +1,201 @@
{
"PowerMac4,4": "eMac",
"PowerMac6,4": "eMac",
"PowerBook2,1": "iBook",
"PowerBook2,2": "iBook",
"PowerBook4,1": "iBook",
"PowerBook4,2": "iBook",
"PowerBook4,3": "iBook",
"PowerBook6,3": "iBook",
"PowerBook6,5": "iBook",
"PowerBook6,7": "iBook",
"iMac,1": "iMac",
"PowerMac2,1": "iMac",
"PowerMac2,2": "iMac",
"PowerMac4,1": "iMac",
"PowerMac4,2": "iMac",
"PowerMac4,5": "iMac",
"PowerMac6,1": "iMac",
"PowerMac6,3*": "iMac",
"PowerMac6,3": "iMac",
"PowerMac8,1": "iMac",
"PowerMac8,2": "iMac",
"PowerMac12,1": "iMac",
"iMac4,1": "iMac",
"iMac4,2": "iMac",
"iMac5,2": "iMac",
"iMac5,1": "iMac",
"iMac6,1": "iMac",
"iMac7,1": "iMac",
"iMac8,1": "iMac",
"iMac9,1": "iMac",
"iMac10,1": "iMac",
"iMac11,1": "iMac",
"iMac11,2": "iMac",
"iMac11,3": "iMac",
"iMac12,1": "iMac",
"iMac12,2": "iMac",
"iMac13,1": "iMac",
"iMac13,2": "iMac",
"iMac14,1": "iMac",
"iMac14,3": "iMac",
"iMac14,2": "iMac",
"iMac14,4": "iMac",
"iMac15,1": "iMac",
"iMac16,1": "iMac",
"iMac16,2": "iMac",
"iMac17,1": "iMac",
"iMac18,1": "iMac",
"iMac18,2": "iMac",
"iMac18,3": "iMac",
"iMac19,2": "iMac",
"iMac19,1": "iMac",
"iMac20,1": "iMac",
"iMac20,2": "iMac",
"iMac21,2": "iMac",
"iMac21,1": "iMac",
"iMacPro1,1": "iMac Pro",
"PowerMac10,1": "Mac mini",
"PowerMac10,2": "Mac mini",
"Macmini1,1": "Mac mini",
"Macmini2,1": "Mac mini",
"Macmini3,1": "Mac mini",
"Macmini4,1": "Mac mini",
"Macmini5,1": "Mac mini",
"Macmini5,2": "Mac mini",
"Macmini5,3": "Mac mini",
"Macmini6,1": "Mac mini",
"Macmini6,2": "Mac mini",
"Macmini7,1": "Mac mini",
"Macmini8,1": "Mac mini",
"ADP3,2": "Mac mini",
"Macmini9,1": "Mac mini",
"Mac14,3": "Mac mini",
"Mac14,12": "Mac mini",
"MacPro1,1*": "Mac Pro",
"MacPro2,1": "Mac Pro",
"MacPro3,1": "Mac Pro",
"MacPro4,1": "Mac Pro",
"MacPro5,1": "Mac Pro",
"MacPro6,1": "Mac Pro",
"MacPro7,1": "Mac Pro",
"N/A*": "Power Macintosh",
"PowerMac1,1": "Power Macintosh",
"PowerMac3,1": "Power Macintosh",
"PowerMac3,3": "Power Macintosh",
"PowerMac3,4": "Power Macintosh",
"PowerMac3,5": "Power Macintosh",
"PowerMac3,6": "Power Macintosh",
"Mac13,1": "Mac Studio",
"Mac13,2": "Mac Studio",
"MacBook1,1": "MacBook",
"MacBook2,1": "MacBook",
"MacBook3,1": "MacBook",
"MacBook4,1": "MacBook",
"MacBook5,1": "MacBook",
"MacBook5,2": "MacBook",
"MacBook6,1": "MacBook",
"MacBook7,1": "MacBook",
"MacBook8,1": "MacBook",
"MacBook9,1": "MacBook",
"MacBook10,1": "MacBook",
"MacBookAir1,1": "MacBook Air",
"MacBookAir2,1": "MacBook Air",
"MacBookAir3,1": "MacBook Air",
"MacBookAir3,2": "MacBook Air",
"MacBookAir4,1": "MacBook Air",
"MacBookAir4,2": "MacBook Air",
"MacBookAir5,1": "MacBook Air",
"MacBookAir5,2": "MacBook Air",
"MacBookAir6,1": "MacBook Air",
"MacBookAir6,2": "MacBook Air",
"MacBookAir7,1": "MacBook Air",
"MacBookAir7,2": "MacBook Air",
"MacBookAir8,1": "MacBook Air",
"MacBookAir8,2": "MacBook Air",
"MacBookAir9,1": "MacBook Air",
"MacBookAir10,1": "MacBook Air",
"Mac14,2": "MacBook Air",
"MacBookPro1,1": "MacBook Pro",
"MacBookPro1,2": "MacBook Pro",
"MacBookPro2,2": "MacBook Pro",
"MacBookPro2,1": "MacBook Pro",
"MacBookPro3,1": "MacBook Pro",
"MacBookPro4,1": "MacBook Pro",
"MacBookPro5,1": "MacBook Pro",
"MacBookPro5,2": "MacBook Pro",
"MacBookPro5,5": "MacBook Pro",
"MacBookPro5,4": "MacBook Pro",
"MacBookPro5,3": "MacBook Pro",
"MacBookPro7,1": "MacBook Pro",
"MacBookPro6,2": "MacBook Pro",
"MacBookPro6,1": "MacBook Pro",
"MacBookPro8,1": "MacBook Pro",
"MacBookPro8,2": "MacBook Pro",
"MacBookPro8,3": "MacBook Pro",
"MacBookPro9,2": "MacBook Pro",
"MacBookPro9,1": "MacBook Pro",
"MacBookPro10,1": "MacBook Pro",
"MacBookPro10,2": "MacBook Pro",
"MacBookPro11,1": "MacBook Pro",
"MacBookPro11,2": "MacBook Pro",
"MacBookPro11,3": "MacBook Pro",
"MacBookPro12,1": "MacBook Pro",
"MacBookPro11,4": "MacBook Pro",
"MacBookPro11,5": "MacBook Pro",
"MacBookPro13,1": "MacBook Pro",
"MacBookPro13,2": "MacBook Pro",
"MacBookPro13,3": "MacBook Pro",
"MacBookPro14,1": "MacBook Pro",
"MacBookPro14,2": "MacBook Pro",
"MacBookPro14,3": "MacBook Pro",
"MacBookPro15,2": "MacBook Pro",
"MacBookPro15,1": "MacBook Pro",
"MacBookPro15,3": "MacBook Pro",
"MacBookPro15,4": "MacBook Pro",
"MacBookPro16,1": "MacBook Pro",
"MacBookPro16,3": "MacBook Pro",
"MacBookPro16,2": "MacBook Pro",
"MacBookPro16,4": "MacBook Pro",
"MacBookPro17,1": "MacBook Pro",
"MacBookPro18,3": "MacBook Pro",
"MacBookPro18,4": "MacBook Pro",
"MacBookPro18,1": "MacBook Pro",
"MacBookPro18,2": "MacBook Pro",
"Mac14,7": "MacBook Pro",
"Mac14,9": "MacBook Pro",
"Mac14,5": "MacBook Pro",
"Mac14,10": "MacBook Pro",
"Mac14,6": "MacBook Pro",
"PowerMac1,2": "Power Macintosh",
"PowerMac5,1": "Power Macintosh",
"PowerMac7,2": "Power Macintosh",
"PowerMac7,3": "Power Macintosh",
"PowerMac9,1": "Power Macintosh",
"PowerMac11,2": "Power Macintosh",
"PowerBook1,1": "PowerBook",
"PowerBook3,1": "PowerBook",
"PowerBook3,2": "PowerBook",
"PowerBook3,3": "PowerBook",
"PowerBook3,4": "PowerBook",
"PowerBook3,5": "PowerBook",
"PowerBook6,1": "PowerBook",
"PowerBook5,1": "PowerBook",
"PowerBook6,2": "PowerBook",
"PowerBook5,2": "PowerBook",
"PowerBook5,3": "PowerBook",
"PowerBook6,4": "PowerBook",
"PowerBook5,4": "PowerBook",
"PowerBook5,5": "PowerBook",
"PowerBook6,8": "PowerBook",
"PowerBook5,6": "PowerBook",
"PowerBook5,7": "PowerBook",
"PowerBook5,8": "PowerBook",
"PowerBook5,9": "PowerBook",
"RackMac1,1": "Xserve",
"RackMac1,2": "Xserve",
"RackMac3,1": "Xserve",
"Xserve1,1": "Xserve",
"Xserve2,1": "Xserve",
"Xserve3,1": "Xserve"
}
+44
View File
@@ -16,6 +16,24 @@ if (!dev) {
} }
export const names = JSON.parse(readFileSync(file, "utf-8")); export const names = JSON.parse(readFileSync(file, "utf-8"));
// Load iOS and Mac model mappings
let iosModelsFile: string;
let macModelsFile: string;
if (!dev) {
iosModelsFile = join(__DIRNAME, "ios_models.json");
macModelsFile = join(__DIRNAME, "mac_models.json");
} else {
iosModelsFile = join("server/db/ios_models.json");
macModelsFile = join("server/db/mac_models.json");
}
const iosModels: Record<string, string> = JSON.parse(
readFileSync(iosModelsFile, "utf-8")
);
const macModels: Record<string, string> = JSON.parse(
readFileSync(macModelsFile, "utf-8")
);
export async function getUniqueClientName(orgId: string): Promise<string> { export async function getUniqueClientName(orgId: string): Promise<string> {
let loops = 0; let loops = 0;
while (true) { while (true) {
@@ -159,3 +177,29 @@ export function generateName(): string {
// clean out any non-alphanumeric characters except for dashes // clean out any non-alphanumeric characters except for dashes
return name.replace(/[^a-z0-9-]/g, ""); return name.replace(/[^a-z0-9-]/g, "");
} }
export function getMacDeviceName(macIdentifier?: string | null): string | null {
if (macIdentifier && macModels[macIdentifier]) {
return macModels[macIdentifier];
}
return null;
}
export function getIosDeviceName(iosIdentifier?: string | null): string | null {
if (iosIdentifier && iosModels[iosIdentifier]) {
return iosModels[iosIdentifier];
}
return null;
}
export function getUserDeviceName(
model: string | null,
fallBack: string | null
): string {
return (
getMacDeviceName(model) ||
getIosDeviceName(model) ||
fallBack ||
"Unknown Device"
);
}
+43 -3
View File
@@ -10,7 +10,15 @@ import {
index index
} from "drizzle-orm/pg-core"; } from "drizzle-orm/pg-core";
import { InferSelectModel } from "drizzle-orm"; import { InferSelectModel } from "drizzle-orm";
import { domains, orgs, targets, users, exitNodes, sessions } from "./schema"; import {
domains,
orgs,
targets,
users,
exitNodes,
sessions,
clients
} from "./schema";
export const certificates = pgTable("certificates", { export const certificates = pgTable("certificates", {
certId: serial("certId").primaryKey(), certId: serial("certId").primaryKey(),
@@ -74,11 +82,14 @@ export const subscriptions = pgTable("subscriptions", {
canceledAt: bigint("canceledAt", { mode: "number" }), canceledAt: bigint("canceledAt", { mode: "number" }),
createdAt: bigint("createdAt", { mode: "number" }).notNull(), createdAt: bigint("createdAt", { mode: "number" }).notNull(),
updatedAt: bigint("updatedAt", { mode: "number" }), updatedAt: bigint("updatedAt", { mode: "number" }),
billingCycleAnchor: bigint("billingCycleAnchor", { mode: "number" }) version: integer("version"),
billingCycleAnchor: bigint("billingCycleAnchor", { mode: "number" }),
type: varchar("type", { length: 50 }) // tier1, tier2, tier3, or license
}); });
export const subscriptionItems = pgTable("subscriptionItems", { export const subscriptionItems = pgTable("subscriptionItems", {
subscriptionItemId: serial("subscriptionItemId").primaryKey(), subscriptionItemId: serial("subscriptionItemId").primaryKey(),
stripeSubscriptionItemId: varchar("stripeSubscriptionItemId", { length: 255 }),
subscriptionId: varchar("subscriptionId", { length: 255 }) subscriptionId: varchar("subscriptionId", { length: 255 })
.notNull() .notNull()
.references(() => subscriptions.subscriptionId, { .references(() => subscriptions.subscriptionId, {
@@ -86,6 +97,7 @@ export const subscriptionItems = pgTable("subscriptionItems", {
}), }),
planId: varchar("planId", { length: 255 }).notNull(), planId: varchar("planId", { length: 255 }).notNull(),
priceId: varchar("priceId", { length: 255 }), priceId: varchar("priceId", { length: 255 }),
featureId: varchar("featureId", { length: 255 }),
meterId: varchar("meterId", { length: 255 }), meterId: varchar("meterId", { length: 255 }),
unitAmount: real("unitAmount"), unitAmount: real("unitAmount"),
tiers: text("tiers"), tiers: text("tiers"),
@@ -128,6 +140,7 @@ export const limits = pgTable("limits", {
}) })
.notNull(), .notNull(),
value: real("value"), value: real("value"),
override: boolean("override").default(false),
description: text("description") description: text("description")
}); });
@@ -206,7 +219,7 @@ export const loginPageOrg = pgTable("loginPageOrg", {
export const loginPageBranding = pgTable("loginPageBranding", { export const loginPageBranding = pgTable("loginPageBranding", {
loginPageBrandingId: serial("loginPageBrandingId").primaryKey(), loginPageBrandingId: serial("loginPageBrandingId").primaryKey(),
logoUrl: text("logoUrl").notNull(), logoUrl: text("logoUrl"),
logoWidth: integer("logoWidth").notNull(), logoWidth: integer("logoWidth").notNull(),
logoHeight: integer("logoHeight").notNull(), logoHeight: integer("logoHeight").notNull(),
primaryColor: text("primaryColor"), primaryColor: text("primaryColor"),
@@ -289,6 +302,33 @@ export const accessAuditLog = pgTable(
] ]
); );
export const approvals = pgTable("approvals", {
approvalId: serial("approvalId").primaryKey(),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: varchar("orgId")
.references(() => orgs.orgId, {
onDelete: "cascade"
})
.notNull(),
clientId: integer("clientId").references(() => clients.clientId, {
onDelete: "cascade"
}), // clients reference user devices (in this case)
userId: varchar("userId")
.references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade"
})
.notNull(),
decision: varchar("decision")
.$type<"approved" | "denied" | "pending">()
.default("pending")
.notNull(),
type: varchar("type")
.$type<"user_device" /*| 'proxy' // for later */>()
.notNull()
});
export type Approval = InferSelectModel<typeof approvals>;
export type Limit = InferSelectModel<typeof limits>; export type Limit = InferSelectModel<typeof limits>;
export type Account = InferSelectModel<typeof account>; export type Account = InferSelectModel<typeof account>;
export type Certificate = InferSelectModel<typeof certificates>; export type Certificate = InferSelectModel<typeof certificates>;
+132 -4
View File
@@ -365,7 +365,8 @@ export const roles = pgTable("roles", {
.notNull(), .notNull(),
isAdmin: boolean("isAdmin"), isAdmin: boolean("isAdmin"),
name: varchar("name").notNull(), name: varchar("name").notNull(),
description: varchar("description") description: varchar("description"),
requireDeviceApproval: boolean("requireDeviceApproval").default(false)
}); });
export const roleActions = pgTable("roleActions", { export const roleActions = pgTable("roleActions", {
@@ -591,7 +592,8 @@ export const idp = pgTable("idp", {
type: varchar("type").notNull(), type: varchar("type").notNull(),
defaultRoleMapping: varchar("defaultRoleMapping"), defaultRoleMapping: varchar("defaultRoleMapping"),
defaultOrgMapping: varchar("defaultOrgMapping"), defaultOrgMapping: varchar("defaultOrgMapping"),
autoProvision: boolean("autoProvision").notNull().default(false) autoProvision: boolean("autoProvision").notNull().default(false),
tags: text("tags")
}); });
export const idpOidcConfig = pgTable("idpOidcConfig", { export const idpOidcConfig = pgTable("idpOidcConfig", {
@@ -688,7 +690,12 @@ export const clients = pgTable("clients", {
online: boolean("online").notNull().default(false), online: boolean("online").notNull().default(false),
// endpoint: varchar("endpoint"), // endpoint: varchar("endpoint"),
lastHolePunch: integer("lastHolePunch"), lastHolePunch: integer("lastHolePunch"),
maxConnections: integer("maxConnections") maxConnections: integer("maxConnections"),
archived: boolean("archived").notNull().default(false),
blocked: boolean("blocked").notNull().default(false),
approvalState: varchar("approvalState").$type<
"pending" | "approved" | "denied"
>()
}); });
export const clientSitesAssociationsCache = pgTable( export const clientSitesAssociationsCache = pgTable(
@@ -712,6 +719,16 @@ export const clientSiteResourcesAssociationsCache = pgTable(
} }
); );
export const clientPostureSnapshots = pgTable("clientPostureSnapshots", {
snapshotId: serial("snapshotId").primaryKey(),
clientId: integer("clientId").references(() => clients.clientId, {
onDelete: "cascade"
}),
collectedAt: integer("collectedAt").notNull()
});
export const olms = pgTable("olms", { export const olms = pgTable("olms", {
olmId: varchar("id").primaryKey(), olmId: varchar("id").primaryKey(),
secretHash: varchar("secretHash").notNull(), secretHash: varchar("secretHash").notNull(),
@@ -726,7 +743,118 @@ export const olms = pgTable("olms", {
userId: text("userId").references(() => users.userId, { userId: text("userId").references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes // optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade" onDelete: "cascade"
}) }),
archived: boolean("archived").notNull().default(false)
});
export const currentFingerprint = pgTable("currentFingerprint", {
fingerprintId: serial("id").primaryKey(),
olmId: text("olmId")
.references(() => olms.olmId, { onDelete: "cascade" })
.notNull(),
firstSeen: integer("firstSeen").notNull(),
lastSeen: integer("lastSeen").notNull(),
lastCollectedAt: integer("lastCollectedAt").notNull(),
username: text("username"),
hostname: text("hostname"),
platform: text("platform"),
osVersion: text("osVersion"),
kernelVersion: text("kernelVersion"),
arch: text("arch"),
deviceModel: text("deviceModel"),
serialNumber: text("serialNumber"),
platformFingerprint: varchar("platformFingerprint"),
// Platform-agnostic checks
biometricsEnabled: boolean("biometricsEnabled").notNull().default(false),
diskEncrypted: boolean("diskEncrypted").notNull().default(false),
firewallEnabled: boolean("firewallEnabled").notNull().default(false),
autoUpdatesEnabled: boolean("autoUpdatesEnabled").notNull().default(false),
tpmAvailable: boolean("tpmAvailable").notNull().default(false),
// Windows-specific posture check information
windowsAntivirusEnabled: boolean("windowsAntivirusEnabled")
.notNull()
.default(false),
// macOS-specific posture check information
macosSipEnabled: boolean("macosSipEnabled").notNull().default(false),
macosGatekeeperEnabled: boolean("macosGatekeeperEnabled")
.notNull()
.default(false),
macosFirewallStealthMode: boolean("macosFirewallStealthMode")
.notNull()
.default(false),
// Linux-specific posture check information
linuxAppArmorEnabled: boolean("linuxAppArmorEnabled")
.notNull()
.default(false),
linuxSELinuxEnabled: boolean("linuxSELinuxEnabled").notNull().default(false)
});
export const fingerprintSnapshots = pgTable("fingerprintSnapshots", {
snapshotId: serial("id").primaryKey(),
fingerprintId: integer("fingerprintId").references(
() => currentFingerprint.fingerprintId,
{
onDelete: "set null"
}
),
username: text("username"),
hostname: text("hostname"),
platform: text("platform"),
osVersion: text("osVersion"),
kernelVersion: text("kernelVersion"),
arch: text("arch"),
deviceModel: text("deviceModel"),
serialNumber: text("serialNumber"),
platformFingerprint: varchar("platformFingerprint"),
// Platform-agnostic checks
biometricsEnabled: boolean("biometricsEnabled").notNull().default(false),
diskEncrypted: boolean("diskEncrypted").notNull().default(false),
firewallEnabled: boolean("firewallEnabled").notNull().default(false),
autoUpdatesEnabled: boolean("autoUpdatesEnabled").notNull().default(false),
tpmAvailable: boolean("tpmAvailable").notNull().default(false),
// Windows-specific posture check information
windowsAntivirusEnabled: boolean("windowsAntivirusEnabled")
.notNull()
.default(false),
// macOS-specific posture check information
macosSipEnabled: boolean("macosSipEnabled").notNull().default(false),
macosGatekeeperEnabled: boolean("macosGatekeeperEnabled")
.notNull()
.default(false),
macosFirewallStealthMode: boolean("macosFirewallStealthMode")
.notNull()
.default(false),
// Linux-specific posture check information
linuxAppArmorEnabled: boolean("linuxAppArmorEnabled")
.notNull()
.default(false),
linuxSELinuxEnabled: boolean("linuxSELinuxEnabled")
.notNull()
.default(false),
hash: text("hash").notNull(),
collectedAt: integer("collectedAt").notNull()
}); });
export const olmSessions = pgTable("clientSession", { export const olmSessions = pgTable("clientSession", {
+10 -2
View File
@@ -1,4 +1,4 @@
import { db, loginPage, LoginPage, loginPageOrg, Org, orgs } from "@server/db"; import { db, loginPage, LoginPage, loginPageOrg, Org, orgs, roles } from "@server/db";
import { import {
Resource, Resource,
ResourcePassword, ResourcePassword,
@@ -108,9 +108,17 @@ export async function getUserSessionWithUser(
*/ */
export async function getUserOrgRole(userId: string, orgId: string) { export async function getUserOrgRole(userId: string, orgId: string) {
const userOrgRole = await db const userOrgRole = await db
.select() .select({
userId: userOrgs.userId,
orgId: userOrgs.orgId,
roleId: userOrgs.roleId,
isOwner: userOrgs.isOwner,
autoProvisioned: userOrgs.autoProvisioned,
roleName: roles.name
})
.from(userOrgs) .from(userOrgs)
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, orgId))) .where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, orgId)))
.leftJoin(roles, eq(userOrgs.roleId, roles.roleId))
.limit(1); .limit(1);
return userOrgRole.length > 0 ? userOrgRole[0] : null; return userOrgRole.length > 0 ? userOrgRole[0] : null;
+33 -3
View File
@@ -6,7 +6,7 @@ import {
sqliteTable, sqliteTable,
text text
} from "drizzle-orm/sqlite-core"; } from "drizzle-orm/sqlite-core";
import { domains, exitNodes, orgs, sessions, users } from "./schema"; import { clients, domains, exitNodes, orgs, sessions, users } from "./schema";
export const certificates = sqliteTable("certificates", { export const certificates = sqliteTable("certificates", {
certId: integer("certId").primaryKey({ autoIncrement: true }), certId: integer("certId").primaryKey({ autoIncrement: true }),
@@ -70,13 +70,16 @@ export const subscriptions = sqliteTable("subscriptions", {
canceledAt: integer("canceledAt"), canceledAt: integer("canceledAt"),
createdAt: integer("createdAt").notNull(), createdAt: integer("createdAt").notNull(),
updatedAt: integer("updatedAt"), updatedAt: integer("updatedAt"),
billingCycleAnchor: integer("billingCycleAnchor") version: integer("version"),
billingCycleAnchor: integer("billingCycleAnchor"),
type: text("type") // tier1, tier2, tier3, or license
}); });
export const subscriptionItems = sqliteTable("subscriptionItems", { export const subscriptionItems = sqliteTable("subscriptionItems", {
subscriptionItemId: integer("subscriptionItemId").primaryKey({ subscriptionItemId: integer("subscriptionItemId").primaryKey({
autoIncrement: true autoIncrement: true
}), }),
stripeSubscriptionItemId: text("stripeSubscriptionItemId"),
subscriptionId: text("subscriptionId") subscriptionId: text("subscriptionId")
.notNull() .notNull()
.references(() => subscriptions.subscriptionId, { .references(() => subscriptions.subscriptionId, {
@@ -84,6 +87,7 @@ export const subscriptionItems = sqliteTable("subscriptionItems", {
}), }),
planId: text("planId").notNull(), planId: text("planId").notNull(),
priceId: text("priceId"), priceId: text("priceId"),
featureId: text("featureId"),
meterId: text("meterId"), meterId: text("meterId"),
unitAmount: real("unitAmount"), unitAmount: real("unitAmount"),
tiers: text("tiers"), tiers: text("tiers"),
@@ -126,6 +130,7 @@ export const limits = sqliteTable("limits", {
}) })
.notNull(), .notNull(),
value: real("value"), value: real("value"),
override: integer("override", { mode: "boolean" }).default(false),
description: text("description") description: text("description")
}); });
@@ -206,7 +211,7 @@ export const loginPageBranding = sqliteTable("loginPageBranding", {
loginPageBrandingId: integer("loginPageBrandingId").primaryKey({ loginPageBrandingId: integer("loginPageBrandingId").primaryKey({
autoIncrement: true autoIncrement: true
}), }),
logoUrl: text("logoUrl").notNull(), logoUrl: text("logoUrl"),
logoWidth: integer("logoWidth").notNull(), logoWidth: integer("logoWidth").notNull(),
logoHeight: integer("logoHeight").notNull(), logoHeight: integer("logoHeight").notNull(),
primaryColor: text("primaryColor"), primaryColor: text("primaryColor"),
@@ -289,6 +294,31 @@ export const accessAuditLog = sqliteTable(
] ]
); );
export const approvals = sqliteTable("approvals", {
approvalId: integer("approvalId").primaryKey({ autoIncrement: true }),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: text("orgId")
.references(() => orgs.orgId, {
onDelete: "cascade"
})
.notNull(),
clientId: integer("clientId").references(() => clients.clientId, {
onDelete: "cascade"
}), // olms reference user devices clients
userId: text("userId").references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade"
}),
decision: text("decision")
.$type<"approved" | "denied" | "pending">()
.default("pending")
.notNull(),
type: text("type")
.$type<"user_device" /*| 'proxy' // for later */>()
.notNull()
});
export type Approval = InferSelectModel<typeof approvals>;
export type Limit = InferSelectModel<typeof limits>; export type Limit = InferSelectModel<typeof limits>;
export type Account = InferSelectModel<typeof account>; export type Account = InferSelectModel<typeof account>;
export type Certificate = InferSelectModel<typeof certificates>; export type Certificate = InferSelectModel<typeof certificates>;
+168 -4
View File
@@ -255,7 +255,9 @@ export const siteResources = sqliteTable("siteResources", {
aliasAddress: text("aliasAddress"), aliasAddress: text("aliasAddress"),
tcpPortRangeString: text("tcpPortRangeString").notNull().default("*"), tcpPortRangeString: text("tcpPortRangeString").notNull().default("*"),
udpPortRangeString: text("udpPortRangeString").notNull().default("*"), udpPortRangeString: text("udpPortRangeString").notNull().default("*"),
disableIcmp: integer("disableIcmp", { mode: "boolean" }).notNull().default(false) disableIcmp: integer("disableIcmp", { mode: "boolean" })
.notNull()
.default(false)
}); });
export const clientSiteResources = sqliteTable("clientSiteResources", { export const clientSiteResources = sqliteTable("clientSiteResources", {
@@ -383,7 +385,12 @@ export const clients = sqliteTable("clients", {
type: text("type").notNull(), // "olm" type: text("type").notNull(), // "olm"
online: integer("online", { mode: "boolean" }).notNull().default(false), online: integer("online", { mode: "boolean" }).notNull().default(false),
// endpoint: text("endpoint"), // endpoint: text("endpoint"),
lastHolePunch: integer("lastHolePunch") lastHolePunch: integer("lastHolePunch"),
archived: integer("archived", { mode: "boolean" }).notNull().default(false),
blocked: integer("blocked", { mode: "boolean" }).notNull().default(false),
approvalState: text("approvalState").$type<
"pending" | "approved" | "denied"
>()
}); });
export const clientSitesAssociationsCache = sqliteTable( export const clientSitesAssociationsCache = sqliteTable(
@@ -423,7 +430,160 @@ export const olms = sqliteTable("olms", {
userId: text("userId").references(() => users.userId, { userId: text("userId").references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes // optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade" onDelete: "cascade"
}),
archived: integer("archived", { mode: "boolean" }).notNull().default(false)
});
export const currentFingerprint = sqliteTable("currentFingerprint", {
fingerprintId: integer("id").primaryKey({ autoIncrement: true }),
olmId: text("olmId")
.references(() => olms.olmId, { onDelete: "cascade" })
.notNull(),
firstSeen: integer("firstSeen").notNull(),
lastSeen: integer("lastSeen").notNull(),
lastCollectedAt: integer("lastCollectedAt").notNull(),
username: text("username"),
hostname: text("hostname"),
platform: text("platform"),
osVersion: text("osVersion"),
kernelVersion: text("kernelVersion"),
arch: text("arch"),
deviceModel: text("deviceModel"),
serialNumber: text("serialNumber"),
platformFingerprint: text("platformFingerprint"),
// Platform-agnostic checks
biometricsEnabled: integer("biometricsEnabled", { mode: "boolean" })
.notNull()
.default(false),
diskEncrypted: integer("diskEncrypted", { mode: "boolean" })
.notNull()
.default(false),
firewallEnabled: integer("firewallEnabled", { mode: "boolean" })
.notNull()
.default(false),
autoUpdatesEnabled: integer("autoUpdatesEnabled", { mode: "boolean" })
.notNull()
.default(false),
tpmAvailable: integer("tpmAvailable", { mode: "boolean" })
.notNull()
.default(false),
// Windows-specific posture check information
windowsAntivirusEnabled: integer("windowsAntivirusEnabled", {
mode: "boolean"
}) })
.notNull()
.default(false),
// macOS-specific posture check information
macosSipEnabled: integer("macosSipEnabled", { mode: "boolean" })
.notNull()
.default(false),
macosGatekeeperEnabled: integer("macosGatekeeperEnabled", {
mode: "boolean"
})
.notNull()
.default(false),
macosFirewallStealthMode: integer("macosFirewallStealthMode", {
mode: "boolean"
})
.notNull()
.default(false),
// Linux-specific posture check information
linuxAppArmorEnabled: integer("linuxAppArmorEnabled", { mode: "boolean" })
.notNull()
.default(false),
linuxSELinuxEnabled: integer("linuxSELinuxEnabled", {
mode: "boolean"
})
.notNull()
.default(false)
});
export const fingerprintSnapshots = sqliteTable("fingerprintSnapshots", {
snapshotId: integer("id").primaryKey({ autoIncrement: true }),
fingerprintId: integer("fingerprintId").references(
() => currentFingerprint.fingerprintId,
{
onDelete: "set null"
}
),
username: text("username"),
hostname: text("hostname"),
platform: text("platform"),
osVersion: text("osVersion"),
kernelVersion: text("kernelVersion"),
arch: text("arch"),
deviceModel: text("deviceModel"),
serialNumber: text("serialNumber"),
platformFingerprint: text("platformFingerprint"),
// Platform-agnostic checks
biometricsEnabled: integer("biometricsEnabled", { mode: "boolean" })
.notNull()
.default(false),
diskEncrypted: integer("diskEncrypted", { mode: "boolean" })
.notNull()
.default(false),
firewallEnabled: integer("firewallEnabled", { mode: "boolean" })
.notNull()
.default(false),
autoUpdatesEnabled: integer("autoUpdatesEnabled", { mode: "boolean" })
.notNull()
.default(false),
tpmAvailable: integer("tpmAvailable", { mode: "boolean" })
.notNull()
.default(false),
// Windows-specific posture check information
windowsAntivirusEnabled: integer("windowsAntivirusEnabled", {
mode: "boolean"
})
.notNull()
.default(false),
// macOS-specific posture check information
macosSipEnabled: integer("macosSipEnabled", { mode: "boolean" })
.notNull()
.default(false),
macosGatekeeperEnabled: integer("macosGatekeeperEnabled", {
mode: "boolean"
})
.notNull()
.default(false),
macosFirewallStealthMode: integer("macosFirewallStealthMode", {
mode: "boolean"
})
.notNull()
.default(false),
// Linux-specific posture check information
linuxAppArmorEnabled: integer("linuxAppArmorEnabled", { mode: "boolean" })
.notNull()
.default(false),
linuxSELinuxEnabled: integer("linuxSELinuxEnabled", {
mode: "boolean"
})
.notNull()
.default(false),
hash: text("hash").notNull(),
collectedAt: integer("collectedAt").notNull()
}); });
export const twoFactorBackupCodes = sqliteTable("twoFactorBackupCodes", { export const twoFactorBackupCodes = sqliteTable("twoFactorBackupCodes", {
@@ -515,7 +675,10 @@ export const roles = sqliteTable("roles", {
.notNull(), .notNull(),
isAdmin: integer("isAdmin", { mode: "boolean" }), isAdmin: integer("isAdmin", { mode: "boolean" }),
name: text("name").notNull(), name: text("name").notNull(),
description: text("description") description: text("description"),
requireDeviceApproval: integer("requireDeviceApproval", {
mode: "boolean"
}).default(false)
}); });
export const roleActions = sqliteTable("roleActions", { export const roleActions = sqliteTable("roleActions", {
@@ -774,7 +937,8 @@ export const idp = sqliteTable("idp", {
mode: "boolean" mode: "boolean"
}) })
.notNull() .notNull()
.default(false) .default(false),
tags: text("tags")
}); });
// Identity Provider OAuth Configuration // Identity Provider OAuth Configuration
@@ -0,0 +1,118 @@
import React from "react";
import { Body, Head, Html, Preview, Tailwind } from "@react-email/components";
import { themeColors } from "./lib/theme";
import {
EmailContainer,
EmailFooter,
EmailGreeting,
EmailHeading,
EmailInfoSection,
EmailLetterHead,
EmailSection,
EmailSignature,
EmailText
} from "./components/Email";
import CopyCodeBox from "./components/CopyCodeBox";
import ButtonLink from "./components/ButtonLink";
type EnterpriseEditionKeyGeneratedProps = {
keyValue: string;
personalUseOnly: boolean;
users: number;
sites: number;
modifySubscriptionLink?: string;
};
export const EnterpriseEditionKeyGenerated = ({
keyValue,
personalUseOnly,
users,
sites,
modifySubscriptionLink
}: EnterpriseEditionKeyGeneratedProps) => {
const previewText = personalUseOnly
? "Your Enterprise Edition key for personal use is ready"
: "Thank you for your purchase — your Enterprise Edition key is ready";
return (
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind config={themeColors}>
<Body className="font-sans bg-gray-50">
<EmailContainer>
<EmailLetterHead />
<EmailGreeting>Hi there,</EmailGreeting>
{personalUseOnly ? (
<EmailText>
Your Enterprise Edition license key has been
generated. Qualifying users can use the
Enterprise Edition for free for{" "}
<strong>personal use only</strong>.
</EmailText>
) : (
<>
<EmailText>
Thank you for your purchase. Your Enterprise
Edition license key is ready. Below are the
terms of your license.
</EmailText>
<EmailInfoSection
title="License details"
items={[
{
label: "Licensed users",
value: users
},
{
label: "Licensed sites",
value: sites
}
]}
/>
{modifySubscriptionLink && (
<EmailSection>
<ButtonLink
href={modifySubscriptionLink}
>
Modify subscription
</ButtonLink>
</EmailSection>
)}
</>
)}
<EmailSection>
<EmailText>Your license key:</EmailText>
<CopyCodeBox
text={keyValue}
hint="Copy this key and use it when activating Enterprise Edition on your Pangolin host."
/>
</EmailSection>
<EmailText>
If you need to purchase additional license keys or
modify your existing license, please reach out to
our support team at{" "}
<a
href="mailto:support@pangolin.net"
className="text-primary font-medium"
>
support@pangolin.net
</a>
.
</EmailText>
<EmailFooter>
<EmailSignature />
</EmailFooter>
</EmailContainer>
</Body>
</Tailwind>
</Html>
);
};
export default EnterpriseEditionKeyGenerated;
@@ -1,6 +1,14 @@
import React from "react"; import React from "react";
export default function CopyCodeBox({ text }: { text: string }) { const DEFAULT_HINT = "Copy and paste this code when prompted";
export default function CopyCodeBox({
text,
hint
}: {
text: string;
hint?: string;
}) {
return ( return (
<div className="inline-block"> <div className="inline-block">
<div className="bg-gray-50 border border-gray-200 rounded-lg px-6 py-4 mx-auto"> <div className="bg-gray-50 border border-gray-200 rounded-lg px-6 py-4 mx-auto">
@@ -8,9 +16,7 @@ export default function CopyCodeBox({ text }: { text: string }) {
{text} {text}
</span> </span>
</div> </div>
<p className="text-xs text-gray-500 mt-2"> <p className="text-xs text-gray-500 mt-2">{hint ?? DEFAULT_HINT}</p>
Copy and paste this code when prompted
</p>
</div> </div>
); );
} }
+7 -5
View File
@@ -105,11 +105,13 @@ function getOpenApiDocumentation() {
servers: [{ url: "/v1" }] servers: [{ url: "/v1" }]
}); });
// convert to yaml and save to file if (!process.env.DISABLE_GEN_OPENAPI) {
const outputPath = path.join(APP_PATH, "openapi.yaml"); // convert to yaml and save to file
const yamlOutput = yaml.dump(generated); const outputPath = path.join(APP_PATH, "openapi.yaml");
fs.writeFileSync(outputPath, yamlOutput, "utf8"); const yamlOutput = yaml.dump(generated);
logger.info(`OpenAPI documentation saved to ${outputPath}`); fs.writeFileSync(outputPath, yamlOutput, "utf8");
logger.info(`OpenAPI documentation saved to ${outputPath}`);
}
return generated; return generated;
} }
+93 -46
View File
@@ -1,30 +1,41 @@
import Stripe from "stripe";
export enum FeatureId { export enum FeatureId {
SITE_UPTIME = "siteUptime",
USERS = "users", USERS = "users",
SITES = "sites",
EGRESS_DATA_MB = "egressDataMb", EGRESS_DATA_MB = "egressDataMb",
DOMAINS = "domains", DOMAINS = "domains",
REMOTE_EXIT_NODES = "remoteExitNodes" REMOTE_EXIT_NODES = "remoteExitNodes",
TIER1 = "tier1"
} }
export const FeatureMeterIds: Record<FeatureId, string> = { export async function getFeatureDisplayName(featureId: FeatureId): Promise<string> {
[FeatureId.SITE_UPTIME]: "mtr_61Srrej5wUJuiTWgo41D3Ee2Ir7WmDLU", switch (featureId) {
[FeatureId.USERS]: "mtr_61SrreISyIWpwUNGR41D3Ee2Ir7WmQro", case FeatureId.USERS:
[FeatureId.EGRESS_DATA_MB]: "mtr_61Srreh9eWrExDSCe41D3Ee2Ir7Wm5YW", return "Users";
[FeatureId.DOMAINS]: "mtr_61Ss9nIKDNMw0LDRU41D3Ee2Ir7WmRPU", case FeatureId.SITES:
[FeatureId.REMOTE_EXIT_NODES]: "mtr_61T86UXnfxTVXy9sD41D3Ee2Ir7WmFTE" return "Sites";
case FeatureId.EGRESS_DATA_MB:
return "Egress Data (MB)";
case FeatureId.DOMAINS:
return "Domains";
case FeatureId.REMOTE_EXIT_NODES:
return "Remote Exit Nodes";
case FeatureId.TIER1:
return "Home Lab";
default:
return featureId;
}
}
// this is from the old system
export const FeatureMeterIds: Partial<Record<FeatureId, string>> = { // right now we are not charging for any data
// [FeatureId.EGRESS_DATA_MB]: "mtr_61Srreh9eWrExDSCe41D3Ee2Ir7Wm5YW"
}; };
export const FeatureMeterIdsSandbox: Record<FeatureId, string> = { export const FeatureMeterIdsSandbox: Partial<Record<FeatureId, string>> = {
[FeatureId.SITE_UPTIME]: "mtr_test_61Snh3cees4w60gv841DCpkOb237BDEu", // [FeatureId.EGRESS_DATA_MB]: "mtr_test_61Snh2a2m6qome5Kv41DCpkOb237B3dQ"
[FeatureId.USERS]: "mtr_test_61Sn5fLtq1gSfRkyA41DCpkOb237B6au",
[FeatureId.EGRESS_DATA_MB]: "mtr_test_61Snh2a2m6qome5Kv41DCpkOb237B3dQ",
[FeatureId.DOMAINS]: "mtr_test_61SsA8qrdAlgPpFRQ41DCpkOb237BGts",
[FeatureId.REMOTE_EXIT_NODES]: "mtr_test_61T86Vqmwa3D9ra3341DCpkOb237B94K"
}; };
export function getFeatureMeterId(featureId: FeatureId): string { export function getFeatureMeterId(featureId: FeatureId): string | undefined {
if ( if (
process.env.ENVIRONMENT == "prod" && process.env.ENVIRONMENT == "prod" &&
process.env.SANDBOX_MODE !== "true" process.env.SANDBOX_MODE !== "true"
@@ -43,45 +54,81 @@ export function getFeatureIdByMetricId(
)?.[0]; )?.[0];
} }
export type FeaturePriceSet = { export type FeaturePriceSet = Partial<Record<FeatureId, string>>;
[key in Exclude<FeatureId, FeatureId.DOMAINS>]: string;
} & { export const tier1FeaturePriceSet: FeaturePriceSet = {
[FeatureId.DOMAINS]?: string; // Optional since domains are not billed [FeatureId.TIER1]: "price_1SzVE3D3Ee2Ir7Wm6wT5Dl3G"
}; };
export const standardFeaturePriceSet: FeaturePriceSet = { export const tier1FeaturePriceSetSandbox: FeaturePriceSet = {
// Free tier matches the freeLimitSet [FeatureId.TIER1]: "price_1SxgpPDCpkOb237Bfo4rIsoT"
[FeatureId.SITE_UPTIME]: "price_1RrQc4D3Ee2Ir7WmaJGZ3MtF",
[FeatureId.USERS]: "price_1RrQeJD3Ee2Ir7WmgveP3xea",
[FeatureId.EGRESS_DATA_MB]: "price_1RrQXFD3Ee2Ir7WmvGDlgxQk",
// [FeatureId.DOMAINS]: "price_1Rz3tMD3Ee2Ir7Wm5qLeASzC",
[FeatureId.REMOTE_EXIT_NODES]: "price_1S46weD3Ee2Ir7Wm94KEHI4h"
}; };
export const standardFeaturePriceSetSandbox: FeaturePriceSet = { export function getTier1FeaturePriceSet(): FeaturePriceSet {
// Free tier matches the freeLimitSet
[FeatureId.SITE_UPTIME]: "price_1RefFBDCpkOb237BPrKZ8IEU",
[FeatureId.USERS]: "price_1ReNa4DCpkOb237Bc67G5muF",
[FeatureId.EGRESS_DATA_MB]: "price_1Rfp9LDCpkOb237BwuN5Oiu0",
// [FeatureId.DOMAINS]: "price_1Ryi88DCpkOb237B2D6DM80b",
[FeatureId.REMOTE_EXIT_NODES]: "price_1RyiZvDCpkOb237BXpmoIYJL"
};
export function getStandardFeaturePriceSet(): FeaturePriceSet {
if ( if (
process.env.ENVIRONMENT == "prod" && process.env.ENVIRONMENT == "prod" &&
process.env.SANDBOX_MODE !== "true" process.env.SANDBOX_MODE !== "true"
) { ) {
return standardFeaturePriceSet; return tier1FeaturePriceSet;
} else { } else {
return standardFeaturePriceSetSandbox; return tier1FeaturePriceSetSandbox;
} }
} }
export function getLineItems( export const tier2FeaturePriceSet: FeaturePriceSet = {
featurePriceSet: FeaturePriceSet [FeatureId.USERS]: "price_1SzVCcD3Ee2Ir7Wmn6U3KvPN"
): Stripe.Checkout.SessionCreateParams.LineItem[] { };
return Object.entries(featurePriceSet).map(([featureId, priceId]) => ({
price: priceId export const tier2FeaturePriceSetSandbox: FeaturePriceSet = {
})); [FeatureId.USERS]: "price_1SxaEHDCpkOb237BD9lBkPiR"
};
export function getTier2FeaturePriceSet(): FeaturePriceSet {
if (
process.env.ENVIRONMENT == "prod" &&
process.env.SANDBOX_MODE !== "true"
) {
return tier2FeaturePriceSet;
} else {
return tier2FeaturePriceSetSandbox;
}
}
export const tier3FeaturePriceSet: FeaturePriceSet = {
[FeatureId.USERS]: "price_1SzVDKD3Ee2Ir7WmPtOKNusv"
};
export const tier3FeaturePriceSetSandbox: FeaturePriceSet = {
[FeatureId.USERS]: "price_1SxaEODCpkOb237BiXdCBSfs"
};
export function getTier3FeaturePriceSet(): FeaturePriceSet {
if (
process.env.ENVIRONMENT == "prod" &&
process.env.SANDBOX_MODE !== "true"
) {
return tier3FeaturePriceSet;
} else {
return tier3FeaturePriceSetSandbox;
}
}
export function getFeatureIdByPriceId(priceId: string): FeatureId | undefined {
// Check all feature price sets
const allPriceSets = [
getTier1FeaturePriceSet(),
getTier2FeaturePriceSet(),
getTier3FeaturePriceSet()
];
for (const priceSet of allPriceSets) {
const entry = (Object.entries(priceSet) as [FeatureId, string][]).find(
([_, price]) => price === priceId
);
if (entry) {
return entry[0];
}
}
return undefined;
} }
+25
View File
@@ -0,0 +1,25 @@
import Stripe from "stripe";
import { FeatureId, FeaturePriceSet } from "./features";
import { usageService } from "./usageService";
export async function getLineItems(
featurePriceSet: FeaturePriceSet,
orgId: string,
): Promise<Stripe.Checkout.SessionCreateParams.LineItem[]> {
const users = await usageService.getUsage(orgId, FeatureId.USERS);
return Object.entries(featurePriceSet).map(([featureId, priceId]) => {
let quantity: number | undefined;
if (featureId === FeatureId.USERS) {
quantity = users?.instantaneousValue || 1;
} else if (featureId === FeatureId.TIER1) {
quantity = 1;
}
return {
price: priceId,
quantity: quantity
};
});
}
+37
View File
@@ -0,0 +1,37 @@
export enum LicenseId {
SMALL_LICENSE = "small_license",
BIG_LICENSE = "big_license"
}
export type LicensePriceSet = {
[key in LicenseId]: string;
};
export const licensePriceSet: LicensePriceSet = {
// Free license matches the freeLimitSet
[LicenseId.SMALL_LICENSE]: "price_1SxKHiD3Ee2Ir7WmvtEh17A8",
[LicenseId.BIG_LICENSE]: "price_1SxKHiD3Ee2Ir7WmMUiP0H6Y"
};
export const licensePriceSetSandbox: LicensePriceSet = {
// Free license matches the freeLimitSet
// when matching license the keys closer to 0 index are matched first so list the licenses in descending order of value
[LicenseId.SMALL_LICENSE]: "price_1SxDwuDCpkOb237Bz0yTiOgN",
[LicenseId.BIG_LICENSE]: "price_1SxDy0DCpkOb237BWJxrxYkl"
};
export function getLicensePriceSet(
environment?: string,
sandbox_mode?: boolean
): LicensePriceSet {
if (
(process.env.ENVIRONMENT == "prod" &&
process.env.SANDBOX_MODE !== "true") ||
(environment === "prod" && sandbox_mode !== true)
) {
// THIS GETS LOADED CLIENT SIDE AND SERVER SIDE
return licensePriceSet;
} else {
return licensePriceSetSandbox;
}
}
+46 -29
View File
@@ -1,50 +1,67 @@
import { FeatureId } from "./features"; import { FeatureId } from "./features";
export type LimitSet = { export type LimitSet = Partial<{
[key in FeatureId]: { [key in FeatureId]: {
value: number | null; // null indicates no limit value: number | null; // null indicates no limit
description?: string; description?: string;
}; };
}; }>;
export const sandboxLimitSet: LimitSet = { export const sandboxLimitSet: LimitSet = {
[FeatureId.SITE_UPTIME]: { value: 2880, description: "Sandbox limit" }, // 1 site up for 2 days
[FeatureId.USERS]: { value: 1, description: "Sandbox limit" }, [FeatureId.USERS]: { value: 1, description: "Sandbox limit" },
[FeatureId.EGRESS_DATA_MB]: { value: 1000, description: "Sandbox limit" }, // 1 GB [FeatureId.SITES]: { value: 1, description: "Sandbox limit" },
[FeatureId.DOMAINS]: { value: 0, description: "Sandbox limit" }, [FeatureId.DOMAINS]: { value: 0, description: "Sandbox limit" },
[FeatureId.REMOTE_EXIT_NODES]: { value: 0, description: "Sandbox limit" } [FeatureId.REMOTE_EXIT_NODES]: { value: 0, description: "Sandbox limit" },
}; };
export const freeLimitSet: LimitSet = { export const freeLimitSet: LimitSet = {
[FeatureId.SITE_UPTIME]: { value: 46080, description: "Free tier limit" }, // 1 site up for 32 days [FeatureId.USERS]: { value: 5, description: "Starter limit" },
[FeatureId.USERS]: { value: 3, description: "Free tier limit" }, [FeatureId.SITES]: { value: 5, description: "Starter limit" },
[FeatureId.EGRESS_DATA_MB]: { [FeatureId.DOMAINS]: { value: 5, description: "Starter limit" },
value: 25000, [FeatureId.REMOTE_EXIT_NODES]: { value: 1, description: "Starter limit" },
description: "Free tier limit"
}, // 25 GB
[FeatureId.DOMAINS]: { value: 3, description: "Free tier limit" },
[FeatureId.REMOTE_EXIT_NODES]: { value: 1, description: "Free tier limit" }
}; };
export const subscribedLimitSet: LimitSet = { export const tier1LimitSet: LimitSet = {
[FeatureId.SITE_UPTIME]: { [FeatureId.USERS]: { value: 7, description: "Home limit" },
value: 2232000, [FeatureId.SITES]: { value: 10, description: "Home limit" },
description: "Contact us to increase soft limit." [FeatureId.DOMAINS]: { value: 10, description: "Home limit" },
}, // 50 sites up for 31 days [FeatureId.REMOTE_EXIT_NODES]: { value: 1, description: "Home limit" },
};
export const tier2LimitSet: LimitSet = {
[FeatureId.USERS]: { [FeatureId.USERS]: {
value: 150, value: 100,
description: "Contact us to increase soft limit." description: "Team limit"
},
[FeatureId.SITES]: {
value: 50,
description: "Team limit"
}, },
[FeatureId.EGRESS_DATA_MB]: {
value: 12000000,
description: "Contact us to increase soft limit."
}, // 12000 GB
[FeatureId.DOMAINS]: { [FeatureId.DOMAINS]: {
value: 25, value: 50,
description: "Contact us to increase soft limit." description: "Team limit"
}, },
[FeatureId.REMOTE_EXIT_NODES]: { [FeatureId.REMOTE_EXIT_NODES]: {
value: 5, value: 3,
description: "Contact us to increase soft limit." description: "Team limit"
} },
};
export const tier3LimitSet: LimitSet = {
[FeatureId.USERS]: {
value: 500,
description: "Business limit"
},
[FeatureId.SITES]: {
value: 250,
description: "Business limit"
},
[FeatureId.DOMAINS]: {
value: 100,
description: "Business limit"
},
[FeatureId.REMOTE_EXIT_NODES]: {
value: 20,
description: "Business limit"
},
}; };
+16
View File
@@ -2,6 +2,7 @@ import { db, limits } from "@server/db";
import { and, eq } from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import { LimitSet } from "./limitSet"; import { LimitSet } from "./limitSet";
import { FeatureId } from "./features"; import { FeatureId } from "./features";
import logger from "@server/logger";
class LimitService { class LimitService {
async applyLimitSetToOrg(orgId: string, limitSet: LimitSet): Promise<void> { async applyLimitSetToOrg(orgId: string, limitSet: LimitSet): Promise<void> {
@@ -13,6 +14,21 @@ class LimitService {
for (const [featureId, entry] of limitEntries) { for (const [featureId, entry] of limitEntries) {
const limitId = `${orgId}-${featureId}`; const limitId = `${orgId}-${featureId}`;
const { value, description } = entry; const { value, description } = entry;
// get the limit first
const [limit] = await trx
.select()
.from(limits)
.where(eq(limits.limitId, limitId))
.limit(1);
// check if its overriden
if (limit && limit.override) {
logger.debug(
`Skipping limit ${limitId} for org ${orgId} since it is overridden...`
);
continue;
}
await trx await trx
.insert(limits) .insert(limits)
.values({ limitId, orgId, featureId, value, description }); .values({ limitId, orgId, featureId, value, description });
+50
View File
@@ -0,0 +1,50 @@
import { Tier } from "@server/types/Tiers";
export enum TierFeature {
OrgOidc = "orgOidc",
LoginPageDomain = "loginPageDomain", // handle downgrade by removing custom domain
DeviceApprovals = "deviceApprovals", // handle downgrade by disabling device approvals
LoginPageBranding = "loginPageBranding", // handle downgrade by setting to default branding
LogExport = "logExport",
AccessLogs = "accessLogs", // set the retention period to none on downgrade
ActionLogs = "actionLogs", // set the retention period to none on downgrade
RotateCredentials = "rotateCredentials",
MaintencePage = "maintencePage", // handle downgrade
DevicePosture = "devicePosture",
TwoFactorEnforcement = "twoFactorEnforcement", // handle downgrade by setting to optional
SessionDurationPolicies = "sessionDurationPolicies", // handle downgrade by setting to default duration
PasswordExpirationPolicies = "passwordExpirationPolicies", // handle downgrade by setting to default duration
AutoProvisioning = "autoProvisioning" // handle downgrade by disabling auto provisioning
}
export const tierMatrix: Record<TierFeature, Tier[]> = {
[TierFeature.OrgOidc]: ["tier1", "tier2", "tier3", "enterprise"],
[TierFeature.LoginPageDomain]: ["tier1", "tier2", "tier3", "enterprise"],
[TierFeature.DeviceApprovals]: ["tier1", "tier3", "enterprise"],
[TierFeature.LoginPageBranding]: ["tier1", "tier3", "enterprise"],
[TierFeature.LogExport]: ["tier3", "enterprise"],
[TierFeature.AccessLogs]: ["tier2", "tier3", "enterprise"],
[TierFeature.ActionLogs]: ["tier2", "tier3", "enterprise"],
[TierFeature.RotateCredentials]: ["tier1", "tier2", "tier3", "enterprise"],
[TierFeature.MaintencePage]: ["tier1", "tier2", "tier3", "enterprise"],
[TierFeature.DevicePosture]: ["tier2", "tier3", "enterprise"],
[TierFeature.TwoFactorEnforcement]: [
"tier1",
"tier2",
"tier3",
"enterprise"
],
[TierFeature.SessionDurationPolicies]: [
"tier1",
"tier2",
"tier3",
"enterprise"
],
[TierFeature.PasswordExpirationPolicies]: [
"tier1",
"tier2",
"tier3",
"enterprise"
],
[TierFeature.AutoProvisioning]: ["tier1", "tier3", "enterprise"]
};
-34
View File
@@ -1,34 +0,0 @@
export enum TierId {
STANDARD = "standard"
}
export type TierPriceSet = {
[key in TierId]: string;
};
export const tierPriceSet: TierPriceSet = {
// Free tier matches the freeLimitSet
[TierId.STANDARD]: "price_1RrQ9cD3Ee2Ir7Wmqdy3KBa0"
};
export const tierPriceSetSandbox: TierPriceSet = {
// Free tier matches the freeLimitSet
// when matching tier the keys closer to 0 index are matched first so list the tiers in descending order of value
[TierId.STANDARD]: "price_1RrAYJDCpkOb237By2s1P32m"
};
export function getTierPriceSet(
environment?: string,
sandbox_mode?: boolean
): TierPriceSet {
if (
(process.env.ENVIRONMENT == "prod" &&
process.env.SANDBOX_MODE !== "true") ||
(environment === "prod" && sandbox_mode !== true)
) {
// THIS GETS LOADED CLIENT SIDE AND SERVER SIDE
return tierPriceSet;
} else {
return tierPriceSetSandbox;
}
}
+85 -435
View File
@@ -1,8 +1,6 @@
import { eq, sql, and } from "drizzle-orm"; import { eq, sql, and } from "drizzle-orm";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { PutObjectCommand } from "@aws-sdk/client-s3"; import { PutObjectCommand } from "@aws-sdk/client-s3";
import * as fs from "fs/promises";
import * as path from "path";
import { import {
db, db,
usage, usage,
@@ -32,11 +30,7 @@ interface StripeEvent {
} }
export function noop() { export function noop() {
if ( if (build !== "saas") {
build !== "saas" ||
!process.env.S3_BUCKET ||
!process.env.LOCAL_FILE_PATH
) {
return true; return true;
} }
return false; return false;
@@ -44,31 +38,40 @@ export function noop() {
export class UsageService { export class UsageService {
private bucketName: string | undefined; private bucketName: string | undefined;
private currentEventFile: string | null = null; private events: StripeEvent[] = [];
private currentFileStartTime: number = 0; private lastUploadTime: number = Date.now();
private eventsDir: string | undefined; private isUploading: boolean = false;
private uploadingFiles: Set<string> = new Set();
constructor() { constructor() {
if (noop()) { if (noop()) {
return; return;
} }
// this.bucketName = privateConfig.getRawPrivateConfig().stripe?.s3Bucket;
// this.eventsDir = privateConfig.getRawPrivateConfig().stripe?.localFilePath;
this.bucketName = process.env.S3_BUCKET || undefined;
this.eventsDir = process.env.LOCAL_FILE_PATH || undefined;
// Ensure events directory exists // this.bucketName = process.env.S3_BUCKET || undefined;
this.initializeEventsDirectory().then(() => {
this.uploadPendingEventFilesOnStartup();
});
// Periodically check for old event files to upload // // Periodically check and upload events
setInterval(() => { // setInterval(() => {
this.uploadOldEventFiles().catch((err) => { // this.checkAndUploadEvents().catch((err) => {
logger.error("Error in periodic event file upload:", err); // logger.error("Error in periodic event upload:", err);
}); // });
}, 30000); // every 30 seconds // }, 30000); // every 30 seconds
// // Handle graceful shutdown on SIGTERM
// process.on("SIGTERM", async () => {
// logger.info(
// "SIGTERM received, uploading events before shutdown..."
// );
// await this.forceUpload();
// logger.info("Events uploaded, proceeding with shutdown");
// });
// // Handle SIGINT as well (Ctrl+C)
// process.on("SIGINT", async () => {
// logger.info("SIGINT received, uploading events before shutdown...");
// await this.forceUpload();
// logger.info("Events uploaded, proceeding with shutdown");
// process.exit(0);
// });
} }
/** /**
@@ -78,85 +81,6 @@ export class UsageService {
return Math.round(value * 100000000000) / 100000000000; // 11 decimal places return Math.round(value * 100000000000) / 100000000000; // 11 decimal places
} }
private async initializeEventsDirectory(): Promise<void> {
if (!this.eventsDir) {
logger.warn(
"Stripe local file path is not configured, skipping events directory initialization."
);
return;
}
try {
await fs.mkdir(this.eventsDir, { recursive: true });
} catch (error) {
logger.error("Failed to create events directory:", error);
}
}
private async uploadPendingEventFilesOnStartup(): Promise<void> {
if (!this.eventsDir || !this.bucketName) {
logger.warn(
"Stripe local file path or bucket name is not configured, skipping leftover event file upload."
);
return;
}
try {
const files = await fs.readdir(this.eventsDir);
for (const file of files) {
if (file.endsWith(".json")) {
const filePath = path.join(this.eventsDir, file);
try {
const fileContent = await fs.readFile(
filePath,
"utf-8"
);
const events = JSON.parse(fileContent);
if (Array.isArray(events) && events.length > 0) {
// Upload to S3
const uploadCommand = new PutObjectCommand({
Bucket: this.bucketName,
Key: file,
Body: fileContent,
ContentType: "application/json"
});
await s3Client.send(uploadCommand);
// Check if file still exists before unlinking
try {
await fs.access(filePath);
await fs.unlink(filePath);
} catch (unlinkError) {
logger.debug(
`Startup file ${file} was already deleted`
);
}
logger.info(
`Uploaded leftover event file ${file} to S3 with ${events.length} events`
);
} else {
// Remove empty file
try {
await fs.access(filePath);
await fs.unlink(filePath);
} catch (unlinkError) {
logger.debug(
`Empty startup file ${file} was already deleted`
);
}
}
} catch (err) {
logger.error(
`Error processing leftover event file ${file}:`,
err
);
}
}
}
} catch (error) {
logger.error("Failed to scan for leftover event files");
}
}
public async add( public async add(
orgId: string, orgId: string,
featureId: FeatureId, featureId: FeatureId,
@@ -206,7 +130,9 @@ export class UsageService {
} }
// Log event for Stripe // Log event for Stripe
await this.logStripeEvent(featureId, value, customerId); // if (privateConfig.getRawPrivateConfig().flags.usage_reporting) {
// await this.logStripeEvent(featureId, value, customerId);
// }
return usage || null; return usage || null;
} catch (error: any) { } catch (error: any) {
@@ -286,7 +212,7 @@ export class UsageService {
return new Date(date * 1000).toISOString().split("T")[0]; return new Date(date * 1000).toISOString().split("T")[0];
} }
async updateDaily( async updateCount(
orgId: string, orgId: string,
featureId: FeatureId, featureId: FeatureId,
value?: number, value?: number,
@@ -312,8 +238,6 @@ export class UsageService {
value = this.truncateValue(value); value = this.truncateValue(value);
} }
const today = this.getTodayDateString();
let currentUsage: Usage | null = null; let currentUsage: Usage | null = null;
await db.transaction(async (trx) => { await db.transaction(async (trx) => {
@@ -327,66 +251,34 @@ export class UsageService {
.limit(1); .limit(1);
if (currentUsage) { if (currentUsage) {
const lastUpdateDate = this.getDateString( await trx
currentUsage.updatedAt .update(usage)
); .set({
const currentRunningTotal = currentUsage.latestValue; instantaneousValue: value,
const lastDailyValue = currentUsage.instantaneousValue || 0; updatedAt: Math.floor(Date.now() / 1000)
})
if (value == undefined || value === null) { .where(eq(usage.usageId, usageId));
value = currentUsage.instantaneousValue || 0;
}
if (lastUpdateDate === today) {
// Same day update: replace the daily value
// Remove old daily value from running total, add new value
const newRunningTotal = this.truncateValue(
currentRunningTotal - lastDailyValue + value
);
await trx
.update(usage)
.set({
latestValue: newRunningTotal,
instantaneousValue: value,
updatedAt: Math.floor(Date.now() / 1000)
})
.where(eq(usage.usageId, usageId));
} else {
// New day: add to running total
const newRunningTotal = this.truncateValue(
currentRunningTotal + value
);
await trx
.update(usage)
.set({
latestValue: newRunningTotal,
instantaneousValue: value,
updatedAt: Math.floor(Date.now() / 1000)
})
.where(eq(usage.usageId, usageId));
}
} else { } else {
// First record for this meter // First record for this meter
const meterId = getFeatureMeterId(featureId); const meterId = getFeatureMeterId(featureId);
const truncatedValue = this.truncateValue(value || 0);
await trx.insert(usage).values({ await trx.insert(usage).values({
usageId, usageId,
featureId, featureId,
orgId, orgId,
meterId, meterId,
instantaneousValue: truncatedValue, instantaneousValue: value || 0,
latestValue: truncatedValue, latestValue: value || 0,
updatedAt: Math.floor(Date.now() / 1000) updatedAt: Math.floor(Date.now() / 1000)
}); });
} }
}); });
await this.logStripeEvent(featureId, value || 0, customerId); // if (privateConfig.getRawPrivateConfig().flags.usage_reporting) {
// await this.logStripeEvent(featureId, value || 0, customerId);
// }
} catch (error) { } catch (error) {
logger.error( logger.error(
`Failed to update daily usage for ${orgId}/${featureId}:`, `Failed to update count usage for ${orgId}/${featureId}:`,
error error
); );
} }
@@ -450,121 +342,58 @@ export class UsageService {
} }
}; };
await this.writeEventToFile(event); this.addEventToMemory(event);
await this.checkAndUploadFile(); await this.checkAndUploadEvents();
} }
private async writeEventToFile(event: StripeEvent): Promise<void> { private addEventToMemory(event: StripeEvent): void {
if (!this.eventsDir || !this.bucketName) { if (!this.bucketName) {
logger.warn( logger.warn(
"Stripe local file path or bucket name is not configured, skipping event file write." "S3 bucket name is not configured, skipping event storage."
); );
return; return;
} }
if (!this.currentEventFile) { this.events.push(event);
this.currentEventFile = this.generateEventFileName();
this.currentFileStartTime = Date.now();
}
const filePath = path.join(this.eventsDir, this.currentEventFile);
try {
let events: StripeEvent[] = [];
// Try to read existing file
try {
const fileContent = await fs.readFile(filePath, "utf-8");
events = JSON.parse(fileContent);
} catch (error) {
// File doesn't exist or is empty, start with empty array
events = [];
}
// Add new event
events.push(event);
// Write back to file
await fs.writeFile(filePath, JSON.stringify(events, null, 2));
} catch (error) {
logger.error("Failed to write event to file:", error);
}
} }
private async checkAndUploadFile(): Promise<void> { private async checkAndUploadEvents(): Promise<void> {
if (!this.currentEventFile) {
return;
}
const now = Date.now(); const now = Date.now();
const fileAge = now - this.currentFileStartTime; const timeSinceLastUpload = now - this.lastUploadTime;
// Check if file is at least 1 minute old // Check if at least 1 minute has passed since last upload
if (fileAge >= 60000) { if (timeSinceLastUpload >= 60000 && this.events.length > 0) {
// 60 seconds await this.uploadEventsToS3();
await this.uploadFileToS3();
} }
} }
private async uploadFileToS3(): Promise<void> { private async uploadEventsToS3(): Promise<void> {
if (!this.bucketName || !this.eventsDir) { if (!this.bucketName) {
logger.warn( logger.warn(
"Stripe local file path or bucket name is not configured, skipping S3 upload." "S3 bucket name is not configured, skipping S3 upload."
);
return;
}
if (!this.currentEventFile) {
return;
}
const fileName = this.currentEventFile;
const filePath = path.join(this.eventsDir, fileName);
// Check if this file is already being uploaded
if (this.uploadingFiles.has(fileName)) {
logger.debug(
`File ${fileName} is already being uploaded, skipping`
); );
return; return;
} }
// Mark file as being uploaded if (this.events.length === 0) {
this.uploadingFiles.add(fileName); return;
}
// Check if already uploading
if (this.isUploading) {
logger.debug("Already uploading events, skipping");
return;
}
this.isUploading = true;
try { try {
// Check if file exists before trying to read it // Take a snapshot of current events and clear the array
try { const eventsToUpload = [...this.events];
await fs.access(filePath); this.events = [];
} catch (error) { this.lastUploadTime = Date.now();
logger.debug(
`File ${fileName} does not exist, may have been already processed`
);
this.uploadingFiles.delete(fileName);
// Reset current file if it was this file
if (this.currentEventFile === fileName) {
this.currentEventFile = null;
this.currentFileStartTime = 0;
}
return;
}
// Check if file exists and has content const fileName = this.generateEventFileName();
const fileContent = await fs.readFile(filePath, "utf-8"); const fileContent = JSON.stringify(eventsToUpload, null, 2);
const events = JSON.parse(fileContent);
if (events.length === 0) {
// No events to upload, just clean up
try {
await fs.unlink(filePath);
} catch (unlinkError) {
// File may have been already deleted
logger.debug(
`File ${fileName} was already deleted during cleanup`
);
}
this.currentEventFile = null;
this.uploadingFiles.delete(fileName);
return;
}
// Upload to S3 // Upload to S3
const uploadCommand = new PutObjectCommand({ const uploadCommand = new PutObjectCommand({
@@ -576,29 +405,15 @@ export class UsageService {
await s3Client.send(uploadCommand); await s3Client.send(uploadCommand);
// Clean up local file - check if it still exists before unlinking
try {
await fs.access(filePath);
await fs.unlink(filePath);
} catch (unlinkError) {
// File may have been already deleted by another process
logger.debug(
`File ${fileName} was already deleted during upload`
);
}
logger.info( logger.info(
`Uploaded ${fileName} to S3 with ${events.length} events` `Uploaded ${fileName} to S3 with ${eventsToUpload.length} events`
); );
// Reset for next file
this.currentEventFile = null;
this.currentFileStartTime = 0;
} catch (error) { } catch (error) {
logger.error(`Failed to upload ${fileName} to S3:`, error); logger.error("Failed to upload events to S3:", error);
// Note: Events are lost if upload fails. In a production system,
// you might want to add the events back to the array or implement retry logic
} finally { } finally {
// Always remove from uploading set this.isUploading = false;
this.uploadingFiles.delete(fileName);
} }
} }
@@ -683,129 +498,16 @@ export class UsageService {
} }
} }
public async getUsageDaily(
orgId: string,
featureId: FeatureId
): Promise<Usage | null> {
if (noop()) {
return null;
}
await this.updateDaily(orgId, featureId); // Ensure daily usage is updated
return this.getUsage(orgId, featureId);
}
public async forceUpload(): Promise<void> { public async forceUpload(): Promise<void> {
await this.uploadFileToS3(); if (this.events.length > 0) {
} // Force upload regardless of time
this.lastUploadTime = 0; // Reset to force upload
/** await this.uploadEventsToS3();
* Scan the events directory for files older than 1 minute and upload them if not empty.
*/
private async uploadOldEventFiles(): Promise<void> {
if (!this.eventsDir || !this.bucketName) {
logger.warn(
"Stripe local file path or bucket name is not configured, skipping old event file upload."
);
return;
}
try {
const files = await fs.readdir(this.eventsDir);
const now = Date.now();
for (const file of files) {
if (!file.endsWith(".json")) continue;
// Skip files that are already being uploaded
if (this.uploadingFiles.has(file)) {
logger.debug(
`Skipping file ${file} as it's already being uploaded`
);
continue;
}
const filePath = path.join(this.eventsDir, file);
try {
// Check if file still exists before processing
try {
await fs.access(filePath);
} catch (accessError) {
logger.debug(`File ${file} does not exist, skipping`);
continue;
}
const stat = await fs.stat(filePath);
const age = now - stat.mtimeMs;
if (age >= 90000) {
// 1.5 minutes - Mark as being uploaded
this.uploadingFiles.add(file);
try {
const fileContent = await fs.readFile(
filePath,
"utf-8"
);
const events = JSON.parse(fileContent);
if (Array.isArray(events) && events.length > 0) {
// Upload to S3
const uploadCommand = new PutObjectCommand({
Bucket: this.bucketName,
Key: file,
Body: fileContent,
ContentType: "application/json"
});
await s3Client.send(uploadCommand);
// Check if file still exists before unlinking
try {
await fs.access(filePath);
await fs.unlink(filePath);
} catch (unlinkError) {
logger.debug(
`File ${file} was already deleted during interval upload`
);
}
logger.info(
`Interval: Uploaded event file ${file} to S3 with ${events.length} events`
);
// If this was the current event file, reset it
if (this.currentEventFile === file) {
this.currentEventFile = null;
this.currentFileStartTime = 0;
}
} else {
// Remove empty file
try {
await fs.access(filePath);
await fs.unlink(filePath);
} catch (unlinkError) {
logger.debug(
`Empty file ${file} was already deleted`
);
}
}
} finally {
// Always remove from uploading set
this.uploadingFiles.delete(file);
}
}
} catch (err) {
logger.error(
`Interval: Error processing event file ${file}:`,
err
);
// Remove from uploading set on error
this.uploadingFiles.delete(file);
}
}
} catch (err) {
logger.error("Interval: Failed to scan for event files:", err);
} }
} }
public async checkLimitSet( public async checkLimitSet(
orgId: string, orgId: string,
kickSites = false,
featureId?: FeatureId, featureId?: FeatureId,
usage?: Usage, usage?: Usage,
trx: Transaction | typeof db = db trx: Transaction | typeof db = db
@@ -879,58 +581,6 @@ export class UsageService {
break; // Exit early if any limit is exceeded break; // Exit early if any limit is exceeded
} }
} }
// If any limits are exceeded, disconnect all sites for this organization
if (hasExceededLimits && kickSites) {
logger.warn(
`Disconnecting all sites for org ${orgId} due to exceeded limits`
);
// Get all sites for this organization
const orgSites = await trx
.select()
.from(sites)
.where(eq(sites.orgId, orgId));
// Mark all sites as offline and send termination messages
const siteUpdates = orgSites.map((site) => site.siteId);
if (siteUpdates.length > 0) {
// Send termination messages to newt sites
for (const site of orgSites) {
if (site.type === "newt") {
const [newt] = await trx
.select()
.from(newts)
.where(eq(newts.siteId, site.siteId))
.limit(1);
if (newt) {
const payload = {
type: `newt/wg/terminate`,
data: {
reason: "Usage limits exceeded"
}
};
// Don't await to prevent blocking
await sendToClient(newt.newtId, payload).catch(
(error: any) => {
logger.error(
`Failed to send termination message to newt ${newt.newtId}:`,
error
);
}
);
}
}
}
logger.info(
`Disconnected ${orgSites.length} sites for org ${orgId} due to exceeded limits`
);
}
}
} catch (error) { } catch (error) {
logger.error(`Error checking limits for org ${orgId}:`, error); logger.error(`Error checking limits for org ${orgId}:`, error);
} }
+13 -18
View File
@@ -31,8 +31,8 @@ import { pickPort } from "@server/routers/target/helpers";
import { resourcePassword } from "@server/db"; import { resourcePassword } from "@server/db";
import { hashPassword } from "@server/auth/password"; import { hashPassword } from "@server/auth/password";
import { isValidCIDR, isValidIP, isValidUrlGlobPattern } from "../validators"; import { isValidCIDR, isValidIP, isValidUrlGlobPattern } from "../validators";
import { isLicensedOrSubscribed } from "../isLicencedOrSubscribed"; import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
import { build } from "@server/build"; import { tierMatrix } from "../billing/tierMatrix";
export type ProxyResourcesResults = { export type ProxyResourcesResults = {
proxyResource: Resource; proxyResource: Resource;
@@ -212,12 +212,8 @@ export async function updateProxyResources(
} else { } else {
// Update existing resource // Update existing resource
const isLicensed = await isLicensedOrSubscribed(orgId); const isLicensed = await isLicensedOrSubscribed(orgId, tierMatrix.maintencePage);
if (build == "enterprise" && !isLicensed) { if (!isLicensed) {
logger.warn(
"Server is not licensed! Clearing set maintenance screen values"
);
// null the maintenance mode fields if not licensed
resourceData.maintenance = undefined; resourceData.maintenance = undefined;
} }
@@ -587,13 +583,15 @@ export async function updateProxyResources(
// Sync rules // Sync rules
for (const [index, rule] of resourceData.rules?.entries() || []) { for (const [index, rule] of resourceData.rules?.entries() || []) {
const intendedPriority = rule.priority ?? index + 1;
const existingRule = existingRules[index]; const existingRule = existingRules[index];
if (existingRule) { if (existingRule) {
if ( if (
existingRule.action !== getRuleAction(rule.action) || existingRule.action !== getRuleAction(rule.action) ||
existingRule.match !== rule.match.toUpperCase() || existingRule.match !== rule.match.toUpperCase() ||
existingRule.value !== existingRule.value !==
getRuleValue(rule.match.toUpperCase(), rule.value) getRuleValue(rule.match.toUpperCase(), rule.value) ||
existingRule.priority !== intendedPriority
) { ) {
validateRule(rule); validateRule(rule);
await trx await trx
@@ -604,7 +602,8 @@ export async function updateProxyResources(
value: getRuleValue( value: getRuleValue(
rule.match.toUpperCase(), rule.match.toUpperCase(),
rule.value rule.value
) ),
priority: intendedPriority
}) })
.where( .where(
eq(resourceRules.ruleId, existingRule.ruleId) eq(resourceRules.ruleId, existingRule.ruleId)
@@ -620,7 +619,7 @@ export async function updateProxyResources(
rule.match.toUpperCase(), rule.match.toUpperCase(),
rule.value rule.value
), ),
priority: index + 1 // start priorities at 1 priority: intendedPriority
}); });
} }
} }
@@ -649,12 +648,8 @@ export async function updateProxyResources(
); );
} }
const isLicensed = await isLicensedOrSubscribed(orgId); const isLicensed = await isLicensedOrSubscribed(orgId, tierMatrix.maintencePage);
if (build == "enterprise" && !isLicensed) { if (!isLicensed) {
logger.warn(
"Server is not licensed! Clearing set maintenance screen values"
);
// null the maintenance mode fields if not licensed
resourceData.maintenance = undefined; resourceData.maintenance = undefined;
} }
@@ -809,7 +804,7 @@ export async function updateProxyResources(
action: getRuleAction(rule.action), action: getRuleAction(rule.action),
match: rule.match.toUpperCase(), match: rule.match.toUpperCase(),
value: getRuleValue(rule.match.toUpperCase(), rule.value), value: getRuleValue(rule.match.toUpperCase(), rule.value),
priority: index + 1 // start priorities at 1 priority: rule.priority ?? index + 1
}); });
} }
+37 -3
View File
@@ -78,7 +78,8 @@ export const RuleSchema = z
.object({ .object({
action: z.enum(["allow", "deny", "pass"]), action: z.enum(["allow", "deny", "pass"]),
match: z.enum(["cidr", "path", "ip", "country", "asn"]), match: z.enum(["cidr", "path", "ip", "country", "asn"]),
value: z.string() value: z.string(),
priority: z.int().optional()
}) })
.refine( .refine(
(rule) => { (rule) => {
@@ -268,6 +269,39 @@ export const ResourceSchema = z
path: ["auth"], path: ["auth"],
error: "When protocol is 'tcp' or 'udp', 'auth' must not be provided" error: "When protocol is 'tcp' or 'udp', 'auth' must not be provided"
} }
)
.refine(
(resource) => {
// Skip validation for targets-only resources
if (isTargetsOnlyResource(resource)) {
return true;
}
// Skip validation if no rules are defined
if (!resource.rules || resource.rules.length === 0) return true;
const finalPriorities: number[] = [];
let priorityCounter = 1;
// Gather priorities, assigning auto-priorities where needed
// following the logic from the backend implementation where
// empty priorities are auto-assigned a value of 1 + index of rule
for (const rule of resource.rules) {
if (rule.priority !== undefined) {
finalPriorities.push(rule.priority);
} else {
finalPriorities.push(priorityCounter);
}
priorityCounter++;
}
// Validate for duplicate priorities
return finalPriorities.length === new Set(finalPriorities).size;
},
{
path: ["rules"],
message:
"Rules have conflicting or invalid priorities (must be unique, including auto-assigned ones)"
}
); );
export function isTargetsOnlyResource(resource: any): boolean { export function isTargetsOnlyResource(resource: any): boolean {
@@ -290,8 +324,8 @@ export const ClientResourceSchema = z
alias: z alias: z
.string() .string()
.regex( .regex(
/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/, /^(?:[a-zA-Z0-9*?](?:[a-zA-Z0-9*?-]{0,61}[a-zA-Z0-9*?])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/,
"Alias must be a fully qualified domain name (e.g., example.com)" "Alias must be a fully qualified domain name with optional wildcards (e.g., example.com, *.example.com, host-0?.example.internal)"
) )
.optional(), .optional(),
roles: z roles: z
+54 -20
View File
@@ -1,21 +1,26 @@
import { listExitNodes } from "#dynamic/lib/exitNodes";
import { build } from "@server/build";
import { import {
approvals,
clients, clients,
db, db,
olms, olms,
orgs, orgs,
roleClients, roleClients,
roles, roles,
Transaction,
userClients, userClients,
userOrgs, userOrgs
Transaction
} from "@server/db"; } from "@server/db";
import { eq, and, notInArray } from "drizzle-orm";
import { listExitNodes } from "#dynamic/lib/exitNodes";
import { getNextAvailableClientSubnet } from "@server/lib/ip";
import logger from "@server/logger";
import { rebuildClientAssociationsFromClient } from "./rebuildClientAssociations";
import { sendTerminateClient } from "@server/routers/client/terminate";
import { getUniqueClientName } from "@server/db/names"; import { getUniqueClientName } from "@server/db/names";
import { getNextAvailableClientSubnet } from "@server/lib/ip";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
import logger from "@server/logger";
import { sendTerminateClient } from "@server/routers/client/terminate";
import { and, eq, notInArray, type InferInsertModel } from "drizzle-orm";
import { rebuildClientAssociationsFromClient } from "./rebuildClientAssociations";
import { OlmErrorCodes } from "@server/routers/olm/error";
import { tierMatrix } from "./billing/tierMatrix";
export async function calculateUserClientsForOrgs( export async function calculateUserClientsForOrgs(
userId: string, userId: string,
@@ -38,13 +43,15 @@ export async function calculateUserClientsForOrgs(
const allUserOrgs = await transaction const allUserOrgs = await transaction
.select() .select()
.from(userOrgs) .from(userOrgs)
.innerJoin(roles, eq(roles.roleId, userOrgs.roleId))
.where(eq(userOrgs.userId, userId)); .where(eq(userOrgs.userId, userId));
const userOrgIds = allUserOrgs.map((uo) => uo.orgId); const userOrgIds = allUserOrgs.map(({ userOrgs: uo }) => uo.orgId);
// For each OLM, ensure there's a client in each org the user is in // For each OLM, ensure there's a client in each org the user is in
for (const olm of userOlms) { for (const olm of userOlms) {
for (const userOrg of allUserOrgs) { for (const userRoleOrg of allUserOrgs) {
const { userOrgs: userOrg, roles: role } = userRoleOrg;
const orgId = userOrg.orgId; const orgId = userOrg.orgId;
const [org] = await transaction const [org] = await transaction
@@ -182,21 +189,47 @@ export async function calculateUserClientsForOrgs(
const niceId = await getUniqueClientName(orgId); const niceId = await getUniqueClientName(orgId);
const isOrgLicensed = await isLicensedOrSubscribed(
userOrg.orgId,
tierMatrix.deviceApprovals
);
const requireApproval =
build !== "oss" &&
isOrgLicensed &&
role.requireDeviceApproval;
const newClientData: InferInsertModel<typeof clients> = {
userId,
orgId: userOrg.orgId,
exitNodeId: randomExitNode.exitNodeId,
name: olm.name || "User Client",
subnet: updatedSubnet,
olmId: olm.olmId,
type: "olm",
niceId,
approvalState: requireApproval ? "pending" : null
};
// Create the client // Create the client
const [newClient] = await transaction const [newClient] = await transaction
.insert(clients) .insert(clients)
.values({ .values(newClientData)
userId,
orgId: userOrg.orgId,
exitNodeId: randomExitNode.exitNodeId,
name: olm.name || "User Client",
subnet: updatedSubnet,
olmId: olm.olmId,
type: "olm",
niceId
})
.returning(); .returning();
// create approval request
if (requireApproval) {
await transaction
.insert(approvals)
.values({
timestamp: Math.floor(new Date().getTime() / 1000),
orgId: userOrg.orgId,
clientId: newClient.clientId,
userId,
type: "user_device"
})
.returning();
}
await rebuildClientAssociationsFromClient( await rebuildClientAssociationsFromClient(
newClient, newClient,
transaction transaction
@@ -275,6 +308,7 @@ async function cleanupOrphanedClients(
if (deletedClient.olmId) { if (deletedClient.olmId) {
await sendTerminateClient( await sendTerminateClient(
deletedClient.clientId, deletedClient.clientId,
OlmErrorCodes.TERMINATED_DELETED,
deletedClient.olmId deletedClient.olmId
); );
} }
+4
View File
@@ -3,6 +3,7 @@ import { cleanUpOldLogs as cleanUpOldAccessLogs } from "#dynamic/lib/logAccessAu
import { cleanUpOldLogs as cleanUpOldActionLogs } from "#dynamic/middlewares/logActionAudit"; import { cleanUpOldLogs as cleanUpOldActionLogs } from "#dynamic/middlewares/logActionAudit";
import { cleanUpOldLogs as cleanUpOldRequestLogs } from "@server/routers/badger/logRequestAudit"; import { cleanUpOldLogs as cleanUpOldRequestLogs } from "@server/routers/badger/logRequestAudit";
import { gt, or } from "drizzle-orm"; import { gt, or } from "drizzle-orm";
import { cleanUpOldFingerprintSnapshots } from "@server/routers/olm/fingerprintingUtils";
export function initLogCleanupInterval() { export function initLogCleanupInterval() {
return setInterval( return setInterval(
@@ -26,6 +27,7 @@ export function initLogCleanupInterval() {
) )
); );
// TODO: handle when there are multiple nodes doing this clearing using redis
for (const org of orgsToClean) { for (const org of orgsToClean) {
const { const {
orgId, orgId,
@@ -55,6 +57,8 @@ export function initLogCleanupInterval() {
); );
} }
} }
await cleanUpOldFingerprintSnapshots(365);
}, },
3 * 60 * 60 * 1000 3 * 60 * 60 * 1000
); // every 3 hours ); // every 3 hours
+5
View File
@@ -107,6 +107,11 @@ export class Config {
process.env.MAXMIND_ASN_PATH = parsedConfig.server.maxmind_asn_path; process.env.MAXMIND_ASN_PATH = parsedConfig.server.maxmind_asn_path;
} }
process.env.DISABLE_ENTERPRISE_FEATURES = parsedConfig.flags
?.disable_enterprise_features
? "true"
: "false";
this.rawConfig = parsedConfig; this.rawConfig = parsedConfig;
} }
+1 -1
View File
@@ -2,7 +2,7 @@ import path from "path";
import { fileURLToPath } from "url"; import { fileURLToPath } from "url";
// This is a placeholder value replaced by the build process // This is a placeholder value replaced by the build process
export const APP_VERSION = "1.14.0"; export const APP_VERSION = "1.15.3";
export const __FILENAME = fileURLToPath(import.meta.url); export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME); export const __DIRNAME = path.dirname(__FILENAME);
+1 -1
View File
@@ -182,7 +182,7 @@ export async function createUserAccountOrg(
const customerId = await createCustomer(orgId, userEmail); const customerId = await createCustomer(orgId, userEmail);
if (customerId) { if (customerId) {
await usageService.updateDaily(orgId, FeatureId.USERS, 1, customerId); // Only 1 because we are crating the org await usageService.updateCount(orgId, FeatureId.USERS, 1, customerId); // Only 1 because we are crating the org
} }
return { return {
+3
View File
@@ -0,0 +1,3 @@
export const getEnvOrYaml = (envVar: string) => (valFromYaml: any) => {
return process.env[envVar] ?? valFromYaml;
};
+6 -15
View File
@@ -1,17 +1,8 @@
import { build } from "@server/build"; import { Tier } from "@server/types/Tiers";
import license from "#dynamic/license/license";
import { getOrgTierData } from "#dynamic/lib/billing";
import { TierId } from "@server/lib/billing/tiers";
export async function isLicensedOrSubscribed(orgId: string): Promise<boolean> { export async function isLicensedOrSubscribed(
if (build === "enterprise") { orgId: string,
return await license.isUnlocked(); tiers: Tier[]
} ): Promise<boolean> {
return false;
if (build === "saas") {
const { tier } = await getOrgTierData(orgId);
return tier === TierId.STANDARD;
}
return true;
} }
+8
View File
@@ -0,0 +1,8 @@
import { Tier } from "@server/types/Tiers";
export async function isSubscribed(
orgId: string,
tiers: Tier[]
): Promise<boolean> {
return false;
}
+7 -6
View File
@@ -3,13 +3,10 @@ import yaml from "js-yaml";
import { configFilePath1, configFilePath2 } from "./consts"; import { configFilePath1, configFilePath2 } from "./consts";
import { z } from "zod"; import { z } from "zod";
import stoi from "./stoi"; import stoi from "./stoi";
import { getEnvOrYaml } from "./getEnvOrYaml";
const portSchema = z.number().positive().gt(0).lte(65535); const portSchema = z.number().positive().gt(0).lte(65535);
const getEnvOrYaml = (envVar: string) => (valFromYaml: any) => {
return process.env[envVar] ?? valFromYaml;
};
export const configSchema = z export const configSchema = z
.object({ .object({
app: z app: z
@@ -311,7 +308,10 @@ export const configSchema = z
.object({ .object({
smtp_host: z.string().optional(), smtp_host: z.string().optional(),
smtp_port: portSchema.optional(), smtp_port: portSchema.optional(),
smtp_user: z.string().optional(), smtp_user: z
.string()
.optional()
.transform(getEnvOrYaml("EMAIL_SMTP_USER")),
smtp_pass: z smtp_pass: z
.string() .string()
.optional() .optional()
@@ -331,7 +331,8 @@ export const configSchema = z
disable_local_sites: z.boolean().optional(), disable_local_sites: z.boolean().optional(),
disable_basic_wireguard_sites: z.boolean().optional(), disable_basic_wireguard_sites: z.boolean().optional(),
disable_config_managed_domains: z.boolean().optional(), disable_config_managed_domains: z.boolean().optional(),
disable_product_help_banners: z.boolean().optional() disable_product_help_banners: z.boolean().optional(),
disable_enterprise_features: z.boolean().optional()
}) })
.optional(), .optional(),
dns: z dns: z
+7 -1
View File
@@ -12,6 +12,10 @@ export type LicenseStatus = {
isLicenseValid: boolean; // Is the license key valid? isLicenseValid: boolean; // Is the license key valid?
hostId: string; // Host ID hostId: string; // Host ID
tier?: LicenseKeyTier; tier?: LicenseKeyTier;
maxSites?: number;
usedSites?: number;
maxUsers?: number;
usedUsers?: number;
}; };
export type LicenseKeyCache = { export type LicenseKeyCache = {
@@ -22,12 +26,14 @@ export type LicenseKeyCache = {
type?: LicenseKeyType; type?: LicenseKeyType;
tier?: LicenseKeyTier; tier?: LicenseKeyTier;
terminateAt?: Date; terminateAt?: Date;
quantity?: number;
quantity_2?: number;
}; };
export class License { export class License {
private serverSecret!: string; private serverSecret!: string;
constructor(private hostMeta: HostMeta) {} constructor(private hostMeta: HostMeta) { }
public async check(): Promise<LicenseStatus> { public async check(): Promise<LicenseStatus> {
return { return {
+1
View File
@@ -29,3 +29,4 @@ export * from "./verifyUserIsOrgOwner";
export * from "./verifySiteResourceAccess"; export * from "./verifySiteResourceAccess";
export * from "./logActionAudit"; export * from "./logActionAudit";
export * from "./verifyOlmAccess"; export * from "./verifyOlmAccess";
export * from "./verifyLimits";
+1
View File
@@ -13,3 +13,4 @@ export * from "./verifyApiKeyIsRoot";
export * from "./verifyApiKeyApiKeyAccess"; export * from "./verifyApiKeyApiKeyAccess";
export * from "./verifyApiKeyClientAccess"; export * from "./verifyApiKeyClientAccess";
export * from "./verifyApiKeySiteResourceAccess"; export * from "./verifyApiKeySiteResourceAccess";
export * from "./verifyApiKeyIdpAccess";
@@ -0,0 +1,88 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { idp, idpOrg, apiKeyOrg } from "@server/db";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
export async function verifyApiKeyIdpAccess(
req: Request,
res: Response,
next: NextFunction
) {
try {
const apiKey = req.apiKey;
const idpId = req.params.idpId || req.body.idpId || req.query.idpId;
const orgId = req.params.orgId;
if (!apiKey) {
return next(
createHttpError(HttpCode.UNAUTHORIZED, "Key not authenticated")
);
}
if (!orgId) {
return next(
createHttpError(HttpCode.BAD_REQUEST, "Invalid organization ID")
);
}
if (!idpId) {
return next(
createHttpError(HttpCode.BAD_REQUEST, "Invalid IDP ID")
);
}
if (apiKey.isRoot) {
// Root keys can access any IDP in any org
return next();
}
const [idpRes] = await db
.select()
.from(idp)
.innerJoin(idpOrg, eq(idp.idpId, idpOrg.idpId))
.where(and(eq(idp.idpId, idpId), eq(idpOrg.orgId, orgId)))
.limit(1);
if (!idpRes || !idpRes.idp || !idpRes.idpOrg) {
return next(
createHttpError(
HttpCode.NOT_FOUND,
`IdP with ID ${idpId} not found for organization ${orgId}`
)
);
}
if (!req.apiKeyOrg) {
const apiKeyOrgRes = await db
.select()
.from(apiKeyOrg)
.where(
and(
eq(apiKeyOrg.apiKeyId, apiKey.apiKeyId),
eq(apiKeyOrg.orgId, idpRes.idpOrg.orgId)
)
);
req.apiKeyOrg = apiKeyOrgRes[0];
}
if (!req.apiKeyOrg) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"Key does not have access to this organization"
)
);
}
return next();
} catch (error) {
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"Error verifying IDP access"
)
);
}
}
@@ -4,7 +4,6 @@ import { apiKeyOrg } from "@server/db";
import { and, eq } from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import logger from "@server/logger";
export async function verifyApiKeyOrgAccess( export async function verifyApiKeyOrgAccess(
req: Request, req: Request,
+43
View File
@@ -0,0 +1,43 @@
import { Request, Response, NextFunction } from "express";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
import { usageService } from "@server/lib/billing/usageService";
import { build } from "@server/build";
export async function verifyLimits(
req: Request,
res: Response,
next: NextFunction
) {
if (build != "saas") {
return next();
}
const orgId = req.userOrgId || req.apiKeyOrg?.orgId || req.params.orgId;
if (!orgId) {
return next(); // its fine if we silently fail here because this is not critical to operation or security and its better user experience if we dont fail
}
try {
const reject = await usageService.checkLimitSet(orgId);
if (reject) {
return next(
createHttpError(
HttpCode.PAYMENT_REQUIRED,
"Organization has exceeded its usage limits. Please upgrade your plan or contact support."
)
);
}
return next();
} catch (e) {
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"Error checking limits"
)
);
}
}
+40 -17
View File
@@ -11,36 +11,59 @@
* This file is not licensed under the AGPLv3. * This file is not licensed under the AGPLv3.
*/ */
import { getTierPriceSet } from "@server/lib/billing/tiers";
import { getOrgSubscriptionData } from "#private/routers/billing/getOrgSubscription";
import { build } from "@server/build"; import { build } from "@server/build";
import { db, customers, subscriptions } from "@server/db";
import { Tier } from "@server/types/Tiers";
import { eq, and, ne } from "drizzle-orm";
export async function getOrgTierData( export async function getOrgTierData(
orgId: string orgId: string
): Promise<{ tier: string | null; active: boolean }> { ): Promise<{ tier: Tier | null; active: boolean }> {
let tier = null; let tier: Tier | null = null;
let active = false; let active = false;
if (build !== "saas") { if (build !== "saas") {
return { tier, active }; return { tier, active };
} }
const { subscription, items } = await getOrgSubscriptionData(orgId); try {
// Get customer for org
const [customer] = await db
.select()
.from(customers)
.where(eq(customers.orgId, orgId))
.limit(1);
if (items && items.length > 0) { if (customer) {
const tierPriceSet = getTierPriceSet(); // Query for active subscriptions that are not license type
// Iterate through tiers in order (earlier keys are higher tiers) const [subscription] = await db
for (const [tierId, priceId] of Object.entries(tierPriceSet)) { .select()
// Check if any subscription item matches this tier's price ID .from(subscriptions)
const matchingItem = items.find((item) => item.priceId === priceId); .where(
if (matchingItem) { and(
tier = tierId; eq(subscriptions.customerId, customer.customerId),
break; eq(subscriptions.status, "active"),
ne(subscriptions.type, "license")
)
)
.limit(1);
if (subscription) {
// Validate that subscription.type is one of the expected tier values
if (
subscription.type === "tier1" ||
subscription.type === "tier2" ||
subscription.type === "tier3"
) {
tier = subscription.type;
active = true;
}
} }
} }
} catch (error) {
// If org not found or error occurs, return null tier and inactive
// This is acceptable behavior as per the function signature
} }
if (subscription && subscription.status === "active") {
active = true;
}
return { tier, active }; return { tier, active };
} }
+1 -10
View File
@@ -19,7 +19,6 @@ import * as fs from "fs";
import logger from "@server/logger"; import logger from "@server/logger";
import cache from "@server/lib/cache"; import cache from "@server/lib/cache";
let encryptionKeyPath = "";
let encryptionKeyHex = ""; let encryptionKeyHex = "";
let encryptionKey: Buffer; let encryptionKey: Buffer;
function loadEncryptData() { function loadEncryptData() {
@@ -27,15 +26,7 @@ function loadEncryptData() {
return; // already loaded return; // already loaded
} }
encryptionKeyPath = config.getRawPrivateConfig().server.encryption_key_path; encryptionKeyHex = config.getRawPrivateConfig().server.encryption_key;
if (!fs.existsSync(encryptionKeyPath)) {
throw new Error(
"Encryption key file not found. Please generate one first."
);
}
encryptionKeyHex = fs.readFileSync(encryptionKeyPath, "utf8").trim();
encryptionKey = Buffer.from(encryptionKeyHex, "hex"); encryptionKey = Buffer.from(encryptionKeyHex, "hex");
} }
+2 -2
View File
@@ -13,8 +13,6 @@
import { build } from "@server/build"; import { build } from "@server/build";
import { db, Org, orgs, ResourceSession, sessions, users } from "@server/db"; import { db, Org, orgs, ResourceSession, sessions, users } from "@server/db";
import { getOrgTierData } from "#private/lib/billing";
import { TierId } from "@server/lib/billing/tiers";
import license from "#private/license/license"; import license from "#private/license/license";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { import {
@@ -80,6 +78,8 @@ export async function checkOrgAccessPolicy(
} }
} }
// TODO: check that the org is subscribed
// get the needed data // get the needed data
if (!props.org) { if (!props.org) {
+5 -10
View File
@@ -65,6 +65,11 @@ export class PrivateConfig {
this.rawPrivateConfig.branding?.logo?.dark_path || undefined; this.rawPrivateConfig.branding?.logo?.dark_path || undefined;
} }
if (this.rawPrivateConfig.app.identity_provider_mode) {
process.env.IDENTITY_PROVIDER_MODE =
this.rawPrivateConfig.app.identity_provider_mode;
}
process.env.BRANDING_LOGO_AUTH_WIDTH = this.rawPrivateConfig.branding process.env.BRANDING_LOGO_AUTH_WIDTH = this.rawPrivateConfig.branding
?.logo?.auth_page?.width ?.logo?.auth_page?.width
? this.rawPrivateConfig.branding?.logo?.auth_page?.width.toString() ? this.rawPrivateConfig.branding?.logo?.auth_page?.width.toString()
@@ -125,16 +130,6 @@ export class PrivateConfig {
this.rawPrivateConfig.server.reo_client_id; this.rawPrivateConfig.server.reo_client_id;
} }
if (this.rawPrivateConfig.stripe?.s3Bucket) {
process.env.S3_BUCKET = this.rawPrivateConfig.stripe.s3Bucket;
}
if (this.rawPrivateConfig.stripe?.localFilePath) {
process.env.LOCAL_FILE_PATH =
this.rawPrivateConfig.stripe.localFilePath;
}
if (this.rawPrivateConfig.stripe?.s3Region) {
process.env.S3_REGION = this.rawPrivateConfig.stripe.s3Region;
}
if (this.rawPrivateConfig.flags.use_pangolin_dns) { if (this.rawPrivateConfig.flags.use_pangolin_dns) {
process.env.USE_PANGOLIN_DNS = process.env.USE_PANGOLIN_DNS =
this.rawPrivateConfig.flags.use_pangolin_dns.toString(); this.rawPrivateConfig.flags.use_pangolin_dns.toString();
@@ -50,10 +50,14 @@ export async function sendToExitNode(
); );
} }
return sendToClient(remoteExitNode.remoteExitNodeId, { return sendToClient(
type: request.remoteType, remoteExitNode.remoteExitNodeId,
data: request.data {
}); type: request.remoteType,
data: request.data
},
{ incrementConfigVersion: true }
);
} else { } else {
let hostname = exitNode.reachableAt; let hostname = exitNode.reachableAt;
+1 -1
View File
@@ -288,7 +288,7 @@ export function selectBestExitNode(
const validNodes = pingResults.filter((n) => !n.error && n.weight > 0); const validNodes = pingResults.filter((n) => !n.error && n.weight > 0);
if (validNodes.length === 0) { if (validNodes.length === 0) {
logger.error("No valid exit nodes available"); logger.debug("No valid exit nodes available");
return null; return null;
} }
@@ -0,0 +1,32 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import { build } from "@server/build";
import license from "#private/license/license";
import { isSubscribed } from "#private/lib/isSubscribed";
import { Tier } from "@server/types/Tiers";
export async function isLicensedOrSubscribed(
orgId: string,
tiers: Tier[]
): Promise<boolean> {
if (build === "enterprise") {
return await license.isUnlocked();
}
if (build === "saas") {
return isSubscribed(orgId, tiers);
}
return false;
}
+29
View File
@@ -0,0 +1,29 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import { build } from "@server/build";
import { getOrgTierData } from "#private/lib/billing";
import { Tier } from "@server/types/Tiers";
export async function isSubscribed(
orgId: string,
tiers: Tier[]
): Promise<boolean> {
if (build === "saas") {
const { tier, active } = await getOrgTierData(orgId);
const isTier = (tier && tiers.includes(tier)) || false;
return active && isTier;
}
return false;
}
+60 -40
View File
@@ -24,7 +24,9 @@ export class LockManager {
*/ */
async acquireLock( async acquireLock(
lockKey: string, lockKey: string,
ttlMs: number = 30000 ttlMs: number = 30000,
maxRetries: number = 3,
retryDelayMs: number = 100
): Promise<boolean> { ): Promise<boolean> {
if (!redis || !redis.status || redis.status !== "ready") { if (!redis || !redis.status || redis.status !== "ready") {
return true; return true;
@@ -35,49 +37,67 @@ export class LockManager {
}:${Date.now()}`; }:${Date.now()}`;
const redisKey = `lock:${lockKey}`; const redisKey = `lock:${lockKey}`;
try { for (let attempt = 0; attempt < maxRetries; attempt++) {
// Use SET with NX (only set if not exists) and PX (expire in milliseconds) try {
// This is atomic and handles both setting and expiration // Use SET with NX (only set if not exists) and PX (expire in milliseconds)
const result = await redis.set( // This is atomic and handles both setting and expiration
redisKey, const result = await redis.set(
lockValue, redisKey,
"PX", lockValue,
ttlMs, "PX",
"NX" ttlMs,
); "NX"
if (result === "OK") {
logger.debug(
`Lock acquired: ${lockKey} by ${
config.getRawConfig().gerbil.exit_node_name
}`
); );
return true;
}
// Check if the existing lock is from this worker (reentrant behavior) if (result === "OK") {
const existingValue = await redis.get(redisKey); logger.debug(
if ( `Lock acquired: ${lockKey} by ${
existingValue && config.getRawConfig().gerbil.exit_node_name
existingValue.startsWith( }`
`${config.getRawConfig().gerbil.exit_node_name}:` );
) return true;
) { }
// Extend the lock TTL since it's the same worker
await redis.pexpire(redisKey, ttlMs);
logger.debug(
`Lock extended: ${lockKey} by ${
config.getRawConfig().gerbil.exit_node_name
}`
);
return true;
}
return false; // Check if the existing lock is from this worker (reentrant behavior)
} catch (error) { const existingValue = await redis.get(redisKey);
logger.error(`Failed to acquire lock ${lockKey}:`, error); if (
return false; existingValue &&
existingValue.startsWith(
`${config.getRawConfig().gerbil.exit_node_name}:`
)
) {
// Extend the lock TTL since it's the same worker
await redis.pexpire(redisKey, ttlMs);
logger.debug(
`Lock extended: ${lockKey} by ${
config.getRawConfig().gerbil.exit_node_name
}`
);
return true;
}
// If this isn't our last attempt, wait before retrying with exponential backoff
if (attempt < maxRetries - 1) {
const delay = retryDelayMs * Math.pow(2, attempt);
logger.debug(
`Lock ${lockKey} not available, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`
);
await new Promise((resolve) => setTimeout(resolve, delay));
}
} catch (error) {
logger.error(`Failed to acquire lock ${lockKey} (attempt ${attempt + 1}/${maxRetries}):`, error);
// On error, still retry if we have attempts left
if (attempt < maxRetries - 1) {
const delay = retryDelayMs * Math.pow(2, attempt);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
} }
logger.debug(
`Failed to acquire lock ${lockKey} after ${maxRetries} attempts`
);
return false;
} }
/** /**
+58 -17
View File
@@ -17,6 +17,7 @@ import { privateConfigFilePath1 } from "@server/lib/consts";
import { z } from "zod"; import { z } from "zod";
import { colorsSchema } from "@server/lib/colorsSchema"; import { colorsSchema } from "@server/lib/colorsSchema";
import { build } from "@server/build"; import { build } from "@server/build";
import { getEnvOrYaml } from "@server/lib/getEnvOrYaml";
const portSchema = z.number().positive().gt(0).lte(65535); const portSchema = z.number().positive().gt(0).lte(65535);
@@ -24,7 +25,8 @@ export const privateConfigSchema = z.object({
app: z app: z
.object({ .object({
region: z.string().optional().default("default"), region: z.string().optional().default("default"),
base_domain: z.string().optional() base_domain: z.string().optional(),
identity_provider_mode: z.enum(["global", "org"]).optional()
}) })
.optional() .optional()
.default({ .default({
@@ -32,19 +34,29 @@ export const privateConfigSchema = z.object({
}), }),
server: z server: z
.object({ .object({
encryption_key_path: z encryption_key: z
.string() .string()
.optional() .optional()
.default("./config/encryption.pem") .transform(getEnvOrYaml("SERVER_ENCRYPTION_KEY")),
.pipe(z.string().min(8)), resend_api_key: z
resend_api_key: z.string().optional(), .string()
reo_client_id: z.string().optional(), .optional()
fossorial_api_key: z.string().optional() .transform(getEnvOrYaml("RESEND_API_KEY")),
reo_client_id: z
.string()
.optional()
.transform(getEnvOrYaml("REO_CLIENT_ID")),
fossorial_api: z
.string()
.optional()
.default("https://api.fossorial.io"),
fossorial_api_key: z
.string()
.optional()
.transform(getEnvOrYaml("FOSSORIAL_API_KEY"))
}) })
.optional() .optional()
.default({ .prefault({}),
encryption_key_path: "./config/encryption.pem"
}),
redis: z redis: z
.object({ .object({
host: z.string(), host: z.string(),
@@ -83,7 +95,8 @@ export const privateConfigSchema = z.object({
flags: z flags: z
.object({ .object({
enable_redis: z.boolean().optional().default(false), enable_redis: z.boolean().optional().default(false),
use_pangolin_dns: z.boolean().optional().default(false) use_pangolin_dns: z.boolean().optional().default(false),
use_org_only_idp: z.boolean().optional()
}) })
.optional() .optional()
.prefault({}), .prefault({}),
@@ -156,14 +169,42 @@ export const privateConfigSchema = z.object({
.optional(), .optional(),
stripe: z stripe: z
.object({ .object({
secret_key: z.string(), secret_key: z
webhook_secret: z.string(), .string()
s3Bucket: z.string(), .optional()
s3Region: z.string().default("us-east-1"), .transform(getEnvOrYaml("STRIPE_SECRET_KEY")),
localFilePath: z.string() webhook_secret: z
.string()
.optional()
.transform(getEnvOrYaml("STRIPE_WEBHOOK_SECRET")),
// s3Bucket: z.string(),
// s3Region: z.string().default("us-east-1"),
// localFilePath: z.string().optional()
}) })
.optional() .optional()
}); })
.transform((data) => {
// this to maintain backwards compatibility with the old config file
const identityProviderMode = data.app?.identity_provider_mode;
const useOrgOnlyIdp = data.flags?.use_org_only_idp;
if (identityProviderMode !== undefined) {
return data;
}
if (useOrgOnlyIdp === true) {
return {
...data,
app: { ...data.app, identity_provider_mode: "org" as const }
};
}
if (useOrgOnlyIdp === false) {
return {
...data,
app: { ...data.app, identity_provider_mode: "global" as const }
};
}
return data;
});
export function readPrivateConfigFile() { export function readPrivateConfigFile() {
if (build == "oss") { if (build == "oss") {
+14
View File
@@ -573,6 +573,20 @@ class RedisManager {
} }
} }
public async incr(key: string): Promise<number> {
if (!this.isRedisEnabled() || !this.writeClient) return 0;
try {
return await this.executeWithRetry(
() => this.writeClient!.incr(key),
"Redis INCR"
);
} catch (error) {
logger.error("Redis INCR error:", error);
return 0;
}
}
public async sadd(key: string, member: string): Promise<boolean> { public async sadd(key: string, member: string): Promise<boolean> {
if (!this.isRedisEnabled() || !this.writeClient) return false; if (!this.isRedisEnabled() || !this.writeClient) return false;
@@ -456,11 +456,11 @@ export async function getTraefikConfig(
// ); // );
} else if (resource.maintenanceModeType === "automatic") { } else if (resource.maintenanceModeType === "automatic") {
showMaintenancePage = !hasHealthyServers; showMaintenancePage = !hasHealthyServers;
if (showMaintenancePage) { // if (showMaintenancePage) {
logger.warn( // logger.warn(
`Resource ${resource.name} (${fullDomain}) has no healthy servers - showing maintenance page (AUTOMATIC mode)` // `Resource ${resource.name} (${fullDomain}) has no healthy servers - showing maintenance page (AUTOMATIC mode)`
); // );
} // }
} }
} }
+45 -6
View File
@@ -11,12 +11,12 @@
* This file is not licensed under the AGPLv3. * This file is not licensed under the AGPLv3.
*/ */
import { db, HostMeta } from "@server/db"; import { db, HostMeta, sites, users } from "@server/db";
import { hostMeta, licenseKey } from "@server/db"; import { hostMeta, licenseKey } from "@server/db";
import logger from "@server/logger"; import logger from "@server/logger";
import NodeCache from "node-cache"; import NodeCache from "node-cache";
import { validateJWT } from "./licenseJwt"; import { validateJWT } from "./licenseJwt";
import { eq } from "drizzle-orm"; import { count, eq } from "drizzle-orm";
import moment from "moment"; import moment from "moment";
import { encrypt, decrypt } from "@server/lib/crypto"; import { encrypt, decrypt } from "@server/lib/crypto";
import { import {
@@ -54,6 +54,7 @@ type TokenPayload = {
type: LicenseKeyType; type: LicenseKeyType;
tier: LicenseKeyTier; tier: LicenseKeyTier;
quantity: number; quantity: number;
quantity_2: number;
terminateAt: string; // ISO terminateAt: string; // ISO
iat: number; // Issued at iat: number; // Issued at
}; };
@@ -140,10 +141,20 @@ LQIDAQAB
}; };
} }
// Count used sites and users for license comparison
const [siteCountRes] = await db
.select({ value: count() })
.from(sites);
const [userCountRes] = await db
.select({ value: count() })
.from(users);
const status: LicenseStatus = { const status: LicenseStatus = {
hostId: this.hostMeta.hostMetaId, hostId: this.hostMeta.hostMetaId,
isHostLicensed: true, isHostLicensed: true,
isLicenseValid: false isLicenseValid: false,
usedSites: siteCountRes?.value ?? 0,
usedUsers: userCountRes?.value ?? 0
}; };
this.checkInProgress = true; this.checkInProgress = true;
@@ -151,6 +162,8 @@ LQIDAQAB
try { try {
if (!this.doRecheck && this.statusCache.has(this.statusKey)) { if (!this.doRecheck && this.statusCache.has(this.statusKey)) {
const res = this.statusCache.get("status") as LicenseStatus; const res = this.statusCache.get("status") as LicenseStatus;
res.usedSites = status.usedSites;
res.usedUsers = status.usedUsers;
return res; return res;
} }
logger.debug("Checking license status..."); logger.debug("Checking license status...");
@@ -193,7 +206,9 @@ LQIDAQAB
type: payload.type, type: payload.type,
tier: payload.tier, tier: payload.tier,
iat: new Date(payload.iat * 1000), iat: new Date(payload.iat * 1000),
terminateAt: new Date(payload.terminateAt) terminateAt: new Date(payload.terminateAt),
quantity: payload.quantity,
quantity_2: payload.quantity_2
}); });
if (payload.type === "host") { if (payload.type === "host") {
@@ -292,6 +307,8 @@ LQIDAQAB
cached.tier = payload.tier; cached.tier = payload.tier;
cached.iat = new Date(payload.iat * 1000); cached.iat = new Date(payload.iat * 1000);
cached.terminateAt = new Date(payload.terminateAt); cached.terminateAt = new Date(payload.terminateAt);
cached.quantity = payload.quantity;
cached.quantity_2 = payload.quantity_2;
// Encrypt the updated token before storing // Encrypt the updated token before storing
const encryptedKey = encrypt( const encryptedKey = encrypt(
@@ -317,7 +334,7 @@ LQIDAQAB
} }
} }
// Compute host status // Compute host status: quantity = users, quantity_2 = sites
for (const key of keys) { for (const key of keys) {
const cached = newCache.get(key.licenseKey)!; const cached = newCache.get(key.licenseKey)!;
@@ -329,6 +346,28 @@ LQIDAQAB
if (!cached.valid) { if (!cached.valid) {
continue; continue;
} }
// Only consider quantity if defined and >= 0 (quantity = users, quantity_2 = sites)
if (
cached.quantity_2 !== undefined &&
cached.quantity_2 >= 0
) {
status.maxSites =
(status.maxSites ?? 0) + cached.quantity_2;
}
if (cached.quantity !== undefined && cached.quantity >= 0) {
status.maxUsers = (status.maxUsers ?? 0) + cached.quantity;
}
}
// Invalidate license if over user or site limits
if (
(status.maxSites !== undefined &&
(status.usedSites ?? 0) > status.maxSites) ||
(status.maxUsers !== undefined &&
(status.usedUsers ?? 0) > status.maxUsers)
) {
status.isLicenseValid = false;
} }
// Invalidate old cache and set new cache // Invalidate old cache and set new cache
@@ -502,7 +541,7 @@ LQIDAQAB
// Calculate exponential backoff delay // Calculate exponential backoff delay
const retryDelay = Math.floor( const retryDelay = Math.floor(
initialRetryDelay * initialRetryDelay *
Math.pow(exponentialFactor, attempt - 1) Math.pow(exponentialFactor, attempt - 1)
); );
logger.debug( logger.debug(
@@ -16,35 +16,61 @@ import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import { build } from "@server/build"; import { build } from "@server/build";
import { getOrgTierData } from "#private/lib/billing"; import { getOrgTierData } from "#private/lib/billing";
import { Tier } from "@server/types/Tiers";
export function verifyValidSubscription(tiers: Tier[]) {
return async function (
req: Request,
res: Response,
next: NextFunction
): Promise<any> {
try {
if (build != "saas") {
return next();
}
const orgId =
req.params.orgId ||
req.body.orgId ||
req.query.orgId ||
req.userOrgId;
if (!orgId) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"Organization ID is required to verify subscription"
)
);
}
const { tier, active } = await getOrgTierData(orgId);
const isTier = tiers.includes(tier as Tier);
if (!active) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"Organization does not have an active subscription"
)
);
}
if (!isTier) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"Organization subscription tier does not have access to this feature"
)
);
}
export async function verifyValidSubscription(
req: Request,
res: Response,
next: NextFunction
) {
try {
if (build != "saas") {
return next(); return next();
} } catch (e) {
const tier = await getOrgTierData(req.params.orgId);
if (!tier.active) {
return next( return next(
createHttpError( createHttpError(
HttpCode.FORBIDDEN, HttpCode.INTERNAL_SERVER_ERROR,
"Organization does not have an active subscription" "Error verifying subscription"
) )
); );
} }
};
return next();
} catch (e) {
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"Error verifying subscription"
)
);
}
} }
@@ -0,0 +1,110 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import logger from "@server/logger";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { z } from "zod";
import { fromError } from "zod-validation-error";
import type { Request, Response, NextFunction } from "express";
import { approvals, db, type Approval } from "@server/db";
import { eq, sql, and } from "drizzle-orm";
import response from "@server/lib/response";
const paramsSchema = z.strictObject({
orgId: z.string()
});
const querySchema = z.strictObject({
approvalState: z
.enum(["pending", "approved", "denied", "all"])
.optional()
.default("all")
.catch("all")
});
export type CountApprovalsResponse = {
count: number;
};
export async function countApprovals(
req: Request,
res: Response,
next: NextFunction
) {
try {
const parsedParams = paramsSchema.safeParse(req.params);
if (!parsedParams.success) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
fromError(parsedParams.error).toString()
)
);
}
const parsedQuery = querySchema.safeParse(req.query);
if (!parsedQuery.success) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
fromError(parsedQuery.error).toString()
)
);
}
const { approvalState } = parsedQuery.data;
const { orgId } = parsedParams.data;
let state: Array<Approval["decision"]> = [];
switch (approvalState) {
case "pending":
state = ["pending"];
break;
case "approved":
state = ["approved"];
break;
case "denied":
state = ["denied"];
break;
default:
state = ["approved", "denied", "pending"];
}
const [{ count }] = await db
.select({ count: sql<number>`count(*)` })
.from(approvals)
.where(
and(
eq(approvals.orgId, orgId),
sql`${approvals.decision} in ${state}`
)
);
return response<CountApprovalsResponse>(res, {
data: {
count
},
success: true,
error: false,
message: "Approval count retrieved successfully",
status: HttpCode.OK
});
} catch (error) {
logger.error(error);
return next(
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
);
}
}
+16
View File
@@ -0,0 +1,16 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
export * from "./listApprovals";
export * from "./processPendingApproval";
export * from "./countApprovals";
@@ -0,0 +1,254 @@
/*
* This file is part of a proprietary work.
*
* Copyright (c) 2025 Fossorial, Inc.
* All rights reserved.
*
* This file is licensed under the Fossorial Commercial License.
* You may not use this file except in compliance with the License.
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
*
* This file is not licensed under the AGPLv3.
*/
import logger from "@server/logger";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { z } from "zod";
import { fromError } from "zod-validation-error";
import type { Request, Response, NextFunction } from "express";
import { build } from "@server/build";
import {
approvals,
clients,
db,
users,
olms,
currentFingerprint,
type Approval
} from "@server/db";
import { eq, isNull, sql, not, and, desc } from "drizzle-orm";
import response from "@server/lib/response";
import { getUserDeviceName } from "@server/db/names";
const paramsSchema = z.strictObject({
orgId: z.string()
});
const querySchema = z.strictObject({
limit: z
.string()
.optional()
.default("1000")
.transform(Number)
.pipe(z.int().nonnegative()),
offset: z
.string()
.optional()
.default("0")
.transform(Number)
.pipe(z.int().nonnegative()),
approvalState: z
.enum(["pending", "approved", "denied", "all"])
.optional()
.default("all")
.catch("all"),
clientId: z
.string()
.optional()
.transform((val) => (val ? Number(val) : undefined))
.pipe(z.number().int().positive().optional())
});
async function queryApprovals(
orgId: string,
limit: number,
offset: number,
approvalState: z.infer<typeof querySchema>["approvalState"],
clientId?: number
) {
let state: Array<Approval["decision"]> = [];
switch (approvalState) {
case "pending":
state = ["pending"];
break;
case "approved":
state = ["approved"];
break;
case "denied":
state = ["denied"];
break;
default:
state = ["approved", "denied", "pending"];
}
const res = await db
.select({
approvalId: approvals.approvalId,
orgId: approvals.orgId,
clientId: approvals.clientId,
decision: approvals.decision,
type: approvals.type,
user: {
name: users.name,
userId: users.userId,
username: users.username,
email: users.email
},
clientName: clients.name,
niceId: clients.niceId,
deviceModel: currentFingerprint.deviceModel,
fingerprintPlatform: currentFingerprint.platform,
fingerprintOsVersion: currentFingerprint.osVersion,
fingerprintKernelVersion: currentFingerprint.kernelVersion,
fingerprintArch: currentFingerprint.arch,
fingerprintSerialNumber: currentFingerprint.serialNumber,
fingerprintUsername: currentFingerprint.username,
fingerprintHostname: currentFingerprint.hostname
})
.from(approvals)
.innerJoin(users, and(eq(approvals.userId, users.userId)))
.leftJoin(
clients,
and(
eq(approvals.clientId, clients.clientId),
not(isNull(clients.userId)) // only user devices
)
)
.leftJoin(olms, eq(clients.clientId, olms.clientId))
.leftJoin(currentFingerprint, eq(olms.olmId, currentFingerprint.olmId))
.where(
and(
eq(approvals.orgId, orgId),
sql`${approvals.decision} in ${state}`,
...(clientId ? [eq(approvals.clientId, clientId)] : [])
)
)
.orderBy(
sql`CASE ${approvals.decision} WHEN 'pending' THEN 0 ELSE 1 END`,
desc(approvals.timestamp)
)
.limit(limit)
.offset(offset);
// Process results to format device names and build fingerprint objects
return res.map((approval) => {
const model = approval.deviceModel || null;
const deviceName = approval.clientName
? getUserDeviceName(model, approval.clientName)
: null;
// Build fingerprint object if any fingerprint data exists
const hasFingerprintData =
approval.fingerprintPlatform ||
approval.fingerprintOsVersion ||
approval.fingerprintKernelVersion ||
approval.fingerprintArch ||
approval.fingerprintSerialNumber ||
approval.fingerprintUsername ||
approval.fingerprintHostname ||
approval.deviceModel;
const fingerprint = hasFingerprintData
? {
platform: approval.fingerprintPlatform || null,
osVersion: approval.fingerprintOsVersion || null,
kernelVersion: approval.fingerprintKernelVersion || null,
arch: approval.fingerprintArch || null,
deviceModel: approval.deviceModel || null,
serialNumber: approval.fingerprintSerialNumber || null,
username: approval.fingerprintUsername || null,
hostname: approval.fingerprintHostname || null
}
: null;
const {
clientName,
deviceModel,
fingerprintPlatform,
fingerprintOsVersion,
fingerprintKernelVersion,
fingerprintArch,
fingerprintSerialNumber,
fingerprintUsername,
fingerprintHostname,
...rest
} = approval;
return {
...rest,
deviceName,
fingerprint,
niceId: approval.niceId || null
};
});
}
export type ListApprovalsResponse = {
approvals: NonNullable<Awaited<ReturnType<typeof queryApprovals>>>;
pagination: { total: number; limit: number; offset: number };
};
export async function listApprovals(
req: Request,
res: Response,
next: NextFunction
) {
try {
const parsedParams = paramsSchema.safeParse(req.params);
if (!parsedParams.success) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
fromError(parsedParams.error).toString()
)
);
}
const parsedQuery = querySchema.safeParse(req.query);
if (!parsedQuery.success) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
fromError(parsedQuery.error).toString()
)
);
}
const { limit, offset, approvalState, clientId } = parsedQuery.data;
const { orgId } = parsedParams.data;
const approvalsList = await queryApprovals(
orgId.toString(),
limit,
offset,
approvalState,
clientId
);
const [{ count }] = await db
.select({ count: sql<number>`count(*)` })
.from(approvals);
return response<ListApprovalsResponse>(res, {
data: {
approvals: approvalsList,
pagination: {
total: count,
limit,
offset
}
},
success: true,
error: false,
message: "Approvals retrieved successfully",
status: HttpCode.OK
});
} catch (error) {
logger.error(error);
return next(
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
);
}
}

Some files were not shown because too many files have changed in this diff Show More