Compare commits

..

792 Commits

Author SHA1 Message Date
miloschwartz
a3b852ef45 Merge branch 'dev' into clients-user 2025-12-05 15:17:32 -05:00
miloschwartz
53bb4efbb2 change tunnel to site 2025-12-05 14:58:09 -05:00
miloschwartz
96dbec9352 small fixes from testing 2025-12-05 14:48:33 -05:00
miloschwartz
2d3fbb9704 translate setup page 2025-12-05 12:19:40 -05:00
miloschwartz
d3be1fbf4c update descriptions and add adress back 2025-12-05 12:09:13 -05:00
Owen
89ee57cdf9 Enforce fqdn 2025-12-05 12:03:00 -05:00
miloschwartz
bdfc7fbcdb change phrase 2025-12-05 11:53:13 -05:00
miloschwartz
8726a7f931 remove device code ip check and fix edit resource dialog state issue 2025-12-05 11:47:59 -05:00
miloschwartz
1cae815be5 split install and run commands 2025-12-05 10:51:38 -05:00
miloschwartz
c5befee134 fix close button spacing on mobile 2025-12-05 10:08:35 -05:00
miloschwartz
9cf2dbc2cc fix login page spacing on mobile 2025-12-05 10:04:12 -05:00
Owen
35f9c67cfe Merge branch 'main' into dev 2025-12-05 09:45:17 -05:00
Owen
6707b3c7fe Merge branch 'main' of github.com:fosrl/pangolin 2025-12-05 09:42:58 -05:00
Owen Schwartz
dfb85f2c89 Merge pull request #1980 from bjoernch/patch-1
Update de-DE.json
2025-12-05 09:42:30 -05:00
Björn Felgner
17dec6cf0b Update de-DE.json
I noticed an odd translation in the Pangolin dashboard for the Client feature. It is currently translated into German as “Kunden”, which actually means customers. In German, there is no 1:1 translation for the IT term client, so this wording is misleading. I would suggest removing the translation entirely and leaving it as "Client" which correctly conveys the meaning of client devices.
2025-12-05 10:41:54 +01:00
miloschwartz
8ee4ee7baf remove bg-muted on target sep 2025-12-04 22:11:27 -05:00
Owen
b1b0702886 Make query optional 2025-12-04 22:07:48 -05:00
Owen
92aed108cd Update package 2025-12-04 22:07:48 -05:00
miloschwartz
2dcc94cd14 fix hc port NaN issue 2025-12-04 22:03:37 -05:00
miloschwartz
a7185ff913 add auth info tip 2025-12-04 21:28:42 -05:00
miloschwartz
04e73515b8 add alias to client resources table 2025-12-04 21:21:48 -05:00
miloschwartz
2bad9daaea move edit resource to proxy subpath 2025-12-04 21:18:17 -05:00
miloschwartz
54670e150d simplify create site wizard 2025-12-04 21:12:14 -05:00
miloschwartz
761ed1de9a ensure unique niceId for site resources and normal resources 2025-12-04 21:07:14 -05:00
miloschwartz
078692c818 invalidate queries on save 2025-12-04 17:56:11 -05:00
Owen
53ab51691a update packages 2025-12-04 17:26:24 -05:00
Milo Schwartz
54e2d95b55 Merge pull request #1977 from Fredkiss3/fix/some-fixes
fix: bugs introduced in `separate-tables`
2025-12-04 14:25:30 -08:00
miloschwartz
6e6fa77625 bump version 2025-12-04 17:10:59 -05:00
Owen
5c0c12cabe Update lock 2025-12-04 17:02:45 -05:00
Owen
b3ed7c0129 Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-12-04 17:00:54 -05:00
miloschwartz
10a00ff225 update next version 2025-12-04 16:56:39 -05:00
Fred KISSIE
ba09479827 ♻️ organize imports 2025-12-04 22:50:17 +01:00
Fred KISSIE
1c5c36fc12 ♻️ set the staleTime to Zero for queries so that they are refetched everytime 2025-12-04 22:50:04 +01:00
Fred KISSIE
d37ff6e15b 🐛 resource rols & resource clients shouldn't have the same query key 2025-12-04 22:49:40 +01:00
Owen Schwartz
9288575341 Merge pull request #1971 from water-sucks/add-tls-server-name-to-health-check-fields
feat(healthcheck): add SNI support for target healthchecks
2025-12-04 14:42:25 -05:00
Fred KISSIE
0ceed4c812 📦 update lockfile 2025-12-04 20:30:41 +01:00
Owen
4b61a38501 Merge branch 'add-tls-server-name-to-health-check-fields' of github.com:water-sucks/pangolin into dev 2025-12-04 12:11:41 -05:00
Varun Narravula
ca9273c9ea feat(healthcheck): add SNI input field to target healthcheck config 2025-12-04 12:11:25 -05:00
Owen
810704e190 Merge branch 'add-tls-server-name-to-health-check-fields' of github.com:water-sucks/pangolin into dev 2025-12-04 12:00:51 -05:00
Varun Narravula
f33be1434b feat(schema): add TLS server name column to target healthcheck tables 2025-12-04 12:00:40 -05:00
Varun Narravula
82a9f2b24f feat(healthcheck): add SNI input field to target healthcheck config 2025-12-04 12:00:40 -05:00
Owen
7204b5f0de Merge branch 'add-tls-server-name-to-health-check-fields' of github.com:water-sucks/pangolin into dev 2025-12-04 12:00:04 -05:00
Owen
9b372780bd Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-12-04 11:59:53 -05:00
Varun Narravula
9065385b87 feat(healthcheck): add SNI input field to target healthcheck config 2025-12-04 11:59:18 -05:00
miloschwartz
77306e8c97 add integration routes 2025-12-04 11:48:01 -05:00
miloschwartz
a746ef36a8 Merge branch 'dev' into clients-user 2025-12-04 11:38:05 -05:00
Owen
6e565f1331 Merge branch 'add-tls-server-name-to-health-check-fields' of github.com:water-sucks/pangolin into dev 2025-12-04 11:28:47 -05:00
Varun Narravula
84c608c2cf feat(healthcheck): add SNI input field to target healthcheck config 2025-12-04 11:27:18 -05:00
Milo Schwartz
6da7f58ced Merge pull request #1897 from Fredkiss3/feat/log-analytics
feat: request log analytics
2025-12-04 07:38:54 -08:00
Varun Narravula
351097b04d feat(healthcheck): add SNI input field to target healthcheck config 2025-12-04 10:33:01 -05:00
Varun Narravula
bd3d339905 feat(schema): add TLS server name column to target healthcheck tables 2025-12-04 10:18:20 -05:00
miloschwartz
c6ad36d78e update to next 15.5.7 2025-12-04 09:58:21 -05:00
miloschwartz
eaeb65e9b4 update wording 2025-12-03 22:26:22 -05:00
miloschwartz
4176bdbc81 clarify rules action types closes #1679 2025-12-03 21:30:44 -05:00
miloschwartz
a2cdd8484c changes to wording 2025-12-03 21:17:10 -05:00
Milo Schwartz
23ab76ae08 Merge pull request #1967 from Fredkiss3/refactor/separate-tables-2
Refactor: separate tables (2)
2025-12-03 17:31:46 -08:00
Owen
8eec122114 Fixing holepunching and other bugs 2025-12-03 20:31:37 -05:00
Fred KISSIE
79ccbc8e92 ♻️ compute everything in useQueries 2025-12-04 00:51:56 +01:00
Fred KISSIE
d70da2aa70 🐛 fix paths 2025-12-04 00:51:40 +01:00
Fred KISSIE
c695f50122 ♻️ use Queries 2025-12-04 00:42:59 +01:00
Fred KISSIE
1b09e5b9f9 🚚 move subpages to correct paths 2025-12-04 00:42:50 +01:00
miloschwartz
7efc947e26 auto collapse sidebar on small screens 2025-12-03 18:33:46 -05:00
miloschwartz
4b580105cd change default sort on logs tables closes #1907 2025-12-03 18:20:28 -05:00
miloschwartz
a61c82570a add logs routes to integration api routes closes #1963 2025-12-03 17:45:19 -05:00
Fred KISSIE
6734003d85 ⬆️ upgrade react & next to fix **CVE-2025-55182** 2025-12-03 22:58:02 +01:00
miloschwartz
e49d796b06 fix headers getting cleared on resource save and hide domain type without pangolin dns 2025-12-03 16:04:44 -05:00
miloschwartz
4ab4029625 ease expand animation a little 2025-12-03 15:53:41 -05:00
miloschwartz
5afff3c662 add extra org policy checks to middlewares 2025-12-03 15:50:24 -05:00
miloschwartz
9be5a01173 add niceId col back to table but hide by default 2025-12-03 15:27:58 -05:00
miloschwartz
357f297a3e remove enable_clients flag from config 2025-12-03 15:02:39 -05:00
miloschwartz
e1edbe6067 remove double clients permissions check boxes 2025-12-03 14:56:10 -05:00
miloschwartz
5a859aad29 update create client description 2025-12-03 14:52:57 -05:00
miloschwartz
a28b15a81d update descriptions 2025-12-03 14:47:59 -05:00
miloschwartz
e62186f395 change olm creds text 2025-12-03 14:46:57 -05:00
miloschwartz
11c1efc19c refactor to use DataTable component 2025-12-03 14:45:21 -05:00
Milo Schwartz
8b0491eb52 Merge pull request #1960 from Fredkiss3/refactor/separate-tables
refactor: separate tables
2025-12-03 11:28:21 -08:00
miloschwartz
0032634004 add owner devices to org on create org 2025-12-03 14:19:18 -05:00
miloschwartz
4af10c8108 change to --disable-clients flag 2025-12-03 14:12:53 -05:00
miloschwartz
56cb685813 fix spinner 2025-12-03 14:05:02 -05:00
miloschwartz
ccfe1f7d0a update description text for subnets 2025-12-03 14:01:13 -05:00
Fred KISSIE
bf987d867c 🚧 WIP 2025-12-03 19:28:07 +01:00
Fred KISSIE
3870ced635 Merge branch 'clients-user' into refactor/separate-tables 2025-12-03 17:01:50 +01:00
Fred KISSIE
cb3861a5c8 🚚 rename react-query-provider to TanstackQueryProvider 2025-12-03 16:58:40 +01:00
Fred KISSIE
f5bfddd262 🚨 run eslint --fix 2025-12-03 16:58:12 +01:00
Fred KISSIE
f060063f53 💬 update text 2025-12-02 19:24:02 +01:00
Fred KISSIE
6eb6b44f41 💬 update some text labels 2025-12-02 19:22:43 +01:00
Fred KISSIE
c93ab34021 ♻️ some refactors 2025-12-02 19:08:35 +01:00
Fred KISSIE
06a31bb716 ♻️ separate machine client & user devices tables + move common functions into hooks 2025-12-02 18:58:51 +01:00
Owen
152fb47ca4 Handle unrelay and relaying better 2025-12-02 11:17:08 -05:00
Fred KISSIE
3d400b2321 ♻️ ignore hydrateSaas script and exit(0) on PG migrations 2025-12-02 16:06:10 +01:00
Fred KISSIE
45a82f3ecc 🚧WIP: Separate user & machine clients 2025-12-02 03:14:02 +01:00
Fred KISSIE
342bedc012 🎨 format with prettier 2025-12-02 02:40:50 +01:00
Fred KISSIE
18db4a11c8 ♻️ separate client & proxy resources tables 2025-12-02 02:33:43 +01:00
Owen
a7e32d4013 Fix bugs with updating a resource 2025-12-01 19:57:23 -05:00
Owen
beea28daf3 Handle hp oddities 2025-12-01 16:20:10 -05:00
Owen
b5e94d44ae Fix switching orgs having connections from other orgs 2025-12-01 15:44:25 -05:00
Owen
a623604e96 Improve holepunching 2025-12-01 13:54:30 -05:00
miloschwartz
8c62dfa706 respond with relative code expiration time 2025-12-01 12:36:13 -05:00
Fred KISSIE
610e46f2d5 🚧 WIP: separate proxy & client resources 2025-12-01 18:26:32 +01:00
Owen
92125611e9 Add validation and fix thrown error from updatePeerData 2025-11-30 17:49:55 -05:00
Owen
096da391e5 Add a utility subnet 2025-11-30 17:38:12 -05:00
Owen
dd6b1d88d3 Update peer data when HP changes 2025-11-30 11:39:40 -05:00
Owen
79f0d60533 Start working on HP IP changes 2025-11-30 11:39:40 -05:00
Owen
67665864c2 Clarify that PP is only for TCP 2025-11-29 22:58:09 -05:00
Owen Schwartz
c4de617751 Merge pull request #1940 from fosrl/dependabot/npm_and_yarn/multi-4aa959df0f
Bump dompurify and monaco-editor
2025-11-29 13:15:49 -05:00
Owen Schwartz
19e3c5045e Merge pull request #1942 from fosrl/dependabot/npm_and_yarn/multi-f170272c46
Bump glob and npm
2025-11-29 13:15:30 -05:00
Owen Schwartz
9f63d8bb5b Merge pull request #1941 from fosrl/dependabot/npm_and_yarn/multi-b50d6d7a59
Bump tar and npm
2025-11-29 13:15:09 -05:00
dependabot[bot]
49348c6ab7 Bump glob and npm
Bumps [glob](https://github.com/isaacs/node-glob) to 11.1.0 and updates ancestor dependencies [glob](https://github.com/isaacs/node-glob) and [npm](https://github.com/npm/cli). These dependencies need to be updated together.


Updates `glob` from 11.0.3 to 11.1.0
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v11.0.3...v11.1.0)

Updates `glob` from 10.4.5 to 10.5.0
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v11.0.3...v11.1.0)

Updates `npm` from 11.6.2 to 11.6.4
- [Release notes](https://github.com/npm/cli/releases)
- [Changelog](https://github.com/npm/cli/blob/latest/CHANGELOG.md)
- [Commits](https://github.com/npm/cli/compare/v11.6.2...v11.6.4)

---
updated-dependencies:
- dependency-name: glob
  dependency-version: 11.1.0
  dependency-type: direct:production
- dependency-name: glob
  dependency-version: 10.5.0
  dependency-type: indirect
- dependency-name: npm
  dependency-version: 11.6.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-29 18:11:23 +00:00
dependabot[bot]
0961ac1da1 Bump tar and npm
Removes [tar](https://github.com/isaacs/node-tar). It's no longer used after updating ancestor dependency [npm](https://github.com/npm/cli). These dependencies need to be updated together.


Removes `tar`

Updates `npm` from 11.6.2 to 11.6.4
- [Release notes](https://github.com/npm/cli/releases)
- [Changelog](https://github.com/npm/cli/blob/latest/CHANGELOG.md)
- [Commits](https://github.com/npm/cli/compare/v11.6.2...v11.6.4)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 
  dependency-type: indirect
- dependency-name: npm
  dependency-version: 11.6.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-29 18:11:22 +00:00
dependabot[bot]
6a79436516 Bump dompurify and monaco-editor
Bumps [dompurify](https://github.com/cure53/DOMPurify) and [monaco-editor](https://github.com/microsoft/monaco-editor). These dependencies needed to be updated together.

Updates `dompurify` from 3.1.7 to 3.2.7
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.1.7...3.2.7)

Updates `monaco-editor` from 0.54.0 to 0.55.1
- [Release notes](https://github.com/microsoft/monaco-editor/releases)
- [Changelog](https://github.com/microsoft/monaco-editor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/microsoft/monaco-editor/compare/v0.54.0...v0.55.1)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.2.7
  dependency-type: indirect
- dependency-name: monaco-editor
  dependency-version: 0.55.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-29 18:11:10 +00:00
Owen Schwartz
85b46392e1 Merge pull request #1922 from fosrl/dependabot/npm_and_yarn/body-parser-2.2.1
Bump body-parser from 2.2.0 to 2.2.1
2025-11-29 13:10:02 -05:00
Owen Schwartz
f721c983aa Merge pull request #1936 from PavanendraBaahubali/Pavan/fix-custom-header-reset
Fix: prevent custom headers from being cleared on save
2025-11-29 11:00:46 -05:00
Pavan Kumar
ff0b30fc2e Merge branch 'main' of https://github.com/fosrl/pangolin into fix-custom-header-reset 2025-11-28 19:06:42 +05:30
Pavan Kumar
18070a37a8 fix: keep custom header values when editing resource 2025-11-28 19:06:09 +05:30
miloschwartz
5bd31f87f0 only allow one device auth per session 2025-11-26 15:48:49 -05:00
Owen
de83cf9d8c Handle delete org and checking org policy 2025-11-26 15:35:33 -05:00
Owen
ceae787cf5 Attempt to handle creating/deleting clients and role 2025-11-25 18:20:02 -05:00
Owen
ce6afd0019 Merge branch 'clients-user' of github.com:fosrl/pangolin into clients-user 2025-11-25 15:47:19 -05:00
miloschwartz
d977d57b2a use border instead of bg 2025-11-25 15:45:32 -05:00
dependabot[bot]
7bcd6adf01 Bump body-parser from 2.2.0 to 2.2.1
Bumps [body-parser](https://github.com/expressjs/body-parser) from 2.2.0 to 2.2.1.
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/v2.2.0...v2.2.1)

---
updated-dependencies:
- dependency-name: body-parser
  dependency-version: 2.2.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-25 18:31:04 +00:00
miloschwartz
ac68dbd545 add my-device and force login 2025-11-25 10:51:53 -05:00
Owen Schwartz
d450e2c3ab Merge pull request #1920 from ThanatosDi/feat/add-zh-tw-language
feat: Add zh-TW language
2025-11-25 10:17:46 -05:00
古丁丁
9440a4f879 feat: Add zh-TW language 2025-11-25 11:23:48 +08:00
Owen
73b0411e1c Add alias config 2025-11-24 20:43:26 -05:00
Fred KISSIE
6368b9d837 ♻️ use linechart 2025-11-21 06:33:47 +01:00
Fred KISSIE
1b643fb4b6 🐛 fix Dockerfile 2025-11-21 06:27:13 +01:00
Fred KISSIE
d118c6b666 ♻️also export build file 2025-11-21 06:18:32 +01:00
Fred KISSIE
380e062d25 ♻️export driver in Dockerfile 2025-11-21 06:17:14 +01:00
Fred KISSIE
261f0333b8 💄 remove chart animations 2025-11-21 06:15:05 +01:00
Fred KISSIE
24adca6108 ♻️add auto refetch every 30 seconds 2025-11-21 06:14:48 +01:00
Fred KISSIE
3f440f0f7a 🏷️ fix type for SQLite 2025-11-21 06:10:01 +01:00
Fred KISSIE
ba6defa87c Add request by day chart 2025-11-21 06:03:34 +01:00
Fred KISSIE
887a0ef574 💄 chart for analytics 2025-11-21 05:36:30 +01:00
Fred KISSIE
200743747d 🚧add css variables for chart 2025-11-21 04:51:10 +01:00
Fred KISSIE
2082c5eed2 🚧 Add shadCN chart 2025-11-21 04:50:06 +01:00
Fred KISSIE
a42d012788 load logs per day 2025-11-21 04:48:01 +01:00
Fred KISSIE
82cc51424b 🔨also export driver in the db driver generation script 2025-11-21 04:47:42 +01:00
Fred KISSIE
7924f195aa 💄handle empty data 2025-11-21 04:47:13 +01:00
Fred KISSIE
d41bd3023f 🐛 filter by resource UI 2025-11-21 03:05:40 +01:00
Fred KISSIE
87a0dd2d12 ♻️ remove click 2025-11-21 02:57:44 +01:00
Fred KISSIE
5fd64596eb add top countries list 2025-11-21 02:00:47 +01:00
Owen
d23f61d995 Take into account the existing associations
Use to filter adds and removes in the associations
2025-11-20 16:42:55 -05:00
Owen
7ac27b3883 Switch to update 2025-11-20 16:08:03 -05:00
Owen
9420b41e39 Update the remote subnets 2025-11-20 15:17:48 -05:00
Owen
2cfb0e05cf Lock working without redis? 2025-11-20 14:03:25 -05:00
Owen
5b9386b18a Add lock 2025-11-20 12:40:25 -05:00
Owen
f5c3dff43c Some small bug fixes 2025-11-20 12:24:24 -05:00
Owen
eeb82c8cfe Merge branch 'main' of github.com:fosrl/pangolin 2025-11-20 10:36:38 -05:00
Owen
3750c36aa7 Working on orchestration 2025-11-20 10:31:09 -05:00
Fred KISSIE
3801354ae6 🚧 add country code flag emoji function 2025-11-20 08:37:49 +01:00
Fred KISSIE
266fbb1762 💄nicer colors 2025-11-20 08:22:16 +01:00
Fred KISSIE
5d1f81a92c world map 2025-11-20 08:19:11 +01:00
Fred KISSIE
d6e8eb5307 🧑‍💻add tailwind indicator component 2025-11-20 05:23:16 +01:00
Fred KISSIE
2bc82f49ed add enpoint for getting all resource names 2025-11-20 04:20:31 +01:00
Fred KISSIE
487985558d add react compiler 2025-11-20 04:19:58 +01:00
Fred KISSIE
dc237b8052 💬 update text message from the API 2025-11-20 03:19:43 +01:00
Fred KISSIE
4ed4515262 🚧 starting request analytics page 2025-11-20 02:55:52 +01:00
Fred KISSIE
cd76fa0139 add analytics endpoint 2025-11-20 02:55:33 +01:00
Fred KISSIE
af4b9e83f7 ✏️ fix typos 2025-11-20 02:55:03 +01:00
Owen
fa5facdf33 Fix bugs 2025-11-19 20:03:57 -05:00
Owen
937b36e756 Build client site resource associations and send messages 2025-11-19 18:05:42 -05:00
Fred KISSIE
e90bdf8f97 ♻️ translate sidebar headings 2025-11-19 21:43:34 +01:00
Owen Schwartz
56491cc17b Merge pull request #1896 from fosrl/copilot/configure-auto-login-idp-blueprints
Add blueprint support for auto-login-idp configuration
2025-11-19 14:33:17 -05:00
copilot-swe-agent[bot]
6da531e99b Use IDP ID instead of IDP name for auto-login-idp
Co-authored-by: oschwartz10612 <4999704+oschwartz10612@users.noreply.github.com>
2025-11-19 19:29:52 +00:00
copilot-swe-agent[bot]
01b5158b73 Add auto-login-idp support to blueprints
Co-authored-by: oschwartz10612 <4999704+oschwartz10612@users.noreply.github.com>
2025-11-19 16:50:06 +00:00
copilot-swe-agent[bot]
8f9b665bef Initial plan 2025-11-19 16:43:50 +00:00
Owen
806949879a Merge branch 'dev' into clients-user 2025-11-18 13:53:12 -05:00
Owen
e72e2b53aa Working on targets 2025-11-18 13:53:04 -05:00
Owen Schwartz
10f42fe2e6 Merge pull request #1884 from v1rusnl/main
Bump Traefik to v3.6 due to Docker 29.X.X compatibility
2025-11-18 09:42:38 -05:00
v1rusnl
51b438117a Update Traefik image version to v3.6 2025-11-18 12:44:10 +01:00
v1rusnl
d73825dd24 Update Traefik image version to v3.6 2025-11-18 12:41:12 +01:00
miloschwartz
b5c6191c67 add email consent and update audience 2025-11-17 20:50:24 -05:00
Owen
97c707248e Working on updating targets 2025-11-17 20:44:39 -05:00
miloschwartz
02fbc279b5 add email consent and update audience 2025-11-17 20:37:24 -05:00
Owen Schwartz
80a68507cd Merge pull request #1876 from fosrl/crowdin_dev
New Crowdin updates
2025-11-17 11:48:54 -05:00
Owen
dbb1e37033 Update lock 2025-11-17 11:30:25 -05:00
Owen
364b84359e Merge branch 'dev' into clients-user 2025-11-17 11:30:12 -05:00
Owen
93d4a40977 Merge branch 'main' into dev 2025-11-17 11:30:05 -05:00
Owen
97312343e4 Merge branch 'dev' into clients-user 2025-11-17 11:28:47 -05:00
Owen Schwartz
1736ad486a New translations en-us.json (Norwegian Bokmal) 2025-11-17 11:03:26 -05:00
Owen Schwartz
a07ad843a2 New translations en-us.json (Chinese Simplified) 2025-11-17 11:03:24 -05:00
Owen Schwartz
fef9101058 New translations en-us.json (Turkish) 2025-11-17 11:03:23 -05:00
Owen Schwartz
2890ff2605 New translations en-us.json (Russian) 2025-11-17 11:03:21 -05:00
Owen Schwartz
026ad2ccb9 New translations en-us.json (Portuguese) 2025-11-17 11:03:19 -05:00
Owen Schwartz
a82969b778 New translations en-us.json (Polish) 2025-11-17 11:03:18 -05:00
Owen Schwartz
612b04c26f New translations en-us.json (Dutch) 2025-11-17 11:03:16 -05:00
Owen Schwartz
2162f5f76f New translations en-us.json (Korean) 2025-11-17 11:03:14 -05:00
Owen Schwartz
710f16ce68 New translations en-us.json (Italian) 2025-11-17 11:03:13 -05:00
Owen Schwartz
61a4f468ba New translations en-us.json (German) 2025-11-17 11:03:11 -05:00
Owen Schwartz
b00fea5656 New translations en-us.json (Czech) 2025-11-17 11:03:09 -05:00
Owen Schwartz
269ff630aa New translations en-us.json (Bulgarian) 2025-11-17 11:03:08 -05:00
Owen Schwartz
986f7121bd New translations en-us.json (Spanish) 2025-11-17 11:03:06 -05:00
Owen Schwartz
21f0501bc6 New translations en-us.json (French) 2025-11-17 11:03:04 -05:00
Owen Schwartz
2b31dd955c Merge pull request #1848 from fosrl/dependabot/npm_and_yarn/dev-minor-updates-040abfaff9
Bump the dev-minor-updates group across 1 directory with 3 updates
2025-11-17 10:54:38 -05:00
Owen Schwartz
e7aeb4ff89 Merge pull request #1849 from fosrl/dependabot/go_modules/install/prod-minor-updates-4e8dbec1a6
Bump golang.org/x/term from 0.36.0 to 0.37.0 in /install in the prod-minor-updates group
2025-11-17 10:54:23 -05:00
Owen Schwartz
9dd1192033 Merge pull request #1855 from fosrl/dependabot/npm_and_yarn/prod-patch-updates-6d8f9bd785
Bump the prod-patch-updates group across 1 directory with 12 updates
2025-11-17 10:54:15 -05:00
Owen Schwartz
e61da0958f Merge pull request #1841 from fosrl/dependabot/github_actions/docker/setup-qemu-action-3.7.0
Bump docker/setup-qemu-action from 3.6.0 to 3.7.0
2025-11-17 10:49:20 -05:00
Owen Schwartz
fce588057e Merge pull request #1870 from fosrl/dependabot/npm_and_yarn/js-yaml-4.1.1
Bump js-yaml from 4.1.0 to 4.1.1
2025-11-17 10:48:32 -05:00
Owen
33331fd3c8 Merge branch 'Lokowitz-fix-zod-new' into dev 2025-11-17 10:46:40 -05:00
Owen
1261ad3a00 Standardize remote subnets build 2025-11-17 10:22:22 -05:00
Owen
7dcf4d5192 Remove remote subnet 2025-11-17 10:22:22 -05:00
Lokowitz
dc87df5d38 remove temp test 2025-11-17 14:01:11 +00:00
Lokowitz
5d2f65daa9 fix for zod 2025-11-17 13:23:30 +00:00
Lokowitz
58cf471bc4 fix z.coerce.number 2025-11-16 14:29:19 +00:00
Lokowitz
7db99a7dd5 used zod codemod 2025-11-16 14:18:17 +00:00
Lokowitz
000904eb31 upgrade zod 2025-11-16 14:09:22 +00:00
dependabot[bot]
6d1713b6b9 Bump js-yaml from 4.1.0 to 4.1.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-16 06:21:01 +00:00
Owen
de8262d7b9 Batch deletes 2025-11-15 11:51:52 -05:00
miloschwartz
4f026acad8 adjust icon in product update 2025-11-14 17:35:51 -05:00
miloschwartz
5b31bbce8d remove frontend env parsing 2025-11-14 12:25:32 -05:00
Milo Schwartz
e6e80f6fc7 Merge pull request #1814 from Fredkiss3/feat/update-popup
Feat: version updates & product updates popup
2025-11-14 09:13:15 -08:00
Milo Schwartz
bde4492d49 Merge branch 'dev' into feat/update-popup 2025-11-14 09:12:11 -08:00
miloschwartz
7c728c144c fix broken inputs in health check form 2025-11-14 12:00:15 -05:00
Owen
8ad7bcc0d6 Adjust rate limiting position 2025-11-14 11:33:52 -05:00
Owen
e62806d6fb Clean up old timestamps 2025-11-14 11:33:51 -05:00
miloschwartz
4e0a2e441b hide domain status info if not flags.use_pangolin_dns 2025-11-14 11:31:44 -05:00
Owen Schwartz
aabe39137b Merge pull request #1856 from LaurenceJJones/fix-remove-return-before-showing-token
fix: Remove return in installer which prevents showing token
2025-11-14 10:23:21 -05:00
miloschwartz
d9564ed6fe improve spacing and colors 2025-11-13 22:04:29 -05:00
miloschwartz
0798a0c6c2 clean up info box 2025-11-13 21:48:37 -05:00
dependabot[bot]
c9786946b7 Bump the prod-patch-updates group across 1 directory with 12 updates
Bumps the prod-patch-updates group with 12 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@radix-ui/react-avatar](https://github.com/radix-ui/primitives) | `1.1.10` | `1.1.11` |
| [@radix-ui/react-label](https://github.com/radix-ui/primitives) | `2.1.7` | `2.1.8` |
| [@radix-ui/react-progress](https://github.com/radix-ui/primitives) | `1.1.7` | `1.1.8` |
| [@radix-ui/react-separator](https://github.com/radix-ui/primitives) | `1.1.7` | `1.1.8` |
| [@radix-ui/react-slot](https://github.com/radix-ui/primitives) | `1.2.3` | `1.2.4` |
| [axios](https://github.com/axios/axios) | `1.13.1` | `1.13.2` |
| [eslint](https://github.com/eslint/eslint) | `9.39.0` | `9.39.1` |
| [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) | `16.0.1` | `16.0.2` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `4.1.0` | `4.1.1` |
| [maxmind](https://github.com/runk/node-maxmind) | `5.0.0` | `5.0.1` |
| [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.11.0` | `5.11.2` |
| [resend](https://github.com/resend/resend-node) | `6.4.0` | `6.4.2` |



Updates `@radix-ui/react-avatar` from 1.1.10 to 1.1.11
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `@radix-ui/react-label` from 2.1.7 to 2.1.8
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `@radix-ui/react-progress` from 1.1.7 to 1.1.8
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `@radix-ui/react-separator` from 1.1.7 to 1.1.8
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `@radix-ui/react-slot` from 1.2.3 to 1.2.4
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `axios` from 1.13.1 to 1.13.2
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.13.1...v1.13.2)

Updates `eslint` from 9.39.0 to 9.39.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.0...v9.39.1)

Updates `eslint-config-next` from 16.0.1 to 16.0.2
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.0.2/packages/eslint-config-next)

Updates `js-yaml` from 4.1.0 to 4.1.1
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

Updates `maxmind` from 5.0.0 to 5.0.1
- [Release notes](https://github.com/runk/node-maxmind/releases)
- [Commits](https://github.com/runk/node-maxmind/compare/v5.0.0...v5.0.1)

Updates `posthog-node` from 5.11.0 to 5.11.2
- [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.11.2/packages/node)

Updates `resend` from 6.4.0 to 6.4.2
- [Release notes](https://github.com/resend/resend-node/releases)
- [Commits](https://github.com/resend/resend-node/compare/v6.4.0...v6.4.2)

---
updated-dependencies:
- dependency-name: "@radix-ui/react-avatar"
  dependency-version: 1.1.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: "@radix-ui/react-label"
  dependency-version: 2.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: "@radix-ui/react-progress"
  dependency-version: 1.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: "@radix-ui/react-separator"
  dependency-version: 1.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: "@radix-ui/react-slot"
  dependency-version: 1.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: axios
  dependency-version: 1.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: eslint
  dependency-version: 9.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: eslint-config-next
  dependency-version: 16.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: maxmind
  dependency-version: 5.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: posthog-node
  dependency-version: 5.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: resend
  dependency-version: 6.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-14 01:24:49 +00:00
dependabot[bot]
9344ab3546 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.36.0 to 0.37.0
- [Commits](https://github.com/golang/term/compare/v0.36.0...v0.37.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-14 01:23:32 +00:00
dependabot[bot]
1a4078b8a1 Bump the dev-minor-updates group across 1 directory with 3 updates
Bumps the dev-minor-updates group with 3 updates in the / directory: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [esbuild](https://github.com/evanw/esbuild) and [esbuild-node-externals](https://github.com/pradel/esbuild-node-externals).


Updates `@types/node` from 24.9.2 to 24.10.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `esbuild` from 0.25.12 to 0.27.0
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.25.12...v0.27.0)

Updates `esbuild-node-externals` from 1.18.0 to 1.19.1
- [Release notes](https://github.com/pradel/esbuild-node-externals/releases)
- [Commits](https://github.com/pradel/esbuild-node-externals/compare/v1.18.0...esbuild-node-externals-v1.19.1)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
- dependency-name: esbuild
  dependency-version: 0.27.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
- dependency-name: esbuild-node-externals
  dependency-version: 1.19.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-14 01:21:19 +00:00
miloschwartz
ca66637270 remove from address in saas suppport email 2025-11-13 17:37:27 -05:00
miloschwartz
8674ca931b remove from address in saas suppport email 2025-11-13 17:34:49 -05:00
miloschwartz
08c82e072e Merge branch 'clients-user' of https://github.com/fosrl/pangolin into clients-user 2025-11-13 17:33:37 -05:00
miloschwartz
23c9827e4c remove create user client route 2025-11-13 17:32:35 -05:00
Owen Schwartz
864b587b89 Merge pull request #1858 from Pallavikumarimdb/role-in-headers
Role in headers
2025-11-13 17:16:31 -05:00
Owen Schwartz
ca89aa7ce8 Merge pull request #1847 from Pallavikumarimdb/fix/ipv6-validation
Fix: Improve IPv6 and IPV4 validation to support all variants using ipaddr.js
2025-11-13 17:10:47 -05:00
Pallavi Kumari
63a1ecfb86 role in header 2025-11-13 23:31:29 +05:30
Laurence Jones
fbce392137 Remove unnecessary return after success message
Remove redundant return statement after success message.
2025-11-13 12:52:21 +00:00
Pallavi Kumari
c004e969cb improve IPv6 validation to support all variants using ipaddr.js 2025-11-12 00:30:08 +05:30
dependabot[bot]
c6611471b1 Bump docker/setup-qemu-action from 3.6.0 to 3.7.0
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.6.0 to 3.7.0.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](29109295f8...c7c5346462)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: 3.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 01:37:59 +00:00
Owen
bdf1625976 Add headers 2025-11-09 10:46:46 -08:00
Owen
0a5dc17800 Merge branch 'dev' into feat/option-to-regenerate-keys 2025-11-09 10:43:26 -08:00
Owen
fa7aa508ea Merge branch 'dev' into pallavi/feat/make-niceId-editable 2025-11-09 10:39:30 -08:00
Owen
2973b61676 Fix merge confilct 2025-11-08 18:01:42 -08:00
Owen
2428413442 Dont create client 2025-11-08 17:57:54 -08:00
miloschwartz
5602d8ee64 sync user clients to org on add/remove user org 2025-11-08 17:52:05 -08:00
Owen
a70799c8c0 Merge branch 'dev' into clients-user 2025-11-08 16:51:45 -08:00
Owen
d38b321f85 Add missing header 2025-11-08 16:47:03 -08:00
Owen Schwartz
b0ff50a76f Merge pull request #1834 from fosrl/dev
Small Bug Fixes
2025-11-08 16:35:50 -08:00
Owen
37acdc2796 Revert transaction 2025-11-08 16:33:48 -08:00
Owen Schwartz
f3d31cb6de Merge pull request #1833 from fosrl/crowdin_dev
New Crowdin updates
2025-11-08 16:23:11 -08:00
Owen Schwartz
a336955066 New translations en-us.json (Norwegian Bokmal) 2025-11-08 16:22:42 -08:00
Owen Schwartz
a229fc1c61 New translations en-us.json (Chinese Simplified) 2025-11-08 16:22:40 -08:00
Owen Schwartz
7995fd364e New translations en-us.json (Turkish) 2025-11-08 16:22:39 -08:00
Owen Schwartz
5e0d822d45 New translations en-us.json (Russian) 2025-11-08 16:22:38 -08:00
Owen Schwartz
4fddaa8f11 New translations en-us.json (Portuguese) 2025-11-08 16:22:36 -08:00
Owen Schwartz
4a87cecf89 New translations en-us.json (Polish) 2025-11-08 16:22:35 -08:00
Owen Schwartz
ac5ee5c7ca New translations en-us.json (Dutch) 2025-11-08 16:22:34 -08:00
Owen Schwartz
8a8c357563 New translations en-us.json (Korean) 2025-11-08 16:22:32 -08:00
Owen Schwartz
263fd80c18 New translations en-us.json (Italian) 2025-11-08 16:22:31 -08:00
Owen Schwartz
7bdf05bdf5 New translations en-us.json (German) 2025-11-08 16:22:30 -08:00
Owen Schwartz
d00f12967d New translations en-us.json (Czech) 2025-11-08 16:22:28 -08:00
Owen Schwartz
d9991a18e2 New translations en-us.json (Bulgarian) 2025-11-08 16:22:27 -08:00
Owen Schwartz
a51c21cdd2 New translations en-us.json (Spanish) 2025-11-08 16:22:26 -08:00
Owen Schwartz
265cab5b64 New translations en-us.json (French) 2025-11-08 16:22:24 -08:00
Owen
da15e5e77b Remove software-properties-common
Fixes #1828
2025-11-08 16:13:42 -08:00
Owen
a717ca2675 Only uppercase the value if its a country
Fixes #1813
2025-11-08 15:42:46 -08:00
miloschwartz
693c9fbe0f make actions sticky in targets and rules input 2025-11-08 14:39:14 -08:00
Owen
564b290244 Fix #1830 2025-11-08 14:24:28 -08:00
Owen
84d78df67e Merge branch 'main' into dev 2025-11-08 14:20:40 -08:00
Owen
107053a98f Merge branch 'main' of github.com:fosrl/pangolin 2025-11-08 14:20:35 -08:00
Owen Schwartz
6422a78e6f Merge pull request #1830 from hetlelid/patch-2
Update resourceRawSettingsDescription with details
2025-11-08 14:20:21 -08:00
miloschwartz
10f8298161 reset nav logo size 2025-11-08 14:18:43 -08:00
miloschwartz
5f11630e27 minor adjustments to blueprints screens 2025-11-08 14:15:47 -08:00
Owen
a776b2ea94 Fix: qiery perferWildcardCert from db
Fixes #1816
Fixes #1829
2025-11-08 14:14:17 -08:00
miloschwartz
b83ec1b503 remove target unique check 2025-11-08 13:57:00 -08:00
Owen
83bd5957cd Dont allow editing a config managed domain
Ref #1816
2025-11-08 12:18:36 -08:00
Owen
f98b4baa73 Add remote subnets back based on resources 2025-11-08 12:17:33 -08:00
Pallavi Kumari
0af51cebbe scope niceid to the orgId 2025-11-08 19:44:23 +05:30
Pallavi Kumari
abc5f8ec68 show the identifier in the info box 2025-11-08 19:44:23 +05:30
Owen
ddc14d164e Rename nice id to Identifier in the ui 2025-11-08 19:44:23 +05:30
Pallavi Kumari
aeda85fcfb move resource niceid update to general page 2025-11-08 19:44:23 +05:30
Pallavi Kumari
66124f09c4 move site niceId details to general setting page 2025-11-08 19:44:23 +05:30
Pallavi Kumari
ac5fe1486a update url to prevent page redirect 2025-11-08 19:44:23 +05:30
Pallavi Kumari
50ac52d316 fix lint 2025-11-08 19:44:22 +05:30
Pallavi Kumari
f85d9f8b6e fix col 2025-11-08 19:44:22 +05:30
Pallavi Kumari
feb0bd58c8 make resource niceid editable 2025-11-08 19:44:22 +05:30
Pallavi Kumari
32949127d2 Make site niceId editable 2025-11-08 19:44:22 +05:30
Pallavi Kumari
84d24d9bf5 niceId inside resource info 2025-11-08 19:44:22 +05:30
Pallavi Kumari
8e1bb6a6fd add niceId inside info box 2025-11-08 19:44:22 +05:30
hetlelid
66c14c2d09 Update resourceRawSettingsDescription with details
Expanded the description for resourceRawSettings to include mapping details and a documentation link.
2025-11-08 13:24:51 +01:00
miloschwartz
cad4d97fb3 update works 2025-11-07 22:26:28 -08:00
Owen
de53cfb912 Update package lock 2025-11-07 21:57:31 -08:00
miloschwartz
55fd276773 update to node 25? 2025-11-07 21:55:09 -08:00
miloschwartz
7125b49024 add fade 2025-11-07 20:38:36 -08:00
miloschwartz
fb9ed8f592 dont auto close hide col popover on click 2025-11-07 18:22:13 -08:00
miloschwartz
020cb2d794 add friendly col names 2025-11-07 18:16:14 -08:00
miloschwartz
9b2c0d0b67 make org selector sticky top 2025-11-07 18:05:34 -08:00
miloschwartz
3993e5b705 add sitcky table cols for left and right cols 2025-11-07 18:03:44 -08:00
Owen
47bcadb329 Also include direct associations 2025-11-07 16:55:32 -08:00
Owen
00df2c876f Fix delete issue 2025-11-07 16:44:31 -08:00
Fred KISSIE
b4535f3dc4 ✏️ typo fix 2025-11-08 01:34:08 +01:00
miloschwartz
e51fca1f61 add clients to resource 2025-11-07 16:33:17 -08:00
Fred KISSIE
0e7f5b1aef 🌐 localize product update empty text 2025-11-08 00:57:07 +01:00
Fred KISSIE
579a4e1021 add flags for enabling notifications for product updates & new releases 2025-11-08 00:51:56 +01:00
Owen
c813202f92 Add DoNotCreateNewClient 2025-11-07 15:24:32 -08:00
Fred KISSIE
94e1c534ca 💄 add link to read more 2025-11-08 00:19:30 +01:00
Owen
41e21acf42 Fix error related to user id col 2025-11-07 14:59:45 -08:00
Pallavi Kumari
b6e98632b5 move re-key API routes to private api 2025-11-08 02:43:47 +05:30
Owen Schwartz
51db267a4a Merge pull request #1779 from fosrl/dependabot/npm_and_yarn/eslint-config-next-16.0.1
Bump eslint-config-next from 15.5.6 to 16.0.1
2025-11-07 12:15:19 -08:00
Pallavi Kumari
8a5f59cb9f disable re-key button for non licensed 2025-11-08 01:38:47 +05:30
dependabot[bot]
669817818a Bump eslint-config-next from 15.5.6 to 16.0.1
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 15.5.6 to 16.0.1.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.0.1/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 16.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-07 20:07:29 +00:00
Owen Schwartz
b84453bfbe Merge pull request #1825 from fosrl/dependabot/npm_and_yarn/dev-patch-updates-282bba5f0a
Bump the dev-patch-updates group across 1 directory with 5 updates
2025-11-07 12:06:08 -08:00
Owen Schwartz
15d561f59f Merge pull request #1824 from robtec/patch-1
Fix typo in shareSeeOnce message
2025-11-07 12:05:59 -08:00
Fred KISSIE
0745734273 ♻️ include build when getting product udpates 2025-11-07 20:05:51 +01:00
Fred KISSIE
aa3f07f1ba ♻️ make fossorial remote API only configurable on the frontend and only in DEV 2025-11-07 20:05:29 +01:00
Pallavi Kumari
2b8204fdc8 seperate credentials rekeying in modal for reuse 2025-11-07 23:30:24 +05:30
Pallavi Kumari
90e72c6aca hide credentials tab for local sites 2025-11-07 19:27:03 +05:30
Pallavi Kumari
62e2b7ca9e change alert text 2025-11-07 19:27:03 +05:30
Pallavi Kumari
f7e7993fd4 regenerate secret for wireguard 2025-11-07 19:27:03 +05:30
Pallavi Kumari
18cdf070c7 add view setting options 2025-11-07 19:27:03 +05:30
Pallavi Kumari
563a5b3e7e disable credential regenerate button for local and wireguard 2025-11-07 19:27:03 +05:30
Pallavi Kumari
3756aaecda change file naming structure to reGenerate exit node keys 2025-11-07 19:27:03 +05:30
Pallavi Kumari
58a13de0ff fix lint 2025-11-07 19:27:03 +05:30
Pallavi Kumari
d32505a833 Option to regenerate Newt keys 2025-11-07 19:27:03 +05:30
Pallavi Kumari
42091e88cb rename exit node tab to credentials 2025-11-07 19:27:03 +05:30
Pallavi Kumari
c2f607bb9a Option to regenerate olm keys inside client 2025-11-07 19:27:03 +05:30
Pallavi Kumari
3f38080b46 fix lint 2025-11-07 19:27:03 +05:30
Pallavi Kumari
9f9aa07c2d Option to regenerate remote-nodes keys 2025-11-07 19:27:03 +05:30
miloschwartz
76d54b2d0f add add/remove user/roles to siteResources/resources to integration api 2025-11-06 21:27:01 -08:00
Owen
bdb564823d Require valid user token 2025-11-06 21:19:37 -08:00
miloschwartz
b3a616c9f3 remove alerts from cleints and resources tables 2025-11-06 20:21:26 -08:00
Owen
ec1f94791a Remove siteIds and build associations from user role chnages 2025-11-06 20:19:15 -08:00
miloschwartz
bea1c65076 remove remote subnets from front end 2025-11-06 20:16:24 -08:00
miloschwartz
2274a3525b update olm and client routes 2025-11-06 20:12:54 -08:00
dependabot[bot]
749cea5a4d Bump the dev-patch-updates group across 1 directory with 5 updates
Bumps the dev-patch-updates group with 4 updates in the / directory: [@dotenvx/dotenvx](https://github.com/dotenvx/dotenvx), [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss), [esbuild](https://github.com/evanw/esbuild) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@dotenvx/dotenvx` from 1.51.0 to 1.51.1
- [Release notes](https://github.com/dotenvx/dotenvx/releases)
- [Changelog](https://github.com/dotenvx/dotenvx/blob/main/CHANGELOG.md)
- [Commits](https://github.com/dotenvx/dotenvx/compare/v1.51.0...v1.51.1)

Updates `@tailwindcss/postcss` from 4.1.16 to 4.1.17
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.17/packages/@tailwindcss-postcss)

Updates `esbuild` from 0.25.11 to 0.25.12
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.25.11...v0.25.12)

Updates `tailwindcss` from 4.1.16 to 4.1.17
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.17/packages/tailwindcss)

Updates `typescript-eslint` from 8.46.2 to 8.46.3
- [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.46.3/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@dotenvx/dotenvx"
  dependency-version: 1.51.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.1.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: esbuild
  dependency-version: 0.25.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: tailwindcss
  dependency-version: 4.1.17
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: typescript-eslint
  dependency-version: 8.46.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-07 01:23:55 +00:00
miloschwartz
999fb2fff1 Merge branch 'dev' into clients-user 2025-11-06 16:55:16 -08:00
miloschwartz
2a7529c39e don't delete user 2025-11-06 16:48:53 -08:00
Fred KISSIE
f27ae210ed Merge branch 'dev' into feat/update-popup 2025-11-07 01:30:18 +01:00
Fred KISSIE
ea744f8d28 💄 show update type 2025-11-07 01:14:05 +01:00
Fred KISSIE
0b70cbb1a3 💄 show update type in badge 2025-11-07 01:10:20 +01:00
miloschwartz
fce887436d fix bug causing auto provision to override manually created users 2025-11-06 15:46:54 -08:00
Fred KISSIE
f928708156 💄 animate exit and more 2025-11-07 00:27:57 +01:00
miloschwartz
fae899a8f1 remove dialog border 2025-11-06 15:17:19 -08:00
Rob
3489107a49 Fix typo in shareSeeOnce message 2025-11-06 23:09:52 +00:00
Fred KISSIE
45fb0a4156 💄 button for mark as read 2025-11-06 23:26:13 +01:00
Fred KISSIE
a62299c387 🎨 prettier format 2025-11-06 23:25:53 +01:00
Fred KISSIE
18757d7eb3 💄 show product updates list 2025-11-06 22:42:49 +01:00
Owen Schwartz
296b220bf3 Merge pull request #1819 from Pallavikumarimdb/fix/resourceTable-typeError
Fix/Revert column from Resource table to fix type error and match overall styling
2025-11-06 12:03:15 -08:00
Pallavi Kumari
0a9f37c44d revert column from resource table 2025-11-06 22:57:03 +05:30
miloschwartz
776c33d79d persist column filters 2025-11-05 17:34:50 -08:00
miloschwartz
9fd6af3a31 view devices for profile 2025-11-05 17:27:16 -08:00
miloschwartz
4ade878320 split clients table 2025-11-05 16:43:27 -08:00
miloschwartz
9e2477587c if one logs dont show nested 2025-11-05 16:13:51 -08:00
miloschwartz
c7787352c8 add sidebar groups 2025-11-05 16:09:12 -08:00
miloschwartz
85892c30b2 add site resource modes and alias 2025-11-05 15:24:07 -08:00
Fred KISSIE
7a2dd31019 🚧 use popup 2025-11-06 00:16:07 +01:00
Fred KISSIE
096ca379ce ♻️ refactor 2025-11-06 00:06:05 +01:00
Fred KISSIE
41601010f4 💡 comment 2025-11-05 23:58:56 +01:00
Fred KISSIE
64b87e203a 💄 animate product updates & new version 2025-11-05 23:57:43 +01:00
Fred KISSIE
c64b102aaa ♻️ refactor 2025-11-05 23:29:48 +01:00
Fred KISSIE
f371c7df81 add headless/ui for better enter/exit animations 2025-11-05 23:29:36 +01:00
Fred KISSIE
030f90db2e ♻️ validate env variables only in DEV 2025-11-05 21:41:29 +01:00
miloschwartz
e51b6b545e add users and roles to site resources 2025-11-05 12:24:50 -08:00
Owen Schwartz
ef5d72663f Merge pull request #1328 from Pallavikumarimdb/enhancement-#906/dashboard-enhancements
Enhancement #906/Resources Dashboard: Targets Column, Customizable Columns & Status Indicators
2025-11-05 11:41:43 -08:00
Owen
6ddfc9b8fe Revert columns 2025-11-05 11:41:07 -08:00
Owen
301654b63e Fix styling 2025-11-05 11:38:14 -08:00
miloschwartz
c73f8c88f7 hide sites inputs on clients 2025-11-05 10:37:52 -08:00
miloschwartz
2274404324 update tables 2025-11-05 10:29:29 -08:00
Fred KISSIE
6d349693a7 🚧 wip 2025-11-05 08:45:56 +01:00
Fred KISSIE
b9ce316574 🚧 wip 2025-11-05 08:38:23 +01:00
Fred KISSIE
a247ef7564 ♻️ import type 2025-11-05 07:33:25 +01:00
Fred KISSIE
18566c09dc add tanstack query 2025-11-05 07:32:28 +01:00
Fred KISSIE
1090dca634 Merge branch 'main' into feat/update-popup 2025-11-05 07:30:12 +01:00
Fred KISSIE
44f419d4f7 💄 animate popup 2025-11-05 07:30:01 +01:00
Fred KISSIE
162c6d567c revert package.json changes 2025-11-05 07:26:41 +01:00
Fred KISSIE
2f1abfbef8 🚧 New version popup 2025-11-05 06:55:08 +01:00
Fred KISSIE
a26a441d56 ♻️ validate env and add remote fossorial API as an env variable 2025-11-05 06:54:56 +01:00
miloschwartz
f628a76223 add them back 2025-11-04 16:56:56 -08:00
miloschwartz
8088e30e06 remove userClients and roleClients 2025-11-04 16:53:00 -08:00
miloschwartz
801cdec7f3 add deviceWebAuthCodes table to pg schema 2025-11-04 16:51:31 -08:00
Owen
3fd3f9871d Remove user check 2025-11-04 11:56:00 -08:00
miloschwartz
959a562e7c fix more shadows 2025-11-04 11:09:08 -08:00
Owen Schwartz
3b12a77cf0 Merge pull request #1809 from clemone210/patch-2
Update German translations for client and blueprint terms
2025-11-04 10:34:26 -08:00
Fred KISSIE
03e0e8d9c2 🚧 wip 2025-11-04 13:57:55 +01:00
Timo
7cd31313d8 Update German translations for client and blueprint terms
"Kunden" is generally used for "Customers", so in this case I suggest to stick with Client, as this is a widely used term in german tech sector. The same for "Bauplan" or "Blaupause". "Bauplan" is a "Construction plan" for building houses. "Blaupause" is pretty much the right translation for blueprints, but I would stick with Blueprint here as well.
2025-11-04 07:40:33 +01:00
miloschwartz
52a311bf36 fix colors and footer 2025-11-03 21:44:34 -08:00
Milo Schwartz
9822deb4bf Update README.md 2025-11-03 22:56:57 -05:00
Owen
83e0282212 Merge branch 'dev' into clients-user 2025-11-03 17:39:10 -08:00
Owen
8942cb7aa7 Update const 2025-11-03 17:38:50 -08:00
Owen
f0f219f293 Merge branch 'main' into dev 2025-11-03 17:38:43 -08:00
Owen
dc75d72522 Merge branch 'dev' into clients-user 2025-11-03 17:38:26 -08:00
Owen
6da81b3817 Fix bad request in non-enterprise 2025-11-03 17:33:50 -08:00
miloschwartz
847479b639 Merge branch 'cli-web-auth' into clients-user 2025-11-03 17:14:12 -08:00
miloschwartz
0790f37f5e hash device codes 2025-11-03 17:03:46 -08:00
Owen
9dd472c59b Creating olm working 2025-11-03 16:54:06 -08:00
miloschwartz
5746d69f98 reduce header padding 2025-11-03 16:22:40 -08:00
Owen
8356c5933f Small fixes around handling olm users 2025-11-03 16:22:13 -08:00
Owen
2c488baa80 Add name and lock client to specific olm 2025-11-03 16:16:19 -08:00
Owen
d30743a428 Update schmea; create client when registering 2025-11-03 15:42:22 -08:00
miloschwartz
009d84a3c6 remove shadows and outline ring 2025-11-03 11:22:00 -08:00
miloschwartz
e888b76747 complete web device auth flow 2025-11-03 11:10:17 -08:00
Owen
6174599754 Allow >30 days on oss 2025-11-03 09:54:41 -08:00
Owen Schwartz
8ba04aeb74 Merge pull request #1802 from fosrl/dependabot/npm_and_yarn/prod-minor-updates-700e856888
Bump the prod-minor-updates group across 1 directory with 9 updates
2025-11-03 09:49:01 -08:00
Owen
43590896e9 Add fosrl 2025-11-02 18:56:46 -08:00
Owen Schwartz
3547c4832b Revert "Refactor CI/CD workflow for improved release process" 2025-11-02 18:56:46 -08:00
Marc Schäfer
1cd098252e Refactor CI/CD workflow for improved release process
Updated CI/CD workflow to include new permissions, job definitions, and steps for version validation, tagging, and artifact management.
2025-11-02 18:56:46 -08:00
Owen
4adbc31dae Fix blueprints not applying
Fixes #1795
2025-11-02 18:56:46 -08:00
Owen
99031feb35 Fix camel case in health checks 2025-11-02 18:56:46 -08:00
Owen
d363b06d0e Fix rewritePath
Closes #1528
2025-11-02 18:56:46 -08:00
Owen
2af100cc86 Warning -> debug 2025-11-02 18:56:46 -08:00
dependabot[bot]
3e90211108 Bump the prod-minor-updates group across 1 directory with 9 updates
Bumps the prod-minor-updates group with 9 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) | `3.908.0` | `3.922.0` |
| [axios](https://github.com/axios/axios) | `1.12.2` | `1.13.1` |
| [eslint](https://github.com/eslint/eslint) | `9.37.0` | `9.39.0` |
| [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) | `8.1.0` | `8.2.1` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.545.0` | `0.552.0` |
| [next-intl](https://github.com/amannn/next-intl) | `4.3.12` | `4.4.0` |
| [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.10.4` | `5.11.0` |
| [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.65.0` | `7.66.0` |
| [resend](https://github.com/resend/resend-node) | `6.1.3` | `6.4.0` |



Updates `@aws-sdk/client-s3` from 3.908.0 to 3.922.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.922.0/clients/client-s3)

Updates `axios` from 1.12.2 to 1.13.1
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.12.2...v1.13.1)

Updates `eslint` from 9.37.0 to 9.39.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.37.0...v9.39.0)

Updates `express-rate-limit` from 8.1.0 to 8.2.1
- [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases)
- [Commits](https://github.com/express-rate-limit/express-rate-limit/compare/v8.1.0...v8.2.1)

Updates `lucide-react` from 0.545.0 to 0.552.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.552.0/packages/lucide-react)

Updates `next-intl` from 4.3.12 to 4.4.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.3.12...v4.4.0)

Updates `posthog-node` from 5.10.4 to 5.11.0
- [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.11.0/packages/node)

Updates `react-hook-form` from 7.65.0 to 7.66.0
- [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.65.0...v7.66.0)

Updates `resend` from 6.1.3 to 6.4.0
- [Release notes](https://github.com/resend/resend-node/releases)
- [Commits](https://github.com/resend/resend-node/compare/v6.1.3...v6.4.0)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-s3"
  dependency-version: 3.922.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: axios
  dependency-version: 1.13.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: eslint
  dependency-version: 9.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: express-rate-limit
  dependency-version: 8.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: lucide-react
  dependency-version: 0.552.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: next-intl
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: posthog-node
  dependency-version: 5.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: react-hook-form
  dependency-version: 7.66.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: resend
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 01:34:13 +00:00
Owen
6dd161fe17 Add fosrl 2025-11-02 15:35:02 -08:00
Owen Schwartz
558bd040c6 Merge pull request #1801 from fosrl/revert-1792-main
Revert "Refactor CI/CD workflow for improved release process"
2025-11-02 15:22:12 -08:00
Owen Schwartz
f2c48975f6 Revert "Refactor CI/CD workflow for improved release process" 2025-11-02 15:22:03 -08:00
Owen Schwartz
fc43a56bb3 Merge pull request #1792 from marcschaeferger/main
Refactor CI/CD workflow for improved release process
2025-11-02 15:00:09 -08:00
Owen
ca7f557a3c Fix blueprints not applying
Fixes #1795
2025-11-02 14:56:19 -08:00
Owen
7477713eef Fix camel case in health checks 2025-11-02 14:17:38 -08:00
Owen
c16e762fa4 Fix rewritePath
Closes #1528
2025-11-02 14:05:41 -08:00
Owen Schwartz
41592133a6 Merge pull request #1788 from Pallavikumarimdb/fix/deleting-and-adding-back-a-target
Add transaction while deleting targets
2025-11-02 13:51:08 -08:00
Pallavi Kumari
54f7525f1b add status column in resource table 2025-11-02 13:55:17 +05:30
Pallavi Kumari
ad6bb3da9f fix type error 2025-11-02 13:55:17 +05:30
Pallavi Kumari
49bc2dc5da fix duplicate 2025-11-02 13:55:16 +05:30
Pallavi
cdf77087cd get niceid 2025-11-02 13:55:16 +05:30
Pallavi
8e5dde887c list targes in frontend 2025-11-02 13:55:16 +05:30
Pallavi
f21188000e remove status check and add column filtering on all of the tables 2025-11-02 13:55:16 +05:30
Pallavi
1b3eb32bf4 Show targets and status icons in the dashboard 2025-11-02 13:55:16 +05:30
Marc Schäfer
eec3f183e6 Refactor CI/CD workflow for improved release process
Updated CI/CD workflow to include new permissions, job definitions, and steps for version validation, tagging, and artifact management.
2025-11-02 00:44:03 +01:00
Owen
31b66cd911 Warning -> debug 2025-11-01 10:46:09 -07:00
Pallavi Kumari
ad425e8d9e add transaction while deleting targets 2025-11-01 11:58:09 +05:30
miloschwartz
da0196a308 no reset password for external users 2025-10-30 22:24:07 -07:00
miloschwartz
e585972b7b remove useSubscriptionStatusContext from HorizontalTabs 2025-10-30 21:31:48 -07:00
miloschwartz
cc62cd4add remove sqlite driver logger 2025-10-30 21:23:05 -07:00
Owen
25225a452c Return instead of throwing error 2025-10-30 21:18:26 -07:00
Owen
678644c7fb Fix empty blueprint 2025-10-30 21:09:20 -07:00
Owen
32f20ed984 Bugfixes for remote nodes 2025-10-30 21:01:45 -07:00
Owen
4eb5bf08d5 UI fixes 2025-10-30 17:44:22 -07:00
Owen
35c93f38e0 Fix small ui issues 2025-10-30 17:32:03 -07:00
Owen
f60c2f4fb9 Make refresh work 2025-10-30 17:25:49 -07:00
Owen
b2cf152b9e Add copy to clip 2025-10-30 16:17:20 -07:00
Owen
444928dffd Add wildcard 2025-10-30 15:27:24 -07:00
Owen
4d7e2d5840 Minor fixes to rc 2025-10-30 11:42:31 -07:00
Owen Schwartz
318046ce1d Merge pull request #1780 from fosrl/crowdin_dev
New Crowdin updates
2025-10-29 21:17:18 -07:00
Owen Schwartz
808ad1e272 New translations en-us.json (Norwegian Bokmal) 2025-10-29 21:16:51 -07:00
Owen Schwartz
05a1195661 New translations en-us.json (Chinese Simplified) 2025-10-29 21:16:49 -07:00
Owen Schwartz
c46322c6a6 New translations en-us.json (Turkish) 2025-10-29 21:16:48 -07:00
Owen Schwartz
80d5efc41f New translations en-us.json (Russian) 2025-10-29 21:16:47 -07:00
Owen Schwartz
0409ab7dc1 New translations en-us.json (Portuguese) 2025-10-29 21:16:46 -07:00
Owen Schwartz
63f079ec76 New translations en-us.json (Polish) 2025-10-29 21:16:45 -07:00
Owen Schwartz
5988f1e8da New translations en-us.json (Dutch) 2025-10-29 21:16:43 -07:00
Owen Schwartz
ed0c0edeba New translations en-us.json (Korean) 2025-10-29 21:16:42 -07:00
Owen Schwartz
34b4841f4d New translations en-us.json (Italian) 2025-10-29 21:16:40 -07:00
Owen Schwartz
ff47c5a8ad New translations en-us.json (German) 2025-10-29 21:16:39 -07:00
Owen Schwartz
9430a53c0c New translations en-us.json (Czech) 2025-10-29 21:16:38 -07:00
Owen Schwartz
03334e3f0f New translations en-us.json (Bulgarian) 2025-10-29 21:16:37 -07:00
Owen Schwartz
6f2ecf9d0d New translations en-us.json (Spanish) 2025-10-29 21:16:35 -07:00
Owen Schwartz
6f803c3b4b New translations en-us.json (French) 2025-10-29 21:16:34 -07:00
Owen
15d400c842 Fix migration and install faker 2025-10-29 21:12:12 -07:00
Owen Schwartz
3ddf150661 New translations en-us.json (Norwegian Bokmal) 2025-10-29 21:00:51 -07:00
Owen Schwartz
5b519afee4 New translations en-us.json (Chinese Simplified) 2025-10-29 21:00:50 -07:00
Owen Schwartz
15ea9f3dcc New translations en-us.json (Turkish) 2025-10-29 21:00:48 -07:00
Owen Schwartz
d5e2536f8d New translations en-us.json (Russian) 2025-10-29 21:00:47 -07:00
Owen Schwartz
d7e9083e06 New translations en-us.json (Portuguese) 2025-10-29 21:00:45 -07:00
Owen Schwartz
e0cc338c3a New translations en-us.json (Polish) 2025-10-29 21:00:44 -07:00
Owen Schwartz
624c5741e2 New translations en-us.json (Dutch) 2025-10-29 21:00:43 -07:00
Owen Schwartz
558507dd71 New translations en-us.json (Korean) 2025-10-29 21:00:41 -07:00
Owen Schwartz
565340bd53 New translations en-us.json (Italian) 2025-10-29 21:00:40 -07:00
Owen Schwartz
756745487a New translations en-us.json (German) 2025-10-29 21:00:39 -07:00
Owen Schwartz
d2ece4d370 New translations en-us.json (Czech) 2025-10-29 21:00:37 -07:00
Owen Schwartz
d5f5d1da1e New translations en-us.json (Bulgarian) 2025-10-29 21:00:35 -07:00
Owen Schwartz
dfaf1a72cc New translations en-us.json (Spanish) 2025-10-29 21:00:34 -07:00
Owen Schwartz
ff8e5b871c New translations en-us.json (French) 2025-10-29 21:00:33 -07:00
Owen
927dda4e53 Add blueprints to migrations 2025-10-29 20:50:36 -07:00
Owen
0e51bac307 Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-10-29 20:46:13 -07:00
Owen Schwartz
7a50af14f3 Merge pull request #1733 from Fredkiss3/feat-blueprint-ui-on-dashboard
feat: blueprint ui on dashboard
2025-10-29 20:45:31 -07:00
Owen
396477c2e2 Update makefiles 2025-10-29 20:42:56 -07:00
Fred KISSIE
8765874d9a ♻️ include Blueprint applied with errors: in blueprint message when it fails 2025-10-30 02:33:45 +01:00
Fred KISSIE
49dffe086d ♻️ show warning toast and do not throw error in case of UI source 2025-10-30 02:18:48 +01:00
Owen Schwartz
77ddadcded Merge pull request #1777 from fosrl/crowdin_dev
New Crowdin updates
2025-10-29 17:51:22 -07:00
Owen Schwartz
05b297ddec New translations en-us.json (Norwegian Bokmal) 2025-10-29 17:49:16 -07:00
Owen Schwartz
feb0de9a08 New translations en-us.json (Chinese Simplified) 2025-10-29 17:49:14 -07:00
Owen Schwartz
f4f2361d22 New translations en-us.json (Turkish) 2025-10-29 17:49:13 -07:00
Owen Schwartz
cae6a9f51c New translations en-us.json (Russian) 2025-10-29 17:49:12 -07:00
Owen Schwartz
2872f5c018 New translations en-us.json (Portuguese) 2025-10-29 17:49:10 -07:00
Owen Schwartz
0512c21ad7 New translations en-us.json (Polish) 2025-10-29 17:49:09 -07:00
Owen Schwartz
922a69feed New translations en-us.json (Dutch) 2025-10-29 17:49:08 -07:00
Owen Schwartz
24192c79d4 New translations en-us.json (Korean) 2025-10-29 17:49:07 -07:00
Owen Schwartz
17c22a635f New translations en-us.json (Italian) 2025-10-29 17:49:05 -07:00
Owen Schwartz
bcbcf417b5 New translations en-us.json (German) 2025-10-29 17:49:04 -07:00
Owen Schwartz
acf7596368 New translations en-us.json (Czech) 2025-10-29 17:49:03 -07:00
Owen Schwartz
34c7d925ca New translations en-us.json (Bulgarian) 2025-10-29 17:49:01 -07:00
Owen Schwartz
c10730ebb9 New translations en-us.json (Spanish) 2025-10-29 17:49:00 -07:00
Owen Schwartz
e50743b922 New translations en-us.json (French) 2025-10-29 17:48:59 -07:00
Owen
75b0745e42 Add proxy procotol to private config 2025-10-29 17:42:21 -07:00
Owen
ebd99f95a3 Also order by id 2025-10-29 17:37:29 -07:00
Owen
0e649883cb More bugfixes 2025-10-29 17:21:32 -07:00
Fred KISSIE
3d376c8d14 ♻️ change default blueprint table ordering to createdAt: desc 2025-10-30 00:55:12 +01:00
Fred KISSIE
adedb0e391 💬 Show Success: Blueprint applied successfully 2025-10-30 00:54:15 +01:00
Fred KISSIE
521935786c 💄 remove rounded-sm 2025-10-30 00:34:14 +01:00
Fred KISSIE
885b9d186b ♻️ remove blueprint name form description 2025-10-30 00:32:55 +01:00
Fred KISSIE
356f023539 💬 fix capitalization 2025-10-30 00:32:08 +01:00
Fred KISSIE
de8d3f45da 💬 uppercase blueprint in create blueprint 2025-10-30 00:30:50 +01:00
Fred KISSIE
72c9956190 💄 Standardize go back to blueprints 2025-10-30 00:27:27 +01:00
Owen
6dc4cbe448 Check country code 2025-10-29 16:24:35 -07:00
Fred KISSIE
77364488c2 💄 show action on the right of the column 2025-10-30 00:21:59 +01:00
Fred KISSIE
5a61040027 💄 remove form description and format w/ prettier 2025-10-30 00:21:39 +01:00
Owen
c6f7be40df Sort by descending 2025-10-29 16:16:25 -07:00
Fred KISSIE
c36fb63f8c 🔨 add drizzle in docker-compose DEV for viewing the postgres db in local development 2025-10-30 00:10:49 +01:00
Owen
48aebea6cf Show error 2025-10-29 15:23:53 -07:00
Owen
55082d2ef8 Rename file 2025-10-29 14:49:53 -07:00
Owen
cc03b97234 Merge branch 'dev' into feat-blueprint-ui-on-dashboard 2025-10-29 14:46:34 -07:00
Owen
5542873368 Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-10-29 14:43:32 -07:00
Owen
1db5d76ef1 Merge branch 'main' into dev 2025-10-29 14:43:18 -07:00
Owen
ca6c45087b Fix the ordering of deleting targets 2025-10-29 14:40:09 -07:00
Owen Schwartz
3333eb95f9 Merge pull request #1773 from Pallavikumarimdb/fix/long-copy-box
Fix text overflow in CopyToClipboard by setting a max width
2025-10-29 14:11:27 -07:00
Pallavi Kumari
d681725fc3 update max width of CopyToClipboard 2025-10-30 00:59:08 +05:30
Owen
f5eadc9e1e Various fixes 2025-10-29 12:16:28 -07:00
miloschwartz
219e213c1e change logs to debug 2025-10-29 11:39:45 -07:00
miloschwartz
af654e663b add missing translation key 2025-10-29 11:34:13 -07:00
Fred KISSIE
39b3b4ef9d 🐛 add missing orgId to blueprints table 2025-10-29 14:39:42 +01:00
Owen Schwartz
6c62a0900f Merge pull request #1763 from fosrl/dependabot/npm_and_yarn/prod-patch-updates-56e321e524
Bump posthog-node from 5.10.3 to 5.10.4 in the prod-patch-updates group
2025-10-28 21:15:31 -07:00
Owen Schwartz
ddd772eb43 Merge pull request #1769 from fosrl/dependabot/npm_and_yarn/dev-patch-updates-a759a3dffa
Bump the dev-patch-updates group across 1 directory with 4 updates
2025-10-28 21:15:24 -07:00
Fred KISSIE
69458ab649 🔇 remove console.log 2025-10-29 04:25:37 +01:00
Fred KISSIE
c7df70143e ♻️ log only in DEV 2025-10-29 03:50:36 +01:00
Fred KISSIE
a81ea7cc8f 🐛 fix merge errors 2025-10-29 03:34:44 +01:00
Fred KISSIE
02330a0756 Merge branch 'dev' into feat-blueprint-ui-on-dashboard 2025-10-29 03:31:51 +01:00
Fred KISSIE
db49b599b5 add faker dependency 2025-10-29 03:09:16 +01:00
Fred KISSIE
bb0bfd440a ♻️ refactor 2025-10-29 03:09:02 +01:00
Fred KISSIE
10ce732b8d 🚚 rename integration API applyBlueprint to apply JSON blueprint and the UI applyBlueprint to apply YAML blueprint 2025-10-29 03:08:48 +01:00
Fred KISSIE
4c567cf2d7 ♻️ refactor docker and websocket blueprint to call the new applyBlueprint function 2025-10-29 03:07:55 +01:00
Fred KISSIE
2783d2989d ♻️ refactor 2025-10-29 03:06:42 +01:00
Fred KISSIE
c3d6510231 💬 update the text in the blueprint details page to say parsed contents 2025-10-29 03:06:28 +01:00
Fred KISSIE
3bb948991f ♻️ applyBlueprint core logic now saves the blueprint in the DB 2025-10-29 03:01:25 +01:00
dependabot[bot]
4b9ce22f06 Bump the dev-patch-updates group across 1 directory with 4 updates
Bumps the dev-patch-updates group with 4 updates in the / directory: [@types/express](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express), [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [@types/pg](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/pg) and [drizzle-kit](https://github.com/drizzle-team/drizzle-orm).


Updates `@types/express` from 5.0.4 to 5.0.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/express)

Updates `@types/node` from 24.9.1 to 24.9.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/pg` from 8.15.5 to 8.15.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/pg)

Updates `drizzle-kit` from 0.31.5 to 0.31.6
- [Release notes](https://github.com/drizzle-team/drizzle-orm/releases)
- [Commits](https://github.com/drizzle-team/drizzle-orm/compare/drizzle-kit@0.31.5...drizzle-kit@0.31.6)

---
updated-dependencies:
- dependency-name: "@types/express"
  dependency-version: 5.0.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@types/node"
  dependency-version: 24.9.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@types/pg"
  dependency-version: 8.15.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: drizzle-kit
  dependency-version: 0.31.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 01:22:53 +00:00
miloschwartz
772bda69f9 check for user email in support request 2025-10-27 21:56:22 -07:00
miloschwartz
8b4722b1c9 add support message button in saas 2025-10-27 21:55:34 -07:00
Owen
9e5c9d9c34 Check role access when inviting users 2025-10-27 20:51:16 -07:00
dependabot[bot]
ee533df38f Bump posthog-node from 5.10.3 to 5.10.4 in the prod-patch-updates group
Bumps the prod-patch-updates group with 1 update: [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node).


Updates `posthog-node` from 5.10.3 to 5.10.4
- [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.10.4/packages/node)

---
updated-dependencies:
- dependency-name: posthog-node
  dependency-version: 5.10.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-28 01:31:57 +00:00
Owen
52dc8e011c Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-10-27 17:55:10 -07:00
Owen
bd5cc790d6 Fixing various things 2025-10-27 17:52:39 -07:00
Milo Schwartz
7d6d5a7787 Update README.md 2025-10-27 20:15:44 -04:00
Milo Schwartz
ba6e7dd06a Update README.md 2025-10-27 20:08:14 -04:00
miloschwartz
6270fb3237 consolidate install commands 2025-10-27 16:58:11 -07:00
miloschwartz
16ec50a6ee add alaytics to saas 2025-10-27 16:43:52 -07:00
miloschwartz
3d2021c8a1 use select component 2025-10-27 16:38:04 -07:00
Owen
15d63ddffa Various fixes for rc 2025-10-27 16:33:21 -07:00
Fred KISSIE
7ce6fadb3d blueprint details page 2025-10-28 00:14:27 +01:00
Owen
6b18a24f9b @server/private -> #dynamic 2025-10-27 13:46:54 -07:00
Owen
a38cb961c7 Create missing stubs 2025-10-27 13:45:24 -07:00
Owen
3c5fe21078 Add missing header 2025-10-27 11:54:56 -07:00
Owen
b44305694f Add postgres migration 2025-10-27 11:52:45 -07:00
Owen
be217e2b6f Create 1.12.0 sqlite migration 2025-10-27 11:47:14 -07:00
Owen
6ce04c2aa1 Change migration to 1.12.0 2025-10-27 11:34:46 -07:00
Owen
85e4b649db Update cicd: allow to run on rc 2025-10-27 11:14:56 -07:00
Owen
73a3335148 Update cicd: login to ghcr 2025-10-27 11:13:05 -07:00
Owen
32845c5a3d Fix const issue 2025-10-27 11:03:16 -07:00
Owen Schwartz
05a878ac34 Merge pull request #1759 from fosrl/crowdin_dev
New Crowdin updates
2025-10-27 10:55:59 -07:00
Owen Schwartz
847d015243 New translations en-us.json (Spanish) 2025-10-27 10:55:27 -07:00
Owen Schwartz
51cde2681c New translations en-us.json (Norwegian Bokmal) 2025-10-27 10:55:26 -07:00
Owen Schwartz
9c0606942c New translations en-us.json (Chinese Simplified) 2025-10-27 10:55:24 -07:00
Owen Schwartz
646d476bdb New translations en-us.json (Turkish) 2025-10-27 10:55:23 -07:00
Owen Schwartz
31261681a0 New translations en-us.json (Russian) 2025-10-27 10:55:21 -07:00
Owen Schwartz
f6fae820c4 New translations en-us.json (Portuguese) 2025-10-27 10:55:20 -07:00
Owen Schwartz
b3cbf925aa New translations en-us.json (Polish) 2025-10-27 10:55:19 -07:00
Owen Schwartz
aa1ae3ee42 New translations en-us.json (Dutch) 2025-10-27 10:55:17 -07:00
Owen Schwartz
80f6c8b74e New translations en-us.json (Korean) 2025-10-27 10:55:16 -07:00
Owen Schwartz
79d8e8d59d New translations en-us.json (Italian) 2025-10-27 10:55:15 -07:00
Owen Schwartz
9193375586 New translations en-us.json (German) 2025-10-27 10:55:13 -07:00
Owen Schwartz
240bcb8759 New translations en-us.json (Czech) 2025-10-27 10:55:12 -07:00
Owen Schwartz
a5dcafb84c New translations en-us.json (Bulgarian) 2025-10-27 10:55:11 -07:00
Owen Schwartz
192207a857 New translations en-us.json (French) 2025-10-27 10:55:09 -07:00
Owen Schwartz
d18fafb0ef Merge pull request #1757 from fosrl/user-compliance
Enforce org user compliance
2025-10-27 10:44:13 -07:00
Owen
380c86898c Fix lint 2025-10-27 10:43:44 -07:00
Owen
b59a6b82ef Merge branch 'dev' into user-compliance 2025-10-27 10:37:53 -07:00
Owen Schwartz
77ba568c36 Merge pull request #1755 from fosrl/audit-logs
Request, action, and access logs
2025-10-27 10:10:57 -07:00
Owen
a0f05cc77b Resolve export of logActionAudit 2025-10-27 10:09:06 -07:00
Owen
80f43a9774 Fix lint 2025-10-27 10:05:31 -07:00
Owen
c04d9eda6b Merge branch 'dev' into audit-logs 2025-10-27 10:02:32 -07:00
Owen Schwartz
cabf3e9695 Merge pull request #1749 from fosrl/dependabot/npm_and_yarn/dev-patch-updates-b7f346f221
Bump the dev-patch-updates group with 7 updates
2025-10-27 09:57:14 -07:00
Owen Schwartz
ff7b4386d6 Merge pull request #1750 from fosrl/dependabot/npm_and_yarn/prod-patch-updates-c81bf49cf4
Bump the prod-patch-updates group with 5 updates
2025-10-27 09:57:03 -07:00
Owen Schwartz
4dbbe159ee Merge pull request #1751 from fosrl/dependabot/github_actions/actions/upload-artifact-5.0.0
Bump actions/upload-artifact from 4.6.2 to 5.0.0
2025-10-27 09:56:52 -07:00
miloschwartz
eeab92719a add smaller time values and update translations 2025-10-27 09:52:25 -07:00
miloschwartz
43e6b7de07 remove delete on cascade for skipToIdp on resource closes #1654 2025-10-27 09:46:26 -07:00
miloschwartz
4cfd1b1ff5 always check resource session length 2025-10-27 09:45:12 -07:00
dependabot[bot]
09ba018493 Bump actions/upload-artifact from 4.6.2 to 5.0.0
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 5.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](ea165f8d65...330a01c490)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 01:41:35 +00:00
dependabot[bot]
7acf7dd0eb Bump the prod-patch-updates group with 5 updates
Bumps the prod-patch-updates group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [canvas-confetti](https://github.com/catdad/canvas-confetti) | `1.9.3` | `1.9.4` |
| [drizzle-orm](https://github.com/drizzle-team/drizzle-orm) | `0.44.6` | `0.44.7` |
| [ioredis](https://github.com/luin/ioredis) | `5.8.1` | `5.8.2` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `7.0.9` | `7.0.10` |
| [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.10.0` | `5.10.3` |


Updates `canvas-confetti` from 1.9.3 to 1.9.4
- [Release notes](https://github.com/catdad/canvas-confetti/releases)
- [Commits](https://github.com/catdad/canvas-confetti/compare/1.9.3...1.9.4)

Updates `drizzle-orm` from 0.44.6 to 0.44.7
- [Release notes](https://github.com/drizzle-team/drizzle-orm/releases)
- [Commits](https://github.com/drizzle-team/drizzle-orm/compare/0.44.6...0.44.7)

Updates `ioredis` from 5.8.1 to 5.8.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.1...v5.8.2)

Updates `nodemailer` from 7.0.9 to 7.0.10
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v7.0.9...v7.0.10)

Updates `posthog-node` from 5.10.0 to 5.10.3
- [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.10.3/packages/node)

---
updated-dependencies:
- dependency-name: canvas-confetti
  dependency-version: 1.9.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: drizzle-orm
  dependency-version: 0.44.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: ioredis
  dependency-version: 5.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: nodemailer
  dependency-version: 7.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: posthog-node
  dependency-version: 5.10.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 01:36:44 +00:00
Owen
592d085de6 Lock down days 2025-10-26 18:36:09 -07:00
dependabot[bot]
2cf2c64651 Bump the dev-patch-updates group with 7 updates
Bumps the dev-patch-updates group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [@react-email/preview-server](https://github.com/resend/react-email/tree/HEAD/packages/preview-server) | `4.3.1` | `4.3.2` |
| [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) | `4.1.15` | `4.1.16` |
| [@types/cookie-parser](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/cookie-parser) | `1.4.9` | `1.4.10` |
| [@types/express](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/express) | `5.0.3` | `5.0.4` |
| [@types/yargs](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/yargs) | `17.0.33` | `17.0.34` |
| [react-email](https://github.com/resend/react-email/tree/HEAD/packages/react-email) | `4.3.1` | `4.3.2` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.1.15` | `4.1.16` |


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

Updates `@tailwindcss/postcss` from 4.1.15 to 4.1.16
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.16/packages/@tailwindcss-postcss)

Updates `@types/cookie-parser` from 1.4.9 to 1.4.10
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/cookie-parser)

Updates `@types/express` from 5.0.3 to 5.0.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/express)

Updates `@types/yargs` from 17.0.33 to 17.0.34
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/yargs)

Updates `react-email` from 4.3.1 to 4.3.2
- [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@4.3.2/packages/react-email)

Updates `tailwindcss` from 4.1.15 to 4.1.16
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.16/packages/tailwindcss)

---
updated-dependencies:
- dependency-name: "@react-email/preview-server"
  dependency-version: 4.3.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.1.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@types/cookie-parser"
  dependency-version: 1.4.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@types/express"
  dependency-version: 5.0.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: "@types/yargs"
  dependency-version: 17.0.34
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: react-email
  dependency-version: 4.3.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: tailwindcss
  dependency-version: 4.1.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 01:27:47 +00:00
Owen
560974f7d2 Merge branch 'feat/add-proxy-protocol-support' into dev 2025-10-26 18:16:38 -07:00
Owen
85270f497a Restrict raw resources and use st from config 2025-10-26 18:15:39 -07:00
miloschwartz
9fbea4a380 move enterprise/subscription required alert to component 2025-10-26 17:12:47 -07:00
miloschwartz
cbf9c5361e redirect to org login via query param 2025-10-26 17:08:35 -07:00
miloschwartz
44316731c0 enforce resource session length 2025-10-26 16:52:15 -07:00
Owen Schwartz
60513af8ed Merge pull request #1716 from fosrl/dependabot/npm_and_yarn/dev-patch-updates-5d11ea411f
Bump the dev-patch-updates group with 3 updates
2025-10-26 16:31:27 -07:00
Owen Schwartz
24cfe02979 Merge pull request #1717 from fosrl/dependabot/npm_and_yarn/dev-minor-updates-648ae407da
Bump @types/node from 24.8.1 to 24.9.1 in the dev-minor-updates group
2025-10-26 16:31:18 -07:00
Owen
8f3324560a Install maxmind by default 2025-10-26 16:04:19 -07:00
Owen
2041edcf30 Allow protocols on the same port
Fixes #1745
2025-10-26 15:57:12 -07:00
miloschwartz
1227b3c11a use alert instead of badge for unlock status 2025-10-25 17:21:21 -07:00
miloschwartz
8973726f63 add org policy check to verify session 2025-10-25 17:15:37 -07:00
Owen
5559fef1bc Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-10-25 16:27:12 -07:00
Owen
9cb3c3821a Merge branch 'Pallavikumarimdb-feat/cert-resolver-through-UI' into dev 2025-10-25 16:25:51 -07:00
Owen
c85e367ded Merge branch 'feat/cert-resolver-through-UI' of github.com:Pallavikumarimdb/pangolin into Pallavikumarimdb-feat/cert-resolver-through-UI 2025-10-25 16:25:42 -07:00
Owen Schwartz
5e20487216 Merge pull request #1732 from Pallavikumarimdb/feat/show-update-for-client-olm
Client olm version show in the table with an update prompt
2025-10-25 16:23:51 -07:00
Owen Schwartz
bc6b9eb905 Merge pull request #1736 from Lokowitz/fix-geoip-blueprint
fix blueprint country issue - fix #1705 - option 2
2025-10-25 16:21:49 -07:00
Owen
5940bbd498 Uppercase 2025-10-25 16:20:50 -07:00
Owen
f4a0f6a2e6 Update ui 2025-10-25 16:17:45 -07:00
Milo Schwartz
0df7d45678 Update README.md 2025-10-25 13:48:14 -04:00
Fred KISSIE
a05ee2483b 💄 adjust form style for createblueprintform 2025-10-25 03:22:51 +02:00
Fred KISSIE
f5dbc18c05 create and apply blueprint 2025-10-25 03:06:54 +02:00
Fred KISSIE
dd052fa1af 💄 Gave a relooking to the blueprint table 2025-10-25 03:06:45 +02:00
Fred KISSIE
2cc4ad9c30 💄 fix header & cell misalignment in table 2025-10-25 03:05:47 +02:00
Fred KISSIE
4dd741cc3f 🔊 log all SQL queries 2025-10-25 02:55:19 +02:00
miloschwartz
9ce81b34c9 add confirm dialog to update security settings 2025-10-24 17:30:39 -07:00
miloschwartz
460df46abc update translation and send password reset email 2025-10-24 17:18:34 -07:00
miloschwartz
1e70e4289b add password expiry enforcement 2025-10-24 17:11:39 -07:00
Owen
5fa0ac5927 Add hybrid request logs function 2025-10-24 17:05:05 -07:00
Owen
4b40e7b8d6 Restrict features 2025-10-24 16:29:37 -07:00
Fred KISSIE
29cd035a05 🚧 add & validate blueprint yaml 2025-10-25 01:25:19 +02:00
miloschwartz
39d6b93d42 enforce max session length 2025-10-24 16:14:21 -07:00
miloschwartz
629f17294a 2fa policy check working 2025-10-24 14:31:50 -07:00
Owen
10a5af67aa Merge branch 'dev' into audit-logs 2025-10-24 11:15:39 -07:00
Owen
b542d82553 Consolidate into central cache 2025-10-24 11:14:07 -07:00
Owen
2a644c3f88 Working on settings 2025-10-24 10:51:32 -07:00
Owen
f6de61968d Merge branch 'dev' into audit-logs 2025-10-24 10:31:54 -07:00
Owen
68f0c4df3a Working on licencing 2025-10-24 10:11:28 -07:00
Pallavi Kumari
0743daf56a add en-US for proxy protocol 2025-10-24 16:30:34 +05:30
Pallavi Kumari
58b6ab2601 Implement Proxy Protocol handling in Traefik config generator 2025-10-24 15:56:46 +05:30
Fred KISSIE
038f8829c2 🚧 create blueprint form 2025-10-24 04:17:13 +02:00
miloschwartz
ddcf77a62d add basic org policy check in middleware 2025-10-23 18:15:00 -07:00
Owen
adefbdbeb3 Fix various ui bugs 2025-10-23 17:36:24 -07:00
Owen
921285e5b1 Filtering on all tables 2025-10-23 15:33:29 -07:00
Owen
264bf46798 Filtering working on both access and request 2025-10-23 14:34:56 -07:00
miloschwartz
5a7b5d65a4 remove org settings json 2025-10-23 14:22:50 -07:00
Fred KISSIE
23b13f0a0e 💄 add toploader navigation 2025-10-23 23:10:28 +02:00
Fred KISSIE
90ddffce0e 🚧 create blueprint page 2025-10-23 22:27:14 +02:00
Fred KISSIE
e30fde5237 💄 blueprint data table 2025-10-23 22:14:09 +02:00
Pallavi Kumari
ac683c3ff7 add pg schema for proxy protocol 2025-10-23 23:24:42 +05:30
Pallavi Kumari
b5a931c96e UI and backend update to add proxy protocol support 2025-10-23 23:07:26 +05:30
Lokowitz
5b61742075 change geoip to country 2025-10-23 13:27:34 +00:00
Lokowitz
4e4a38f7e9 move to match type country instead of geoip 2025-10-23 13:19:27 +00:00
miloschwartz
c1bb029a1c simplify telemetry collection 2025-10-22 21:41:36 -07:00
Owen
eae2c37388 Add expandable columns 2025-10-22 18:21:54 -07:00
dependabot[bot]
7193fea068 Bump the dev-patch-updates group with 3 updates
Bumps the dev-patch-updates group with 3 updates: [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss), [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@tailwindcss/postcss` from 4.1.14 to 4.1.15
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.15/packages/@tailwindcss-postcss)

Updates `tailwindcss` from 4.1.14 to 4.1.15
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.15/packages/tailwindcss)

Updates `typescript-eslint` from 8.46.1 to 8.46.2
- [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.46.2/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.1.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: tailwindcss
  dependency-version: 4.1.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: typescript-eslint
  dependency-version: 8.46.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-23 01:20:34 +00:00
dependabot[bot]
9b85deebf8 Bump @types/node from 24.8.1 to 24.9.1 in the dev-minor-updates group
Bumps the dev-minor-updates group with 1 update: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node).


Updates `@types/node` from 24.8.1 to 24.9.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.9.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-23 01:20:13 +00:00
Owen
0211f75cb6 Access logs working 2025-10-22 17:42:27 -07:00
Fred KISSIE
fa6b7ca3ed 🚧 (WIP) blueprints table 2025-10-23 00:33:49 +02:00
Fred KISSIE
007d03e7f6 ♻️ refactor 2025-10-23 00:27:07 +02:00
Fred KISSIE
a534301eb7 ♻️ make source not null 2025-10-23 00:26:41 +02:00
miloschwartz
1baa987016 update resend ids 2025-10-22 15:14:57 -07:00
Fred KISSIE
a5b48ab392 🚧 blueprints page 2025-10-23 00:13:31 +02:00
Owen
7f981f05fb Show resource link in table for requests 2025-10-22 14:58:18 -07:00
Fred KISSIE
259cea1c42 add API endpoint for listing blueprints 2025-10-22 23:49:43 +02:00
Fred KISSIE
9024b2a974 🗃️ finish db schemas for blueprints 2025-10-22 23:49:13 +02:00
Owen
f2c31d3ca6 Add actor data to request 2025-10-22 14:27:21 -07:00
miloschwartz
6f8b5dd909 change get to post for whitelist 2025-10-22 14:02:43 -07:00
Fred KISSIE
6521b66b7c 🍱 add jsonschema for blueprint yaml validation 2025-10-22 21:58:19 +02:00
Fred KISSIE
202d2075a6 🚧 add blueprint to the sidebar and scaffold page 2025-10-22 21:56:26 +02:00
Fred KISSIE
e575fae73b 🚧 SQLite database schema with modes (is it okay ?) 2025-10-22 21:56:10 +02:00
Fred KISSIE
d84ee3d03d 🌐 add blueprint section title in the sidebar in messages (en-US for now) 2025-10-22 21:55:41 +02:00
Fred KISSIE
ba745588e9 🎨 format with prettier 2025-10-22 21:55:09 +02:00
Pallavi Kumari
84731bdc19 client olm version show in the table 2025-10-23 00:55:48 +05:30
Owen
f748c5dbe4 Basic request log working 2025-10-22 12:23:48 -07:00
Owen
fdd4d5244f Temp dont ignore org 2025-10-22 10:59:35 -07:00
Owen
9301477262 Merge branch 'dev' into audit-logs 2025-10-22 10:34:31 -07:00
Owen
9a787e6ef8 Merge branch 'main' into dev 2025-10-22 10:34:21 -07:00
Owen Schwartz
5b8cdf7884 Merge pull request #1730 from Pallavikumarimdb/fix/shareable-link-resource-URI
Update shareable link resource URI to use NiceId instead of resourceId
2025-10-22 10:11:10 -07:00
Fred KISSIE
5fd104bb30 🗃️ add bluePrintRuns model 2025-10-22 14:02:37 +02:00
Pallavi Kumari
9ba42a8fa3 add niceid to CreateShareLinkForm 2025-10-22 16:18:19 +05:30
Pallavi Kumari
fe8fd2e3a8 change shareable link resource URI from resource Id to NiceId 2025-10-22 15:53:29 +05:30
Owen
9ebce35d2b Dont do local sites undefined in cloud 2025-10-21 22:02:09 -07:00
Owen
654145be84 Clean up imports and ordering 2025-10-21 21:58:09 -07:00
Owen
3662d42374 Add resource id and cc 2025-10-21 21:42:53 -07:00
Owen
d392fb371e Add logging for all auth 2025-10-21 21:22:56 -07:00
Owen
1142d6ac48 Date picker working 2025-10-21 20:15:43 -07:00
Owen
bdc3b2425b Basic table working 2025-10-21 17:35:13 -07:00
Owen
9a64f45815 Basic log table there 2025-10-21 15:26:03 -07:00
Fred KISSIE
3633e02ff7 🔨 run next server with turbopack (easy win) 2025-10-22 00:17:42 +02:00
Owen Schwartz
2c502ec764 Merge pull request #1728 from jonasmerkel/main
Update German translations for client terminology
2025-10-21 14:29:23 -07:00
Jonas
b17d7f0e27 Update German translations for client terminology 2025-10-21 23:26:27 +02:00
Owen
65364d6b0f Merge branch 'dev' into audit-logs 2025-10-21 11:31:33 -07:00
Owen
6fd6c77ce6 Further revert 2025-10-21 11:29:27 -07:00
Owen
e447549de1 revert changes around sites assigned to exit nodes 2025-10-21 11:12:27 -07:00
Pallavi Kumari
6b0dd00aa5 show IP of the server inside DNS records 2025-10-21 20:43:42 +05:30
Pallavi Kumari
461866836e Remove the popup after creating domain and redirect to domain details page 2025-10-21 17:41:14 +05:30
Pallavi Kumari
3ae42f054f show the wildcard record info 2025-10-21 17:07:34 +05:30
Pallavi Kumari
5a571f19e1 add each form control it's own form field/item/control 2025-10-21 16:10:23 +05:30
Owen
70aeaf7b5d Change badges and button size 2025-10-21 15:37:03 +05:30
Pallavi Kumari
7a6838f5a5 fix lint 2025-10-21 15:37:03 +05:30
Pallavi Kumari
07f5e8f215 add update domain Settings for wildcard 2025-10-21 15:37:03 +05:30
Pallavi Kumari
2b05bc1f5f ui and layout fix 2025-10-21 15:37:03 +05:30
Pallavi Kumari
edf64ae7b5 fix invalid "default" 2025-10-21 15:37:03 +05:30
Pallavi Kumari
7370448be9 pg schema 2025-10-21 15:37:02 +05:30
Pallavi Kumari
51af293d66 add doc link button and fix continuous polling 2025-10-21 15:37:02 +05:30
Pallavi Kumari
d37e28215e add restart button 2025-10-21 15:37:02 +05:30
Pallavi Kumari
2c01849f2e fix import 2025-10-21 15:37:02 +05:30
Pallavi Kumari
c29ba9bb5f add DNS Records table 2025-10-21 15:37:02 +05:30
Pallavi Kumari
8fdf120ec2 backend setup to store and get DNS Records 2025-10-21 15:37:02 +05:30
Pallavi Kumari
a9b9161c40 template for Domain Settings 2025-10-21 15:37:02 +05:30
Pallavi Kumari
43f907ebec remove import 2025-10-21 15:37:02 +05:30
Pallavi Kumari
ae670e1eb5 initial setup for viewing domain details 2025-10-21 15:37:02 +05:30
Pallavi Kumari
f102718901 add edit button to domain table 2025-10-21 15:37:02 +05:30
Pallavi Kumari
9d452efc7d fix treafik config mismatch 2025-10-21 15:37:02 +05:30
Pallavi Kumari
156fe529b5 fix code conflicts and match dev change 2025-10-21 15:37:02 +05:30
Owen
df24525105 Fix type issues 2025-10-21 15:37:02 +05:30
Owen
d938345deb Copy in config to db, remove 2nd column, + prefer 2025-10-21 15:37:02 +05:30
Pallavi Kumari
d6681733dd remove custom cery type form config file 2025-10-21 15:37:02 +05:30
Pallavi Kumari
2f1aec02f0 traefik config update for custom Cert Resolver 2025-10-21 15:37:01 +05:30
Pallavi Kumari
d30e0a3c51 schema add 2025-10-21 15:37:01 +05:30
Pallavi Kumari
3f3e9cf1bb add cert resolver 2025-10-21 15:37:01 +05:30
Owen
e77909d498 Change runs on 2025-10-20 21:45:40 -07:00
Owen
d10830f892 Fix exitNodeId col 2025-10-20 21:34:10 -07:00
Owen
18d8f72da2 Change runner back 2025-10-20 21:01:45 -07:00
Owen
4a59823e58 Actually run the migrations; update exit nodes
Fix #1718
Fix #1720
2025-10-20 20:55:47 -07:00
Owen
f3149e46cd Starting to create frontend 2025-10-20 20:40:04 -07:00
Owen
60379a7b4e Merge branch 'dev' 2025-10-20 17:17:02 -07:00
dependabot[bot]
605b3cccee Bump @types/node from 24.7.2 to 24.8.1 in the dev-minor-updates group
Bumps the dev-minor-updates group with 1 update: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node).


Updates `@types/node` from 24.7.2 to 24.8.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.8.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 17:16:40 -07:00
dependabot[bot]
843799f4f6 Bump the dev-patch-updates group with 2 updates
Bumps the dev-patch-updates group with 2 updates: [@react-email/preview-server](https://github.com/resend/react-email/tree/HEAD/packages/preview-server) and [react-email](https://github.com/resend/react-email/tree/HEAD/packages/react-email).


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

Updates `react-email` from 4.3.0 to 4.3.1
- [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@4.3.1/packages/react-email)

---
updated-dependencies:
- dependency-name: "@react-email/preview-server"
  dependency-version: 4.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: react-email
  dependency-version: 4.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 17:16:40 -07:00
Marc Schäfer
a69cda5c13 ci(actions): add GHCR mirroring and cosign signing for Docker images
- mirror images from Docker Hub to GHCR using skopeo (preserves multi-arch manifests)
- login to GHCR via docker/login-action for signing/pushing
- install cosign and perform dual signing: keyless (OIDC) + key-based; verify signatures
- add required permissions for id-token/packages and reference necessary secrets
2025-10-20 17:16:40 -07:00
Marc Schäfer
dbaa3dbd52 ci(actions): add permissions section to workflows 2025-10-20 17:16:40 -07:00
Marc Schäfer
58197c6fb2 ci(actions): change runner from ubuntu-latest to amd64-runner 2025-10-20 17:16:40 -07:00
Marc Schäfer
7813093452 ci(actions): pin action versions to commit SHAs for security
- Pin actions/checkout to SHA for v5.0.0
- Pin docker/setup-qemu-action to SHA for v3.6.0
- Pin docker/setup-buildx-action to SHA for v3.11.1
- Pin docker/login-action to SHA for v3.6.0
- Pin actions/setup-go to SHA for v6.0.0
- Pin actions/upload-artifact to SHA for v4.6.2
- Pin actions/setup-node to SHA for v6.0.0
- Pin actions/stale to SHA for v10.1.0
2025-10-20 17:16:40 -07:00
Marc Schäfer
3f2c3dc987 feat(actions): Sync Images from Docker to GHCR 2025-10-20 17:16:40 -07:00
miloschwartz
08ddba25d0 hide method selector on raw resources 2025-10-20 17:15:45 -07:00
Owen Schwartz
d47fa7e64f Merge pull request #1715 from marcschaeferger/gh-action
Adding GHCR to CI/CD Release Workflow & further improvements
2025-10-20 17:12:05 -07:00
Marc Schäfer
c87aa2e537 Merge branch 'fosrl:main' into gh-action 2025-10-21 02:09:04 +02:00
Marc Schäfer
bc430546bc ci(actions): add GHCR mirroring and cosign signing for Docker images
- mirror images from Docker Hub to GHCR using skopeo (preserves multi-arch manifests)
- login to GHCR via docker/login-action for signing/pushing
- install cosign and perform dual signing: keyless (OIDC) + key-based; verify signatures
- add required permissions for id-token/packages and reference necessary secrets
2025-10-21 02:07:26 +02:00
Owen Schwartz
9428e065eb Merge pull request #1707 from fosrl/dependabot/npm_and_yarn/dev-minor-updates-be6156b6cb
Bump @types/node from 24.7.2 to 24.8.1 in the dev-minor-updates group
2025-10-20 17:06:20 -07:00
Owen Schwartz
10408c5717 Merge pull request #1706 from fosrl/dependabot/npm_and_yarn/dev-patch-updates-b03f25c1b7
Bump the dev-patch-updates group with 2 updates
2025-10-20 17:06:13 -07:00
Owen Schwartz
ae902da913 Merge pull request #1714 from fosrl/crowdin_dev
New Crowdin updates
2025-10-20 17:06:00 -07:00
Owen Schwartz
0be5a91eff New translations en-us.json (Spanish) 2025-10-20 17:05:44 -07:00
Owen Schwartz
7dcf46ce98 New translations en-us.json (Norwegian Bokmal) 2025-10-20 17:05:42 -07:00
Owen Schwartz
33e6e4b411 New translations en-us.json (Chinese Simplified) 2025-10-20 17:05:41 -07:00
Owen Schwartz
bab6e4eb0d New translations en-us.json (Turkish) 2025-10-20 17:05:39 -07:00
Owen Schwartz
6a7c7521d8 New translations en-us.json (Russian) 2025-10-20 17:05:38 -07:00
Owen Schwartz
d070244ea7 New translations en-us.json (Portuguese) 2025-10-20 17:05:37 -07:00
Owen Schwartz
9219bb7d6e New translations en-us.json (Polish) 2025-10-20 17:05:35 -07:00
Owen Schwartz
54e83f35e5 New translations en-us.json (Dutch) 2025-10-20 17:05:34 -07:00
Owen Schwartz
eb138d6526 New translations en-us.json (Korean) 2025-10-20 17:05:33 -07:00
Owen Schwartz
edd0c3099b New translations en-us.json (Italian) 2025-10-20 17:05:31 -07:00
Owen Schwartz
04455d40cf New translations en-us.json (German) 2025-10-20 17:05:30 -07:00
Owen Schwartz
221af94d15 New translations en-us.json (Czech) 2025-10-20 17:05:29 -07:00
Owen Schwartz
48ac3bb7af New translations en-us.json (Bulgarian) 2025-10-20 17:05:27 -07:00
Owen Schwartz
07273b8b7f New translations en-us.json (French) 2025-10-20 17:05:26 -07:00
Marc Schäfer
bfb5b2864d ci(actions): add permissions section to workflows 2025-10-21 01:59:52 +02:00
Marc Schäfer
07330e84fb ci(actions): change runner from ubuntu-latest to amd64-runner 2025-10-21 01:54:23 +02:00
Marc Schäfer
0e39704b3a ci(actions): pin action versions to commit SHAs for security
- Pin actions/checkout to SHA for v5.0.0
- Pin docker/setup-qemu-action to SHA for v3.6.0
- Pin docker/setup-buildx-action to SHA for v3.11.1
- Pin docker/login-action to SHA for v3.6.0
- Pin actions/setup-go to SHA for v6.0.0
- Pin actions/upload-artifact to SHA for v4.6.2
- Pin actions/setup-node to SHA for v6.0.0
- Pin actions/stale to SHA for v10.1.0
2025-10-21 01:53:20 +02:00
miloschwartz
f25e794e7c add checks to prevent fk failure in ensureActions 2025-10-20 16:01:40 -07:00
Owen Schwartz
df46ce8bdc Merge pull request #1712 from marcschaeferger/ghcr
feat(actions): Sync Images from Docker to GHCR
2025-10-20 13:07:34 -07:00
Marc Schäfer
4d83f537dc feat(actions): Sync Images from Docker to GHCR 2025-10-20 22:06:36 +02:00
Owen
58443ef53f Reorder log middleware 2025-10-19 22:25:00 -07:00
Owen
1ee52ad86b Add headers 2025-10-19 21:59:51 -07:00
Owen
bc941239ec Fix the indexes 2025-10-19 21:59:41 -07:00
Owen
9a52d5387d Merge branch 'dev' into audit-logs 2025-10-19 21:54:26 -07:00
Owen
1f50bc3752 Add logActionAudit and query endpoint 2025-10-19 21:53:00 -07:00
dependabot[bot]
0819df0910 Bump @types/node from 24.7.2 to 24.8.1 in the dev-minor-updates group
Bumps the dev-minor-updates group with 1 update: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node).


Updates `@types/node` from 24.7.2 to 24.8.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.8.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 01:35:01 +00:00
dependabot[bot]
663787c15b Bump the dev-patch-updates group with 2 updates
Bumps the dev-patch-updates group with 2 updates: [@react-email/preview-server](https://github.com/resend/react-email/tree/HEAD/packages/preview-server) and [react-email](https://github.com/resend/react-email/tree/HEAD/packages/react-email).


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

Updates `react-email` from 4.3.0 to 4.3.1
- [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@4.3.1/packages/react-email)

---
updated-dependencies:
- dependency-name: "@react-email/preview-server"
  dependency-version: 4.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: react-email
  dependency-version: 4.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 01:32:52 +00:00
Owen
2c39d07261 Add missing headers 2025-10-19 17:59:40 -07:00
Owen
dce84b9b09 Add action audit middleware and tables 2025-10-19 17:58:52 -07:00
Owen
a5bab6bb80 Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-10-19 12:04:59 -07:00
miloschwartz
7536c03f63 add int api routes for add/remote email to resource email whitelist 2025-10-19 12:04:20 -07:00
Owen
ada5d2ef0e Update domain 2025-10-19 11:59:10 -07:00
Owen
b8bead0590 Select exit node for local sites 2025-10-19 11:13:33 -07:00
Milo Schwartz
68f852d6d1 Merge pull request #1699 from Pallavikumarimdb/make-easier-to-delete
Make it easier to delete things
2025-10-19 14:00:19 -04:00
Owen
d9fe5a8819 Always set exit node to online
Fixes #1692
2025-10-19 10:47:32 -07:00
Owen
346183a23f Only allow nodes to pull with defined exitNodeID 2025-10-19 10:46:25 -07:00
Owen
dcfd7f5443 Merge branch 'dev' of github.com:fosrl/pangolin into dev 2025-10-19 10:43:39 -07:00
Pallavi Kumari
e59cd6672b fix space 2025-10-19 22:23:57 +05:30
Pallavi Kumari
7c8c440f67 fix text 2025-10-19 21:36:47 +05:30
Pallavi Kumari
f258c41f15 easier to delete 2025-10-19 20:37:07 +05:30
Pallavi Kumari
ae4a24f4aa easier to delete resources 2025-10-19 15:50:00 +05:30
Pallavi Kumari
476cdcfe86 easier to delete sites 2025-10-19 15:02:35 +05:30
Owen
f869df2f65 Working on fixing exit node issue 2025-10-18 21:32:26 -07:00
Owen Schwartz
03cfabacd9 Merge pull request #1695 from Pallavikumarimdb/fix/rule-priority-input
Make priority input box focused on pressing the up/down arrows
2025-10-18 13:38:54 -07:00
miloschwartz
47ac5875f3 change digpangolin.com to pangolin.net 2025-10-18 11:51:09 -07:00
miloschwartz
f67327358e Merge branch 'main' into dev 2025-10-18 11:41:06 -07:00
Milo Schwartz
4901823f15 Update README.md 2025-10-18 14:25:22 -04:00
Pallavi Kumari
5407e3c821 make priority input box focus on up/down click 2025-10-18 23:38:14 +05:30
Owen Schwartz
1d5cdad8b7 Merge pull request #1693 from Pallavikumarimdb/fix/sorting-resources-alphabetically-by-default
Sorting Resources Alphabetically by Default
2025-10-18 10:03:28 -07:00
Owen Schwartz
cd2424cb77 Merge pull request #1691 from fosrl/dependabot/npm_and_yarn/prod-patch-updates-30703f013a
Bump the prod-patch-updates group across 1 directory with 4 updates
2025-10-18 10:03:23 -07:00
Pallavi Kumari
c17efde6bf Sorting Resources Alphabetically by Default 2025-10-18 14:43:54 +05:30
Owen
40cd8cdec7 Merge branch 'dev' 2025-10-17 16:25:01 -07:00
Owen
6768672a44 Merge branch 'main' of github.com:fosrl/pangolin 2025-10-17 16:24:55 -07:00
Owen
240c5b005b Add more transactions support 2025-10-17 16:22:43 -07:00
dependabot[bot]
8dde170a35 Bump the prod-patch-updates group across 1 directory with 4 updates
Bumps the prod-patch-updates group with 3 updates in the / directory: [@react-email/components](https://github.com/resend/react-email/tree/HEAD/packages/components), [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) and [next](https://github.com/vercel/next.js).


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

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

Updates `eslint-config-next` from 15.5.5 to 15.5.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.5.6/packages/eslint-config-next)

Updates `next` from 15.5.5 to 15.5.6
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.5.5...v15.5.6)

---
updated-dependencies:
- dependency-name: "@react-email/components"
  dependency-version: 0.5.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: "@react-email/render"
  dependency-version: 1.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-patch-updates
- dependency-name: eslint-config-next
  dependency-version: 15.5.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: next
  dependency-version: 15.5.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-17 21:06:44 +00:00
Owen
c07abf8ff9 Pass through transaction 2025-10-17 14:05:17 -07:00
Owen
e5a436593f Delete all before migrating 2025-10-17 14:05:17 -07:00
Owen
bb6e093ac6 Priority needs to be def 2025-10-17 14:05:17 -07:00
Milo Schwartz
59a334ce24 Update README.md 2025-10-17 14:05:17 -07:00
Owen
d241dcfb27 Fix typo 2025-10-17 14:05:17 -07:00
Owen
af263e7913 Pass through transaction 2025-10-17 14:04:49 -07:00
Owen Schwartz
6610e7d405 Merge pull request #1673 from fosrl/dependabot/npm_and_yarn/prod-patch-updates-ac45ae572b
Bump the prod-patch-updates group across 1 directory with 2 updates
2025-10-17 14:02:36 -07:00
Owen Schwartz
c476e65cf2 Merge pull request #1677 from fosrl/dependabot/npm_and_yarn/dev-patch-updates-3f2a7d9f8f
Bump the dev-patch-updates group across 1 directory with 2 updates
2025-10-17 14:01:57 -07:00
Owen Schwartz
b69b2eeeb3 Merge pull request #1689 from barnabehvrd/patch-2
FR translation update
2025-10-17 13:57:09 -07:00
Barnabé Havard
89dab0917b Fixed (again ...) indentation issues 2025-10-17 22:42:07 +02:00
Barnabé Havard
73efdb95ae Fixed indentation issues 2025-10-17 22:36:08 +02:00
Barnabé Havard
1bcca88614 Updated several translation 2025-10-17 22:32:51 +02:00
Owen Schwartz
8387571c1d Merge pull request #1684 from Pallavikumarimdb/fix/make-priority-optional
Make priority optional in schema
2025-10-17 10:14:01 -07:00
Pallavi Kumari
1d017f60b4 make priority optional in schema 2025-10-17 19:51:32 +05:30
dependabot[bot]
81effda9e8 Bump the prod-patch-updates group across 1 directory with 2 updates
Bumps the prod-patch-updates group with 2 updates in the / directory: [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) and [next](https://github.com/vercel/next.js).


Updates `eslint-config-next` from 15.5.4 to 15.5.5
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v15.5.5/packages/eslint-config-next)

Updates `next` from 15.5.4 to 15.5.5
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.5.4...v15.5.5)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-version: 15.5.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
- dependency-name: next
  dependency-version: 15.5.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-17 01:22:32 +00:00
dependabot[bot]
9343906ab1 Bump the dev-patch-updates group across 1 directory with 2 updates
Bumps the dev-patch-updates group with 2 updates in the / directory: [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) and [esbuild](https://github.com/evanw/esbuild).


Updates `@types/react-dom` from 19.2.1 to 19.2.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `esbuild` from 0.25.10 to 0.25.11
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.25.10...v0.25.11)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
- dependency-name: esbuild
  dependency-version: 0.25.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-17 01:20:39 +00:00
616 changed files with 51664 additions and 13923 deletions

View File

@@ -1,34 +1,62 @@
name: CI/CD 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
# Required secrets:
# - DOCKER_HUB_USERNAME / DOCKER_HUB_ACCESS_TOKEN: push to Docker Hub
# - GITHUB_TOKEN: used for GHCR login and OIDC keyless signing
# - COSIGN_PRIVATE_KEY / COSIGN_PASSWORD / COSIGN_PUBLIC_KEY: for key-based signing
on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+.rc.[0-9]+"
concurrency:
group: ${{ github.ref }}
cancel-in-progress: true
jobs:
release:
name: Build and Release
runs-on: amd64-runner
runs-on: [self-hosted, linux, x64]
# Job-level timeout to avoid runaway or stuck runs
timeout-minutes: 120
env:
# Target images
DOCKERHUB_IMAGE: docker.io/fosrl/${{ github.event.repository.name }}
GHCR_IMAGE: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Extract tag name
id: get-tag
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
shell: bash
- name: Install Go
uses: actions/setup-go@v6
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: 1.24
@@ -37,18 +65,21 @@ jobs:
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: Pull latest Gerbil version
id: get-gerbil-tag
run: |
LATEST_TAG=$(curl -s https://api.github.com/repos/fosrl/gerbil/tags | jq -r '.[0].name')
echo "LATEST_GERBIL_TAG=$LATEST_TAG" >> $GITHUB_ENV
shell: bash
- name: Pull latest Badger version
id: get-badger-tag
run: |
LATEST_TAG=$(curl -s https://api.github.com/repos/fosrl/badger/tags | jq -r '.[0].name')
echo "LATEST_BADGER_TAG=$LATEST_TAG" >> $GITHUB_ENV
shell: bash
- name: Update install/main.go
run: |
@@ -60,6 +91,7 @@ jobs:
sed -i "s/config.BadgerVersion = \".*\"/config.BadgerVersion = \"$BADGER_VERSION\"/" install/main.go
echo "Updated install/main.go with Pangolin version $PANGOLIN_VERSION, Gerbil version $GERBIL_VERSION, and Badger version $BADGER_VERSION"
cat install/main.go
shell: bash
- name: Build installer
working-directory: install
@@ -67,12 +99,82 @@ jobs:
make go-build-release
- name: Upload artifacts from /install/bin
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: install-bin
path: install/bin/
- name: Build and push Docker images
- name: Build and push Docker images (Docker Hub)
run: |
TAG=${{ env.TAG }}
make build-release tag=$TAG
echo "Built & pushed to: ${{ env.DOCKERHUB_IMAGE }}:${TAG}"
shell: bash
- name: Install skopeo + jq
# skopeo: copy/inspect images between registries
# jq: JSON parsing tool used to extract digest values
run: |
sudo apt-get update -y
sudo apt-get install -y skopeo jq
skopeo --version
shell: bash
- name: Login to GHCR
run: |
skopeo login ghcr.io -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}"
shell: bash
- name: Copy tag from Docker Hub to GHCR
# Mirror the already-built image (all architectures) to GHCR so we can sign it
run: |
set -euo pipefail
TAG=${{ env.TAG }}
echo "Copying ${{ env.DOCKERHUB_IMAGE }}:${TAG} -> ${{ env.GHCR_IMAGE }}:${TAG}"
skopeo copy --all --retry-times 3 \
docker://$DOCKERHUB_IMAGE:$TAG \
docker://$GHCR_IMAGE:$TAG
shell: bash
- name: Install cosign
# cosign is used to sign and verify container images (key and keyless)
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- name: Dual-sign and verify (GHCR & Docker Hub)
# Sign each image by digest using keyless (OIDC) and key-based signing,
# then verify both the public key signature and the keyless OIDC signature.
env:
TAG: ${{ env.TAG }}
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
COSIGN_PUBLIC_KEY: ${{ secrets.COSIGN_PUBLIC_KEY }}
COSIGN_YES: "true"
run: |
set -euo pipefail
issuer="https://token.actions.githubusercontent.com"
id_regex="^https://github.com/${{ github.repository }}/.+" # accept this repo (all workflows/refs)
for IMAGE in "${GHCR_IMAGE}" "${DOCKERHUB_IMAGE}"; do
echo "Processing ${IMAGE}:${TAG}"
DIGEST="$(skopeo inspect --retry-times 3 docker://${IMAGE}:${TAG} | jq -r '.Digest')"
REF="${IMAGE}@${DIGEST}"
echo "Resolved digest: ${REF}"
echo "==> cosign sign (keyless) --recursive ${REF}"
cosign sign --recursive "${REF}"
echo "==> cosign sign (key) --recursive ${REF}"
cosign sign --key env://COSIGN_PRIVATE_KEY --recursive "${REF}"
echo "==> cosign verify (public key) ${REF}"
cosign verify --key env://COSIGN_PUBLIC_KEY "${REF}" -o text
echo "==> cosign verify (keyless policy) ${REF}"
cosign verify \
--certificate-oidc-issuer "${issuer}" \
--certificate-identity-regexp "${id_regex}" \
"${REF}" -o text
done
shell: bash

View File

@@ -1,5 +1,8 @@
name: ESLint
permissions:
contents: read
on:
pull_request:
paths:
@@ -18,10 +21,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Set up Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: '22'
@@ -32,4 +35,4 @@ jobs:
run: npm run set:oss
- name: Run ESLint
run: npx eslint . --ext .js,.jsx,.ts,.tsx
run: npx eslint . --ext .js,.jsx,.ts,.tsx

132
.github/workflows/mirror.yaml vendored Normal file
View File

@@ -0,0 +1,132 @@
name: Mirror & Sign (Docker Hub to GHCR)
on:
workflow_dispatch: {}
permissions:
contents: read
packages: write
id-token: write # for keyless OIDC
env:
SOURCE_IMAGE: docker.io/fosrl/pangolin
DEST_IMAGE: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
jobs:
mirror-and-dual-sign:
runs-on: amd64-runner
steps:
- name: Install skopeo + jq
run: |
sudo apt-get update -y
sudo apt-get install -y skopeo jq
skopeo --version
- name: Install cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- name: Input check
run: |
test -n "${SOURCE_IMAGE}" || (echo "SOURCE_IMAGE is empty" && exit 1)
echo "Source : ${SOURCE_IMAGE}"
echo "Target : ${DEST_IMAGE}"
# Auth for skopeo (containers-auth)
- name: Skopeo login to GHCR
run: |
skopeo login ghcr.io -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}"
# Auth for cosign (docker-config)
- name: Docker login to GHCR (for cosign)
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
- name: List source tags
run: |
set -euo pipefail
skopeo list-tags --retry-times 3 docker://"${SOURCE_IMAGE}" \
| jq -r '.Tags[]' | sort -u > src-tags.txt
echo "Found source tags: $(wc -l < src-tags.txt)"
head -n 20 src-tags.txt || true
- name: List destination tags (skip existing)
run: |
set -euo pipefail
if skopeo list-tags --retry-times 3 docker://"${DEST_IMAGE}" >/tmp/dst.json 2>/dev/null; then
jq -r '.Tags[]' /tmp/dst.json | sort -u > dst-tags.txt
else
: > dst-tags.txt
fi
echo "Existing destination tags: $(wc -l < dst-tags.txt)"
- name: Mirror, dual-sign, and verify
env:
# keyless
COSIGN_YES: "true"
# key-based
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
# verify
COSIGN_PUBLIC_KEY: ${{ secrets.COSIGN_PUBLIC_KEY }}
run: |
set -euo pipefail
copied=0; skipped=0; v_ok=0; errs=0
issuer="https://token.actions.githubusercontent.com"
id_regex="^https://github.com/${{ github.repository }}/.+"
while read -r tag; do
[ -z "$tag" ] && continue
if grep -Fxq "$tag" dst-tags.txt; then
echo "::notice ::Skip (exists) ${DEST_IMAGE}:${tag}"
skipped=$((skipped+1))
continue
fi
echo "==> Copy ${SOURCE_IMAGE}:${tag} → ${DEST_IMAGE}:${tag}"
if ! skopeo copy --all --retry-times 3 \
docker://"${SOURCE_IMAGE}:${tag}" docker://"${DEST_IMAGE}:${tag}"; then
echo "::warning title=Copy failed::${SOURCE_IMAGE}:${tag}"
errs=$((errs+1)); continue
fi
copied=$((copied+1))
digest="$(skopeo inspect --retry-times 3 docker://"${DEST_IMAGE}:${tag}" | jq -r '.Digest')"
ref="${DEST_IMAGE}@${digest}"
echo "==> cosign sign (keyless) --recursive ${ref}"
if ! cosign sign --recursive "${ref}"; then
echo "::warning title=Keyless sign failed::${ref}"
errs=$((errs+1))
fi
echo "==> cosign sign (key) --recursive ${ref}"
if ! cosign sign --key env://COSIGN_PRIVATE_KEY --recursive "${ref}"; then
echo "::warning title=Key sign failed::${ref}"
errs=$((errs+1))
fi
echo "==> cosign verify (public key) ${ref}"
if ! cosign verify --key env://COSIGN_PUBLIC_KEY "${ref}" -o text; then
echo "::warning title=Verify(pubkey) failed::${ref}"
errs=$((errs+1))
fi
echo "==> cosign verify (keyless policy) ${ref}"
if ! cosign verify \
--certificate-oidc-issuer "${issuer}" \
--certificate-identity-regexp "${id_regex}" \
"${ref}" -o text; then
echo "::warning title=Verify(keyless) failed::${ref}"
errs=$((errs+1))
else
v_ok=$((v_ok+1))
fi
done < src-tags.txt
echo "---- Summary ----"
echo "Copied : $copied"
echo "Skipped : $skipped"
echo "Verified OK : $v_ok"
echo "Errors : $errs"

View File

@@ -14,7 +14,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
with:
days-before-stale: 14
days-before-close: 14
@@ -34,4 +34,4 @@ jobs:
operations-per-run: 100
remove-stale-when-updated: true
delete-branch: false
enable-statistics: true
enable-statistics: true

View File

@@ -1,5 +1,8 @@
name: Run Tests
permissions:
contents: read
on:
pull_request:
branches:
@@ -11,9 +14,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/setup-node@v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: '22'

3
.gitignore vendored
View File

@@ -49,4 +49,5 @@ postgres/
dynamic/
*.mmdb
scratch/
tsconfig.json
tsconfig.json
hydrateSaas.ts

2
.nvmrc
View File

@@ -1 +1 @@
22
25

View File

@@ -4,7 +4,7 @@ Contributions are welcome!
Please see the contribution and local development guide on the docs page before getting started:
https://docs.digpangolin.com/development/contributing
https://docs.pangolin.net/development/contributing
### Licensing Considerations

View File

@@ -1,10 +1,12 @@
FROM node:22-alpine AS builder
FROM node:25-alpine AS builder
WORKDIR /app
ARG BUILD=oss
ARG DATABASE=sqlite
RUN apk add --no-cache curl tzdata python3 make g++
# COPY package.json package-lock.json ./
COPY package*.json ./
RUN npm ci
@@ -12,8 +14,9 @@ RUN npm ci
COPY . .
RUN echo "export * from \"./$DATABASE\";" > server/db/index.ts
RUN echo "export const driver: \"pg\" | \"sqlite\" = \"$DATABASE\";" >> server/db/index.ts
RUN echo "export const build = \"$BUILD\" as any;" > server/build.ts
RUN echo "export const build = \"$BUILD\" as \"saas\" | \"enterprise\" | \"oss\";" > server/build.ts
# Copy the appropriate TypeScript configuration based on build type
RUN if [ "$BUILD" = "oss" ]; then cp tsconfig.oss.json tsconfig.json; \
@@ -30,9 +33,9 @@ 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; \
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; \
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
@@ -40,12 +43,13 @@ RUN test -f dist/server.mjs
RUN npm run build:cli
FROM node:22-alpine AS runner
FROM node:25-alpine AS runner
WORKDIR /app
# Curl used for the health checks
RUN apk add --no-cache curl tzdata
# Python and build tools needed for better-sqlite3 native compilation
RUN apk add --no-cache curl tzdata python3 make g++
# COPY package.json package-lock.json ./
COPY package*.json ./

View File

@@ -44,6 +44,36 @@ build-release:
--tag fosrl/pangolin:ee-postgresql-$(tag) \
--push .
build-rc:
@if [ -z "$(tag)" ]; then \
echo "Error: tag is required. Usage: make build-release tag=<tag>"; \
exit 1; \
fi
docker buildx build \
--build-arg BUILD=oss \
--build-arg DATABASE=sqlite \
--platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:$(tag) \
--push .
docker buildx build \
--build-arg BUILD=oss \
--build-arg DATABASE=pg \
--platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:postgresql-$(tag) \
--push .
docker buildx build \
--build-arg BUILD=enterprise \
--build-arg DATABASE=sqlite \
--platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:ee-$(tag) \
--push .
docker buildx build \
--build-arg BUILD=enterprise \
--build-arg DATABASE=pg \
--platform linux/arm64,linux/amd64 \
--tag fosrl/pangolin:ee-postgresql-$(tag) \
--push .
build-arm:
docker buildx build --platform linux/arm64 -t fosrl/pangolin:latest .

View File

@@ -1,6 +1,6 @@
<div align="center">
<h2>
<a href="https://digpangolin.com">
<a href="https://pangolin.net/">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="public/logo/word_mark_white.png">
<img alt="Pangolin Logo" src="public/logo/word_mark_black.png" width="350">
@@ -11,15 +11,15 @@
<div align="center">
<h5>
<a href="https://digpangolin.com">
<a href="https://pangolin.net/">
Website
</a>
<span> | </span>
<a href="https://docs.digpangolin.com/">
<a href="https://docs.pangolin.net/">
Documentation
</a>
<span> | </span>
<a href="mailto:contact@fossorial.io">
<a href="mailto:contact@pangolin.net">
Contact Us
</a>
</h5>
@@ -28,7 +28,7 @@
<div align="center">
[![Discord](https://img.shields.io/discord/1325658630518865980?logo=discord&style=flat-square)](https://discord.gg/HCJR8Xhme4)
[![Slack](https://img.shields.io/badge/chat-slack-yellow?style=flat-square&logo=slack)](https://digpangolin.com/slack)
[![Slack](https://img.shields.io/badge/chat-slack-yellow?style=flat-square&logo=slack)](https://pangolin.net/slack)
[![Docker](https://img.shields.io/docker/pulls/fosrl/pangolin?style=flat-square)](https://hub.docker.com/r/fosrl/pangolin)
![Stars](https://img.shields.io/github/stars/fosrl/pangolin?style=flat-square)
[![YouTube](https://img.shields.io/badge/YouTube-red?logo=youtube&logoColor=white&style=flat-square)](https://www.youtube.com/@fossorial-app)
@@ -37,7 +37,7 @@
<p align="center">
<strong>
Start testing Pangolin at <a href="https://pangolin.fossorial.io/auth/signup">pangolin.fossorial.io</a>
Start testing Pangolin at <a href="https://app.pangolin.net/auth/signup">app.pangolin.net</a>
</strong>
</p>
@@ -45,7 +45,10 @@ Pangolin is a self-hosted tunneled reverse proxy server with identity and contex
## Installation
Check out the [quick install guide](https://docs.digpangolin.com/self-host/quick-install) for how to install and set up Pangolin.
- Check out the [quick install guide](https://docs.pangolin.net/self-host/quick-install) for how to install and set up Pangolin.
- Install from the [DigitalOcean marketplace](https://marketplace.digitalocean.com/apps/pangolin-ce-1?refcode=edf0480eeb81) for a one-click pre-configured installer.
<img src="public/screenshots/hero.png" />
## Deployment Options
@@ -53,7 +56,7 @@ Check out the [quick install guide](https://docs.digpangolin.com/self-host/quick
|-----------------|--------------|
| **Self-Host: Community Edition** | Free, open source, and licensed under AGPL-3. |
| **Self-Host: Enterprise Edition** | Licensed under Fossorial Commercial License. Free for personal and hobbyist use, and for businesses earning under \$100K USD annually. |
| **Pangolin Cloud** | Fully managed service with instant setup and pay-as-you-go pricing — no infrastructure required. Or, self-host your own [remote node](https://docs.digpangolin.com/manage/remote-node/nodes) and connect to our control plane. |
| **Pangolin Cloud** | Fully managed service with instant setup and pay-as-you-go pricing — no infrastructure required. Or, self-host your own [remote node](https://docs.pangolin.net/manage/remote-node/nodes) and connect to our control plane. |
## Key Features
@@ -71,18 +74,22 @@ Pangolin packages everything you need for seamless application access and exposu
### Check out the docs
We encourage everyone to read the full documentation first, which is
available at [docs.digpangolin.com](https://docs.digpangolin.com). This README provides only a very brief subset of
available at [docs.pangolin.net](https://docs.pangolin.net). This README provides only a very brief subset of
the docs to illustrate some basic ideas.
### Sign up and try now
For Pangolin's managed service, you will first need to create an account at
[pangolin.fossorial.io](https://pangolin.fossorial.io). We have a generous free tier to get started.
[app.pangolin.net](https://app.pangolin.net). We have a generous free tier to get started.
## Licensing
Pangolin is dual licensed under the AGPL-3 and the [Fossorial Commercial License](https://digpangolin.com/fcl.html). For inquiries about commercial licensing, please contact us at [contact@fossorial.io](mailto:contact@fossorial.io).
Pangolin is dual licensed under the AGPL-3 and the [Fossorial Commercial License](https://pangolin.net/fcl.html). For inquiries about commercial licensing, please contact us at [contact@pangolin.net](mailto:contact@pangolin.net).
## Contributions
Please see [CONTRIBUTING](./CONTRIBUTING.md) in the repository for guidelines and best practices.
---
WireGuard® is a registered trademark of Jason A. Donenfeld.

View File

@@ -3,7 +3,7 @@
If you discover a security vulnerability, please follow the steps below to responsibly disclose it to us:
1. **Do not create a public GitHub issue or discussion post.** This could put the security of other users at risk.
2. Send a detailed report to [security@fossorial.io](mailto:security@fossorial.io) or send a **private** message to a maintainer on [Discord](https://discord.gg/HCJR8Xhme4). Include:
2. Send a detailed report to [security@pangolin.net](mailto:security@pangolin.net) or send a **private** message to a maintainer on [Discord](https://discord.gg/HCJR8Xhme4). Include:
- Description and location of the vulnerability.
- Potential impact of the vulnerability.

View File

@@ -8,7 +8,7 @@ import base64
YAML_FILE_PATH = 'blueprint.yaml'
# The API endpoint and headers from the curl request
API_URL = 'http://api.pangolin.fossorial.io/v1/org/test/blueprint'
API_URL = 'http://api.pangolin.net/v1/org/test/blueprint'
HEADERS = {
'accept': '*/*',
'Authorization': 'Bearer <your_token_here>',

View File

@@ -28,9 +28,10 @@ proxy-resources:
# sso-roles:
# - Member
# sso-users:
# - owen@fossorial.io
# - owen@pangolin.net
# whitelist-users:
# - owen@fossorial.io
# - owen@pangolin.net
# auto-login-idp: 1
headers:
- name: X-Example-Header
value: example-value

View File

@@ -5,14 +5,14 @@ meta {
}
post {
url: http://localhost:4000/api/v1/auth/login
url: http://localhost:3000/api/v1/auth/login
body: json
auth: none
}
body:json {
{
"email": "owen@fossorial.io",
"email": "admin@fosrl.io",
"password": "Password123!"
}
}

View File

@@ -12,6 +12,6 @@ post {
body:json {
{
"email": "milo@fossorial.io"
"email": "milo@pangolin.net"
}
}

View File

@@ -12,7 +12,7 @@ put {
body:json {
{
"email": "numbat@fossorial.io",
"email": "numbat@pangolin.net",
"password": "Password123!"
}
}

15
bruno/Olm/createOlm.bru Normal file
View File

@@ -0,0 +1,15 @@
meta {
name: createOlm
type: http
seq: 1
}
put {
url: http://localhost:3000/api/v1/olm
body: none
auth: inherit
}
settings {
encodeUrl: true
}

8
bruno/Olm/folder.bru Normal file
View File

@@ -0,0 +1,8 @@
meta {
name: Olm
seq: 15
}
auth {
mode: inherit
}

View File

@@ -1,6 +1,6 @@
{
"version": "1",
"name": "Pangolin Saas",
"name": "Pangolin",
"type": "collection",
"ignore": [
"node_modules",

View File

@@ -90,7 +90,8 @@ export const setAdminCredentials: CommandModule<{}, SetAdminCredentialsArgs> = {
passwordHash,
dateCreated: moment().toISOString(),
serverAdmin: true,
emailVerified: true
emailVerified: true,
lastPasswordChange: new Date().getTime()
});
console.log("Server admin created");

View File

@@ -1,5 +1,5 @@
# To see all available options, please visit the docs:
# https://docs.digpangolin.com/self-host/advanced/config-file
# https://docs.pangolin.net/self-host/advanced/config-file
app:
dashboard_url: http://localhost:3002
@@ -25,4 +25,3 @@ flags:
disable_user_create_org: true
allow_raw_resources: true
enable_integration_api: true
enable_clients: true

View File

@@ -0,0 +1,15 @@
services:
drizzle-gateway:
image: ghcr.io/drizzle-team/gateway:latest
ports:
- "4984:4983"
depends_on:
- db
environment:
- STORE_PATH=/app
- DATABASE_URL=postgresql://postgres:password@db:5432/postgres
volumes:
- drizzle-gateway-data:/app
volumes:
drizzle-gateway-data:

View File

@@ -35,7 +35,7 @@ services:
- 80:80 # Port for traefik because of the network_mode
traefik:
image: traefik:v3.5
image: traefik:v3.6
container_name: traefik
restart: unless-stopped
network_mode: service:gerbil # Ports appear on the gerbil service
@@ -52,4 +52,4 @@ networks:
default:
driver: bridge
name: pangolin
enable_ipv6: true
enable_ipv6: true

View File

@@ -11,7 +11,7 @@ services:
- ./config/postgres:/var/lib/postgresql/data
ports:
- "5432:5432" # Map host port 5432 to container port 5432
restart: no
restart: no
redis:
image: redis:latest # Use the latest Redis image

View File

@@ -18,7 +18,11 @@ put-back:
mv main.go.bak main.go
dev-update-versions:
PANGOLIN_VERSION=$$(curl -s https://api.github.com/repos/fosrl/pangolin/tags | jq -r '.[0].name') && \
if [ -z "$(tag)" ]; then \
PANGOLIN_VERSION=$$(curl -s https://api.github.com/repos/fosrl/pangolin/tags | jq -r '.[0].name'); \
else \
PANGOLIN_VERSION=$(tag); \
fi && \
GERBIL_VERSION=$$(curl -s https://api.github.com/repos/fosrl/gerbil/tags | jq -r '.[0].name') && \
BADGER_VERSION=$$(curl -s https://api.github.com/repos/fosrl/badger/tags | jq -r '.[0].name') && \
echo "Latest versions - Pangolin: $$PANGOLIN_VERSION, Gerbil: $$GERBIL_VERSION, Badger: $$BADGER_VERSION" && \

View File

@@ -1,5 +1,5 @@
# To see all available options, please visit the docs:
# https://docs.digpangolin.com/
# https://docs.pangolin.net/
gerbil:
start_port: 51820
@@ -14,7 +14,6 @@ app:
domains:
domain1:
base_domain: "{{.BaseDomain}}"
cert_resolver: "letsencrypt"
server:
secret: "{{.Secret}}"
@@ -36,4 +35,4 @@ flags:
require_email_verification: {{.EnableEmail}}
disable_signup_without_invite: true
disable_user_create_org: false
allow_raw_resources: true
allow_raw_resources: true

View File

@@ -35,7 +35,7 @@ services:
- 80:80
{{end}}
traefik:
image: docker.io/traefik:v3.5
image: docker.io/traefik:v3.6
container_name: traefik
restart: unless-stopped
{{if .InstallGerbil}}
@@ -59,4 +59,4 @@ networks:
default:
driver: bridge
name: pangolin
{{if .EnableIPv6}} enable_ipv6: true{{end}}
{{if .EnableIPv6}} enable_ipv6: true{{end}}

View File

@@ -51,3 +51,12 @@ http:
loadBalancer:
servers:
- url: "http://pangolin:3000" # API/WebSocket server
tcp:
serversTransports:
pp-transport-v1:
proxyProtocol:
version: 1
pp-transport-v2:
proxyProtocol:
version: 2

View File

@@ -73,7 +73,7 @@ func installDocker() error {
case strings.Contains(osRelease, "ID=ubuntu"):
installCmd = exec.Command("bash", "-c", fmt.Sprintf(`
apt-get update &&
apt-get install -y apt-transport-https ca-certificates curl software-properties-common &&
apt-get install -y apt-transport-https ca-certificates curl &&
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg &&
echo "deb [arch=%s signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list &&
apt-get update &&
@@ -82,7 +82,7 @@ func installDocker() error {
case strings.Contains(osRelease, "ID=debian"):
installCmd = exec.Command("bash", "-c", fmt.Sprintf(`
apt-get update &&
apt-get install -y apt-transport-https ca-certificates curl software-properties-common &&
apt-get install -y apt-transport-https ca-certificates curl &&
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg &&
echo "deb [arch=%s signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list &&
apt-get update &&

View File

@@ -3,8 +3,8 @@ module installer
go 1.24.0
require (
golang.org/x/term v0.36.0
golang.org/x/term v0.37.0
gopkg.in/yaml.v3 v3.0.1
)
require golang.org/x/sys v0.37.0 // indirect
require golang.org/x/sys v0.38.0 // indirect

View File

@@ -1,7 +1,7 @@
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@@ -238,7 +238,6 @@ func main() {
}
fmt.Println("CrowdSec installed successfully!")
return
}
}
}
@@ -378,7 +377,7 @@ func collectUserInput(reader *bufio.Reader) Config {
fmt.Println("\n=== Advanced Configuration ===")
config.EnableIPv6 = readBool(reader, "Is your server IPv6 capable?", true)
config.EnableGeoblocking = readBool(reader, "Do you want to download the MaxMind GeoLite2 database for geoblocking functionality?", false)
config.EnableGeoblocking = readBool(reader, "Do you want to download the MaxMind GeoLite2 database for geoblocking functionality?", true)
if config.DashboardDomain == "" {
fmt.Println("Error: Dashboard Domain name is required")

View File

@@ -47,9 +47,8 @@
"edit": "Редактиране",
"siteConfirmDelete": "Потвърждение на изтриване на сайта",
"siteDelete": "Изтриване на сайта",
"siteMessageRemove": "След изтриване, сайтът няма повече да бъде достъпен. Всички ресурси и цели, свързани със сайта, също ще бъдат премахнати.",
"siteMessageConfirm": "За потвърждение, моля, напишете името на сайта по-долу.",
"siteQuestionRemove": "Сигурни ли сте, че искате да премахнете сайта {selectedSite} от организацията?",
"siteMessageRemove": "След премахване, сайтът вече няма да бъде достъпен. Всички цели, свързани със сайта, също ще бъдат премахнати.",
"siteQuestionRemove": "Сигурни ли сте, че искате да премахнете сайта от организацията?",
"siteManageSites": "Управление на сайтове",
"siteDescription": "Позволете свързване към вашата мрежа чрез сигурни тунели",
"siteCreate": "Създайте сайт",
@@ -96,7 +95,7 @@
"siteWgDescription": "Use any WireGuard client to establish a tunnel. Manual NAT setup required. ONLY WORKS ON SELF HOSTED NODES",
"siteWgDescriptionSaas": "Използвайте всеки WireGuard клиент за установяване на тунел. Ръчно нат задаване е необходимо. РАБОТИ САМО НА СОБСТВЕНИ УЗЛИ.",
"siteLocalDescription": "Local resources only. No tunneling. ONLY WORKS ON SELF HOSTED NODES",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Само локални ресурси. Без тунелиране. Достъпно само на отдалечени възли.",
"siteSeeAll": "Вижте всички сайтове",
"siteTunnelDescription": "Определете как искате да се свържете с вашия сайт",
"siteNewtCredentials": "Newt Удостоверения",
@@ -132,7 +131,7 @@
"expireIn": "Изтече",
"neverExpire": "Никога не изтича",
"shareExpireDescription": "Времето на изтичане е колко дълго връзката ще бъде използваема и ще предоставя достъп до ресурса. След това време, връзката няма да работи и потребителите, които са я използвали, ще загубят достъп до ресурса.",
"shareSeeOnce": "Ще можете да видите тази връзка само веднъж. Уверете се да я копирате.",
"shareSeeOnce": "Ще можете да видите този линк само веднъж. Уверете се, че го копирате.",
"shareAccessHint": "Всеки с тази връзка може да има достъп до ресурса. Споделяйте я с внимание.",
"shareTokenUsage": "Вижте използването на токена за достъп",
"createLink": "Създаване на връзка",
@@ -154,8 +153,7 @@
"protected": "Защита",
"notProtected": "Не защитен",
"resourceMessageRemove": "След като се премахне, ресурсът няма повече да бъде достъпен. Всички цели, свързани с ресурса, също ще бъдат премахнати.",
"resourceMessageConfirm": "За потвърждение, моля, напишете името на ресурса по-долу.",
"resourceQuestionRemove": "Сигурни ли сте, че искате да премахнете ресурса {selectedResource} от организацията?",
"resourceQuestionRemove": "Сигурни ли сте, че искате да премахнете ресурса от организацията?",
"resourceHTTP": "HTTPS ресурс",
"resourceHTTPDescription": "Прокси заявки към вашето приложение през HTTPS с помощта на субдомейн или базов домейн.",
"resourceRaw": "Суров TCP/UDP ресурс",
@@ -181,7 +179,7 @@
"baseDomain": "Базов домейн",
"subdomnainDescription": "Субдомейнът, в който ще бъде достъпен вашият ресурс.",
"resourceRawSettings": "TCP/UDP настройки",
"resourceRawSettingsDescription": "Конфигурирайте как вашият ресурс ще бъде достъпен през TCP/UDP",
"resourceRawSettingsDescription": "Настройте как ресурсът ви ще бъде достъпен през TCP/UDP. Свързвате ресурса към порт на хост сървъра Pangolin, за да го достъпвате от server-public-ip:mapped-port.",
"protocol": "Протокол",
"protocolSelect": "Изберете протокол",
"resourcePortNumber": "Номер на порт",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Потвърдете изтриване на организация",
"orgMessageRemove": "Това действие е необратимо и ще изтрие всички свързани данни.",
"orgMessageConfirm": "За потвърждение, моля, напишете името на организацията по-долу.",
"orgQuestionRemove": "Сигурни ли сте, че искате да премахнете организацията {selectedOrg}?",
"orgQuestionRemove": "Сигурни ли сте, че искате да премахнете организацията?",
"orgUpdated": "Организацията е актуализирана",
"orgUpdatedDescription": "Организацията е обновена.",
"orgErrorUpdate": "Неуспешно актуализиране на организацията",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Генерирайте API ключ",
"apiKeysErrorDelete": "Грешка при изтриване на API ключ",
"apiKeysErrorDeleteMessage": "Грешка при изтриване на API ключ",
"apiKeysQuestionRemove": "Сигурни ли сте, че искате да премахнете API ключа {selectedApiKey} от организацията?",
"apiKeysQuestionRemove": "Сигурни ли сте, че искате да премахнете API ключа от организацията?",
"apiKeysMessageRemove": "След като бъде премахнат, API ключът няма вече да може да се използва.",
"apiKeysMessageConfirm": "За потвърждение, моля, напишете името на API ключа по-долу.",
"apiKeysDeleteConfirm": "Потвърдете изтриване на API ключ",
"apiKeysDelete": "Изтрийте API ключа",
"apiKeysManage": "Управление на API ключове",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Потвърдете изтриването на потребител",
"userDeleteServer": "Изтрийте потребителя от сървъра",
"userMessageRemove": "Потребителят ще бъде премахнат от всички организации и напълно заличен от сървъра.",
"userMessageConfirm": "За да потвърдите, въведете името на потребителя по-долу.",
"userQuestionRemove": "Сигурни ли сте, че искате да изтриете завинаги {selectedUser} от сървъра?",
"userQuestionRemove": "Сигурни ли сте, че искате да изтриете потребител от сървъра?",
"licenseKey": "Ключ за лиценз",
"valid": "Валиден",
"numberOfSites": "Брой сайтове",
@@ -339,7 +335,7 @@
"fossorialLicense": "Преглед на търговски условия и абонамент за Fossorial",
"licenseMessageRemove": "Това ще премахне лицензионния ключ и всички свързани права, предоставени от него.",
"licenseMessageConfirm": "За да потвърдите, въведете лицензионния ключ по-долу.",
"licenseQuestionRemove": "Сигурни ли сте, че искате да изтриете лицензионния ключ {selectedKey}?",
"licenseQuestionRemove": "Сигурни ли сте, че искате да премахнете лицензионния ключ?",
"licenseKeyDelete": "Изтриване на лицензионен ключ",
"licenseKeyDeleteConfirm": "Потвърдете изтриването на лицензионен ключ",
"licenseTitle": "Управление на лицензионния статус",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Възникна грешка при премахване на поканата.",
"inviteRemoved": "Поканата е премахната",
"inviteRemovedDescription": "Поканата за {имейл} е премахната.",
"inviteQuestionRemove": "Сигурни ли сте, че искате да премахнете поканата {email}?",
"inviteQuestionRemove": "Сигурни ли сте, че искате да премахнете поканата?",
"inviteMessageRemove": "След като бъде премахната, тази покана няма да е валидна. Винаги можете да поканите потребителя отново по-късно.",
"inviteMessageConfirm": "За да потвърдите, въведете имейл адреса на поканата по-долу.",
"inviteQuestionRegenerate": "Сигурни ли сте, че искате да регенерирате поканата за {email}? Това ще отмени предишната покана.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Възникна грешка при премахване на потребителя.",
"userOrgRemoved": "Потребителят е премахнат",
"userOrgRemovedDescription": "Потребителят {email} беше премахнат от организацията.",
"userQuestionOrgRemove": "Сигурни ли сте, че искате да премахнете {email} от организацията?",
"userQuestionOrgRemove": "Сигурни ли сте, че искате да премахнете този потребител от организацията?",
"userMessageOrgRemove": "След като бъде премахнат, този потребител няма да има достъп до организацията. Винаги можете да го поканите отново по-късно, но той ще трябва да приеме отново поканата.",
"userMessageOrgConfirm": "За да потвърдите, въведете името на потребителя по-долу.",
"userRemoveOrgConfirm": "Потвърдете премахването на потребителя",
"userRemoveOrg": "Премахване на потребителя от организацията",
"users": "Потребители",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Администратор на сървър - Панголин",
"licenseTierProfessional": "Професионален лиценз",
"licenseTierEnterprise": "Предприятие лиценз",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Персонален лиценз",
"licensed": "Лицензиран",
"yes": "Да",
"no": "Не",
@@ -742,7 +737,7 @@
"idpManageDescription": "Прегледайте и управлявайте доставчици на идентичност в системата",
"idpDeletedDescription": "Доставчик на идентичност успешно изтрит",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Сигурни ли сте, че искате да изтриете трайно доставчика на идентичност {name}",
"idpQuestionRemove": "Сигурни ли сте, че искате да изтриете доставчика за идентичност?",
"idpMessageRemove": "Това ще премахне доставчика на идентичност и всички свързани конфигурации. Потребителите, които се удостоверяват през този доставчик, вече няма да могат да влязат.",
"idpMessageConfirm": "За потвърждение, моля въведете името на доставчика на идентичност по-долу.",
"idpConfirmDelete": "Потвърдите изтриването на доставчик на идентичност",
@@ -765,7 +760,7 @@
"idpDisplayName": "Име за показване за този доставчик на идентичност",
"idpAutoProvisionUsers": "Автоматично потребителско създаване",
"idpAutoProvisionUsersDescription": "Когато е активирано, потребителите ще бъдат автоматично създадени в системата при първо влизане с възможност за свързване на потребителите с роли и организации.",
"licenseBadge": "EE",
"licenseBadge": "ЕЕ",
"idpType": "Тип доставчик",
"idpTypeDescription": "Изберете типа доставчик на идентичност, който искате да конфигурирате",
"idpOidcConfigure": "Конфигурация на OAuth2/OIDC",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Проверете имейла си за код за нулиране.",
"passwordNew": "Нова парола",
"passwordNewConfirm": "Потвърдете новата парола",
"changePassword": "Промяна на парола",
"changePasswordDescription": "Актуализиране на паролата на акаунта",
"oldPassword": "Текуща парола",
"newPassword": "Нова парола",
"confirmNewPassword": "Потвърдете новата парола",
"changePasswordError": "Неуспешна промяна на парола",
"changePasswordErrorDescription": "Възникна грешка при промяна на вашата парола",
"changePasswordSuccess": "Паролата беше успешно променена",
"changePasswordSuccessDescription": "Вашата парола беше успешно актуализирана",
"passwordExpiryRequired": "Изисква се изтичане на срока на годност на паролата",
"passwordExpiryDescription": "Тази организация изисква да сменяте паролата си на всеки {maxDays} дни.",
"changePasswordNow": "Сменете паролата сега",
"pincodeAuth": "Код на удостоверителя",
"pincodeSubmit2": "Изпрати код",
"passwordResetSubmit": "Заявка за нулиране",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Всички потребители",
"sidebarIdentityProviders": "Идентификационни доставчици",
"sidebarLicense": "Лиценз",
"sidebarClients": "Clients",
"sidebarClients": "Клиенти",
"sidebarDomains": "Домейни",
"sidebarBluePrints": "Чертежи",
"blueprints": "Чертежи",
"blueprintsDescription": "Прилагайте декларативни конфигурации и преглеждайте предишни изпълнения",
"blueprintAdd": "Добави Чертеж",
"blueprintGoBack": "Виж всички Чертежи",
"blueprintCreate": "Създай Чертеж",
"blueprintCreateDescription2": "Следвайте стъпките по-долу, за да създадете и приложите нов чертеж",
"blueprintDetails": "Детайли на чертежа",
"blueprintDetailsDescription": "Вижте резултата от приложените чертежи и всички възникнали грешки",
"blueprintInfo": "Информация за Чертежа",
"message": "Съобщение",
"blueprintContentsDescription": "Дефинирайте YAML съдържанието, описващо вашата инфраструктура",
"blueprintErrorCreateDescription": "Възникна грешка при прилагането на чертежа",
"blueprintErrorCreate": "Грешка при създаването на чертеж",
"searchBlueprintProgress": "Търси чертежи...",
"appliedAt": "Приложено във",
"source": "Източник",
"contents": "Съдържание",
"parsedContents": "Парсирано съдържание (само за четене)",
"enableDockerSocket": "Активиране на Docker Чернова",
"enableDockerSocketDescription": "Активиране на Docker Socket маркировка за изтегляне на етикети на чернова. Пътят на гнездото трябва да бъде предоставен на Newt.",
"enableDockerSocketLink": "Научете повече",
@@ -1211,9 +1237,8 @@
"domainCreate": "Създаване на домейн",
"domainCreatedDescription": "Домейнът е създаден успешно",
"domainDeletedDescription": "Домейнът е изтрит успешно",
"domainQuestionRemove": "Сигурни ли сте, че искате да премахнете домейна {domain} от вашия профил?",
"domainQuestionRemove": "Сигурни ли сте, че искате да премахнете домейна от вашия профил?",
"domainMessageRemove": "След премахването, домейнът вече няма да бъде свързан с вашия профил.",
"domainMessageConfirm": "За потвърждение, моля въведете името на домейна по-долу.",
"domainConfirmDelete": "Потвърдете изтриването на домейн",
"domainDelete": "Изтриване на домейн",
"domain": "Домейн",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Възникна грешка при обновяване на настройките",
"sidebarCollapse": "Свиване",
"sidebarExpand": "Разширяване",
"productUpdateMoreInfo": "{noOfUpdates} още актуализации",
"productUpdateInfo": "{noOfUpdates} актуализации",
"productUpdateWhatsNew": "Какво ново",
"productUpdateTitle": "Актуализации на продукта",
"productUpdateEmpty": "Няма актуализации",
"dismissAll": "Отхвърляне на всички",
"pangolinUpdateAvailable": "Налична е нова версия",
"pangolinUpdateAvailableInfo": "Версия {version} е готова за инсталиране",
"pangolinUpdateAvailableReleaseNotes": "Преглед на бележките за издание",
"newtUpdateAvailable": "Ново обновление",
"newtUpdateAvailableInfo": "Нова версия на Newt е налична. Моля, обновете до последната версия за най-добро изживяване.",
"domainPickerEnterDomain": "Домейн",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Безплатен план",
"billingWarningOverLimit": "Предупреждение: Превишили сте една или повече лимити за използване. Вашите сайтове няма да се свържат, докато не промените абонамента си или не коригирате използването.",
"billingUsageLimitsOverview": "Преглед на лимитите за използване",
"billingMonitorUsage": "Следете използването спрямо конфигурираните лимити. Ако ви е необходимо увеличаване на лимитите, моля, свържете се с нас на support@fossorial.io.",
"billingMonitorUsage": "Следете своята употреба спрямо конфигурираните лимити. Ако имате нужда от увеличаване на лимитите, моля свържете се с нас support@pangolin.net.",
"billingDataUsage": "Използване на данни",
"billingOnlineTime": "Време на работа на сайта",
"billingUsers": "Активни потребители",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Възникна проблем при използването на ключа за сигурност. Моля, опитайте отново.",
"twoFactorRequired": "Двуфакторното удостоверяване е необходимо за регистрация на ключ за защита.",
"twoFactor": "Двуфакторно удостоверяване",
"twoFactorAuthentication": "Двуфакторно удостоверяване",
"twoFactorDescription": "Тази организация изисква двуфакторно удостоверяване.",
"enableTwoFactor": "Активиране на двуфакторно удостоверяване",
"organizationSecurityPolicy": "Политика за сигурност на организацията",
"organizationSecurityPolicyDescription": "Тази организация има изисквания за сигурност, които трябва да бъдат изпълнени, за да имате достъп до нея.",
"securityRequirements": "Изисквания за сигурност",
"allRequirementsMet": "Всички изисквания са изпълнени",
"completeRequirementsToContinue": "Завършете изискванията по-долу, за да продължите достъпа до тази организация",
"youCanNowAccessOrganization": "Вече можете да получите достъп до тази организация",
"reauthenticationRequired": "Продължителност на сесията",
"reauthenticationDescription": "Тази организация изисква да влизате на всеки {maxDays} дни.",
"reauthenticationDescriptionHours": "Тази организация изисква да влизате на всеки {maxHours} часа.",
"reauthenticateNow": "Влезте отново",
"adminEnabled2FaOnYourAccount": "Вашият администратор е активирал двуфакторно удостоверяване за {email}. Моля, завършете процеса по настройка, за да продължите.",
"securityKeyAdd": "Добавяне на ключ за сигурност",
"securityKeyRegisterTitle": "Регистриране на нов ключ за сигурност",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Тези ресурси са за използване с",
"resourcesTableClients": "Клиенти",
"resourcesTableAndOnlyAccessibleInternally": са достъпни само вътрешно при свързване с клиент.",
"resourcesTableNoTargets": "Без цели",
"resourcesTableHealthy": "Здрав",
"resourcesTableDegraded": "Влошен",
"resourcesTableOffline": "Извън линия",
"resourcesTableUnknown": "Неизвестно",
"resourcesTableNotMonitored": "Не е наблюдавано",
"editInternalResourceDialogEditClientResource": "Редактиране на клиентски ресурс",
"editInternalResourceDialogUpdateResourceProperties": "Актуализирайте свойствата на ресурса и конфигурацията на целите за {resourceName}.",
"editInternalResourceDialogResourceProperties": "Свойствата на ресурса",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Не е получен URL за пренасочване от доставчика на идентификационни данни.",
"autoLoginErrorGeneratingUrl": "Неуспешно генериране на URL за удостоверяване.",
"remoteExitNodeManageRemoteExitNodes": "Отдалечени възли",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Самостоятелно хоствайте един или повече отдалечени възли, за да разширите своята мрежова връзка и намалите зависимостта от облака.",
"remoteExitNodes": "Възли",
"searchRemoteExitNodes": "Търсене на възли...",
"remoteExitNodeAdd": "Добавяне на възел",
"remoteExitNodeErrorDelete": "Грешка при изтриване на възел",
"remoteExitNodeQuestionRemove": "Сигурни ли сте, че искате да премахнете възела {selectedNode} от организацията?",
"remoteExitNodeQuestionRemove": "Сигурни ли сте, че искате да премахнете възела от организацията?",
"remoteExitNodeMessageRemove": "След премахване, възелът вече няма да бъде достъпен.",
"remoteExitNodeMessageConfirm": "За потвърждение, моля въведете името на възела по-долу.",
"remoteExitNodeConfirmDelete": "Потвърдете изтриването на възела (\"Confirm Delete Site\" match)",
"remoteExitNodeDelete": "Изтрийте възела (\"Delete Site\" match)",
"sidebarRemoteExitNodes": "Отдалечени възли",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Редактиране на файл: docker-compose.yml",
"emailVerificationRequired": "Потвърждението на Email е необходимо. Моля, влезте отново чрез {dashboardUrl}/auth/login, за да завършите тази стъпка. След това, върнете се тук.",
"twoFactorSetupRequired": "Необходима е настройка на двуфакторно удостоверяване. Моля, влезте отново чрез {dashboardUrl}/auth/login, за да завършите тази стъпка. След това, върнете се тук.",
"additionalSecurityRequired": "Необходима е допълнителна сигурност",
"organizationRequiresAdditionalSteps": "Тази организация изисква допълнителни стъпки за сигурност, за да получите достъп до ресурсите.",
"completeTheseSteps": "Завършете тези стъпки",
"enableTwoFactorAuthentication": "Активирайте двуфакторното удостоверяване",
"completeSecuritySteps": "Завършете стъпките за сигурност",
"securitySettings": "Настройки за сигурност",
"securitySettingsDescription": "Конфигурирайте политиките за сигурност на вашата организация",
"requireTwoFactorForAllUsers": "Изисквайте двуфакторно удостоверяване за всички потребители",
"requireTwoFactorDescription": "Когато е активирано, всички вътрешни потребители в организацията трябва да имат активирано двуфакторно удостоверяване, за да имат достъп до организацията.",
"requireTwoFactorDisabledDescription": "Тази функция изисква валиден лиценз (Enterprise) или активен абонамент (SaaS).",
"requireTwoFactorCannotEnableDescription": "Трябва да активирате двуфакторното удостоверяване за вашия акаунт, преди да го наложите за всички потребители.",
"maxSessionLength": "Максимална продължителност на сесията",
"maxSessionLengthDescription": "Задайте максималната продължителност на потребителските сесии. След това време потребителите ще трябва да се удостоверят отново.",
"maxSessionLengthDisabledDescription": "Тази функция изисква валиден лиценз (Enterprise) или активен абонамент (SaaS).",
"selectSessionLength": "Изберете продължителност на сесията",
"unenforced": "Неналожено",
"1Hour": "1 час",
"3Hours": "3 часа",
"6Hours": "6 часа",
"12Hours": "12 часа",
"1DaySession": "1 ден",
"3Days": "3 дни",
"7Days": "7 дни",
"14Days": "14 дни",
"30DaysSession": "30 дни",
"90DaysSession": "90 дни",
"180DaysSession": "180 дни",
"passwordExpiryDays": "Изтичане на парола",
"editPasswordExpiryDescription": "Задайте броя дни, след които потребителите трябва да сменят паролата си.",
"selectPasswordExpiry": "Изберете изтичането на парола",
"30Days": "30 дни",
"1Day": "1 ден",
"60Days": "60 дни",
"90Days": "90 дни",
"180Days": "180 дни",
"1Year": "1 година",
"subscriptionBadge": "Изисква се абонамент",
"securityPolicyChangeWarning": "Предупреждение за промяна на политиката за сигурност",
"securityPolicyChangeDescription": "Ще променяте настройките на политиката за сигурност. След запазване може да се наложи да се удостоверите отново, за да се съобразите с тези актуализации. Всички потребители, които не са съвместими, също ще трябва да се удостоверят отново.",
"securityPolicyChangeConfirmMessage": "Потвърждавам",
"securityPolicyChangeWarningText": "Това ще засегне всички потребители в организацията",
"authPageErrorUpdateMessage": "Възникна грешка при актуализирането на настройките на страницата за удостоверяване",
"authPageErrorUpdate": "Неуспешно актуализиране на страницата за удостоверяване",
"authPageUpdated": "Страницата за удостоверяване е актуализирана успешно",
"healthCheckNotAvailable": "Локална",
"rewritePath": "Пренапиши път",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Автентикацията в заглавката беше премахната успешно.",
"resourceErrorHeaderAuthRemove": "Неуспешно премахване на автентикация в заглавката",
"resourceErrorHeaderAuthRemoveDescription": "Не беше възможно премахването на автентикацията в заглавката за ресурса.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Активирано удостоверяване чрез заглавие",
"resourceHeaderAuthProtectionDisabled": "Деактивирано удостоверяване чрез заглавие",
"headerAuthRemove": "Премахни удостоверяване чрез заглавие",
"headerAuthAdd": "Добави удостоверяване чрез заглавие",
"resourceErrorHeaderAuthSetup": "Неуспешно задаване на автентикация в заглавката",
"resourceErrorHeaderAuthSetupDescription": "Не беше възможно задаването на автентикация в заглавката за ресурса.",
"resourceHeaderAuthSetup": "Автентикацията в заглавката беше зададена успешно",
"resourceHeaderAuthSetupDescription": "Автентикацията в заглавката беше успешно зададена.",
"resourceHeaderAuthSetupTitle": "Задаване на автентикация в заглавката",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Задайте базови идентификационни данни (потребителско име и парола), за да защитите този ресурс чрез HTTP удостоверяване чрез заглавие. Достъпете до него, използвайки формата https://потребител:парола@ресурс.example.com",
"resourceHeaderAuthSubmit": "Задаване на автентикация в заглавката",
"actionSetResourceHeaderAuth": "Задаване на автентикация в заглавката",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"enterpriseEdition": "Корпоративно издание",
"unlicensed": "Без лиценз",
"beta": "Бета",
"manageClients": "Управление на клиенти",
"manageClientsDescription": "Клиентите са устройства, които могат да се свързват към вашите сайтове",
"licenseTableValidUntil": "Валиден до",
"saasLicenseKeysSettingsTitle": "Корпоративни лицензи",
"saasLicenseKeysSettingsDescription": "Генериране и управление на корпоративни лицензионни ключове за самостоятелно хоствани инстанции на Pangolin",
"sidebarEnterpriseLicenses": "Лицензи",
"generateLicenseKey": "Генерация на лицензионен ключ",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Моля въведете валиден имейл адрес",
"useCaseTypeRequired": "Моля изберете тип на употреба",
"firstNameRequired": "Името е задължително",
"lastNameRequired": "Фамилията е задължителна",
"primaryUseRequired": "Моля опишете основната си употреба",
"jobTitleRequiredBusiness": "Позицията е задължителна за бизнес изполване",
"industryRequiredBusiness": "Индустрията е задължителна за бизнес изполване",
"stateProvinceRegionRequired": "Държава/Област/Регион е задължително",
"postalZipCodeRequired": "Пощенски/ЗИП Код е задължителен",
"companyNameRequiredBusiness": "Фирменото име е задължително за бизнес изполване",
"countryOfResidenceRequiredBusiness": "Държавата на пребиваване е задължителна за бизнес изполване",
"countryRequiredPersonal": "Държавата е задължителна за лична употреба",
"agreeToTermsRequired": "Трябва да се съгласите с условията",
"complianceConfirmationRequired": "Трябва да потвърдите съответствието с Fossorial Commercial License"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Лична употреба",
"description": "За индивидуална, некомерсиална употреба като учене, лични проекти или експериментиране."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Бизнес употреба",
"description": "За вътрешно използване във фирми, компании или комерсиални или доходоносни дейности."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "Имейл и тип лиценз",
"description": "Въведете своя имейл и изберете вид на лиценза"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Лична информация",
"description": "Разкажете ни за себе си"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Контактна информация",
"description": "Вашите контактни данни"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Условия и генериране",
"description": "Прегледайте и приемете условията, за да генерирате своя лиценз"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Разкриване на употреба",
"description": "Изберете лицензионен клас, който точно отразява вашата целена употреба. Персоналният лиценз позволява безплатно ползване на софтуера за индивидуална, некомерсиална или маломащабна комерсиална дейност с годишен брутен приход под 100,000 USD. Всяко ползване извън тези граници — включително ползване във фирма, организация или друга доходоносна среда — изисква валиден корпоративен лиценз и плащане на съответната лицензионна такса. Всички потребители, независимо дали са лични или корпоративни, трябва да спазват Условията на Fossorial Commercial License."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Информация за пробен период",
"description": "Този лицензионен ключ предоставя функции на Enterprise за 7-дневен пробен период. За продължен достъп до платени функции след изтичането на пробния период е необходима активация под валиден персонален или корпоративен лиценз. За корпоративно лицензиране се свържете с sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Използвате ли Pangolin за лична или бизнес употреба?",
"firstName": "Име",
"lastName": "Фамилия",
"jobTitle": "Позиция",
"primaryUseQuestion": "Каква е основната ви цел да използвате Pangolin?",
"industryQuestion": "Какъв е вашият отрасъл?",
"prospectiveUsersQuestion": "Колко потенциални потребители очаквате да имате?",
"prospectiveSitesQuestion": "Колко потенциални сайтове (тунели) очаквате да имате?",
"companyName": "Фирмено име",
"countryOfResidence": "Държава на пребиваване",
"stateProvinceRegion": "Държава / Област / Регион",
"postalZipCode": "Пощенски / ЗИП код",
"companyWebsite": "Фирмен уебсайт",
"companyPhoneNumber": "Фирмен телефонен номер",
"country": "Държава",
"phoneNumberOptional": "Телефонен номер (по избор)",
"complianceConfirmation": "Потвърждавам, че предоставената от мен информация е точна и че съм в съответствие с търговския лиценз Fossorial. Съобщаването на неточна информация или неправилното идентифициране на използването на продукта е нарушение на лиценза и може да доведе до анулиране на вашия ключ."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Затвори",
"previous": "Предишен",
"next": "Следващ",
"generateLicenseKey": "Генериране на лицензионен ключ"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Лицензионният ключ е успешно генериран",
"description": "Вашият лицензионен ключ е генериран и готов за употреба."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Грешка при генериране на лицензионен ключ",
"description": "Възникна грешка при генериране на лицензионния ключ."
}
}
},
"priority": "Приоритет",
"priorityDescription": "По-високите приоритетни маршрути се оценяват първи. Приоритет = 100 означава автоматично подреждане (системата решава). Използвайте друго число, за да наложите ръчен приоритет.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"instanceName": "Име на инстанция",
"pathMatchModalTitle": "Конфигурация на съвпадение по пътека",
"pathMatchModalDescription": "Настройте как трябва да бъдат съвпадани входящите заявки въз основа на техния път.",
"pathMatchType": "Вид на съвпадението",
"pathMatchPrefix": "Префикс",
"pathMatchExact": "Точно",
"pathMatchRegex": "Регекс",
"pathMatchValue": "Стойност на пътя",
"clear": "Изчисти",
"saveChanges": "Запиши промените",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathMatchDefaultPlaceholder": "/път",
"pathMatchPrefixHelp": "Пример: /api съвпада /api, /api/потребители и т.н.",
"pathMatchExactHelp": "Пример: /api съвпада само с /api",
"pathMatchRegexHelp": "Пример: ^/api/.* съвпада с /api/всичко",
"pathRewriteModalTitle": "Конфигурация на пренаписване на пътя",
"pathRewriteModalDescription": "Преобразуване на съвпаднатия път преди препращане към целта.",
"pathRewriteType": "Вид на пренаписването",
"pathRewritePrefixOption": "Префикс - Подмяна на префикса",
"pathRewriteExactOption": "Точно - Замяна на целия път",
"pathRewriteRegexOption": "Регекс - Смяна на модела",
"pathRewriteStripPrefixOption": "Премахване на префикса",
"pathRewriteValue": "Стойност на пренаписването",
"pathRewriteRegexPlaceholder": "/нов/$1",
"pathRewriteDefaultPlaceholder": "/нов-пътека",
"pathRewritePrefixHelp": "Заменете съвпаднатия префикс с тази стойност",
"pathRewriteExactHelp": "Заменете целия път с тази стойност, когато пътят съвпада точно",
"pathRewriteRegexHelp": "Използвайте групи за улавяне като $1, $2 за заместване",
"pathRewriteStripPrefixHelp": "Оставете празно, за да премахнете префикса или предоставете нов префикс",
"pathRewritePrefix": "Префикс",
"pathRewriteExact": "Точно",
"pathRewriteRegex": "Регекс",
"pathRewriteStrip": "Премахване",
"pathRewriteStripLabel": "премахване",
"sidebarEnableEnterpriseLicense": "Активиране на корпоративен лиценз",
"cannotbeUndone": "Това не може да се отмени.",
"toConfirm": "за потвърждение",
"deleteClientQuestion": "Сигурни ли сте, че искате да премахнете клиента от сайта и организацията?",
"clientMessageRemove": "След като клиентът бъде премахнат, той вече няма да може да се свързва с сайта.",
"sidebarLogs": "Логове",
"request": "Изискване",
"logs": "Логове",
"logsSettingsDescription": "Следете логовете, събрани от тази организация",
"searchLogs": "Търсете в логовете...",
"action": "Действие",
"actor": "Извършващ",
"timestamp": "Отбелязано време",
"accessLogs": "Достъп до логове",
"exportCsv": "Експортиране в CSV",
"actorId": "ID на извършващия",
"allowedByRule": "Разрешено от правило",
"allowedNoAuth": "Разрешено без удостоверение",
"validAccessToken": "Валиден токен за достъп",
"validHeaderAuth": "Валиден заглавен авто",
"validPincode": "Валиден ПИН код",
"validPassword": "Валидна парола",
"validEmail": "Валиден имейл",
"validSSO": "Валидно SSO",
"resourceBlocked": "Блокирани ресурси",
"droppedByRule": "Прекратено от правило",
"noSessions": "Няма сесии",
"temporaryRequestToken": "Временен токен на заявка",
"noMoreAuthMethods": "Няма валидни методи за удостоверение",
"ip": "IP",
"reason": "Причина",
"requestLogs": "Заявка за логове",
"host": "Хост",
"location": "Местоположение",
"actionLogs": "Дневници на действията",
"sidebarLogsRequest": "Заявка за логове",
"sidebarLogsAccess": "Достъп до логове",
"sidebarLogsAction": "Дневници на действията",
"logRetention": "Задържане на логове",
"logRetentionDescription": "Управлявайте времето за задържане на различни видове логове за тази организация или ги деактивирайте",
"requestLogsDescription": "Прегледайте подробни логове на заявки за ресурси в тази организация",
"logRetentionRequestLabel": "Задържане на логове на заявки",
"logRetentionRequestDescription": "Колко дълго да се задържат логовете на заявките",
"logRetentionAccessLabel": "Задържане на логове за достъп",
"logRetentionAccessDescription": "Колко дълго да се задържат логовете за достъп",
"logRetentionActionLabel": "Задържане на логове за действия",
"logRetentionActionDescription": "Колко дълго да се задържат логовете за действия",
"logRetentionDisabled": "Деактивирано",
"logRetention3Days": "3 дни",
"logRetention7Days": "7 дни",
"logRetention14Days": "14 дни",
"logRetention30Days": "30 дни",
"logRetention90Days": "90 дни",
"logRetentionForever": "Завинаги",
"actionLogsDescription": "Прегледайте историята на действията, извършени в тази организация",
"accessLogsDescription": "Прегледайте заявките за удостоверяване на достъпа до ресурсите в тази организация",
"licenseRequiredToUse": "Необходим е лиценз Enterprise, за да се използва тази функция.",
"certResolver": "Решавач на сертификати",
"certResolverDescription": "Изберете решавач на сертификати за използване за този ресурс.",
"selectCertResolver": "Изберете решавач на сертификати",
"enterCustomResolver": "Въведете персонализиран решавач",
"preferWildcardCert": "Предпочитайте универсален сертификат",
"unverified": "Невалидиран",
"domainSetting": "Настройки на домейните",
"domainSettingDescription": "Конфигурирайте настройките за вашия домейн",
"preferWildcardCertDescription": "Опит за генериране на универсален сертификат (изисква правилно конфигуриран решавач на сертификати).",
"recordName": "Име на запис",
"auto": "Автоматично",
"TTL": "TTL",
"howToAddRecords": "Как да добавите записи",
"dnsRecord": "DNS записи",
"required": "Задължително",
"domainSettingsUpdated": "Настройките на домейна са успешно актуализирани",
"orgOrDomainIdMissing": "Липсва идентификатор на организация или домейн",
"loadingDNSRecords": "Зареждане на DNS записи...",
"olmUpdateAvailableInfo": "Налична е актуализирана версия на Olm. Моля, актуализирайте до най-новата версия за най-добро преживяване.",
"client": "Клиент",
"proxyProtocol": "Настройки на прокси протокол",
"proxyProtocolDescription": "Конфигурирайте прокси протокол за запазване на IP адресите на клиентите за TCP/UDP услуги.",
"enableProxyProtocol": "Активирайте прокси протокола",
"proxyProtocolInfo": "Запазете IP адресите на клиентите за TCP/UDP бекенди",
"proxyProtocolVersion": "Версия на прокси протокола",
"version1": "Версия 1 (Препоръчително)",
"version2": "Версия 2",
"versionDescription": "Версия 1 е текстово-базирана и широко поддържана. Версия 2 е бърна и по-ефективна, но по-малко съвместима.",
"warning": "Предупреждение",
"proxyProtocolWarning": "Вашето бекенд приложение трябва да бъде конфигурирано да приема прокси протоколни връзки. Ако вашият бекенд не поддържа прокси протокол, активирането му ще прекъсне всички връзки. Уверете се, че сте конфигурирали вашия бекенд да се доверява на заглавията на прокси протокола от Traefik.",
"restarting": "Рестартиране...",
"manual": "Ръководство",
"messageSupport": "Съобщение до поддръжката",
"supportNotAvailableTitle": "Поддръжката не е налична",
"supportNotAvailableDescription": "Поддръжката не е налична в момента. Можете да изпратите имейл на support@pangolin.net.",
"supportRequestSentTitle": "Заявката за поддръжка е изпратена",
"supportRequestSentDescription": "Вашето съобщение беше изпратено успешно.",
"supportRequestFailedTitle": "Неуспешно изпращане на заявка",
"supportRequestFailedDescription": "Възникна грешка при изпращането на вашата заявка за поддръжка.",
"supportSubjectRequired": "Необходимо е въведеното описание",
"supportSubjectMaxLength": "Темата трябва да бъде до 255 символа",
"supportMessageRequired": "Необходимо е съобщение",
"supportReplyTo": "Отговор до",
"supportSubject": "Тема",
"supportSubjectPlaceholder": "Въведете тема",
"supportMessage": "Съобщение",
"supportMessagePlaceholder": "Въведете вашето съобщение",
"supportSending": "Изпращане...",
"supportSend": "Изпрати",
"supportMessageSent": "Съобщението е изпратено!",
"supportWillContact": "Ще се свържем с вас скоро!",
"selectLogRetention": "Изберете съхранение на логовете",
"showColumns": "Покажи колони",
"hideColumns": "Скрий колони",
"columnVisibility": "Видимост на колоните",
"toggleColumn": "Превключване на колоната {columnName}",
"allColumns": "Всички колони",
"defaultColumns": "По подразбиране колони",
"customizeView": "Персонализиране на изгледа",
"viewOptions": "Опции за изгледа",
"selectAll": "Избери всички",
"selectNone": "Избери нищо",
"selectedResources": "Избрани ресурси",
"enableSelected": "Разреши избраните",
"disableSelected": "Забрани избраните",
"checkSelectedStatus": "Проверете състоянието на избраните",
"credentials": "Удостоверения",
"savecredentials": "Запазване на удостоверения",
"regeneratecredentials": "Прегенериране",
"regenerateCredentials": "Прегенериране и запазване на удостоверенията ви",
"generatedcredentials": "Прегенерирани удостоверения",
"copyandsavethesecredentials": "Копирайте и запазете тези удостоверения",
"copyandsavethesecredentialsdescription": "Тези удостоверения няма да бъдат показани отново след като напуснете тази страница. Запазете ги сигурно сега.",
"credentialsSaved": "Удостоверенията са запазени",
"credentialsSavedDescription": "Удостоверенията бяха прегенерирани и успешно запазени.",
"credentialsSaveError": "Грешка при запазването на удостоверенията",
"credentialsSaveErrorDescription": "Възникна грешка при прегенерирането и запазването на удостоверенията.",
"regenerateCredentialsWarning": "Прегенерирането на удостоверения ще анулира предишните. Уверете се, че актуализирате всички конфигурации, които използват тези удостоверения.",
"confirm": "Потвърждаване",
"regenerateCredentialsConfirmation": "Сигурни ли сте, че искате да прегенерирате удостоверенията?",
"endpoint": "Крайна точка",
"Id": "Идентификатор",
"SecretKey": "Таен ключ",
"featureDisabledTooltip": "Тази функция е налична само в корпоративния пакет и изисква лиценз за използване.",
"niceId": "Красив ID",
"niceIdUpdated": "Красив ID е обновен",
"niceIdUpdatedSuccessfully": "Красив ID е успешно обновен",
"niceIdUpdateError": "Грешка при обновяването на Красив ID",
"niceIdUpdateErrorDescription": "Възникна грешка при обновяването на Красив ID.",
"niceIdCannotBeEmpty": "Красив ID не може да бъде празен",
"enterIdentifier": "Въведете идентификатор",
"identifier": "Идентификатор"
}

View File

@@ -47,9 +47,8 @@
"edit": "Upravit",
"siteConfirmDelete": "Potvrdit odstranění lokality",
"siteDelete": "Odstranění lokality",
"siteMessageRemove": "Jakmile lokalitu odstraníte, nebude dostupná. Všechny související služby a cíle budou také odstraněny.",
"siteMessageConfirm": "Pro potvrzení zadejte prosím název lokality.",
"siteQuestionRemove": "Opravdu chcete odstranit lokalitu {selectedSite} z organizace?",
"siteMessageRemove": "Po odstranění webu již nebude přístupný. Všechny cíle spojené s webem budou také odstraněny.",
"siteQuestionRemove": "Jste si jisti, že chcete odstranit tuto stránku z organizace?",
"siteManageSites": "Správa lokalit",
"siteDescription": "Umožní připojení k vaší síti prostřednictvím zabezpečených tunelů",
"siteCreate": "Vytvořit lokalitu",
@@ -96,7 +95,7 @@
"siteWgDescription": "Použijte jakéhokoli klienta WireGuard abyste sestavili tunel. Vyžaduje se ruční nastavení NAT.",
"siteWgDescriptionSaas": "Použijte jakéhokoli klienta WireGuard abyste sestavili tunel. Vyžaduje se ruční nastavení NAT. FUNGUJE POUZE NA SELF-HOSTED SERVERECH",
"siteLocalDescription": "Pouze lokální zdroje. Žádný tunel.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Pouze místní zdroje. Žádný tunel. Dostupné pouze na vzdálených uzlech.",
"siteSeeAll": "Zobrazit všechny lokality",
"siteTunnelDescription": "Určete jak se chcete připojit k vaší lokalitě",
"siteNewtCredentials": "Přihlašovací údaje Newt",
@@ -132,7 +131,7 @@
"expireIn": "Platnost vyprší za",
"neverExpire": "Nikdy nevyprší",
"shareExpireDescription": "Doba platnosti určuje, jak dlouho bude odkaz použitelný a bude poskytovat přístup ke zdroji. Po této době odkaz již nebude fungovat a uživatelé kteří tento odkaz používali ztratí přístup ke zdroji.",
"shareSeeOnce": "Tento odkaz uvidíte pouze jednou. Ujistěte se, že jste jej zkopírovali.",
"shareSeeOnce": "Tento odkaz uvidíte pouze jednou. Nezapomeňte jej zkopírovat.",
"shareAccessHint": "Kdokoli s tímto odkazem může přistupovat ke zdroji. Sdílejte jej s rozvahou.",
"shareTokenUsage": "Zobrazit využití přístupového tokenu",
"createLink": "Vytvořit odkaz",
@@ -154,8 +153,7 @@
"protected": "Chráněno",
"notProtected": "Nechráněno",
"resourceMessageRemove": "Jakmile zdroj odstraníte, nebude dostupný. Všechny související služby a cíle budou také odstraněny.",
"resourceMessageConfirm": "Pro potvrzení zadejte prosím název zdroje.",
"resourceQuestionRemove": "Opravdu chcete odstranit zdroj {selectedResource} z organizace?",
"resourceQuestionRemove": "Jste si jisti, že chcete odstranit zdroj z organizace?",
"resourceHTTP": "Zdroj HTTPS",
"resourceHTTPDescription": "Požadavky na proxy pro vaši aplikaci přes HTTPS pomocí subdomény nebo základní domény.",
"resourceRaw": "Surový TCP/UDP zdroj",
@@ -181,7 +179,7 @@
"baseDomain": "Základní doména",
"subdomnainDescription": "Subdoména, kde bude váš zdroj přístupný.",
"resourceRawSettings": "Nastavení TCP/UDP",
"resourceRawSettingsDescription": "Nakonfigurujte, jak bude váš dokument přístupný přes TCP/UDP",
"resourceRawSettingsDescription": "Nakonfigurujte, jak bude váš dokument přístupný přes TCP/UDP. Mapováte zdroj na port na serveru Pangolin, takže můžete přistupovat ke zdroji ze serveru-veřejné ip:mapped-port.",
"protocol": "Protokol",
"protocolSelect": "Vybrat protokol",
"resourcePortNumber": "Číslo portu",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Potvrdit odstranění organizace",
"orgMessageRemove": "Tato akce je nevratná a odstraní všechna související data.",
"orgMessageConfirm": "Pro potvrzení zadejte níže uvedený název organizace.",
"orgQuestionRemove": "Opravdu chcete odstranit organizaci {selectedOrg}?",
"orgQuestionRemove": "Jste si jisti, že chcete odstranit organizaci?",
"orgUpdated": "Organizace byla aktualizována",
"orgUpdatedDescription": "Organizace byla aktualizována.",
"orgErrorUpdate": "Aktualizace organizace se nezdařila",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Generovat API klíč",
"apiKeysErrorDelete": "Chyba při odstraňování API klíče",
"apiKeysErrorDeleteMessage": "Chyba při odstraňování API klíče",
"apiKeysQuestionRemove": "Opravdu chcete odstranit API klíč {selectedApiKey} z organizace?",
"apiKeysQuestionRemove": "Jste si jisti, že chcete odstranit klíč API z organizace?",
"apiKeysMessageRemove": "Po odstranění klíče API již nebude možné použít.",
"apiKeysMessageConfirm": "Pro potvrzení zadejte název klíče API.",
"apiKeysDeleteConfirm": "Potvrdit odstranění API klíče",
"apiKeysDelete": "Odstranit klíč API",
"apiKeysManage": "Správa API klíčů",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Potvrdit odstranění uživatele",
"userDeleteServer": "Odstranit uživatele ze serveru",
"userMessageRemove": "Uživatel bude odstraněn ze všech organizací a bude zcela odstraněn ze serveru.",
"userMessageConfirm": "Pro potvrzení zadejte níže uvedené jméno uživatele.",
"userQuestionRemove": "Opravdu chcete trvale odstranit {selectedUser} ze serveru?",
"userQuestionRemove": "Jste si jisti, že chcete trvale odstranit uživatele ze serveru?",
"licenseKey": "Licenční klíč",
"valid": "Valid",
"numberOfSites": "Počet stránek",
@@ -339,7 +335,7 @@
"fossorialLicense": "Zobrazit Fossorial Commercial License & Subscription terms",
"licenseMessageRemove": "Tímto odstraníte licenční klíč a všechna s ním spojená oprávnění, která mu byla udělena.",
"licenseMessageConfirm": "Pro potvrzení zadejte licenční klíč níže.",
"licenseQuestionRemove": "Jste si jisti, že chcete odstranit licenční klíč {selectedKey}?",
"licenseQuestionRemove": "Jste si jisti, že chcete odstranit licenční klíč?",
"licenseKeyDelete": "Odstranit licenční klíč",
"licenseKeyDeleteConfirm": "Potvrdit odstranění licenčního klíče",
"licenseTitle": "Správa stavu licence",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Došlo k chybě při odstraňování pozvánky.",
"inviteRemoved": "Pozvánka odstraněna",
"inviteRemovedDescription": "Pozvánka pro {email} byla odstraněna.",
"inviteQuestionRemove": "Jste si jisti, že chcete odstranit pozvánku {email}?",
"inviteQuestionRemove": "Jste si jisti, že chcete odstranit pozvánku?",
"inviteMessageRemove": "Po odstranění, tato pozvánka již nebude platná. Později můžete uživatele znovu pozvat.",
"inviteMessageConfirm": "Pro potvrzení zadejte prosím níže uvedenou e-mailovou adresu.",
"inviteQuestionRegenerate": "Jste si jisti, že chcete obnovit pozvánku pro {email}? Tato akce zruší předchozí pozvánku.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Došlo k chybě při odebírání uživatele.",
"userOrgRemoved": "Uživatel odstraněn",
"userOrgRemovedDescription": "Uživatel {email} byl odebrán z organizace.",
"userQuestionOrgRemove": "Jste si jisti, že chcete odstranit {email} z organizace?",
"userQuestionOrgRemove": "Jste si jisti, že chcete odstranit tohoto uživatele z organizace?",
"userMessageOrgRemove": "Po odstranění tohoto uživatele již nebude mít přístup k organizaci. Vždy je můžete znovu pozvat později, ale budou muset pozvání znovu přijmout.",
"userMessageOrgConfirm": "Pro potvrzení, zadejte prosím jméno uživatele níže.",
"userRemoveOrgConfirm": "Potvrdit odebrání uživatele",
"userRemoveOrg": "Odebrat uživatele z organizace",
"users": "Uživatelé",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Správce serveru - Pangolin",
"licenseTierProfessional": "Profesionální licence",
"licenseTierEnterprise": "Podniková licence",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Osobní licence",
"licensed": "Licencováno",
"yes": "Ano",
"no": "Ne",
@@ -742,7 +737,7 @@
"idpManageDescription": "Zobrazit a spravovat poskytovatele identity v systému",
"idpDeletedDescription": "Poskytovatel identity byl úspěšně odstraněn",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Jste si jisti, že chcete trvale odstranit poskytovatele identity {name}?",
"idpQuestionRemove": "Jste si jisti, že chcete trvale odstranit poskytovatele identity?",
"idpMessageRemove": "Tímto odstraníte poskytovatele identity a všechny přidružené konfigurace. Uživatelé, kteří se autentizují prostřednictvím tohoto poskytovatele, se již nebudou moci přihlásit.",
"idpMessageConfirm": "Pro potvrzení zadejte níže uvedené jméno poskytovatele identity.",
"idpConfirmDelete": "Potvrdit odstranění poskytovatele identity",
@@ -765,7 +760,7 @@
"idpDisplayName": "Zobrazované jméno tohoto poskytovatele identity",
"idpAutoProvisionUsers": "Automatická úprava uživatelů",
"idpAutoProvisionUsersDescription": "Pokud je povoleno, uživatelé budou automaticky vytvářeni v systému při prvním přihlášení, s možností namapovat uživatele na role a organizace.",
"licenseBadge": "EE",
"licenseBadge": "PE",
"idpType": "Typ poskytovatele",
"idpTypeDescription": "Vyberte typ poskytovatele identity, který chcete nakonfigurovat",
"idpOidcConfigure": "Nastavení OAuth2/OIDC",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Zkontrolujte svůj e-mail pro kód pro obnovení.",
"passwordNew": "Nové heslo",
"passwordNewConfirm": "Potvrdit nové heslo",
"changePassword": "Změnit heslo",
"changePasswordDescription": "Aktualizujte heslo k účtu",
"oldPassword": "Aktuální heslo",
"newPassword": "Nové heslo",
"confirmNewPassword": "Potvrdit nové heslo",
"changePasswordError": "Změna hesla se nezdařila",
"changePasswordErrorDescription": "Došlo k chybě při změně hesla",
"changePasswordSuccess": "Heslo úspěšně změněno",
"changePasswordSuccessDescription": "Vaše heslo bylo úspěšně aktualizováno",
"passwordExpiryRequired": "Vyžaduje vypršení platnosti hesla",
"passwordExpiryDescription": "Tato organizace vyžaduje změnu hesla každých {maxDays} dní.",
"changePasswordNow": "Změnit heslo",
"pincodeAuth": "Ověřovací kód",
"pincodeSubmit2": "Odeslat kód",
"passwordResetSubmit": "Žádost o obnovení",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Všichni uživatelé",
"sidebarIdentityProviders": "Poskytovatelé identity",
"sidebarLicense": "Licence",
"sidebarClients": "Clients",
"sidebarClients": "Klienti",
"sidebarDomains": "Domény",
"sidebarBluePrints": "Plány",
"blueprints": "Plány",
"blueprintsDescription": "Použít deklarativní konfigurace a zobrazit předchozí běhy",
"blueprintAdd": "Přidat plán",
"blueprintGoBack": "Zobrazit všechny plány",
"blueprintCreate": "Vytvořit plán",
"blueprintCreateDescription2": "Postupujte podle níže uvedených kroků pro vytvoření a použití nového plánu",
"blueprintDetails": "Podrobnosti plánu",
"blueprintDetailsDescription": "Podívejte se na výsledek použitého plánu a případné chyby, které se vyskytly",
"blueprintInfo": "Informace o plánu",
"message": "Zpráva",
"blueprintContentsDescription": "Definujte obsah YAML popisující vaši infrastrukturu",
"blueprintErrorCreateDescription": "Při aplikaci plánu došlo k chybě",
"blueprintErrorCreate": "Chyba při vytváření plánu",
"searchBlueprintProgress": "Hledat plány...",
"appliedAt": "Použito v",
"source": "Zdroj",
"contents": "Obsah",
"parsedContents": "Parsed content (Pouze pro čtení)",
"enableDockerSocket": "Povolit Docker plán",
"enableDockerSocketDescription": "Povolte seškrábání štítků na Docker Socket pro popisky plánů. Nová cesta musí být k dispozici.",
"enableDockerSocketLink": "Zjistit více",
@@ -1211,9 +1237,8 @@
"domainCreate": "Vytvořit doménu",
"domainCreatedDescription": "Doména byla úspěšně vytvořena",
"domainDeletedDescription": "Doména byla úspěšně odstraněna",
"domainQuestionRemove": "Opravdu chcete odstranit doménu {domain} z vašeho účtu?",
"domainQuestionRemove": "Opravdu chcete odstranit doménu z vašeho účtu?",
"domainMessageRemove": "Po odstranění domény již nebude přiřazena k vašemu účtu.",
"domainMessageConfirm": "Pro potvrzení zadejte název domény níže.",
"domainConfirmDelete": "Potvrdit odstranění domény",
"domainDelete": "Odstranit doménu",
"domain": "Doména",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Došlo k chybě při aktualizaci nastavení",
"sidebarCollapse": "Sbalit",
"sidebarExpand": "Rozbalit",
"productUpdateMoreInfo": "{noOfUpdates} další aktualizace",
"productUpdateInfo": "Aktualizace {noOfUpdates}",
"productUpdateWhatsNew": "Co je nového",
"productUpdateTitle": "Aktualizace produktu",
"productUpdateEmpty": "Žádné aktualizace",
"dismissAll": "Odmítnout vše",
"pangolinUpdateAvailable": "K dispozici je nová verze",
"pangolinUpdateAvailableInfo": "Verze {version} je připravena k instalaci",
"pangolinUpdateAvailableReleaseNotes": "Zobrazit poznámky k vydání",
"newtUpdateAvailable": "Dostupná aktualizace",
"newtUpdateAvailableInfo": "Je k dispozici nová verze Newt. Pro nejlepší zážitek prosím aktualizujte na nejnovější verzi.",
"domainPickerEnterDomain": "Doména",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Volná úroveň",
"billingWarningOverLimit": "Upozornění: Překročili jste jeden nebo více omezení používání. Vaše stránky se nepřipojí dokud nezměníte předplatné nebo neupravíte své používání.",
"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@fossorial.io.",
"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",
"billingOnlineTime": "Stránka online čas",
"billingUsers": "Aktivní uživatelé",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Vyskytl se problém s použitím bezpečnostního klíče. Zkuste to prosím znovu.",
"twoFactorRequired": "Pro registraci bezpečnostního klíče je nutné dvoufaktorové ověření.",
"twoFactor": "Dvoufaktorové ověření",
"twoFactorAuthentication": "Dvoufaktorové ověření",
"twoFactorDescription": "Tato organizace vyžaduje dvoufaktorové ověření.",
"enableTwoFactor": "Povolit dvoufaktorové ověření",
"organizationSecurityPolicy": "Bezpečnostní politika organizace",
"organizationSecurityPolicyDescription": "Tato organizace má bezpečnostní požadavky, které musí být splněny, než k ní budete mít přístup",
"securityRequirements": "Bezpečnostní požadavky",
"allRequirementsMet": "Všechny požadavky byly splněny",
"completeRequirementsToContinue": "Pro pokračování v přístupu k této organizaci splněte níže uvedené požadavky",
"youCanNowAccessOrganization": "Nyní můžete přistupovat k této organizaci",
"reauthenticationRequired": "Délka relace",
"reauthenticationDescription": "Tato organizace vyžaduje, abyste se přihlásili každých {maxDays} dní.",
"reauthenticationDescriptionHours": "Tato organizace vyžaduje, abyste se přihlásili každých {maxHours} hodin.",
"reauthenticateNow": "Přihlásit se znovu",
"adminEnabled2FaOnYourAccount": "Váš správce povolil dvoufaktorové ověřování pro {email}. Chcete-li pokračovat, dokončete proces nastavení.",
"securityKeyAdd": "Přidat bezpečnostní klíč",
"securityKeyRegisterTitle": "Registrovat nový bezpečnostní klíč",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Tyto zdroje jsou určeny pro použití s",
"resourcesTableClients": "Klienti",
"resourcesTableAndOnlyAccessibleInternally": "a jsou interně přístupné pouze v případě, že jsou propojeni s klientem.",
"resourcesTableNoTargets": "Žádné cíle",
"resourcesTableHealthy": "Zdravé",
"resourcesTableDegraded": "Rozklad",
"resourcesTableOffline": "Offline",
"resourcesTableUnknown": "Neznámý",
"resourcesTableNotMonitored": "Není sledováno",
"editInternalResourceDialogEditClientResource": "Upravit klientský dokument",
"editInternalResourceDialogUpdateResourceProperties": "Aktualizujte vlastnosti zdroje a cílovou konfiguraci pro {resourceName}.",
"editInternalResourceDialogResourceProperties": "Vlastnosti zdroje",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Od poskytovatele identity nebyla obdržena žádná adresa URL.",
"autoLoginErrorGeneratingUrl": "Nepodařilo se vygenerovat ověřovací URL.",
"remoteExitNodeManageRemoteExitNodes": "Vzdálené uzly",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Hostujte jeden nebo více vlastních vzdálených uzlů, abyste rozšířili síťová připojení a snížili závislost na cloudu",
"remoteExitNodes": "Uzly",
"searchRemoteExitNodes": "Hledat uzly...",
"remoteExitNodeAdd": "Přidat uzel",
"remoteExitNodeErrorDelete": "Chyba při odstraňování uzlu",
"remoteExitNodeQuestionRemove": "Jste si jisti, že chcete odstranit uzel {selectedNode} z organizace?",
"remoteExitNodeQuestionRemove": "Jste si jisti, že chcete odstranit uzel z organizace?",
"remoteExitNodeMessageRemove": "Po odstranění uzel již nebude přístupný.",
"remoteExitNodeMessageConfirm": "Pro potvrzení zadejte název uzlu níže.",
"remoteExitNodeConfirmDelete": "Potvrdit odstranění uzlu",
"remoteExitNodeDelete": "Odstranit uzel",
"sidebarRemoteExitNodes": "Vzdálené uzly",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Upravit soubor: docker-compose.yml",
"emailVerificationRequired": "Je vyžadováno ověření e-mailu. Přihlaste se znovu pomocí {dashboardUrl}/auth/login dokončete tento krok. Poté se vraťte zde.",
"twoFactorSetupRequired": "Je vyžadováno nastavení dvoufaktorového ověřování. Přihlaste se znovu pomocí {dashboardUrl}/autentizace/přihlášení dokončí tento krok. Poté se vraťte zde.",
"additionalSecurityRequired": "Vyžadováno další zabezpečení",
"organizationRequiresAdditionalSteps": "Tato organizace vyžaduje další bezpečnostní kroky, než budete moci přistupovat ke zdrojům.",
"completeTheseSteps": "Dokončete tyto kroky",
"enableTwoFactorAuthentication": "Povolit dvoufaktorové ověření",
"completeSecuritySteps": "Dokončit bezpečnostní kroky",
"securitySettings": "Nastavení zabezpečení",
"securitySettingsDescription": "Konfigurace bezpečnostních zásad pro vaši organizaci",
"requireTwoFactorForAllUsers": "Vyžadovat dvoufaktorové ověření pro všechny uživatele",
"requireTwoFactorDescription": "Pokud je povoleno, všichni interní uživatelé v této organizaci musí mít dvoufaktorové ověření povoleno pro přístup k organizaci.",
"requireTwoFactorDisabledDescription": "Tato funkce vyžaduje platnou licenci (Enterprise) nebo aktivní předplatné (SaaS)",
"requireTwoFactorCannotEnableDescription": "Před vynucením dvoufaktorového ověření vašeho účtu musíte povolit dvoufaktorové ověření pro všechny uživatele",
"maxSessionLength": "Maximální délka relace",
"maxSessionLengthDescription": "Nastavte maximální dobu trvání relace uživatele. Po této době se uživatelé budou muset znovu přihlásit.",
"maxSessionLengthDisabledDescription": "Tato funkce vyžaduje platnou licenci (Enterprise) nebo aktivní předplatné (SaaS)",
"selectSessionLength": "Vyberte délku relace",
"unenforced": "Nevynucené",
"1Hour": "1 hodina",
"3Hours": "3 hodiny",
"6Hours": "6 hodin",
"12Hours": "12 hodin",
"1DaySession": "1 den",
"3Days": "3 dny",
"7Days": "7 dní",
"14Days": "14 dní",
"30DaysSession": "30 dní",
"90DaysSession": "90 dní",
"180DaysSession": "180 dní",
"passwordExpiryDays": "Platnost hesla",
"editPasswordExpiryDescription": "Nastavte počet dní před tím, než jsou uživatelé povinni změnit své heslo.",
"selectPasswordExpiry": "Vyberte vypršení platnosti hesla",
"30Days": "30 dní",
"1Day": "1 den",
"60Days": "60 dní",
"90Days": "90 dní",
"180Days": "180 dní",
"1Year": "1 rok",
"subscriptionBadge": "Vyžadováno předplatné",
"securityPolicyChangeWarning": "Upozornění na změnu bezpečnostní politiky",
"securityPolicyChangeDescription": "Chystáte se změnit nastavení bezpečnostních pravidel. Po uložení bude možná nutné znovu ověřit, abyste dodrželi tyto aktualizace přístupových práv. Všichni uživatelé, kteří nevyhovují, se také budou muset znovu přihlásit.",
"securityPolicyChangeConfirmMessage": "Potvrzuji",
"securityPolicyChangeWarningText": "Toto ovlivní všechny uživatele v organizaci",
"authPageErrorUpdateMessage": "Při aktualizaci nastavení autentizační stránky došlo k chybě",
"authPageErrorUpdate": "Nelze aktualizovat ověřovací stránku",
"authPageUpdated": "Autentizační stránka byla úspěšně aktualizována",
"healthCheckNotAvailable": "Místní",
"rewritePath": "Přepsat cestu",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Úspěšně odstraněna autentizace záhlaví.",
"resourceErrorHeaderAuthRemove": "Nepodařilo se odstranit Autentizaci Záhlaví",
"resourceErrorHeaderAuthRemoveDescription": "Nepodařilo se odstranit autentizaci záhlaví ze zdroje.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Ověřování pomocí hlaviček zapnuto",
"resourceHeaderAuthProtectionDisabled": "Ověřování pomocí hlaviček vypnuto",
"headerAuthRemove": "Odstranit ověřování pomocí hlaviček",
"headerAuthAdd": "Přidat ověřování pomocí hlaviček",
"resourceErrorHeaderAuthSetup": "Nepodařilo se nastavit Autentizaci Záhlaví",
"resourceErrorHeaderAuthSetupDescription": "Nepodařilo se nastavit autentizaci záhlaví ze zdroje.",
"resourceHeaderAuthSetup": "Úspěšně nastavena Autentizace Záhlaví",
"resourceHeaderAuthSetupDescription": "Autentizace záhlaví byla úspěšně nastavena.",
"resourceHeaderAuthSetupTitle": "Nastavit Autentizaci Záhlaví",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Nastavte přihlašovací údaje basic auth (uživatelské jméno a heslo) abyste tento zdroj chránili ověřováním pomocí HTTP hlaviček. Pro přístup použijte adresu ve formátu https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Nastavit Autentizaci Záhlaví",
"actionSetResourceHeaderAuth": "Nastavit Autentizaci Záhlaví",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"enterpriseEdition": "Podniková edice",
"unlicensed": "Nelicencováno",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"manageClients": "Spravovat klienty",
"manageClientsDescription": "Klienti jsou zařízení, která se mohou připojit k vašim lokalitám",
"licenseTableValidUntil": "Platná do",
"saasLicenseKeysSettingsTitle": "Podniková licence",
"saasLicenseKeysSettingsDescription": "Vygenerovat a spravovat podnikové licence pro instance Pangolin na vlastním hostingu",
"sidebarEnterpriseLicenses": "Licence",
"generateLicenseKey": "Vygenerovat licenční klíč",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Prosím zadejte platnou emailovou adresu",
"useCaseTypeRequired": "Vyberte prosím typ použití",
"firstNameRequired": "Zadejte křestní jméno",
"lastNameRequired": "Zadejte příjmení",
"primaryUseRequired": "Popište prosím účel použití",
"jobTitleRequiredBusiness": "Pro komerční využití zadejte název pracovní pozice",
"industryRequiredBusiness": "Pro komerční využití zadejte odvětví společnosti",
"stateProvinceRegionRequired": "Zadejte stát/provincii/oblast",
"postalZipCodeRequired": "Zadejte PSČ",
"companyNameRequiredBusiness": "Pro komerční využití zadejte název společnosti",
"countryOfResidenceRequiredBusiness": "Pro komerční využití zadejte zemi sídla společnosti",
"countryRequiredPersonal": "Pro osobní využití zadejte zemi",
"agreeToTermsRequired": "Musíte souhlasit s podmínkami",
"complianceConfirmationRequired": "Musíte potvrdit dodržování Fossorial Commercial Licence"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Osobní využití",
"description": "Pro osobní nekomerční využití jako je vzdělávání, osobní projekty nebo experimentování."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Podnikové využití",
"description": "Pro použití v organizacích, společnostech nebo při činnostech generujících zisk."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "Email a typ licence",
"description": "Zadejte svůj email a vyberte typ licence"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Osobní údaje",
"description": "Povězte nám něco o sobě"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Kontaktní údaje",
"description": "Vaše kontaktní údaje"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Podmínky a vygenerovat",
"description": "Zkontrolujte a přijměte podmínky pro vygenerování vaší licence"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Poskytnutí využití",
"description": "Vyberte si typ licence který odráží způsob využití. Osobní licence dovoluje používat aplikaci pro osobní využití, nekomerční využití nebo v malých organizacích do ročního obratu pod 100 000 USD. Jakékoliv jiné využití včetně využití pro podnikání, organizace nebo jiná prostředí generující zisk vyžaduje platnou podnikovou licenci a platbu licenčních poplatků. Všichni uživatelé, ať už osobních nebo podnikových licencí, musí souhlasit s Fossorial Commercial License Terms."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Informace o zkušební době",
"description": "Tento licenční klíč umožňuje používat podnikové funkce po dobu sedmidenní zkušební doby. Abyste zachovali přístup k placeným funkcím po skončení zkušební doby, musíte aktivovat platnou osobní nebo podnikovou licenci. Pro podnikové licence kontaktujte sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Používáte Pangolin pro osobní nebo obchodní účely?",
"firstName": "Křestní jméno",
"lastName": "Příjmení",
"jobTitle": "Pracovní pozice",
"primaryUseQuestion": "Na co budete především používat Pangolin?",
"industryQuestion": "Jaké je vaše odvětví?",
"prospectiveUsersQuestion": "Kolik potenciálních uživatelů předpokládáte?",
"prospectiveSitesQuestion": "Kolik předpokládáte lokalit (tunelů)?",
"companyName": "Název společnosti",
"countryOfResidence": "Země sídla společnosti",
"stateProvinceRegion": "Stát / kraj / oblast",
"postalZipCode": "P",
"companyWebsite": "Stránky společnosti",
"companyPhoneNumber": "Telefonní číslo společnosti",
"country": "Země",
"phoneNumberOptional": "Telefonní číslo (nepovinné)",
"complianceConfirmation": "Potvrzuji, že informace které jsem poskytl jsou přesné a že jsem v souladu s licencí Fossorial Commercial License. Poskutnutí nepřesných informací nebo nesprávné určení použití produktu je porušením licence a může vést ke zrušení platnosti klíče."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Zavřít",
"previous": "Předchozí",
"next": "Následující",
"generateLicenseKey": "Vygenerovat licenční klíč"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Licenční klíč byl úspěšně vytvořen",
"description": "Váš licenční klíč byl vytvořen a je připraven k použití."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Nepodařilo se vytvořit licenční klíč",
"description": "Při generování licenčního klíče došlo k chybě."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"instanceName": "Název instance",
"pathMatchModalTitle": "Nastavit porovnávání cest",
"pathMatchModalDescription": "Nastavte jak se bude ověřovat, ze cesty příchozích požadavků se shodují.",
"pathMatchType": "Typ shody",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"pathMatchExact": "Přesná",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Hodnota cesty",
"clear": "Smazat",
"saveChanges": "Uložit změny",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathMatchDefaultPlaceholder": "/cesta",
"pathMatchPrefixHelp": "Příklad: /api se shoduje s cestami /api, /api/users atd.",
"pathMatchExactHelp": "Příklad: /api se shoduje pouze s cestou /api",
"pathMatchRegexHelp": "Příklad: ^/api/.* se shoduje s /api/cokoliv",
"pathRewriteModalTitle": "Nastavit přepis cesty",
"pathRewriteModalDescription": "Upravit shodující se cestu před odesláním požadavku do cíle.",
"pathRewriteType": "Typ přepisu",
"pathRewritePrefixOption": "Prefix - Nahradí prefix",
"pathRewriteExactOption": "Přesný - Nahradí celou cestu",
"pathRewriteRegexOption": "Regex - Nahrazení pomocí vzorů",
"pathRewriteStripPrefixOption": "Odstranit prefix - Odstraní prefix",
"pathRewriteValue": "Přepisovaná hodnota",
"pathRewriteRegexPlaceholder": "/nová/$1",
"pathRewriteDefaultPlaceholder": "/nová-cesta",
"pathRewritePrefixHelp": "Nahradit odpovídající prefix touto hodnotou",
"pathRewriteExactHelp": "Nahradit celou cestu touto hodnotou, pokud cesta přesně odpovídá",
"pathRewriteRegexHelp": "K nahrazení použít capture groups jako $1, $2",
"pathRewriteStripPrefixHelp": "Ponechte prázdné pro odstranění prefixu nebo zadejte nový prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewriteExact": "Přesný",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Odstranit",
"pathRewriteStripLabel": "odstranit",
"sidebarEnableEnterpriseLicense": "Použít podnikovou licenci",
"cannotbeUndone": "To nelze vrátit zpět.",
"toConfirm": "Potvrdit",
"deleteClientQuestion": "Jste si jisti, že chcete odstranit klienta z webu a organizace?",
"clientMessageRemove": "Po odstranění se klient již nebude moci připojit k webu.",
"sidebarLogs": "Logy",
"request": "Žádost",
"logs": "Logy",
"logsSettingsDescription": "Monitorovat logy shromážděné z této orginizace",
"searchLogs": "Hledat logy...",
"action": "Akce",
"actor": "Aktér",
"timestamp": "Časové razítko",
"accessLogs": "Protokoly přístupu",
"exportCsv": "Exportovat CSV",
"actorId": "ID aktéra",
"allowedByRule": "Povoleno pomocí pravidla",
"allowedNoAuth": "Povoleno bez ověření",
"validAccessToken": "Platný přístupový token",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Platné heslo",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Zablokované zdroje",
"droppedByRule": "Zrušeno pravidlem",
"noSessions": "Žádné relace",
"temporaryRequestToken": "Dočasný požadavek token",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP adresa",
"reason": "Důvod",
"requestLogs": "Záznamy požadavků",
"host": "Hostitel",
"location": "Poloha",
"actionLogs": "Záznamy akcí",
"sidebarLogsRequest": "Záznamy požadavků",
"sidebarLogsAccess": "Protokoly přístupu",
"sidebarLogsAction": "Záznamy akcí",
"logRetention": "Zaznamenávání záznamu",
"logRetentionDescription": "Spravovat, jak dlouho jsou různé typy logů uloženy pro tuto organizaci nebo je zakázat",
"requestLogsDescription": "Zobrazit podrobné protokoly požadavků pro zdroje v této organizaci",
"logRetentionRequestLabel": "Zachování logu žádosti",
"logRetentionRequestDescription": "Jak dlouho uchovávat záznamy požadavků",
"logRetentionAccessLabel": "Zachování záznamu přístupu",
"logRetentionAccessDescription": "Jak dlouho uchovávat přístupové záznamy",
"logRetentionActionLabel": "Uchovávání protokolu akcí",
"logRetentionActionDescription": "Jak dlouho uchovávat záznamy akcí",
"logRetentionDisabled": "Zakázáno",
"logRetention3Days": "3 dny",
"logRetention7Days": "7 dní",
"logRetention14Days": "14 dní",
"logRetention30Days": "30 dní",
"logRetention90Days": "90 dní",
"logRetentionForever": "Navždy",
"actionLogsDescription": "Zobrazit historii akcí provedených 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í.",
"certResolver": "Oddělovač certifikátů",
"certResolverDescription": "Vyberte řešitele certifikátů pro tento dokument.",
"selectCertResolver": "Vyberte řešič certifikátů",
"enterCustomResolver": "Zadejte vlastní rozlišovač",
"preferWildcardCert": "Preferovat Wildcard certifikát",
"unverified": "Neověřeno",
"domainSetting": "Nastavení domény",
"domainSettingDescription": "Konfigurace nastavení pro vaši doménu",
"preferWildcardCertDescription": "Pokus o vygenerování zástupného certifikátu (vyžaduje správně nakonfigurovaný certifikát).",
"recordName": "Název záznamu",
"auto": "Automaticky",
"TTL": "TTL",
"howToAddRecords": "Jak přidat záznamy",
"dnsRecord": "Záznamy DNS",
"required": "Požadováno",
"domainSettingsUpdated": "Nastavení domény bylo úspěšně aktualizováno",
"orgOrDomainIdMissing": "Chybí ID organizace nebo domény",
"loadingDNSRecords": "Načítání DNS záznamů...",
"olmUpdateAvailableInfo": "Je k dispozici aktualizovaná verze Olm. Pro nejlepší zážitek prosím aktualizujte na nejnovější verzi.",
"client": "Zákazník",
"proxyProtocol": "Nastavení proxy protokolu",
"proxyProtocolDescription": "Konfigurace Proxy protokolu pro zachování klientských IP adres pro služby TCP/UDP.",
"enableProxyProtocol": "Povolit Proxy protokol",
"proxyProtocolInfo": "Zachovat IP adresy klienta pro TCP/UDP backends",
"proxyProtocolVersion": "Verze proxy protokolu",
"version1": " Verze 1 (doporučeno)",
"version2": "Verze 2",
"versionDescription": "Verze 1 je textová a široce podporovaná. Verze 2 je binární a efektivnější, ale méně kompatibilní.",
"warning": "Varování",
"proxyProtocolWarning": "Vaše backend aplikace musí být nakonfigurována, aby mohla být přijata spojení s Proxy protokolem. Pokud vaše backend nepodporuje Proxy protokol, povolením tohoto protokolu dojde k přerušení všech připojení. Ujistěte se, že nastavíte svou backend a důvěřujte hlavičkám Proxy protokolu z Traefik.",
"restarting": "Restartování...",
"manual": "Ruční",
"messageSupport": "Podpora zpráv",
"supportNotAvailableTitle": "Podpora není k dispozici",
"supportNotAvailableDescription": "Podpora není momentálně k dispozici. Můžete poslat e-mail na support@pangolin.net.",
"supportRequestSentTitle": "Žádost o podporu odeslána",
"supportRequestSentDescription": "Vaše zpráva byla úspěšně odeslána.",
"supportRequestFailedTitle": "Nepodařilo se odeslat žádost",
"supportRequestFailedDescription": "Při odesílání vaší žádosti o podporu došlo k chybě.",
"supportSubjectRequired": "Předmět je povinný",
"supportSubjectMaxLength": "Předmět musí být 255 znaků nebo méně",
"supportMessageRequired": "Je vyžadována zpráva",
"supportReplyTo": "Odpovědět na",
"supportSubject": "Předmět",
"supportSubjectPlaceholder": "Zadejte předmět",
"supportMessage": "Zpráva",
"supportMessagePlaceholder": "Zadejte svou zprávu",
"supportSending": "Odesílání...",
"supportSend": "Poslat",
"supportMessageSent": "Zpráva odeslána!",
"supportWillContact": "Brzy budeme v kontaktu!",
"selectLogRetention": "Vyberte záznam",
"showColumns": "Zobrazit sloupce",
"hideColumns": "Skrýt sloupce",
"columnVisibility": "Viditelnost sloupců",
"toggleColumn": "Přepnout sloupec {columnName}",
"allColumns": "Všechny sloupce",
"defaultColumns": "Výchozí sloupce",
"customizeView": "Přizpůsobit zobrazení",
"viewOptions": "Možnosti zobrazení",
"selectAll": "Vybrat vše",
"selectNone": "Nevybrat žádný",
"selectedResources": "Vybrané zdroje",
"enableSelected": "Povolit vybrané",
"disableSelected": "Zakázat vybrané",
"checkSelectedStatus": "Zkontrolovat stav vybraného",
"credentials": "Pověření",
"savecredentials": "Uložit přihlašovací údaje",
"regeneratecredentials": "Znovu klíče",
"regenerateCredentials": "Regenerovat a uložit vaše přihlašovací údaje",
"generatedcredentials": "Vygenerovaná pověření",
"copyandsavethesecredentials": "Zkopírovat a ukládat tato pověření",
"copyandsavethesecredentialsdescription": "Tyto přihlašovací údaje se znovu nezobrazí po opuštění této stránky. Uložte je bezpečně.",
"credentialsSaved": "Pověření uloženo",
"credentialsSavedDescription": "Pověření byla úspěšně obnovena a uložena.",
"credentialsSaveError": "Chyba při ukládání pověření",
"credentialsSaveErrorDescription": "Došlo k chybě při obnovování a ukládání přihlašovacích údajů.",
"regenerateCredentialsWarning": "Obnovení přihlašovacích údajů zneplatní ty předchozí. Ujistěte se, že aktualizujete všechny konfigurace, které tyto přihlašovací údaje používají.",
"confirm": "Potvrdit",
"regenerateCredentialsConfirmation": "Jste si jisti, že chcete obnovit přihlašovací údaje?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Tajný klíč",
"featureDisabledTooltip": "Tato funkce je dostupná pouze v podnikovém plánu a vyžaduje její používání.",
"niceId": "Pěkné ID",
"niceIdUpdated": "Nice ID aktualizováno",
"niceIdUpdatedSuccessfully": "Nice ID úspěšně aktualizováno",
"niceIdUpdateError": "Chyba při aktualizaci Nice ID",
"niceIdUpdateErrorDescription": "Došlo k chybě při aktualizaci identifikátoru Nice.",
"niceIdCannotBeEmpty": "Nice ID nemůže být prázdné",
"enterIdentifier": "Zadejte identifikátor",
"identifier": "Identifier"
}

View File

@@ -10,7 +10,7 @@
"setupErrorIdentifier": "Organisations-ID ist bereits vergeben. Bitte wähle eine andere.",
"componentsErrorNoMemberCreate": "Du bist derzeit kein Mitglied einer Organisation. Erstelle eine Organisation, um zu starten.",
"componentsErrorNoMember": "Du bist aktuell kein Mitglied einer Organisation.",
"welcome": "Willkommen zu Pangolin",
"welcome": "Willkommen bei Pangolin!",
"welcomeTo": "Willkommen bei",
"componentsCreateOrg": "Erstelle eine Organisation",
"componentsMember": "Du bist Mitglied von {count, plural, =0 {keiner Organisation} one {einer Organisation} other {# Organisationen}}.",
@@ -27,7 +27,7 @@
"inviteLogInOtherUser": "Als anderer Benutzer anmelden",
"createAnAccount": "Konto erstellen",
"inviteNotAccepted": "Einladung nicht angenommen",
"authCreateAccount": "Erstellen ein Konto um loszulegen",
"authCreateAccount": "Erstelle ein Konto um loszulegen",
"authNoAccount": "Du besitzt noch kein Konto?",
"email": "E-Mail",
"password": "Passwort",
@@ -47,9 +47,8 @@
"edit": "Bearbeiten",
"siteConfirmDelete": "Standort löschen bestätigen",
"siteDelete": "Standort löschen",
"siteMessageRemove": "Sobald dieser Standort entfernt ist, wird er nicht mehr zugänglich sein. Alle Ressourcen und Ziele, die mit diesem Standort verbunden sind, werden ebenfalls entfernt.",
"siteMessageConfirm": "Um zu bestätigen, gib den Namen des Standortes unten ein.",
"siteQuestionRemove": "Bist du sicher, dass der Standort {selectedSite} aus der Organisation entfernt werden soll?",
"siteMessageRemove": "Sobald die Site entfernt ist, wird sie nicht mehr zugänglich sein. Alle mit der Site verbundenen Ziele werden ebenfalls entfernt.",
"siteQuestionRemove": "Sind Sie sicher, dass Sie die Site aus der Organisation entfernen möchten?",
"siteManageSites": "Standorte verwalten",
"siteDescription": "Verbindung zum Netzwerk durch sichere Tunnel erlauben",
"siteCreate": "Standort erstellen",
@@ -64,7 +63,7 @@
"siteLearnNewt": "Wie du Newt auf deinem System installieren kannst",
"siteSeeConfigOnce": "Du kannst die Konfiguration nur einmalig ansehen.",
"siteLoadWGConfig": "Lade WireGuard Konfiguration...",
"siteDocker": "Erweitern für Docker Details",
"siteDocker": "Docker-Details anzeigen",
"toggle": "Umschalten",
"dockerCompose": "Docker Compose",
"dockerRun": "Docker Run",
@@ -96,7 +95,7 @@
"siteWgDescription": "Verwende jeden WireGuard-Client, um einen Tunnel einzurichten. Manuelles NAT-Setup erforderlich.",
"siteWgDescriptionSaas": "Verwenden Sie jeden WireGuard-Client, um einen Tunnel zu erstellen. Manuelles NAT-Setup erforderlich. FUNKTIONIERT NUR BEI SELBSTGEHOSTETEN KNOTEN",
"siteLocalDescription": "Nur lokale Ressourcen. Kein Tunneling.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Nur lokale Ressourcen. Kein Tunneling. Nur für entfernte Knoten verfügbar.",
"siteSeeAll": "Alle Standorte anzeigen",
"siteTunnelDescription": "Lege fest, wie du dich mit deinem Standort verbinden möchtest",
"siteNewtCredentials": "Neue Newt Zugangsdaten",
@@ -119,7 +118,7 @@
"tokenId": "Token-ID",
"requestHeades": "Anfrage-Header",
"queryParameter": "Abfrageparameter",
"importantNote": "Wichtige Notiz",
"importantNote": "Wichtiger Hinweis",
"shareImportantDescription": "Aus Sicherheitsgründen wird die Verwendung von Headern über Abfrageparameter empfohlen, wenn möglich, da Abfrageparameter in Server-Logs oder Browserverlauf protokolliert werden können.",
"token": "Token",
"shareTokenSecurety": "Halten Sie Ihr Zugangs-Token sicher. Teilen Sie es nicht in öffentlich zugänglichen Bereichen oder Client-seitigem Code.",
@@ -132,7 +131,7 @@
"expireIn": "Verfällt in",
"neverExpire": "Nie ablaufen",
"shareExpireDescription": "Ablaufzeit ist, wie lange der Link verwendet werden kann und bietet Zugriff auf die Ressource. Nach dieser Zeit wird der Link nicht mehr funktionieren und Benutzer, die diesen Link benutzt haben, verlieren den Zugriff auf die Ressource.",
"shareSeeOnce": "Sie können diese Linie nur sehen. Bitte kopieren Sie sie.",
"shareSeeOnce": "Sie können diesen Link nur einmal sehen. Bitte kopieren Sie ihn.",
"shareAccessHint": "Jeder mit diesem Link kann auf die Ressource zugreifen. Teilen Sie sie mit Vorsicht.",
"shareTokenUsage": "Zugriffstoken-Nutzung anzeigen",
"createLink": "Link erstellen",
@@ -154,11 +153,10 @@
"protected": "Geschützt",
"notProtected": "Nicht geschützt",
"resourceMessageRemove": "Einmal entfernt, wird die Ressource nicht mehr zugänglich sein. Alle mit der Ressource verbundenen Ziele werden ebenfalls entfernt.",
"resourceMessageConfirm": "Um zu bestätigen, geben Sie bitte den Namen der Ressource unten ein.",
"resourceQuestionRemove": "Sind Sie sicher, dass Sie die Ressource {selectedResource} aus der Organisation entfernen möchten?",
"resourceQuestionRemove": "Sind Sie sicher, dass Sie die Ressource aus der Organisation entfernen möchten?",
"resourceHTTP": "HTTPS-Ressource",
"resourceHTTPDescription": "Proxy-Anfragen an Ihre App über HTTPS unter Verwendung einer Subdomain oder einer Basis-Domain.",
"resourceRaw": "Rohe TCP/UDP Ressource",
"resourceRaw": "Direkte TCP/UDP Ressource (raw)",
"resourceRawDescription": "Proxy-Anfragen an Ihre App über TCP/UDP mit einer Portnummer.",
"resourceCreate": "Ressource erstellen",
"resourceCreateDescription": "Folgen Sie den Schritten unten, um eine neue Ressource zu erstellen",
@@ -176,12 +174,12 @@
"resourceTypeDescription": "Legen Sie fest, wie Sie auf Ihre Ressource zugreifen möchten",
"resourceHTTPSSettings": "HTTPS-Einstellungen",
"resourceHTTPSSettingsDescription": "Konfigurieren Sie den Zugriff auf Ihre Ressource über HTTPS",
"domainType": "Domänentyp",
"domainType": "Domain-Typ",
"subdomain": "Subdomain",
"baseDomain": "Basisdomäne",
"subdomnainDescription": "Die Subdomäne, auf die Ihre Ressource zugegriffen werden soll.",
"baseDomain": "Basis-Domain",
"subdomnainDescription": "Die Subdomain, auf der Ihre Ressource erreichbar sein soll.",
"resourceRawSettings": "TCP/UDP Einstellungen",
"resourceRawSettingsDescription": "Konfigurieren Sie den Zugriff auf Ihre Ressource über TCP/UDP",
"resourceRawSettingsDescription": "Legen Sie fest, wie auf Ihre Ressource über TCP/UDP zugegriffen wird. Sie ordnen die Ressource einem Port auf dem Pangolin-Server zu, so dass Sie auf die Ressource von server-public-ip:mapped-port zugreifen können.",
"protocol": "Protokoll",
"protocolSelect": "Wählen Sie ein Protokoll",
"resourcePortNumber": "Portnummer",
@@ -190,7 +188,7 @@
"resourceConfig": "Konfiguration Snippets",
"resourceConfigDescription": "Kopieren und fügen Sie diese Konfigurations-Snippets ein, um Ihre TCP/UDP Ressource einzurichten",
"resourceAddEntrypoints": "Traefik: Einstiegspunkte hinzufügen",
"resourceExposePorts": "Gerbil: Ports im Docker Compose ausblenden",
"resourceExposePorts": "Gerbil: Ports im Docker Compose freigeben",
"resourceLearnRaw": "Lernen Sie, wie Sie TCP/UDP Ressourcen konfigurieren",
"resourceBack": "Zurück zu den Ressourcen",
"resourceGoTo": "Zu Ressource gehen",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Organisation löschen bestätigen",
"orgMessageRemove": "Diese Aktion ist unwiderruflich und löscht alle zugehörigen Daten.",
"orgMessageConfirm": "Um zu bestätigen, geben Sie bitte den Namen der Organisation unten ein.",
"orgQuestionRemove": "Sind Sie sicher, dass Sie die Organisation {selectedOrg} entfernen möchten?",
"orgQuestionRemove": "Sind Sie sicher, dass Sie die Organisation entfernen möchten?",
"orgUpdated": "Organisation aktualisiert",
"orgUpdatedDescription": "Die Organisation wurde aktualisiert.",
"orgErrorUpdate": "Fehler beim Aktualisieren der Organisation",
@@ -287,9 +285,8 @@
"apiKeysAdd": "API-Schlüssel generieren",
"apiKeysErrorDelete": "Fehler beim Löschen des API-Schlüssels",
"apiKeysErrorDeleteMessage": "Fehler beim Löschen des API-Schlüssels",
"apiKeysQuestionRemove": "Sind Sie sicher, dass Sie den API-Schlüssel {selectedApiKey} aus der Organisation entfernen möchten?",
"apiKeysQuestionRemove": "Sind Sie sicher, dass Sie den API-Schlüssel aus der Organisation entfernen möchten?",
"apiKeysMessageRemove": "Einmal entfernt, kann der API-Schlüssel nicht mehr verwendet werden.",
"apiKeysMessageConfirm": "Zur Bestätigung geben Sie bitte den Namen des API-Schlüssels unten ein.",
"apiKeysDeleteConfirm": "Löschen des API-Schlüssels bestätigen",
"apiKeysDelete": "API-Schlüssel löschen",
"apiKeysManage": "API-Schlüssel verwalten",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Benutzer löschen bestätigen",
"userDeleteServer": "Benutzer vom Server löschen",
"userMessageRemove": "Der Benutzer wird von allen Organisationen entfernt und vollständig vom Server entfernt.",
"userMessageConfirm": "Um zu bestätigen, geben Sie bitte den Namen des Benutzers unten ein.",
"userQuestionRemove": "Sind Sie sicher, dass Sie {selectedUser} dauerhaft vom Server löschen möchten?",
"userQuestionRemove": "Sind Sie sicher, dass Sie den Benutzer dauerhaft vom Server löschen möchten?",
"licenseKey": "Lizenzschlüssel",
"valid": "Gültig",
"numberOfSites": "Anzahl der Standorte",
@@ -339,7 +335,7 @@
"fossorialLicense": "Fossorial Gewerbelizenz & Abonnementbedingungen anzeigen",
"licenseMessageRemove": "Dadurch werden der Lizenzschlüssel und alle zugehörigen Berechtigungen entfernt.",
"licenseMessageConfirm": "Um zu bestätigen, geben Sie bitte den Lizenzschlüssel unten ein.",
"licenseQuestionRemove": "Sind Sie sicher, dass Sie den Lizenzschlüssel {selectedKey} löschen möchten?",
"licenseQuestionRemove": "Sind Sie sicher, dass Sie den Lizenzschlüssel löschen möchten?",
"licenseKeyDelete": "Lizenzschlüssel löschen",
"licenseKeyDeleteConfirm": "Lizenzschlüssel löschen bestätigen",
"licenseTitle": "Lizenzstatus verwalten",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Beim Entfernen der Einladung ist ein Fehler aufgetreten.",
"inviteRemoved": "Einladung entfernt",
"inviteRemovedDescription": "Die Einladung für {email} wurde entfernt.",
"inviteQuestionRemove": "Sind Sie sicher, dass Sie die Einladung {email} entfernen möchten?",
"inviteQuestionRemove": "Sind Sie sicher, dass Sie die Einladung entfernen möchten?",
"inviteMessageRemove": "Sobald entfernt, wird diese Einladung nicht mehr gültig sein. Sie können den Benutzer später jederzeit erneut einladen.",
"inviteMessageConfirm": "Bitte geben Sie zur Bestätigung die E-Mail-Adresse der Einladung unten ein.",
"inviteQuestionRegenerate": "Sind Sie sicher, dass Sie die Einladung {email} neu generieren möchten? Dies wird die vorherige Einladung widerrufen.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Beim Entfernen des Benutzers ist ein Fehler aufgetreten.",
"userOrgRemoved": "Benutzer entfernt",
"userOrgRemovedDescription": "Der Benutzer {email} wurde aus der Organisation entfernt.",
"userQuestionOrgRemove": "Sind Sie sicher, dass Sie {email} aus der Organisation entfernen möchten?",
"userQuestionOrgRemove": "Sind Sie sicher, dass Sie diesen Benutzer aus der Organisation entfernen möchten?",
"userMessageOrgRemove": "Nach dem Entfernen hat dieser Benutzer keinen Zugriff mehr auf die Organisation. Sie können ihn später jederzeit wieder einladen, aber er muss die Einladung erneut annehmen.",
"userMessageOrgConfirm": "Geben Sie zur Bestätigung den Namen des Benutzers unten ein.",
"userRemoveOrgConfirm": "Entfernen des Benutzers bestätigen",
"userRemoveOrg": "Benutzer aus der Organisation entfernen",
"users": "Benutzer",
@@ -466,8 +461,8 @@
"accessUsersRolesDescription": "Laden Sie Benutzer ein und fügen Sie sie zu Rollen hinzu, um den Zugriff auf Ihre Organisation zu verwalten",
"key": "Schlüssel",
"createdAt": "Erstellt am",
"proxyErrorInvalidHeader": "Ungültiger benutzerdefinierter Host-Header-Wert. Verwenden Sie das Domänennamensformat oder speichern Sie leer, um den benutzerdefinierten Host-Header zu deaktivieren.",
"proxyErrorTls": "Ungültiger TLS-Servername. Verwenden Sie das Domänennamensformat oder speichern Sie leer, um den TLS-Servernamen zu entfernen.",
"proxyErrorInvalidHeader": "Ungültiger benutzerdefinierter Host-Header-Wert. Verwenden Sie das Domain-Namensformat oder speichern Sie leer, um den benutzerdefinierten Host-Header zu deaktivieren.",
"proxyErrorTls": "Ungültiger TLS-Servername. Verwenden Sie das Domain-Namensformat oder speichern Sie leer, um den TLS-Servernamen zu entfernen.",
"proxyEnableSSL": "SSL aktivieren",
"proxyEnableSSLDescription": "Aktiviere SSL/TLS-Verschlüsselung für sichere HTTPS-Verbindungen zu deinen Zielen.",
"target": "Target",
@@ -531,7 +526,7 @@
"ipAddressErrorInvalidFormat": "Ungültiges IP-Adressformat",
"ipAddressErrorInvalidOctet": "Ungültiges IP-Adress-Oktett",
"path": "Pfad",
"matchPath": "Spielpfad",
"matchPath": "Match-Pfad",
"ipAddressRange": "IP-Bereich",
"rulesErrorFetch": "Fehler beim Abrufen der Regeln",
"rulesErrorFetchDescription": "Beim Abrufen der Regeln ist ein Fehler aufgetreten",
@@ -591,7 +586,7 @@
"none": "Keine",
"unknown": "Unbekannt",
"resources": "Ressourcen",
"resourcesDescription": "Ressourcen sind Proxies zu Anwendungen in Ihrem privaten Netzwerk. Erstellen Sie eine Ressource für jeden HTTP/HTTPS- oder rohen TCP/UDP-Dienst in Ihrem privaten Netzwerk. Jede Ressource muss mit einer Site verbunden sein, um private, sichere Konnektivität über einen verschlüsselten WireGuard-Tunnel zu ermöglichen.",
"resourcesDescription": "Ressourcen sind Proxies zu Anwendungen in Ihrem privaten Netzwerk. Erstellen Sie eine Ressource für jeden HTTP/HTTPS- oder direkten TCP/UDP-Dienst in Ihrem privaten Netzwerk. Jede Ressource muss mit einer Site verbunden sein, um private, sichere Konnektivität über einen verschlüsselten WireGuard-Tunnel zu ermöglichen.",
"resourcesWireGuardConnect": "Sichere Verbindung mit WireGuard-Verschlüsselung",
"resourcesMultipleAuthenticationMethods": "Mehrere Authentifizierungsmethoden konfigurieren",
"resourcesUsersRolesAccess": "Benutzer- und rollenbasierte Zugriffskontrolle",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Server-Admin - Pangolin",
"licenseTierProfessional": "Professional Lizenz",
"licenseTierEnterprise": "Enterprise Lizenz",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Persönliche Lizenz",
"licensed": "Lizenziert",
"yes": "Ja",
"no": "Nein",
@@ -742,7 +737,7 @@
"idpManageDescription": "Identitätsanbieter im System anzeigen und verwalten",
"idpDeletedDescription": "Identitätsanbieter erfolgreich gelöscht",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Sind Sie sicher, dass Sie den Identitätsanbieter {name} dauerhaft löschen möchten?",
"idpQuestionRemove": "Sind Sie sicher, dass Sie den Identitätsanbieter dauerhaft löschen möchten?",
"idpMessageRemove": "Dies wird den Identitätsanbieter und alle zugehörigen Konfigurationen entfernen. Benutzer, die sich über diesen Anbieter authentifizieren, können sich nicht mehr anmelden.",
"idpMessageConfirm": "Bitte geben Sie zur Bestätigung den Namen des Identitätsanbieters unten ein.",
"idpConfirmDelete": "Löschen des Identitätsanbieters bestätigen",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Prüfen Sie Ihre E-Mail für den Reset-Code.",
"passwordNew": "Neues Passwort",
"passwordNewConfirm": "Neues Passwort bestätigen",
"changePassword": "Passwort ändern",
"changePasswordDescription": "Passwort des Kontos aktualisieren",
"oldPassword": "Aktuelles Passwort",
"newPassword": "Neues Passwort",
"confirmNewPassword": "Neues Passwort bestätigen",
"changePasswordError": "Fehler beim Ändern des Passworts",
"changePasswordErrorDescription": "Fehler beim Ändern Ihres Passworts",
"changePasswordSuccess": "Passwort erfolgreich geändert",
"changePasswordSuccessDescription": "Ihr Passwort wurde erfolgreich aktualisiert",
"passwordExpiryRequired": "Passwortablauf erforderlich",
"passwordExpiryDescription": "Diese Organisation erfordert, dass Sie Ihr Passwort alle {maxDays} Tage ändern.",
"changePasswordNow": "Passwort jetzt ändern",
"pincodeAuth": "Authentifizierungscode",
"pincodeSubmit2": "Code absenden",
"passwordResetSubmit": "Zurücksetzung anfordern",
@@ -1009,7 +1016,7 @@
"actionUpdateUser": "Benutzer aktualisieren",
"actionGetUser": "Benutzer abrufen",
"actionGetOrgUser": "Organisationsbenutzer abrufen",
"actionListOrgDomains": "Organisationsdomänen auflisten",
"actionListOrgDomains": "Organisationsdomains auflisten",
"actionCreateSite": "Standort erstellen",
"actionDeleteSite": "Standort löschen",
"actionGetSite": "Standort abrufen",
@@ -1076,7 +1083,7 @@
"actionCreateClient": "Kunde erstellen",
"actionDeleteClient": "Kunde löschen",
"actionUpdateClient": "Kunde aktualisieren",
"actionListClients": "Kunden auflisten",
"actionListClients": "Clients auflisten",
"actionGetClient": "Kunde holen",
"actionCreateSiteResource": "Site-Ressource erstellen",
"actionDeleteSiteResource": "Site-Ressource löschen",
@@ -1156,6 +1163,25 @@
"sidebarLicense": "Lizenz",
"sidebarClients": "Clients",
"sidebarDomains": "Domänen",
"sidebarBluePrints": "Baupläne",
"blueprints": "Baupläne",
"blueprintsDescription": "Deklarative Konfigurationen anwenden und vorherige Abläufe anzeigen",
"blueprintAdd": "Blaupause hinzufügen",
"blueprintGoBack": "Alle Blaupausen ansehen",
"blueprintCreate": "Blaupause erstellen",
"blueprintCreateDescription2": "Folge den Schritten unten, um eine neue Blaupause zu erstellen und anzuwenden",
"blueprintDetails": "Blaupausendetails",
"blueprintDetailsDescription": "Siehe das Ergebnis der angewendeten Blaupause und alle aufgetretenen Fehler",
"blueprintInfo": "Blaupauseninformation",
"message": "Nachricht",
"blueprintContentsDescription": "Definieren Sie den YAML-Inhalt, der Ihre Infrastruktur beschreibt",
"blueprintErrorCreateDescription": "Fehler beim Anwenden der Blaupause",
"blueprintErrorCreate": "Fehler beim Erstellen der Blaupause",
"searchBlueprintProgress": "Blaupausen suchen...",
"appliedAt": "Angewandt am",
"source": "Quelle",
"contents": "Inhalt",
"parsedContents": "Analysierte Inhalte (Nur lesen)",
"enableDockerSocket": "Docker Blaupause aktivieren",
"enableDockerSocketDescription": "Aktiviere Docker-Socket-Label-Scraping für Blaupausenbeschriftungen. Der Socket-Pfad muss neu angegeben werden.",
"enableDockerSocketLink": "Mehr erfahren",
@@ -1163,15 +1189,15 @@
"containersIn": "Container in {siteName}",
"selectContainerDescription": "Wählen Sie einen Container, der als Hostname für dieses Ziel verwendet werden soll. Klicken Sie auf einen Port, um einen Port zu verwenden.",
"containerName": "Name",
"containerImage": "Bild",
"containerState": "Bundesland",
"containerImage": "Image",
"containerState": "Status",
"containerNetworks": "Netzwerke",
"containerHostnameIp": "Hostname/IP",
"containerLabels": "Etiketten",
"containerLabelsCount": "{count, plural, one {# Etikett} other {# Etiketten}}",
"containerLabelsTitle": "Container-Labels",
"containerLabelEmpty": "<leer>",
"containerPorts": "Häfen",
"containerPorts": "Ports",
"containerPortsMore": "+{count} mehr",
"containerActions": "Aktionen",
"select": "Auswählen",
@@ -1183,7 +1209,7 @@
"searchResultsCount": "{count, plural, one {# Ergebnis} other {# Ergebnisse}}",
"filters": "Filter",
"filterOptions": "Filteroptionen",
"filterPorts": "Häfen",
"filterPorts": "Ports",
"filterStopped": "Stoppt",
"clearAllFilters": "Alle Filter löschen",
"columns": "Spalten",
@@ -1211,9 +1237,8 @@
"domainCreate": "Domain erstellen",
"domainCreatedDescription": "Domain erfolgreich erstellt",
"domainDeletedDescription": "Domain erfolgreich gelöscht",
"domainQuestionRemove": "Möchten Sie die Domain {domain} wirklich aus Ihrem Konto entfernen?",
"domainQuestionRemove": "Sind Sie sicher, dass Sie die Domain von Ihrem Konto entfernen möchten?",
"domainMessageRemove": "Nach dem Entfernen wird die Domain nicht mehr mit Ihrem Konto verknüpft.",
"domainMessageConfirm": "Um zu bestätigen, geben Sie bitte den Domainnamen unten ein.",
"domainConfirmDelete": "Domain-Löschung bestätigen",
"domainDelete": "Domain löschen",
"domain": "Domäne",
@@ -1253,13 +1278,22 @@
"settingsErrorUpdate": "Einstellungen konnten nicht aktualisiert werden",
"settingsErrorUpdateDescription": "Beim Aktualisieren der Einstellungen ist ein Fehler aufgetreten",
"sidebarCollapse": "Zusammenklappen",
"sidebarExpand": "Erweitern",
"sidebarExpand": "Aufklappen",
"productUpdateMoreInfo": "{noOfUpdates} weitere Updates",
"productUpdateInfo": "{noOfUpdates} Updates",
"productUpdateWhatsNew": "Was ist neu",
"productUpdateTitle": "Produkt-Updates",
"productUpdateEmpty": "Keine Updates",
"dismissAll": "Alle verwerfen",
"pangolinUpdateAvailable": "Neue Version verfügbar",
"pangolinUpdateAvailableInfo": "Version {version} ist bereit zur Installation",
"pangolinUpdateAvailableReleaseNotes": "Versionshinweise anzeigen",
"newtUpdateAvailable": "Update verfügbar",
"newtUpdateAvailableInfo": "Eine neue Version von Newt ist verfügbar. Bitte aktualisieren Sie auf die neueste Version für das beste Erlebnis.",
"domainPickerEnterDomain": "Domäne",
"domainPickerPlaceholder": "myapp.example.com",
"domainPickerDescription": "Geben Sie die vollständige Domäne der Ressource ein, um verfügbare Optionen zu sehen.",
"domainPickerDescriptionSaas": "Geben Sie eine vollständige Domäne, Subdomäne oder einfach einen Namen ein, um verfügbare Optionen zu sehen",
"domainPickerDescription": "Geben Sie die vollständige Domain der Ressource ein, um verfügbare Optionen zu sehen.",
"domainPickerDescriptionSaas": "Geben Sie eine vollständige Domain, Subdomain oder einfach einen Namen ein, um verfügbare Optionen zu sehen",
"domainPickerTabAll": "Alle",
"domainPickerTabOrganization": "Organisation",
"domainPickerTabProvided": "Bereitgestellt",
@@ -1280,11 +1314,11 @@
"billingFreeTier": "Kostenlose Stufe",
"billingWarningOverLimit": "Warnung: Sie haben ein oder mehrere Nutzungslimits überschritten. Ihre Webseiten werden nicht verbunden, bis Sie Ihr Abonnement ändern oder Ihren Verbrauch anpassen.",
"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@fossorial.io.",
"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",
"billingOnlineTime": "Online-Zeit der Seite",
"billingUsers": "Aktive Benutzer",
"billingDomains": "Aktive Domänen",
"billingDomains": "Aktive Domains",
"billingRemoteExitNodes": "Aktive selbstgehostete Nodes",
"billingNoLimitConfigured": "Kein Limit konfiguriert",
"billingEstimatedPeriod": "Geschätzter Abrechnungszeitraum",
@@ -1312,7 +1346,7 @@
"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.",
"billingUsersInfo": "Ihnen wird für jeden Benutzer in Ihrer Organisation berechnet. Die Abrechnung erfolgt täglich basierend auf der Anzahl der aktiven Benutzerkonten in Ihrer Organisation.",
"billingDomainInfo": "Ihnen wird für jede Domäne in Ihrer Organisation berechnet. Die Abrechnung erfolgt täglich basierend auf der Anzahl der aktiven Domänenkonten in Ihrer Organisation.",
"billingDomainInfo": "Ihnen wird jede Domain in Ihrer Organisation berechnet. Die Abrechnung erfolgt täglich, basierend auf der Anzahl der aktiven Domain-Konten in Ihrer Organisation.",
"billingRemoteExitNodesInfo": "Ihnen wird für jeden verwalteten Node in Ihrer Organisation berechnet. Die Abrechnung erfolgt täglich basierend auf der Anzahl der aktiven verwalteten Nodes in Ihrer Organisation.",
"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.",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Es gab ein Problem mit Ihrem Sicherheitsschlüssel. Bitte versuchen Sie es erneut.",
"twoFactorRequired": "Zur Registrierung eines Sicherheitsschlüssels ist eine Zwei-Faktor-Authentifizierung erforderlich.",
"twoFactor": "Zwei-Faktor-Authentifizierung",
"twoFactorAuthentication": "Zwei-Faktor-Authentifizierung",
"twoFactorDescription": "Diese Organisation erfordert Zwei-Faktor-Authentifizierung.",
"enableTwoFactor": "Zwei-Faktor-Authentifizierung aktivieren",
"organizationSecurityPolicy": "Sicherheitsrichtlinien der Organisation",
"organizationSecurityPolicyDescription": "Diese Organisation hat Sicherheitsanforderungen, die erfüllt werden müssen, bevor Sie darauf zugreifen können",
"securityRequirements": "Sicherheitsanforderungen",
"allRequirementsMet": "Alle Anforderungen wurden erfüllt",
"completeRequirementsToContinue": "Erfülle die folgenden Anforderungen, um weiterhin auf diese Organisation zuzugreifen",
"youCanNowAccessOrganization": "Sie können nun auf diese Organisation zugreifen",
"reauthenticationRequired": "Sitzungslänge",
"reauthenticationDescription": "Diese Organisation erfordert, dass Sie sich alle {maxDays} Tage anmelden.",
"reauthenticationDescriptionHours": "Diese Organisation erfordert, dass Sie sich alle {maxHours} Stunden einloggen.",
"reauthenticateNow": "Erneut anmelden",
"adminEnabled2FaOnYourAccount": "Ihr Administrator hat die Zwei-Faktor-Authentifizierung für {email} aktiviert. Bitte schließen Sie den Einrichtungsprozess ab, um fortzufahren.",
"securityKeyAdd": "Sicherheitsschlüssel hinzufügen",
"securityKeyRegisterTitle": "Neuen Sicherheitsschlüssel registrieren",
@@ -1385,14 +1432,14 @@
},
"siteRequired": "Standort ist erforderlich.",
"olmTunnel": "Olm-Tunnel",
"olmTunnelDescription": "Nutzen Sie Olm für die Kundenverbindung",
"olmTunnelDescription": "Nutzen Sie Olm für die Client-Verbindung",
"errorCreatingClient": "Fehler beim Erstellen des Clients",
"clientDefaultsNotFound": "Kundenvorgaben nicht gefunden",
"clientDefaultsNotFound": "Standardeinstellungen des Clients nicht gefunden",
"createClient": "Client erstellen",
"createClientDescription": "Erstellen Sie einen neuen Client für die Verbindung zu Ihren Standorten.",
"seeAllClients": "Alle Clients anzeigen",
"clientInformation": "Kundeninformationen",
"clientNamePlaceholder": "Kundenname",
"clientInformation": "Client-Informationen",
"clientNamePlaceholder": "Client-Name",
"address": "Adresse",
"subnetPlaceholder": "Subnetz",
"addressDescription": "Die Adresse, die dieser Client für die Verbindung verwenden wird.",
@@ -1464,13 +1511,13 @@
"httpMethod": "HTTP-Methode",
"selectHttpMethod": "HTTP-Methode auswählen",
"domainPickerSubdomainLabel": "Subdomain",
"domainPickerBaseDomainLabel": "Basisdomäne",
"domainPickerBaseDomainLabel": "Basisdomain",
"domainPickerSearchDomains": "Domains suchen...",
"domainPickerNoDomainsFound": "Keine Domains gefunden",
"domainPickerLoadingDomains": "Domains werden geladen...",
"domainPickerSelectBaseDomain": "Basisdomäne auswählen...",
"domainPickerSelectBaseDomain": "Basisdomain auswählen...",
"domainPickerNotAvailableForCname": "Für CNAME-Domains nicht verfügbar",
"domainPickerEnterSubdomainOrLeaveBlank": "Geben Sie eine Subdomain ein oder lassen Sie das Feld leer, um die Basisdomäne zu verwenden.",
"domainPickerEnterSubdomainOrLeaveBlank": "Geben Sie eine Subdomain ein oder lassen Sie das Feld leer, um die Basisdomain zu verwenden.",
"domainPickerEnterSubdomainToSearch": "Geben Sie eine Subdomain ein, um verfügbare freie Domains zu suchen und auszuwählen.",
"domainPickerFreeDomains": "Freie Domains",
"domainPickerSearchForAvailableDomains": "Verfügbare Domains suchen",
@@ -1485,8 +1532,14 @@
"resourcesTableNoInternalResourcesFound": "Keine internen Ressourcen gefunden.",
"resourcesTableDestination": "Ziel",
"resourcesTableTheseResourcesForUseWith": "Diese Ressourcen sind zur Verwendung mit",
"resourcesTableClients": "Kunden",
"resourcesTableClients": "Clients",
"resourcesTableAndOnlyAccessibleInternally": "und sind nur intern zugänglich, wenn mit einem Client verbunden.",
"resourcesTableNoTargets": "Keine Ziele",
"resourcesTableHealthy": "Gesund",
"resourcesTableDegraded": "Degradiert",
"resourcesTableOffline": "Offline",
"resourcesTableUnknown": "Unbekannt",
"resourcesTableNotMonitored": "Nicht überwacht",
"editInternalResourceDialogEditClientResource": "Client-Ressource bearbeiten",
"editInternalResourceDialogUpdateResourceProperties": "Aktualisieren Sie die Ressourceneigenschaften und die Zielkonfiguration für {resourceName}.",
"editInternalResourceDialogResourceProperties": "Ressourceneigenschaften",
@@ -1558,20 +1611,19 @@
"autoLoginErrorNoRedirectUrl": "Keine Weiterleitungs-URL vom Identitätsanbieter erhalten.",
"autoLoginErrorGeneratingUrl": "Fehler beim Generieren der Authentifizierungs-URL.",
"remoteExitNodeManageRemoteExitNodes": "Entfernte Knoten",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Self-Hosten Sie einen oder mehrere entfernte Knoten, um Ihr Netzwerk zu erweitern und die Abhängigkeit von der Cloud zu verringern",
"remoteExitNodes": "Knoten",
"searchRemoteExitNodes": "Knoten suchen...",
"remoteExitNodeAdd": "Knoten hinzufügen",
"remoteExitNodeErrorDelete": "Fehler beim Löschen des Knotens",
"remoteExitNodeQuestionRemove": "Sind Sie sicher, dass Sie den Knoten {selectedNode} aus der Organisation entfernen möchten?",
"remoteExitNodeQuestionRemove": "Sind Sie sicher, dass Sie den Knoten aus der Organisation entfernen möchten?",
"remoteExitNodeMessageRemove": "Einmal entfernt, wird der Knoten nicht mehr zugänglich sein.",
"remoteExitNodeMessageConfirm": "Um zu bestätigen, geben Sie bitte den Namen des Knotens unten ein.",
"remoteExitNodeConfirmDelete": "Löschknoten bestätigen",
"remoteExitNodeDelete": "Knoten löschen",
"sidebarRemoteExitNodes": "Entfernte Knoten",
"remoteExitNodeCreate": {
"title": "Knoten erstellen",
"description": "Erstellen Sie einen neuen Knoten, um Ihre Netzwerkverbindung zu erweitern",
"description": "Erstellen Sie einen neuen Knoten, um Ihr Netzwerk zu erweitern",
"viewAllButton": "Alle Knoten anzeigen",
"strategy": {
"title": "Erstellungsstrategie",
@@ -1679,7 +1731,7 @@
"idpAzureConfigurationDescription": "Konfigurieren Sie Ihre Azure Entra ID OAuth2 Zugangsdaten",
"idpTenantId": "Mandanten-ID",
"idpTenantIdPlaceholder": "deine Mandant-ID",
"idpAzureTenantIdDescription": "Ihre Azure Mieter-ID (gefunden in Azure Active Directory Übersicht)",
"idpAzureTenantIdDescription": "Ihre Azure Tenant-ID (gefunden in Azure Active Directory Übersicht)",
"idpAzureClientIdDescription": "Ihre Azure App Registration Client ID",
"idpAzureClientSecretDescription": "Ihr Azure App Registration Client Secret",
"idpGoogleTitle": "Google",
@@ -1698,7 +1750,7 @@
"authPage": "Auth Seite",
"authPageDescription": "Konfigurieren Sie die Auth-Seite für Ihre Organisation",
"authPageDomain": "Domain der Auth Seite",
"noDomainSet": "Keine Domäne gesetzt",
"noDomainSet": "Keine Domain gesetzt",
"changeDomain": "Domain ändern",
"selectDomain": "Domain auswählen",
"restartCertificate": "Zertifikat neu starten",
@@ -1714,7 +1766,7 @@
"domainPickerUnverified": "Nicht verifiziert",
"domainPickerInvalidSubdomainStructure": "Diese Subdomain enthält ungültige Zeichen oder Struktur. Sie wird beim Speichern automatisch bereinigt.",
"domainPickerError": "Fehler",
"domainPickerErrorLoadDomains": "Fehler beim Laden der Organisations-Domänen",
"domainPickerErrorLoadDomains": "Fehler beim Laden der Organisations-Domains",
"domainPickerErrorCheckAvailability": "Fehler beim Prüfen der Domain-Verfügbarkeit",
"domainPickerInvalidSubdomain": "Ungültige Subdomain",
"domainPickerInvalidSubdomainRemoved": "Die Eingabe \"{sub}\" wurde entfernt, weil sie nicht gültig ist.",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Datei bearbeiten: docker-compose.yml",
"emailVerificationRequired": "E-Mail-Verifizierung ist erforderlich. Bitte melden Sie sich erneut über {dashboardUrl}/auth/login an. Kommen Sie dann wieder hierher.",
"twoFactorSetupRequired": "Die Zwei-Faktor-Authentifizierung ist erforderlich. Bitte melden Sie sich erneut über {dashboardUrl}/auth/login an. Dann kommen Sie hierher zurück.",
"additionalSecurityRequired": "Zusätzliche Sicherheit erforderlich",
"organizationRequiresAdditionalSteps": "Diese Organisation erfordert zusätzliche Sicherheitsschritte, bevor Sie auf Ressourcen zugreifen können.",
"completeTheseSteps": "Schließe diese Schritte ab",
"enableTwoFactorAuthentication": "Zwei-Faktor-Authentifizierung aktivieren",
"completeSecuritySteps": "Schließe Sicherheitsschritte ab",
"securitySettings": "Sicherheitseinstellungen",
"securitySettingsDescription": "Konfigurieren Sie Sicherheitsrichtlinien für Ihre Organisation",
"requireTwoFactorForAllUsers": "Zwei-Faktor-Authentifizierung für alle Benutzer erforderlich",
"requireTwoFactorDescription": "Wenn aktiviert, müssen alle internen Benutzer in dieser Organisation die Zwei-Faktor-Authentifizierung aktiviert haben, um auf die Organisation zuzugreifen.",
"requireTwoFactorDisabledDescription": "Diese Funktion erfordert eine gültige Lizenz (Unternehmen) oder ein aktives Abonnement (SaaS)",
"requireTwoFactorCannotEnableDescription": "Sie müssen die Zwei-Faktor-Authentifizierung für Ihr Konto aktivieren, bevor Sie es für alle Benutzer erzwingen können",
"maxSessionLength": "Maximale Sitzungslänge",
"maxSessionLengthDescription": "Legen Sie die maximale Dauer für Benutzersitzungen fest. Nach dieser Zeit müssen Benutzer erneut authentifizieren.",
"maxSessionLengthDisabledDescription": "Diese Funktion erfordert eine gültige Lizenz (Unternehmen) oder ein aktives Abonnement (SaaS)",
"selectSessionLength": "Sitzungslänge auswählen",
"unenforced": "Unerzwungen",
"1Hour": "1 Stunde",
"3Hours": "3 Stunden",
"6Hours": "6 Stunden",
"12Hours": "12 Stunden",
"1DaySession": "1 Tag",
"3Days": "3 Tage",
"7Days": "7 Tage",
"14Days": "14 Tage",
"30DaysSession": "30 Tage",
"90DaysSession": "90 Tage",
"180DaysSession": "180 Tage",
"passwordExpiryDays": "Passwortablauf",
"editPasswordExpiryDescription": "Legen Sie die Anzahl der Tage fest, bevor Benutzer ihr Passwort ändern müssen.",
"selectPasswordExpiry": "Ablauf des Passworts auswählen",
"30Days": "30 Tage",
"1Day": "1 Tag",
"60Days": "60 Tage",
"90Days": "90 Tage",
"180Days": "180 Tage",
"1Year": "1 Jahr",
"subscriptionBadge": "Abonnement erforderlich",
"securityPolicyChangeWarning": "Sicherheitsrichtlinienänderungs-Warnung",
"securityPolicyChangeDescription": "Sie sind dabei, die Sicherheitseinstellungen zu ändern. Nach dem Speichern müssen Sie sich erneut authentifizieren, um diesen Richtlinien-Aktualisierungen nachzukommen. Alle Benutzer, die nicht konform sind, müssen sich ebenfalls neu authentifizieren.",
"securityPolicyChangeConfirmMessage": "Ich bestätige",
"securityPolicyChangeWarningText": "Dies betrifft alle Benutzer in der Organisation",
"authPageErrorUpdateMessage": "Beim Aktualisieren der Auth-Seiten-Einstellungen ist ein Fehler aufgetreten",
"authPageErrorUpdate": "Auth Seite kann nicht aktualisiert werden",
"authPageUpdated": "Auth-Seite erfolgreich aktualisiert",
"healthCheckNotAvailable": "Lokal",
"rewritePath": "Pfad neu schreiben",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Header-Authentifizierung erfolgreich entfernt.",
"resourceErrorHeaderAuthRemove": "Fehler beim Entfernen der Header-Authentifizierung",
"resourceErrorHeaderAuthRemoveDescription": "Die Headerauthentifizierung für die Ressource konnte nicht entfernt werden.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Header-Authentifizierung aktiviert",
"resourceHeaderAuthProtectionDisabled": "Header-Authentifizierung deaktiviert",
"headerAuthRemove": "Header-Auth entfernen",
"headerAuthAdd": "Header-Auth hinzufügen",
"resourceErrorHeaderAuthSetup": "Fehler beim Setzen der Header-Authentifizierung",
"resourceErrorHeaderAuthSetupDescription": "Konnte Header-Authentifizierung für die Ressource nicht festlegen.",
"resourceHeaderAuthSetup": "Header-Authentifizierung erfolgreich festgelegt",
"resourceHeaderAuthSetupDescription": "Header-Authentifizierung wurde erfolgreich festgelegt.",
"resourceHeaderAuthSetupTitle": "Header-Authentifizierung festlegen",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Legen Sie die grundlegenden Authentifizierungsdaten (Benutzername und Passwort) fest, um diese Ressource mit HTTP-Header-Authentifizierung zu schützen. Greifen Sie auf sie mit dem Format https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Header-Authentifizierung festlegen",
"actionSetResourceHeaderAuth": "Header-Authentifizierung festlegen",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"unlicensed": "Nicht lizenziert",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"manageClients": "Clients verwalten",
"manageClientsDescription": "Clients sind Geräte, die sich mit Ihren Websites verbinden können",
"licenseTableValidUntil": "Gültig bis",
"saasLicenseKeysSettingsTitle": "Enterprise-Lizenzen",
"saasLicenseKeysSettingsDescription": "Erstelle und verwalte Enterprise-Lizenzschlüssel für selbst gehostete Pangolin-Instanzen",
"sidebarEnterpriseLicenses": "Lizenzen",
"generateLicenseKey": "Lizenzschlüssel generieren",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
"useCaseTypeRequired": "Bitte wählen Sie einen Anwendungsfall",
"firstNameRequired": "Vorname ist erforderlich",
"lastNameRequired": "Nachname ist erforderlich",
"primaryUseRequired": "Bitte beschreiben Sie Ihre primäre Verwendung",
"jobTitleRequiredBusiness": "Job-Titel ist für die geschäftliche Nutzung erforderlich",
"industryRequiredBusiness": "Industrie ist für die geschäftliche Nutzung erforderlich",
"stateProvinceRegionRequired": "Bundesland/Provinz/Region ist erforderlich",
"postalZipCodeRequired": "Postleitzahl ist erforderlich",
"companyNameRequiredBusiness": "Firmenname ist erforderlich für den geschäftlichen Gebrauch",
"countryOfResidenceRequiredBusiness": "Land des Wohnsitzes ist für die geschäftliche Nutzung erforderlich",
"countryRequiredPersonal": "Land ist für den persönlichen Gebrauch erforderlich",
"agreeToTermsRequired": "Sie müssen den Bedingungen zustimmen",
"complianceConfirmationRequired": "Sie müssen die Einhaltung der Fossorial Commercial License bestätigen"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Persönliche Nutzung",
"description": "Für den individuellen, nicht-kommerziellen Gebrauch wie Lernen, persönliche Projekte oder Experimente."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Business-Nutzung",
"description": "Für den Einsatz innerhalb von Organisationen, Unternehmen oder kommerziellen oder einkommensfördernden Aktivitäten."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "E-Mail & Lizenztyp",
"description": "Geben Sie Ihre E-Mail ein und wählen Sie Ihren Lizenztyp"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Persönliche Informationen",
"description": "Erzählen Sie uns über sich selbst"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Kontaktinformationen",
"description": "Ihre Kontaktdaten"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Begriffe & Generieren",
"description": "Bedingungen überprüfen und akzeptieren, um Ihre Lizenz zu generieren"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Verwendungsanzeige",
"description": "Wählen Sie die Lizenz-Ebene, die Ihre beabsichtigte Nutzung genau widerspiegelt. Die Persönliche Lizenz erlaubt die freie Nutzung der Software für individuelle, nicht-kommerzielle oder kleine kommerzielle Aktivitäten mit jährlichen Brutto-Einnahmen von 100.000 USD. Über diese Grenzen hinausgehende Verwendungszwecke einschließlich der Verwendung innerhalb eines Unternehmens, einer Organisation, oder eine andere umsatzgenerierende Umgebung — erfordert eine gültige Enterprise-Lizenz und die Zahlung der Lizenzgebühr. Alle Benutzer, ob Personal oder Enterprise, müssen die Fossorial Commercial License Bedingungen einhalten."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Testperiode Information",
"description": "Dieser Lizenzschlüssel ermöglicht Enterprise-Funktionen für einen 7-tägigen Bewertungszeitraum. Der fortgesetzte Zugriff auf kostenpflichtige Funktionen über den Bewertungszeitraum hinaus erfordert die Aktivierung unter einer gültigen Personen- oder Enterprise-Lizenz. Für die Enterprise-Lizenzierung wenden Sie sich bitte an sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Benutzen Sie Pangolin für den persönlichen oder geschäftlichen Gebrauch?",
"firstName": "Vorname",
"lastName": "Nachname",
"jobTitle": "Job Titel",
"primaryUseQuestion": "Wofür planen Sie in erster Linie Pangolin zu benutzen?",
"industryQuestion": "Was ist Ihre Branche?",
"prospectiveUsersQuestion": "Wie viele Interessenten erwarten Sie?",
"prospectiveSitesQuestion": "Wie viele potentielle Standorte (Tunnel) erwarten Sie?",
"companyName": "Firmenname",
"countryOfResidence": "Land des Wohnsitzes",
"stateProvinceRegion": "Bundesland / Provinz / Region",
"postalZipCode": "Postleitzahl",
"companyWebsite": "Firmen-Webseite",
"companyPhoneNumber": "Firmennummer",
"country": "Land",
"phoneNumberOptional": "Telefonnummer (optional)",
"complianceConfirmation": "Ich bestätige, dass die von mir übermittelten Informationen korrekt sind und dass ich im Einklang mit der Fossorial Commercial License bin. Die Meldung ungenauer Informationen oder die falsche Identifizierung der Nutzung des Produkts stellt eine Verletzung der Lizenz dar und kann dazu führen, dass Ihr Schlüssel widerrufen wird."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Schließen",
"previous": "Vorherige",
"next": "Nächste",
"generateLicenseKey": "Lizenzschlüssel generieren"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Lizenzschlüssel erfolgreich erstellt",
"description": "Ihr Lizenzschlüssel wurde generiert und kann verwendet werden."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Fehler beim Generieren des Lizenzschlüssels",
"description": "Beim Generieren des Lizenzschlüssels ist ein Fehler aufgetreten."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Instanzname",
"pathMatchModalTitle": "Pfad anpassen konfigurieren",
"pathMatchModalDescription": "Legen Sie fest, wie eingehende Anfragen basierend auf ihrem Pfad übereinstimmen sollen.",
"pathMatchType": "Übereinstimmungstyp",
"pathMatchPrefix": "Präfix",
"pathMatchExact": "Exakt",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Pfadwert",
"clear": "Leeren",
"saveChanges": "Änderungen speichern",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathMatchDefaultPlaceholder": "/Pfad",
"pathMatchPrefixHelp": "Beispiel: /api trifft /api, /api/users etc.",
"pathMatchExactHelp": "Beispiel: /api passt nur auf /api",
"pathMatchRegexHelp": "Beispiel: ^/api/.* entspricht /api/anything",
"pathRewriteModalTitle": "Pfad Rewriting konfigurieren",
"pathRewriteModalDescription": "Transformieren Sie den übereinstimmenden Pfad bevor Sie zum Ziel weiterleiten.",
"pathRewriteType": "Rewrite Typ",
"pathRewritePrefixOption": "Präfix - Präfix ersetzen",
"pathRewriteExactOption": "Exakt - Gesamten Pfad ersetzen",
"pathRewriteRegexOption": "Regex - Musterersetzung",
"pathRewriteStripPrefixOption": "Präfix entfernen - Präfix entfernen",
"pathRewriteValue": "Wert umschreiben",
"pathRewriteRegexPlaceholder": "/neu/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewritePrefixHelp": "Ersetze das passende Präfix mit diesem Wert",
"pathRewriteExactHelp": "Ersetze den gesamten Pfad mit diesem Wert, wenn der Pfad genau zutrifft",
"pathRewriteRegexHelp": "Capture-Gruppen wie $1, $2 zum Ersetzen verwenden",
"pathRewriteStripPrefixHelp": "Leer lassen, um Präfix zu entfernen oder neues Präfix anzugeben",
"pathRewritePrefix": "Präfix",
"pathRewriteExact": "Exakt",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Entfernen",
"pathRewriteStripLabel": "entfernen",
"sidebarEnableEnterpriseLicense": "Enterprise-Lizenz aktivieren",
"cannotbeUndone": "Dies kann nicht rückgängig gemacht werden.",
"toConfirm": "bestätigen",
"deleteClientQuestion": "Sind Sie sicher, dass Sie den Client von der Website und der Organisation entfernen möchten?",
"clientMessageRemove": "Nach dem Entfernen kann sich der Client nicht mehr mit der Website verbinden.",
"sidebarLogs": "Logs",
"request": "Anfrage",
"logs": "Logs",
"logsSettingsDescription": "Aus dieser Orginisierung gesammelte Logs überwachen",
"searchLogs": "Logs suchen...",
"action": "Aktion",
"actor": "Akteur",
"timestamp": "Zeitstempel",
"accessLogs": "Zugriffsprotokolle",
"exportCsv": "CSV exportieren",
"actorId": "Akteur-ID",
"allowedByRule": "Erlaubt durch Regel",
"allowedNoAuth": "Keine Auth erlaubt",
"validAccessToken": "Gültiges Zugriffstoken",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Gültiges Passwort",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Ressource blockiert",
"droppedByRule": "Abgelegt durch Regel",
"noSessions": "Keine Sitzungen",
"temporaryRequestToken": "Temporäres Anfrage-Token",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP",
"reason": "Grund",
"requestLogs": "Logs anfordern",
"host": "Host",
"location": "Standort",
"actionLogs": "Aktionsprotokolle",
"sidebarLogsRequest": "Logs anfordern",
"sidebarLogsAccess": "Zugriffsprotokolle",
"sidebarLogsAction": "Aktionsprotokolle",
"logRetention": "Log-Speicherung",
"logRetentionDescription": "Verwalten, wie lange verschiedene Logs für diese Organisation gespeichert werden oder deaktivieren",
"requestLogsDescription": "Detaillierte Request-Logs für Ressourcen in dieser Organisation anzeigen",
"logRetentionRequestLabel": "Log-Speicherung anfordern",
"logRetentionRequestDescription": "Wie lange sollen Request-Logs gespeichert werden",
"logRetentionAccessLabel": "Zugriffsprotokoll-Speicherung",
"logRetentionAccessDescription": "Wie lange Zugriffsprotokolle beibehalten werden sollen",
"logRetentionActionLabel": "Aktionsprotokoll-Speicherung",
"logRetentionActionDescription": "Dauer des Action-Logs",
"logRetentionDisabled": "Deaktiviert",
"logRetention3Days": "3 Tage",
"logRetention7Days": "7 Tage",
"logRetention14Days": "14 Tage",
"logRetention30Days": "30 Tage",
"logRetention90Days": "90 Tage",
"logRetentionForever": "Für immer",
"actionLogsDescription": "Verlauf der in dieser Organisation durchgeführten Aktionen anzeigen",
"accessLogsDescription": "Zugriffsauth-Anfragen für Ressourcen in dieser Organisation anzeigen",
"licenseRequiredToUse": "Um diese Funktion nutzen zu können, ist eine Enterprise-Lizenz erforderlich.",
"certResolver": "Zertifikatsauflöser",
"certResolverDescription": "Wählen Sie den Zertifikatslöser aus, der für diese Ressource verwendet werden soll.",
"selectCertResolver": "Zertifikatsauflöser auswählen",
"enterCustomResolver": "Eigenen Auflöser eingeben",
"preferWildcardCert": "Wildcard-Zertifikat bevorzugen",
"unverified": "Nicht verifiziert",
"domainSetting": "Domänen-Einstellungen",
"domainSettingDescription": "Einstellungen für Ihre Domain konfigurieren",
"preferWildcardCertDescription": "Versuch ein Platzhalterzertifikat zu generieren (erfordert einen richtig konfigurierten Zertifikatslöser).",
"recordName": "Name des Datensatzes",
"auto": "Auto",
"TTL": "TTL",
"howToAddRecords": "So kann man Datensätze hinzufügen",
"dnsRecord": "DNS-Einträge",
"required": "Benötigt",
"domainSettingsUpdated": "Domain-Einstellungen erfolgreich aktualisiert",
"orgOrDomainIdMissing": "Organisation oder Domänen-ID fehlt",
"loadingDNSRecords": "Lade DNS-Einträge...",
"olmUpdateAvailableInfo": "Eine aktualisierte Version von Olm ist verfügbar. Bitte aktualisieren Sie auf die neueste Version für die beste Erfahrung.",
"client": "Client",
"proxyProtocol": "Proxy-Protokoll-Einstellungen",
"proxyProtocolDescription": "Konfigurieren Sie das Proxy-Protokoll, um die IP-Adressen des Clients für TCP/UDP-Dienste zu erhalten.",
"enableProxyProtocol": "Proxy-Protokoll aktivieren",
"proxyProtocolInfo": "Client-IP-Adressen für TCP/UDP Backends beibehalten",
"proxyProtocolVersion": "Proxy-Protokollversion",
"version1": " Version 1 (empfohlen)",
"version2": "Version 2",
"versionDescription": "Die Version 1 ist textbasiert und unterstützt die Version 2, ist binär und effizienter, aber weniger kompatibel.",
"warning": "Warnung",
"proxyProtocolWarning": "Ihre Backend-Anwendung muss so konfiguriert sein, dass sie Proxy-Protokoll-Verbindungen akzeptiert. Wenn Ihr Backend das Proxy-Protokoll nicht unterstützt, wird die Aktivierung dieser Option alle Verbindungen zerstören. Stellen Sie sicher, dass Sie Ihr Backend so konfigurieren, dass es Proxy-Protokoll-Header von Traefik vertraut.",
"restarting": "Neustarten...",
"manual": "Manuell",
"messageSupport": "Nachrichtenunterstützung",
"supportNotAvailableTitle": "Support nicht verfügbar",
"supportNotAvailableDescription": "Support ist momentan nicht verfügbar. Sie können eine E-Mail an support@pangolin.net senden.",
"supportRequestSentTitle": "Supportanfrage gesendet",
"supportRequestSentDescription": "Ihre Nachricht wurde erfolgreich gesendet.",
"supportRequestFailedTitle": "Senden der Anfrage fehlgeschlagen",
"supportRequestFailedDescription": "Beim Senden Ihrer Supportanfrage ist ein Fehler aufgetreten.",
"supportSubjectRequired": "Betreff ist erforderlich",
"supportSubjectMaxLength": "Betreff muss mindestens 255 Zeichen lang sein",
"supportMessageRequired": "Nachricht ist erforderlich",
"supportReplyTo": "Antwort an",
"supportSubject": "Betreff",
"supportSubjectPlaceholder": "Betreff eingeben",
"supportMessage": "Nachricht",
"supportMessagePlaceholder": "Geben Sie Ihre Nachricht ein",
"supportSending": "Senden...",
"supportSend": "Senden",
"supportMessageSent": "Nachricht gesendet!",
"supportWillContact": "Wir werden in Kürze kontaktieren!",
"selectLogRetention": "Log-Speicherung auswählen",
"showColumns": "Spalten anzeigen",
"hideColumns": "Spalten ausblenden",
"columnVisibility": "Spaltensichtbarkeit",
"toggleColumn": "{columnName} Spalte umschalten",
"allColumns": "Alle Spalten",
"defaultColumns": "Standardspalten",
"customizeView": "Ansicht anpassen",
"viewOptions": "Optionen anzeigen",
"selectAll": "Alle auswählen",
"selectNone": "Nichts auswählen",
"selectedResources": "Ausgewählte Ressourcen",
"enableSelected": "Ausgewählte aktivieren",
"disableSelected": "Ausgewählte deaktivieren",
"credentials": "Zugangsdaten",
"savecredentials": "Zugangsdaten speichern",
"regeneratecredentials": "Re-Key",
"regenerateCredentials": "Regenerieren und speichern Sie Ihre Zugangsdaten",
"generatedcredentials": "Generierte Zugangsdaten",
"copyandsavethesecredentials": "Diese Zugangsdaten kopieren und speichern",
"copyandsavethesecredentialsdescription": "Diese Zugangsdaten werden nach dem Verlassen dieser Seite nicht mehr angezeigt. Speichern Sie sie jetzt sicher.",
"credentialsSaved": "Zugangsdaten gespeichert",
"credentialsSavedDescription": "Zugangsdaten wurden neu erstellt und erfolgreich gespeichert.",
"credentialsSaveError": "Fehler beim Speichern der Zugangsdaten",
"credentialsSaveErrorDescription": "Beim Erneuern und Speichern der Zugangsdaten ist ein Fehler aufgetreten.",
"regenerateCredentialsWarning": "Das Regenerieren von Zugangsdaten wird die vorhergehenden ungültig machen. Bitte aktualisieren die Konfigurationen, welche diese Zugangsdaten verwenden.",
"confirm": "Bestätigen",
"regenerateCredentialsConfirmation": "Sind Sie sicher, dass Sie die Zugangsdaten neu generieren möchten?",
"endpoint": "Endpunkt",
"Id": "ID",
"SecretKey": "Geheimer Schlüssel",
"featureDisabledTooltip": "Diese Funktion ist nur im Enterprise-Plan verfügbar und erfordert eine Lizenz, um sie zu nutzen.",
"niceId": "Schöne ID",
"niceIdUpdated": "Schöne ID aktualisiert",
"niceIdUpdatedSuccessfully": "Nice ID erfolgreich aktualisiert",
"niceIdUpdateError": "Fehler beim Aktualisieren der Nizza-ID",
"niceIdUpdateErrorDescription": "Beim Aktualisieren der Nizza-ID ist ein Fehler aufgetreten.",
"niceIdCannotBeEmpty": "Nizza-ID darf nicht leer sein",
"enterIdentifier": "Identifikator eingeben",
"identifier": "Identifier",
"checkSelectedStatus": "Status der Auswahl überprüfen"
}

File diff suppressed because it is too large Load Diff

View File

@@ -47,9 +47,8 @@
"edit": "Editar",
"siteConfirmDelete": "Confirmar Borrar Sitio",
"siteDelete": "Eliminar sitio",
"siteMessageRemove": "Una vez eliminado, el sitio ya no será accesible. Todos los recursos y objetivos asociados con el sitio también serán eliminados.",
"siteMessageConfirm": "Para confirmar, por favor escriba el nombre del sitio a continuación.",
"siteQuestionRemove": "¿Está seguro de que desea eliminar el sitio {selectedSite} de la organización?",
"siteMessageRemove": "Una vez eliminado, el sitio ya no será accesible. Todos los objetivos asociados con el sitio también serán eliminados.",
"siteQuestionRemove": "¿Está seguro que desea eliminar el sitio de la organización?",
"siteManageSites": "Administrar Sitios",
"siteDescription": "Permitir conectividad a tu red a través de túneles seguros",
"siteCreate": "Crear sitio",
@@ -96,7 +95,7 @@
"siteWgDescription": "Utilice cualquier cliente Wirex Guard para establecer un túnel. Se requiere una configuración manual de NAT.",
"siteWgDescriptionSaas": "Utilice cualquier cliente de WireGuard para establecer un túnel. Se requiere configuración manual de NAT. SOLO FUNCIONA EN NODOS AUTOGESTIONADOS",
"siteLocalDescription": "Solo recursos locales. Sin túneles.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Solo recursos locales. No hay túneles. Sólo disponible en nodos remotos.",
"siteSeeAll": "Ver todos los sitios",
"siteTunnelDescription": "Determina cómo quieres conectarte a tu sitio",
"siteNewtCredentials": "Credenciales nuevas",
@@ -132,7 +131,7 @@
"expireIn": "Caduca en",
"neverExpire": "Nunca expirar",
"shareExpireDescription": "El tiempo de caducidad es cuánto tiempo el enlace será utilizable y proporcionará acceso al recurso. Después de este tiempo, el enlace ya no funcionará, y los usuarios que usaron este enlace perderán el acceso al recurso.",
"shareSeeOnce": "Sólo podrá ver este enlace una vez. Asegúrese de copiarlo.",
"shareSeeOnce": "Sólo podrás ver este enlace una vez. Asegúrate de copiarlo.",
"shareAccessHint": "Cualquiera con este enlace puede acceder al recurso. Compártelo con cuidado.",
"shareTokenUsage": "Ver Uso de Token de Acceso",
"createLink": "Crear enlace",
@@ -154,8 +153,7 @@
"protected": "Protegido",
"notProtected": "No protegido",
"resourceMessageRemove": "Una vez eliminado, el recurso ya no será accesible. Todos los objetivos asociados con el recurso también serán eliminados.",
"resourceMessageConfirm": "Para confirmar, por favor escriba el nombre del recurso a continuación.",
"resourceQuestionRemove": "¿Está seguro de que desea eliminar el recurso {selectedResource} de la organización?",
"resourceQuestionRemove": "¿Está seguro que desea eliminar el recurso de la organización?",
"resourceHTTP": "HTTPS Recurso",
"resourceHTTPDescription": "Solicitudes de proxy a tu aplicación sobre HTTPS usando un subdominio o dominio base.",
"resourceRaw": "Recurso TCP/UDP sin procesar",
@@ -181,7 +179,7 @@
"baseDomain": "Dominio base",
"subdomnainDescription": "El subdominio al que su recurso será accesible.",
"resourceRawSettings": "Configuración TCP/UDP",
"resourceRawSettingsDescription": "Configurar cómo se accederá a su recurso a través de TCP/UDP",
"resourceRawSettingsDescription": "Configure cómo se accederá a su recurso a través de TCP/UDP. Mapeas el recurso a un puerto en el servidor Pangolin host, así puedes acceder al recurso desde el servidor-public-ip:mapped-port.",
"protocol": "Protocolo",
"protocolSelect": "Seleccionar un protocolo",
"resourcePortNumber": "Número de puerto",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Confirmar eliminación de organización",
"orgMessageRemove": "Esta acción es irreversible y eliminará todos los datos asociados.",
"orgMessageConfirm": "Para confirmar, por favor escriba el nombre de la organización a continuación.",
"orgQuestionRemove": "¿Está seguro que desea eliminar la organización {selectedOrg}?",
"orgQuestionRemove": "¿Está seguro que desea eliminar la organización?",
"orgUpdated": "Organización actualizada",
"orgUpdatedDescription": "La organización ha sido actualizada.",
"orgErrorUpdate": "Error al actualizar la organización",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Generar clave API",
"apiKeysErrorDelete": "Error al eliminar la clave API",
"apiKeysErrorDeleteMessage": "Error al eliminar la clave API",
"apiKeysQuestionRemove": "¿Está seguro de que desea eliminar la clave de API {selectedApiKey} de la organización?",
"apiKeysQuestionRemove": "¿Está seguro que desea eliminar la clave API de la organización?",
"apiKeysMessageRemove": "Una vez eliminada, la clave API ya no podrá ser utilizada.",
"apiKeysMessageConfirm": "Para confirmar, por favor escriba el nombre de la clave API a continuación.",
"apiKeysDeleteConfirm": "Confirmar Borrar Clave API",
"apiKeysDelete": "Borrar Clave API",
"apiKeysManage": "Administrar claves API",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Confirmar Borrar Usuario",
"userDeleteServer": "Eliminar usuario del servidor",
"userMessageRemove": "El usuario será eliminado de todas las organizaciones y será eliminado completamente del servidor.",
"userMessageConfirm": "Para confirmar, por favor escriba el nombre del usuario a continuación.",
"userQuestionRemove": "¿Está seguro que desea eliminar permanentemente {selectedUser} del servidor?",
"userQuestionRemove": "¿Está seguro que desea eliminar permanentemente al usuario del servidor?",
"licenseKey": "Clave de licencia",
"valid": "Válido",
"numberOfSites": "Número de sitios",
@@ -339,7 +335,7 @@
"fossorialLicense": "Ver Términos de suscripción y licencia comercial",
"licenseMessageRemove": "Esto eliminará la clave de licencia y todos los permisos asociados otorgados por ella.",
"licenseMessageConfirm": "Para confirmar, por favor escriba la clave de licencia a continuación.",
"licenseQuestionRemove": "¿Está seguro que desea eliminar la clave de licencia {selectedKey}?",
"licenseQuestionRemove": "¿Está seguro que desea eliminar la clave de licencia?",
"licenseKeyDelete": "Eliminar clave de licencia",
"licenseKeyDeleteConfirm": "Confirmar eliminar clave de licencia",
"licenseTitle": "Administrar estado de licencia",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Ocurrió un error mientras se eliminaba la invitación.",
"inviteRemoved": "Invitación eliminada",
"inviteRemovedDescription": "La invitación para {email} ha sido eliminada.",
"inviteQuestionRemove": "¿Está seguro de que desea eliminar la invitación {email}?",
"inviteQuestionRemove": "¿Está seguro de que desea eliminar la invitación?",
"inviteMessageRemove": "Una vez eliminada, esta invitación ya no será válida. Siempre puede volver a invitar al usuario más tarde.",
"inviteMessageConfirm": "Para confirmar, por favor escriba la dirección de correo electrónico de la invitación a continuación.",
"inviteQuestionRegenerate": "¿Estás seguro de que quieres regenerar la invitación para {email}? Esto revocará la invitación anterior.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Ocurrió un error mientras se eliminaba el usuario.",
"userOrgRemoved": "Usuario eliminado",
"userOrgRemovedDescription": "El usuario {email} ha sido eliminado de la organización.",
"userQuestionOrgRemove": "¿Estás seguro de que quieres eliminar {email} de la organización?",
"userQuestionOrgRemove": "¿Está seguro que desea eliminar este usuario de la organización?",
"userMessageOrgRemove": "Una vez eliminado, este usuario ya no tendrá acceso a la organización. Siempre puede volver a invitarlos más tarde, pero tendrán que aceptar la invitación de nuevo.",
"userMessageOrgConfirm": "Para confirmar, por favor escriba el nombre del usuario a continuación.",
"userRemoveOrgConfirm": "Confirmar eliminar usuario",
"userRemoveOrg": "Eliminar usuario de la organización",
"users": "Usuarios",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Admin Servidor - Pangolin",
"licenseTierProfessional": "Licencia profesional",
"licenseTierEnterprise": "Licencia Enterprise",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Licencia personal",
"licensed": "Licenciado",
"yes": "Sí",
"no": "Nu",
@@ -742,7 +737,7 @@
"idpManageDescription": "Ver y administrar proveedores de identidad en el sistema",
"idpDeletedDescription": "Proveedor de identidad eliminado correctamente",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "¿Está seguro que desea eliminar permanentemente el proveedor de identidad {name}?",
"idpQuestionRemove": "¿Está seguro que desea eliminar permanentemente el proveedor de identidad?",
"idpMessageRemove": "Esto eliminará el proveedor de identidad y todas las configuraciones asociadas. Los usuarios que se autentifiquen a través de este proveedor ya no podrán iniciar sesión.",
"idpMessageConfirm": "Para confirmar, por favor escriba el nombre del proveedor de identidad a continuación.",
"idpConfirmDelete": "Confirmar eliminar proveedor de identidad",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Revisa tu correo electrónico para ver el código de restablecimiento.",
"passwordNew": "Nueva contraseña",
"passwordNewConfirm": "Confirmar nueva contraseña",
"changePassword": "Cambiar Contraseña",
"changePasswordDescription": "Actualizar la contraseña de tu cuenta",
"oldPassword": "Contraseña Actual",
"newPassword": "Nueva Contraseña",
"confirmNewPassword": "Confirme Nueva Contraseña",
"changePasswordError": "Error al cambiar la contraseña",
"changePasswordErrorDescription": "Se ha producido un error al cambiar la contraseña",
"changePasswordSuccess": "La contraseña ha sido cambiada correctamente",
"changePasswordSuccessDescription": "Su contraseña ha sido actualizada correctamente",
"passwordExpiryRequired": "Contraseña con caducidad requerida",
"passwordExpiryDescription": "Esta organización requiere que cambies tu contraseña cada {maxDays} días.",
"changePasswordNow": "Cambiar Contraseña Ahora",
"pincodeAuth": "Código de autenticación",
"pincodeSubmit2": "Enviar código",
"passwordResetSubmit": "Reiniciar Solicitud",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Todos los usuarios",
"sidebarIdentityProviders": "Proveedores de identidad",
"sidebarLicense": "Licencia",
"sidebarClients": "Clients",
"sidebarClients": "Clientes",
"sidebarDomains": "Dominios",
"sidebarBluePrints": "Planos",
"blueprints": "Planos",
"blueprintsDescription": "Aplicar configuraciones declarativas y ver ejecuciones anteriores",
"blueprintAdd": "Añadir plano",
"blueprintGoBack": "Ver todos los Planos",
"blueprintCreate": "Crear Plano",
"blueprintCreateDescription2": "Siga los siguientes pasos para crear y aplicar un nuevo plano",
"blueprintDetails": "Detalles del plano",
"blueprintDetailsDescription": "Ver el resultado del plano aplicado y cualquier error que haya ocurrido",
"blueprintInfo": "Información del plano",
"message": "Mensaje",
"blueprintContentsDescription": "Defina el contenido YAML describiendo su infraestructura",
"blueprintErrorCreateDescription": "Se ha producido un error al aplicar el plano",
"blueprintErrorCreate": "Error al crear el plano",
"searchBlueprintProgress": "Buscar planos...",
"appliedAt": "Aplicado en",
"source": "Fuente",
"contents": "Contenido",
"parsedContents": "Contenido analizado (Sólo lectura)",
"enableDockerSocket": "Habilitar Plano Docker",
"enableDockerSocketDescription": "Activar el raspado de etiquetas de Socket Docker para etiquetas de planos. La ruta del Socket debe proporcionarse a Newt.",
"enableDockerSocketLink": "Saber más",
@@ -1211,9 +1237,8 @@
"domainCreate": "Crear dominio",
"domainCreatedDescription": "Dominio creado con éxito",
"domainDeletedDescription": "Dominio eliminado exitosamente",
"domainQuestionRemove": "¿Está seguro de que desea eliminar el dominio {domain} de su cuenta?",
"domainQuestionRemove": "¿Está seguro que desea eliminar el dominio de su cuenta?",
"domainMessageRemove": "Una vez eliminado, el dominio ya no estará asociado con su cuenta.",
"domainMessageConfirm": "Para confirmar, por favor escriba el nombre del dominio abajo.",
"domainConfirmDelete": "Confirmar eliminación del dominio",
"domainDelete": "Eliminar dominio",
"domain": "Dominio",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Ocurrió un error al actualizar ajustes",
"sidebarCollapse": "Colapsar",
"sidebarExpand": "Expandir",
"productUpdateMoreInfo": "{noOfUpdates} actualizaciones más",
"productUpdateInfo": "{noOfUpdates} actualizaciones",
"productUpdateWhatsNew": "Novedades",
"productUpdateTitle": "Actualizaciones de producto",
"productUpdateEmpty": "Sin actualizaciones",
"dismissAll": "Descartar todo",
"pangolinUpdateAvailable": "Nueva versión disponible",
"pangolinUpdateAvailableInfo": "La versión {version} está lista para instalar",
"pangolinUpdateAvailableReleaseNotes": "Ver notas del lanzamiento",
"newtUpdateAvailable": "Nueva actualización disponible",
"newtUpdateAvailableInfo": "Hay una nueva versión de Newt disponible. Actualice a la última versión para la mejor experiencia.",
"domainPickerEnterDomain": "Dominio",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Nivel Gratis",
"billingWarningOverLimit": "Advertencia: Has excedido uno o más límites de uso. Tus sitios no se conectarán hasta que modifiques tu suscripción o ajustes tu 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@fossorial.io.",
"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",
"billingOnlineTime": "Tiempo en línea del sitio",
"billingUsers": "Usuarios activos",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Hubo un problema al usar tu llave de seguridad. Por favor, inténtalo de nuevo.",
"twoFactorRequired": "Se requiere autenticación de dos factores para registrar una llave de seguridad.",
"twoFactor": "Autenticación de dos factores",
"twoFactorAuthentication": "Autenticación de Dos Factores",
"twoFactorDescription": "Esta organización requiere autenticación de dos factores.",
"enableTwoFactor": "Habilitar autenticación de dos factores",
"organizationSecurityPolicy": "Política de Seguridad de la Organización",
"organizationSecurityPolicyDescription": "Esta organización tiene requisitos de seguridad que deben cumplirse antes de poder acceder a ella",
"securityRequirements": "Requisitos de seguridad",
"allRequirementsMet": "Todos los requisitos han sido cumplidos",
"completeRequirementsToContinue": "Completa los siguientes requisitos para seguir accediendo a esta organización",
"youCanNowAccessOrganization": "Ahora puedes acceder a esta organización",
"reauthenticationRequired": "Longitud de la sesión",
"reauthenticationDescription": "Esta organización requiere que inicies sesión cada {maxDays} días.",
"reauthenticationDescriptionHours": "Esta organización requiere que inicies sesión cada {maxHours} horas.",
"reauthenticateNow": "Iniciar sesión de nuevo",
"adminEnabled2FaOnYourAccount": "Su administrador ha habilitado la autenticación de dos factores para {email}. Por favor, complete el proceso de configuración para continuar.",
"securityKeyAdd": "Agregar llave de seguridad",
"securityKeyRegisterTitle": "Registrar nueva llave de seguridad",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Estos recursos son para uso con",
"resourcesTableClients": "Clientes",
"resourcesTableAndOnlyAccessibleInternally": "y solo son accesibles internamente cuando se conectan con un cliente.",
"resourcesTableNoTargets": "Sin objetivos",
"resourcesTableHealthy": "Saludable",
"resourcesTableDegraded": "Degrado",
"resourcesTableOffline": "Desconectado",
"resourcesTableUnknown": "Desconocido",
"resourcesTableNotMonitored": "No supervisado",
"editInternalResourceDialogEditClientResource": "Editar recurso del cliente",
"editInternalResourceDialogUpdateResourceProperties": "Actualizar las propiedades del recurso y la configuración del objetivo para {resourceName}.",
"editInternalResourceDialogResourceProperties": "Propiedades del recurso",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "No se recibió URL de redirección del proveedor de identidad.",
"autoLoginErrorGeneratingUrl": "Error al generar URL de autenticación.",
"remoteExitNodeManageRemoteExitNodes": "Nodos remotos",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Autoalojar uno o más nodos remotos para extender la conectividad de red y reducir la dependencia de la nube",
"remoteExitNodes": "Nodos",
"searchRemoteExitNodes": "Buscar nodos...",
"remoteExitNodeAdd": "Añadir Nodo",
"remoteExitNodeErrorDelete": "Error al eliminar el nodo",
"remoteExitNodeQuestionRemove": "¿Está seguro de que desea eliminar el nodo {selectedNode} de la organización?",
"remoteExitNodeQuestionRemove": "¿Está seguro que desea eliminar el nodo de la organización?",
"remoteExitNodeMessageRemove": "Una vez eliminado, el nodo ya no será accesible.",
"remoteExitNodeMessageConfirm": "Para confirmar, por favor escriba el nombre del nodo a continuación.",
"remoteExitNodeConfirmDelete": "Confirmar eliminar nodo",
"remoteExitNodeDelete": "Eliminar Nodo",
"sidebarRemoteExitNodes": "Nodos remotos",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Editar archivo: docker-compose.yml",
"emailVerificationRequired": "Se requiere verificación de correo electrónico. Por favor, inicie sesión de nuevo a través de {dashboardUrl}/auth/login complete este paso. Luego, vuelva aquí.",
"twoFactorSetupRequired": "La configuración de autenticación de doble factor es requerida. Por favor, inicia sesión de nuevo a través de {dashboardUrl}/auth/login completa este paso. Luego, vuelve aquí.",
"additionalSecurityRequired": "Seguridad adicional requerida",
"organizationRequiresAdditionalSteps": "Esta organización requiere pasos de seguridad adicionales antes de poder acceder a los recursos.",
"completeTheseSteps": "Completa estos pasos",
"enableTwoFactorAuthentication": "Habilitar autenticación de doble factor",
"completeSecuritySteps": "Pasos de seguridad completos",
"securitySettings": "Ajustes de seguridad",
"securitySettingsDescription": "Configurar políticas de seguridad para su organización",
"requireTwoFactorForAllUsers": "Requiere autenticación de doble factor para todos los usuarios",
"requireTwoFactorDescription": "Cuando está activado, todos los usuarios internos de esta organización deben tener habilitada la autenticación de dos factores para acceder a la organización.",
"requireTwoFactorDisabledDescription": "Esta característica requiere una licencia válida (Enterprise) o una suscripción activa (SaBudget)",
"requireTwoFactorCannotEnableDescription": "Debes habilitar la autenticación de doble factor para tu cuenta antes de aplicarla a todos los usuarios",
"maxSessionLength": "Longitud máxima de la sesión",
"maxSessionLengthDescription": "Establecer la duración máxima de las sesiones de usuario. Después de este tiempo, los usuarios tendrán que volver a autenticarse.",
"maxSessionLengthDisabledDescription": "Esta característica requiere una licencia válida (Enterprise) o una suscripción activa (SaBudget)",
"selectSessionLength": "Seleccionar duración de sesión",
"unenforced": "No aplicado",
"1Hour": "1 hora",
"3Hours": "3 horas",
"6Hours": "6 horas",
"12Hours": "12 horas",
"1DaySession": "1 día",
"3Days": "3 días",
"7Days": "7 días",
"14Days": "14 días",
"30DaysSession": "30 días",
"90DaysSession": "90 días",
"180DaysSession": "180 días",
"passwordExpiryDays": "Caduca la contraseña",
"editPasswordExpiryDescription": "Establecer el número de días antes de que los usuarios tengan que cambiar su contraseña.",
"selectPasswordExpiry": "Seleccione la contraseña expirada",
"30Days": "30 días",
"1Day": "1 día",
"60Days": "60 días",
"90Days": "90 días",
"180Days": "180 días",
"1Year": "1 año",
"subscriptionBadge": "Suscripción requerida",
"securityPolicyChangeWarning": "Advertencia de cambio de política de seguridad",
"securityPolicyChangeDescription": "Está a punto de cambiar la configuración de la política de seguridad. Después de guardar, puede que necesite volver a autenticarse para cumplir con estas actualizaciones de política. Todos los usuarios que no cumplan con los requisitos también tendrán que volver a autenticarse.",
"securityPolicyChangeConfirmMessage": "Confirmo",
"securityPolicyChangeWarningText": "Esto afectará a todos los usuarios de la organización",
"authPageErrorUpdateMessage": "Ocurrió un error mientras se actualizaban los ajustes de la página auth",
"authPageErrorUpdate": "No se puede actualizar la página de autenticación",
"authPageUpdated": "Página auth actualizada correctamente",
"healthCheckNotAvailable": "Local",
"rewritePath": "Reescribir Ruta",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Autenticación de cabecera eliminada correctamente.",
"resourceErrorHeaderAuthRemove": "Error al eliminar autenticación de cabecera",
"resourceErrorHeaderAuthRemoveDescription": "No se pudo eliminar la autenticación de cabecera del recurso.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Autenticación de cabecera habilitada",
"resourceHeaderAuthProtectionDisabled": "Autenticación de cabecera desactivada",
"headerAuthRemove": "Eliminar Auth del Encabezado",
"headerAuthAdd": "Añadir autenticación de cabecera",
"resourceErrorHeaderAuthSetup": "Error al establecer autenticación de cabecera",
"resourceErrorHeaderAuthSetupDescription": "No se pudo establecer autenticación de cabecera para el recurso.",
"resourceHeaderAuthSetup": "Autenticación de cabecera establecida correctamente",
"resourceHeaderAuthSetupDescription": "La autenticación de cabecera se ha establecido correctamente.",
"resourceHeaderAuthSetupTitle": "Establecer autenticación de cabecera",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Establezca las credenciales básicas de autenticación (nombre de usuario y contraseña) para proteger este recurso con autenticación de HTTP Header. Acceda a él usando el formato https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Establecer autenticación de cabecera",
"actionSetResourceHeaderAuth": "Establecer autenticación de cabecera",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"enterpriseEdition": "Edición corporativa",
"unlicensed": "Sin licencia",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"manageClients": "Administrar clientes",
"manageClientsDescription": "Los clientes son dispositivos que pueden conectarse a sus sitios",
"licenseTableValidUntil": "Válido hasta",
"saasLicenseKeysSettingsTitle": "Licencias empresariales",
"saasLicenseKeysSettingsDescription": "Generar y administrar claves de licencia Enterprise para instancias Pangolin autoalojadas",
"sidebarEnterpriseLicenses": "Licencias",
"generateLicenseKey": "Generar clave de licencia",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Por favor, introduzca una dirección de correo válida",
"useCaseTypeRequired": "Por favor, seleccione un tipo de caso de uso",
"firstNameRequired": "El nombre es obligatorio",
"lastNameRequired": "Se requiere apellido",
"primaryUseRequired": "Por favor describa su uso principal",
"jobTitleRequiredBusiness": "El título de la tarea es obligatorio para uso empresarial",
"industryRequiredBusiness": "La industria es necesaria para uso comercial",
"stateProvinceRegionRequired": "Se requiere estado/Province/región",
"postalZipCodeRequired": "Código Postal/ZIP es requerido",
"companyNameRequiredBusiness": "El nombre de la empresa es obligatorio para uso comercial",
"countryOfResidenceRequiredBusiness": "El país de residencia es obligatorio para uso de negocios",
"countryRequiredPersonal": "El país es obligatorio para uso personal",
"agreeToTermsRequired": "Debe aceptar los términos",
"complianceConfirmationRequired": "Debe confirmar el cumplimiento de la Licencia Comercial Fossorial"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Uso personal",
"description": "Para uso individual y no comercial, tales como aprendizaje, proyectos personales o experimentación."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Uso de Negocio",
"description": "Para uso dentro de organizaciones, empresas o actividades comerciales o generadoras de ingresos."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "Email y tipo de licencia",
"description": "Introduzca su correo electrónico y elija su tipo de licencia"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Información Personal",
"description": "Cuéntanos acerca de ti"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Información de contacto",
"description": "Sus datos de contacto"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Términos y Generar",
"description": "Revisar y aceptar términos para generar su licencia"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Divulgación de uso",
"description": "Seleccione el nivel de licencia que refleje con precisión su uso previsto. La Licencia Personal permite el uso libre del Software para actividades comerciales individuales, no comerciales o de pequeña escala con ingresos brutos anuales inferiores a $100,000 USD. Cualquier uso más allá de estos límites — incluyendo el uso dentro de una empresa, organización, u otro entorno de generación de ingresos — requiere una Licencia Empresarial válida y el pago de la cuota de licencia aplicable. Todos los usuarios, ya sean personales o empresariales, deben cumplir con las Condiciones de Licencia Comercial Fossorial."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Información del período de prueba",
"description": "Esta Clave de Licencia permite las funciones de la Empresa durante un período de evaluación de 7 días. El acceso continuado a las características de pago más allá del período de evaluación requiere una activación bajo una Licencia Personal o Empresarial válida. Para licencias de la Empresa, póngase en contacto con sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "¿Estás usando Pangolin para uso personal o de negocios?",
"firstName": "Nombre",
"lastName": "Apellido",
"jobTitle": "Trabajo",
"primaryUseQuestion": "¿Para qué planeas usar principalmente Pangolin?",
"industryQuestion": "¿Cuál es su industria?",
"prospectiveUsersQuestion": "¿Cuántos usuarios potenciales esperas tener?",
"prospectiveSitesQuestion": "¿Cuántos sitios potenciales (túneles) esperas tener?",
"companyName": "Nombre de la empresa",
"countryOfResidence": "País de residencia",
"stateProvinceRegion": "Estado / Province / Región",
"postalZipCode": "Código postal",
"companyWebsite": "Sitio web de la empresa",
"companyPhoneNumber": "Número de teléfono de la empresa",
"country": "País",
"phoneNumberOptional": "Número de teléfono (opcional)",
"complianceConfirmation": "Confirmo que la información que he proporcionado es exacta y que estoy en conformidad con la Licencia Comercial Fossorial. Informar de información inexacta o identificar mal el uso del producto es una violación de la licencia y puede resultar en que su clave sea revocada."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Cerrar",
"previous": "Anterior",
"next": "Siguiente",
"generateLicenseKey": "Generar clave de licencia"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Clave de licencia generada con éxito",
"description": "Su clave de licencia ha sido generada y está lista para usar."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Error al generar la clave de licencia",
"description": "Se ha producido un error al generar la clave de licencia."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Nombre de instancia",
"pathMatchModalTitle": "Configurar ruta coincidente",
"pathMatchModalDescription": "Configurar cómo deben coincidir las peticiones entrantes en función de su ruta.",
"pathMatchType": "Tipo de partida",
"pathMatchPrefix": "Prefijo",
"pathMatchExact": "Exacto",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Valor de ruta",
"clear": "Claro",
"saveChanges": "Guardar Cambios",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathMatchDefaultPlaceholder": "/ruta",
"pathMatchPrefixHelp": "Ejemplo: /api coincide con /api, /api/users, etc.",
"pathMatchExactHelp": "Ejemplo: /api coincide sólo con /api",
"pathMatchRegexHelp": "Ejemplo: ^/api/.* coincide con /api/anything",
"pathRewriteModalTitle": "Configurar ruta de reescritura",
"pathRewriteModalDescription": "Transforma la ruta coincidente antes de reenviarla al objetivo.",
"pathRewriteType": "Tipo de reescritura",
"pathRewritePrefixOption": "Prefijo - Reemplazar prefijo",
"pathRewriteExactOption": "Exacto - Reemplazar toda la ruta",
"pathRewriteRegexOption": "Regex - Reemplazo de patrón",
"pathRewriteStripPrefixOption": "Prefijo de clip - Quitar prefijo",
"pathRewriteValue": "Reescribir valor",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewritePrefixHelp": "Reemplazar el prefijo coincidente con este valor",
"pathRewriteExactHelp": "Reemplaza toda la ruta con este valor cuando la ruta coincida exactamente",
"pathRewriteRegexHelp": "Usar grupos de captura como $1, $2 para reemplazar",
"pathRewriteStripPrefixHelp": "Dejar en blanco para el prefijo strip o proporcionar un nuevo prefijo",
"pathRewritePrefix": "Prefijo",
"pathRewriteExact": "Exacto",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Clip",
"pathRewriteStripLabel": "clip",
"sidebarEnableEnterpriseLicense": "Activar licencia corporativa",
"cannotbeUndone": "Esto no se puede deshacer.",
"toConfirm": "confirmar",
"deleteClientQuestion": "¿Está seguro que desea eliminar el cliente del sitio y la organización?",
"clientMessageRemove": "Una vez eliminado, el cliente ya no podrá conectarse al sitio.",
"sidebarLogs": "Registros",
"request": "Solicitud",
"logs": "Registros",
"logsSettingsDescription": "Monitorear registros recogidos de esta orginización",
"searchLogs": "Buscar registros...",
"action": "Accin",
"actor": "Actor",
"timestamp": "Timestamp",
"accessLogs": "Registros de acceso",
"exportCsv": "Exportar CSV",
"actorId": "ID de Actor",
"allowedByRule": "Permitido por regla",
"allowedNoAuth": "No se permite autorización",
"validAccessToken": "Token de Acceso Válido",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Contraseña válida",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Recurso bloqueado",
"droppedByRule": "Soltado por regla",
"noSessions": "No hay sesiones",
"temporaryRequestToken": "Token de solicitud temporal",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP",
"reason": "Razón",
"requestLogs": "Registros de Solicitud",
"host": "Anfitrión",
"location": "Ubicación",
"actionLogs": "Registros de acción",
"sidebarLogsRequest": "Registros de Solicitud",
"sidebarLogsAccess": "Registros de acceso",
"sidebarLogsAction": "Registros de acción",
"logRetention": "Retención de Log",
"logRetentionDescription": "Administrar cuánto tiempo se conservan los diferentes tipos de registros para esta organización o desactivarlos",
"requestLogsDescription": "Ver registros de solicitudes detallados para los recursos de esta organización",
"logRetentionRequestLabel": "Retención de Registro de Solicitud",
"logRetentionRequestDescription": "Cuánto tiempo conservar los registros de solicitudes",
"logRetentionAccessLabel": "Retención de Log de Acceso",
"logRetentionAccessDescription": "Cuánto tiempo retener los registros de acceso",
"logRetentionActionLabel": "Retención de registro de acción",
"logRetentionActionDescription": "Cuánto tiempo retener los registros de acción",
"logRetentionDisabled": "Deshabilitado",
"logRetention3Days": "3 días",
"logRetention7Days": "7 días",
"logRetention14Days": "14 días",
"logRetention30Days": "30 días",
"logRetention90Days": "90 días",
"logRetentionForever": "Para siempre",
"actionLogsDescription": "Ver un historial de acciones realizadas en 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.",
"certResolver": "Resolver certificado",
"certResolverDescription": "Seleccione la resolución de certificados a utilizar para este recurso.",
"selectCertResolver": "Seleccionar Resolver Certificado",
"enterCustomResolver": "Introducir resolución personalizada",
"preferWildcardCert": "Certificado de comodín preferido",
"unverified": "Sin verificar",
"domainSetting": "Ajustes de dominio",
"domainSettingDescription": "Configurar ajustes para tu dominio",
"preferWildcardCertDescription": "Intento de generar un certificado comodín (requiere una resolución de certificados correctamente configurada).",
"recordName": "Nombre del registro",
"auto": "Auto",
"TTL": "TTL",
"howToAddRecords": "Cómo añadir registros",
"dnsRecord": "Registros DNS",
"required": "Requerido",
"domainSettingsUpdated": "Configuración de dominio actualizada correctamente",
"orgOrDomainIdMissing": "Falta el ID de organización o dominio",
"loadingDNSRecords": "Cargando registros DNS...",
"olmUpdateAvailableInfo": "Una versión actualizada de Olm está disponible. Por favor, actualice a la última versión para obtener la mejor experiencia.",
"client": "Cliente",
"proxyProtocol": "Configuración del Protocolo Proxy",
"proxyProtocolDescription": "Configurar el protocolo de proxy para preservar las direcciones IP del cliente para los servicios TCP/UDP.",
"enableProxyProtocol": "Habilitar protocolo proxy",
"proxyProtocolInfo": "Conservar direcciones IP del cliente para backends TCP/UDP",
"proxyProtocolVersion": "Versión del Protocolo Proxy",
"version1": " Versión 1 (Recomendado)",
"version2": "Versión 2",
"versionDescription": "La versión 1 está basada en texto y es ampliamente soportada. La versión 2 es binaria y más eficiente pero menos compatible.",
"warning": "Advertencia",
"proxyProtocolWarning": "Su aplicación de backend debe estar configurada para aceptar conexiones Proxy Protocol. Si su backend no soporta Proxy Protocol, habilitando esto romperá todas las conexiones. Asegúrese de configurar su backend para que confíe en las cabeceras del protocolo Proxy de Traefik.",
"restarting": "Reiniciando...",
"manual": "Manual",
"messageSupport": "Soporte de mensajes",
"supportNotAvailableTitle": "Soporte no disponible",
"supportNotAvailableDescription": "El soporte no está disponible en este momento. Puedes enviar un correo electrónico a support@pangolin.net.",
"supportRequestSentTitle": "Solicitud de soporte enviada",
"supportRequestSentDescription": "Su mensaje ha sido enviado con éxito.",
"supportRequestFailedTitle": "Error al enviar la solicitud",
"supportRequestFailedDescription": "Se ha producido un error al enviar su solicitud de soporte.",
"supportSubjectRequired": "El asunto es obligatorio",
"supportSubjectMaxLength": "El asunto debe tener 255 caracteres o menos",
"supportMessageRequired": "El mensaje es obligatorio",
"supportReplyTo": "Responder a",
"supportSubject": "Asunto",
"supportSubjectPlaceholder": "Introducir asunto",
"supportMessage": "Mensaje",
"supportMessagePlaceholder": "Introduce tu mensaje",
"supportSending": "Enviando...",
"supportSend": "Enviar",
"supportMessageSent": "¡Mensaje enviado!",
"supportWillContact": "¡Estaremos en contacto en breve!",
"selectLogRetention": "Seleccionar retención de registro",
"showColumns": "Mostrar columnas",
"hideColumns": "Ocultar columnas",
"columnVisibility": "Visibilidad de la columna",
"toggleColumn": "Cambiar columna {columnName}",
"allColumns": "Todas las columnas",
"defaultColumns": "Columnas por defecto",
"customizeView": "Personalizar vista",
"viewOptions": "Ver opciones",
"selectAll": "Seleccionar todo",
"selectNone": "No seleccionar",
"selectedResources": "Recursos seleccionados",
"enableSelected": "Habilitar seleccionados",
"disableSelected": "Desactivar Seleccionado",
"checkSelectedStatus": "Comprobar el estado de selección",
"credentials": "Credenciales",
"savecredentials": "Guardar credenciales",
"regeneratecredentials": "Re-clave",
"regenerateCredentials": "Regenerar y guardar tus credenciales",
"generatedcredentials": "Credenciales generadas",
"copyandsavethesecredentials": "Copiar y guardar estas credenciales",
"copyandsavethesecredentialsdescription": "Estas credenciales no se mostrarán de nuevo después de salir de esta página. Guárdelas de forma segura ahora.",
"credentialsSaved": "Credenciales guardadas",
"credentialsSavedDescription": "Las credenciales se han regenerado y guardado correctamente.",
"credentialsSaveError": "Error al guardar las credenciales",
"credentialsSaveErrorDescription": "Se ha producido un error al regenerar y guardar las credenciales.",
"regenerateCredentialsWarning": "Regenerar las credenciales invalidará las anteriores. Asegúrese de actualizar cualquier configuración que use estas credenciales.",
"confirm": "Confirmar",
"regenerateCredentialsConfirmation": "¿Está seguro que desea regenerar las credenciales?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Clave secreta",
"featureDisabledTooltip": "Esta característica sólo está disponible en el plan empresarial y requiere una licencia para usarla.",
"niceId": "ID bonita",
"niceIdUpdated": "Bonito ID actualizado",
"niceIdUpdatedSuccessfully": "Bonito ID actualizado correctamente",
"niceIdUpdateError": "Error al actualizar Nice ID",
"niceIdUpdateErrorDescription": "Se ha producido un error al actualizar el ID de Niza.",
"niceIdCannotBeEmpty": "El ID de Niza no puede estar vacío",
"enterIdentifier": "Introducir identificador",
"identifier": "Identifier"
}

File diff suppressed because it is too large Load Diff

View File

@@ -47,9 +47,8 @@
"edit": "Modifica",
"siteConfirmDelete": "Conferma Eliminazione Sito",
"siteDelete": "Elimina Sito",
"siteMessageRemove": "Una volta rimosso, il sito non sarà più accessibile. Anche tutte le risorse e gli obiettivi associati al sito saranno rimossi.",
"siteMessageConfirm": "Per confermare, digita il nome del sito qui sotto.",
"siteQuestionRemove": "Sei sicuro di voler rimuovere il sito {selectedSite} dall'organizzazione?",
"siteMessageRemove": "Una volta rimosso il sito non sarà più accessibile. Tutti gli obiettivi associati al sito verranno rimossi.",
"siteQuestionRemove": "Sei sicuro di voler rimuovere il sito dall'organizzazione?",
"siteManageSites": "Gestisci Siti",
"siteDescription": "Consenti la connettività alla rete attraverso tunnel sicuri",
"siteCreate": "Crea Sito",
@@ -96,7 +95,7 @@
"siteWgDescription": "Usa qualsiasi client WireGuard per stabilire un tunnel. Impostazione NAT manuale richiesta.",
"siteWgDescriptionSaas": "Usa qualsiasi client WireGuard per stabilire un tunnel. Impostazione NAT manuale richiesta. FUNZIONA SOLO SU NODI AUTO-OSPITATI",
"siteLocalDescription": "Solo risorse locali. Nessun tunneling.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Solo risorse locali. Nessun tunneling. Disponibile solo su nodi remoti.",
"siteSeeAll": "Vedi Tutti I Siti",
"siteTunnelDescription": "Determina come vuoi connetterti al tuo sito",
"siteNewtCredentials": "Credenziali Newt",
@@ -132,7 +131,7 @@
"expireIn": "Scadenza In",
"neverExpire": "Mai scadere",
"shareExpireDescription": "Il tempo di scadenza è per quanto tempo il link sarà utilizzabile e fornirà accesso alla risorsa. Dopo questo tempo, il link non funzionerà più e gli utenti che hanno utilizzato questo link perderanno l'accesso alla risorsa.",
"shareSeeOnce": "Potrai vedere solo questo linkonce. Assicurati di copiarlo.",
"shareSeeOnce": "Potrai vedere questo link solo una volta. Assicurati di copiarlo.",
"shareAccessHint": "Chiunque abbia questo link può accedere alla risorsa. Condividilo con cura.",
"shareTokenUsage": "Vedi Utilizzo Token Di Accesso",
"createLink": "Crea Collegamento",
@@ -154,8 +153,7 @@
"protected": "Protetto",
"notProtected": "Non Protetto",
"resourceMessageRemove": "Una volta rimossa, la risorsa non sarà più accessibile. Tutti gli obiettivi associati alla risorsa saranno rimossi.",
"resourceMessageConfirm": "Per confermare, digita il nome della risorsa qui sotto.",
"resourceQuestionRemove": "Sei sicuro di voler rimuovere la risorsa {selectedResource} dall'organizzazione?",
"resourceQuestionRemove": "Sei sicuro di voler rimuovere la risorsa dall'organizzazione?",
"resourceHTTP": "Risorsa HTTPS",
"resourceHTTPDescription": "Richieste proxy alla tua app tramite HTTPS utilizzando un sottodominio o un dominio di base.",
"resourceRaw": "Risorsa Raw TCP/UDP",
@@ -181,7 +179,7 @@
"baseDomain": "Dominio Base",
"subdomnainDescription": "Il sottodominio in cui la tua risorsa sarà accessibile.",
"resourceRawSettings": "Impostazioni TCP/UDP",
"resourceRawSettingsDescription": "Configura come accedere alla tua risorsa tramite TCP/UDP",
"resourceRawSettingsDescription": "Configura come sarà possibile accedere alla tua risorsa tramite TCP/UDP. Mappare la risorsa a una porta sul server host Pangolin, in modo da poter accedere alla risorsa dal server-public ip:mapped-port.",
"protocol": "Protocollo",
"protocolSelect": "Seleziona un protocollo",
"resourcePortNumber": "Numero Porta",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Conferma Elimina Organizzazione",
"orgMessageRemove": "Questa azione è irreversibile e cancellerà tutti i dati associati.",
"orgMessageConfirm": "Per confermare, digita il nome dell'organizzazione qui sotto.",
"orgQuestionRemove": "Sei sicuro di voler rimuovere l'organizzazione {selectedOrg}?",
"orgQuestionRemove": "Sei sicuro di voler rimuovere l'organizzazione?",
"orgUpdated": "Organizzazione aggiornata",
"orgUpdatedDescription": "L'organizzazione è stata aggiornata.",
"orgErrorUpdate": "Impossibile aggiornare l'organizzazione",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Genera Chiave API",
"apiKeysErrorDelete": "Errore nell'eliminazione della chiave API",
"apiKeysErrorDeleteMessage": "Errore nell'eliminazione della chiave API",
"apiKeysQuestionRemove": "Sei sicuro di voler rimuovere la chiave API {selectedApiKey} dall'organizzazione?",
"apiKeysQuestionRemove": "Sei sicuro di voler rimuovere la chiave API dall'organizzazione?",
"apiKeysMessageRemove": "Una volta rimossa, la chiave API non potrà più essere utilizzata.",
"apiKeysMessageConfirm": "Per confermare, digita il nome della chiave API qui sotto.",
"apiKeysDeleteConfirm": "Conferma Eliminazione Chiave API",
"apiKeysDelete": "Elimina Chiave API",
"apiKeysManage": "Gestisci Chiavi API",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Conferma Eliminazione Utente",
"userDeleteServer": "Elimina utente dal server",
"userMessageRemove": "L'utente verrà rimosso da tutte le organizzazioni ed essere completamente rimosso dal server.",
"userMessageConfirm": "Per confermare, digita il nome dell'utente qui sotto.",
"userQuestionRemove": "Sei sicuro di voler eliminare definitivamente {selectedUser} dal server?",
"userQuestionRemove": "Sei sicuro di voler eliminare definitivamente l'utente dal server?",
"licenseKey": "Chiave Di Licenza",
"valid": "Valido",
"numberOfSites": "Numero di siti",
@@ -339,7 +335,7 @@
"fossorialLicense": "Visualizza I Termini Di Licenza Commerciale Fossorial E Abbonamento",
"licenseMessageRemove": "Questo rimuoverà la chiave di licenza e tutti i permessi associati da essa concessi.",
"licenseMessageConfirm": "Per confermare, digitare la chiave di licenza qui sotto.",
"licenseQuestionRemove": "Sei sicuro di voler eliminare la chiave di licenza {selectedKey}?",
"licenseQuestionRemove": "Sei sicuro di voler eliminare la chiave di licenza?",
"licenseKeyDelete": "Elimina Chiave Di Licenza",
"licenseKeyDeleteConfirm": "Conferma Elimina Chiave Di Licenza",
"licenseTitle": "Gestisci Stato Licenza",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Si è verificato un errore durante la rimozione dell'invito.",
"inviteRemoved": "Invito rimosso",
"inviteRemovedDescription": "L'invito per {email} è stato rimosso.",
"inviteQuestionRemove": "Sei sicuro di voler rimuovere l'invito {email}?",
"inviteQuestionRemove": "Sei sicuro di voler rimuovere l'invito?",
"inviteMessageRemove": "Una volta rimosso, questo invito non sarà più valido. Puoi sempre reinvitare l'utente in seguito.",
"inviteMessageConfirm": "Per confermare, digita l'indirizzo email dell'invito qui sotto.",
"inviteQuestionRegenerate": "Sei sicuro di voler rigenerare l'invito {email}? Questo revocherà l'invito precedente.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Si è verificato un errore durante la rimozione dell'utente.",
"userOrgRemoved": "Utente rimosso",
"userOrgRemovedDescription": "L'utente {email} è stato rimosso dall'organizzazione.",
"userQuestionOrgRemove": "Sei sicuro di voler rimuovere {email} dall'organizzazione?",
"userQuestionOrgRemove": "Sei sicuro di voler rimuovere questo utente dall'organizzazione?",
"userMessageOrgRemove": "Una volta rimosso, questo utente non avrà più accesso all'organizzazione. Puoi sempre reinvitarlo in seguito, ma dovrà accettare nuovamente l'invito.",
"userMessageOrgConfirm": "Per confermare, digita il nome dell'utente qui sotto.",
"userRemoveOrgConfirm": "Conferma Rimozione Utente",
"userRemoveOrg": "Rimuovi Utente dall'Organizzazione",
"users": "Utenti",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Server Admin - Pangolina",
"licenseTierProfessional": "Licenza Professional",
"licenseTierEnterprise": "Licenza Enterprise",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Licenza Personale",
"licensed": "Con Licenza",
"yes": "Sì",
"no": "No",
@@ -742,7 +737,7 @@
"idpManageDescription": "Visualizza e gestisci i provider di identità nel sistema",
"idpDeletedDescription": "Provider di identità eliminato con successo",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Sei sicuro di voler eliminare definitivamente il provider di identità {name}?",
"idpQuestionRemove": "Sei sicuro di voler eliminare definitivamente il provider di identità?",
"idpMessageRemove": "Questo rimuoverà il provider di identità e tutte le configurazioni associate. Gli utenti che si autenticano tramite questo provider non potranno più accedere.",
"idpMessageConfirm": "Per confermare, digita il nome del provider di identità qui sotto.",
"idpConfirmDelete": "Conferma Eliminazione Provider di Identità",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Controlla la tua email per il codice di reset.",
"passwordNew": "Nuova Password",
"passwordNewConfirm": "Conferma Nuova Password",
"changePassword": "Cambia Password",
"changePasswordDescription": "Aggiorna la password del tuo account",
"oldPassword": "Password Attuale",
"newPassword": "Nuova Password",
"confirmNewPassword": "Conferma Nuova Password",
"changePasswordError": "Impossibile cambiare la password",
"changePasswordErrorDescription": "Si è verificato un errore durante la modifica della password",
"changePasswordSuccess": "Password Cambiata Con Successo",
"changePasswordSuccessDescription": "La password è stata aggiornata con successo",
"passwordExpiryRequired": "Scadenza Password Richiesta",
"passwordExpiryDescription": "Questa organizzazione richiede di cambiare la password ogni {maxDays} giorni.",
"changePasswordNow": "Cambia Password Ora",
"pincodeAuth": "Codice Autenticatore",
"pincodeSubmit2": "Invia Codice",
"passwordResetSubmit": "Richiedi Reset",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Tutti Gli Utenti",
"sidebarIdentityProviders": "Fornitori Di Identità",
"sidebarLicense": "Licenza",
"sidebarClients": "Clients",
"sidebarClients": "Client",
"sidebarDomains": "Domini",
"sidebarBluePrints": "Progetti",
"blueprints": "Progetti",
"blueprintsDescription": "Applica le configurazioni dichiarative e visualizza le partite precedenti",
"blueprintAdd": "Aggiungi Progetto",
"blueprintGoBack": "Vedi tutti i progetti",
"blueprintCreate": "Crea Progetto",
"blueprintCreateDescription2": "Segui i passaggi qui sotto per creare e applicare un nuovo progetto",
"blueprintDetails": "Dettagli Progetto",
"blueprintDetailsDescription": "Vedere il risultato del progetto applicato e gli eventuali errori verificatisi",
"blueprintInfo": "Informazioni Sul Progetto",
"message": "Messaggio",
"blueprintContentsDescription": "Definisci il contenuto di YAML che descrive la tua infrastruttura",
"blueprintErrorCreateDescription": "Si è verificato un errore durante l'applicazione del progetto",
"blueprintErrorCreate": "Errore nella creazione del progetto",
"searchBlueprintProgress": "Cerca progetti...",
"appliedAt": "Applicato Il",
"source": "Fonte",
"contents": "Contenuti",
"parsedContents": "Sommario Analizzato (Solo Lettura)",
"enableDockerSocket": "Abilita Progetto Docker",
"enableDockerSocketDescription": "Abilita la raschiatura dell'etichetta Docker Socket per le etichette dei progetti. Il percorso del socket deve essere fornito a Newt.",
"enableDockerSocketLink": "Scopri di più",
@@ -1211,9 +1237,8 @@
"domainCreate": "Crea Dominio",
"domainCreatedDescription": "Dominio creato con successo",
"domainDeletedDescription": "Dominio eliminato con successo",
"domainQuestionRemove": "Sei sicuro di voler rimuovere il dominio {domain} dal tuo account?",
"domainQuestionRemove": "Sei sicuro di voler rimuovere il dominio dal tuo account?",
"domainMessageRemove": "Una volta rimosso, il dominio non sarà più associato al tuo account.",
"domainMessageConfirm": "Per confermare, digita il nome del dominio qui sotto.",
"domainConfirmDelete": "Conferma Eliminazione Dominio",
"domainDelete": "Elimina Dominio",
"domain": "Dominio",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Si è verificato un errore durante l'aggiornamento delle impostazioni",
"sidebarCollapse": "Comprimi",
"sidebarExpand": "Espandi",
"productUpdateMoreInfo": "{noOfUpdates} altri aggiornamenti",
"productUpdateInfo": "{noOfUpdates} aggiornamenti",
"productUpdateWhatsNew": "Novità",
"productUpdateTitle": "Aggiornamenti Prodotto",
"productUpdateEmpty": "Nessun aggiornamento",
"dismissAll": "Ignora tutto",
"pangolinUpdateAvailable": "Nuova versione disponibile",
"pangolinUpdateAvailableInfo": "La versione {version} è pronta per l'installazione",
"pangolinUpdateAvailableReleaseNotes": "Visualizza note di rilascio",
"newtUpdateAvailable": "Aggiornamento Disponibile",
"newtUpdateAvailableInfo": "È disponibile una nuova versione di Newt. Si prega di aggiornare all'ultima versione per la migliore esperienza.",
"domainPickerEnterDomain": "Dominio",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Piano Gratuito",
"billingWarningOverLimit": "Avviso: Hai superato uno o più limiti di utilizzo. I tuoi siti non si connetteranno finché non modifichi il tuo abbonamento o non adegui il tuo 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@fossorial.io.",
"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",
"billingOnlineTime": "Tempo Online del Sito",
"billingUsers": "Utenti Attivi",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Si è verificato un problema con la tua chiave di sicurezza. Riprova.",
"twoFactorRequired": "È richiesta l'autenticazione a due fattori per registrare una chiave di sicurezza.",
"twoFactor": "Autenticazione a Due Fattori",
"twoFactorAuthentication": "Autenticazione A Due Fattori",
"twoFactorDescription": "Questa organizzazione richiede l'autenticazione a due fattori.",
"enableTwoFactor": "Abilita Autenticazione A Due Fattori",
"organizationSecurityPolicy": "Politica Di Sicurezza Dell'Organizzazione",
"organizationSecurityPolicyDescription": "Questa organizzazione ha requisiti di sicurezza che devono essere soddisfatti prima di poter accedere",
"securityRequirements": "Requisiti Di Sicurezza",
"allRequirementsMet": "Tutti i requisiti sono stati soddisfatti",
"completeRequirementsToContinue": "Completa i requisiti qui sotto per continuare ad accedere a questa organizzazione",
"youCanNowAccessOrganization": "Ora puoi accedere a questa organizzazione",
"reauthenticationRequired": "Durata Sessione",
"reauthenticationDescription": "Questa organizzazione richiede di accedere ogni {maxDays} giorni.",
"reauthenticationDescriptionHours": "Questa organizzazione richiede di accedere ogni {maxHours} ore.",
"reauthenticateNow": "Accedi Di Nuovo",
"adminEnabled2FaOnYourAccount": "Il tuo amministratore ha abilitato l'autenticazione a due fattori per {email}. Completa il processo di configurazione per continuare.",
"securityKeyAdd": "Aggiungi Chiave di Sicurezza",
"securityKeyRegisterTitle": "Registra Nuova Chiave di Sicurezza",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Queste risorse sono per uso con",
"resourcesTableClients": "Client",
"resourcesTableAndOnlyAccessibleInternally": "e sono accessibili solo internamente quando connessi con un client.",
"resourcesTableNoTargets": "Nessun obiettivo",
"resourcesTableHealthy": "Sano",
"resourcesTableDegraded": "Degraded",
"resourcesTableOffline": "Offline",
"resourcesTableUnknown": "Sconosciuto",
"resourcesTableNotMonitored": "Non monitorato",
"editInternalResourceDialogEditClientResource": "Modifica Risorsa Client",
"editInternalResourceDialogUpdateResourceProperties": "Aggiorna le proprietà della risorsa e la configurazione del target per {resourceName}.",
"editInternalResourceDialogResourceProperties": "Proprietà della Risorsa",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Nessun URL di reindirizzamento ricevuto dal provider di identità.",
"autoLoginErrorGeneratingUrl": "Impossibile generare l'URL di autenticazione.",
"remoteExitNodeManageRemoteExitNodes": "Nodi Remoti",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Self-host uno o più nodi remoti per estendere la connettività di rete e ridurre la dipendenza dal cloud",
"remoteExitNodes": "Nodi",
"searchRemoteExitNodes": "Cerca nodi...",
"remoteExitNodeAdd": "Aggiungi Nodo",
"remoteExitNodeErrorDelete": "Errore nell'eliminare il nodo",
"remoteExitNodeQuestionRemove": "Sei sicuro di voler rimuovere il nodo {selectedNode} dall'organizzazione?",
"remoteExitNodeQuestionRemove": "Sei sicuro di voler rimuovere il nodo dall'organizzazione?",
"remoteExitNodeMessageRemove": "Una volta rimosso, il nodo non sarà più accessibile.",
"remoteExitNodeMessageConfirm": "Per confermare, digita il nome del nodo qui sotto.",
"remoteExitNodeConfirmDelete": "Conferma Eliminazione Nodo",
"remoteExitNodeDelete": "Elimina Nodo",
"sidebarRemoteExitNodes": "Nodi Remoti",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Modifica file: docker-compose.yml",
"emailVerificationRequired": "Verifica via email. Effettua nuovamente il login via {dashboardUrl}/auth/login completa questo passaggio. Quindi, torna qui.",
"twoFactorSetupRequired": "È richiesta la configurazione di autenticazione a due fattori. Effettua nuovamente l'accesso tramite {dashboardUrl}/auth/login completa questo passaggio. Quindi, torna qui.",
"additionalSecurityRequired": "Necessaria Sicurezza Aggiuntiva",
"organizationRequiresAdditionalSteps": "Questa organizzazione richiede ulteriori passi di sicurezza prima di poter accedere alle risorse.",
"completeTheseSteps": "Completa questi passaggi",
"enableTwoFactorAuthentication": "Abilita autenticazione a due fattori",
"completeSecuritySteps": "Passi Di Sicurezza Completa",
"securitySettings": "Impostazioni Di Sicurezza",
"securitySettingsDescription": "Configura i criteri di sicurezza per la tua organizzazione",
"requireTwoFactorForAllUsers": "Richiede l'autenticazione a due fattori per tutti gli utenti",
"requireTwoFactorDescription": "Se abilitata, tutti gli utenti interni di questa organizzazione devono avere un'autenticazione a due fattori abilitata per accedere all'organizzazione.",
"requireTwoFactorDisabledDescription": "Questa funzione richiede una licenza valida (Enterprise) o un abbonamento attivo (SaaS)",
"requireTwoFactorCannotEnableDescription": "Devi abilitare l'autenticazione a due fattori per il tuo account prima di applicarla per tutti gli utenti",
"maxSessionLength": "Lunghezza Massima Della Sessione",
"maxSessionLengthDescription": "Imposta la durata massima per le sessioni utente. Dopo questo periodo, gli utenti dovranno autenticarsi.",
"maxSessionLengthDisabledDescription": "Questa funzione richiede una licenza valida (Enterprise) o un abbonamento attivo (SaaS)",
"selectSessionLength": "Seleziona lunghezza sessione",
"unenforced": "Non Applicato",
"1Hour": "1 ora",
"3Hours": "3 ore",
"6Hours": "6 ore",
"12Hours": "12 ore",
"1DaySession": "1 giorno",
"3Days": "3 giorni",
"7Days": "7 giorni",
"14Days": "14 giorni",
"30DaysSession": "30 giorni",
"90DaysSession": "90 giorni",
"180DaysSession": "180 giorni",
"passwordExpiryDays": "Scadenza Password",
"editPasswordExpiryDescription": "Imposta il numero di giorni prima che gli utenti debbano cambiare la password.",
"selectPasswordExpiry": "Seleziona scadenza password",
"30Days": "30 giorni",
"1Day": "1 giorno",
"60Days": "60 giorni",
"90Days": "90 giorni",
"180Days": "180 giorni",
"1Year": "1 anno",
"subscriptionBadge": "Abbonamento Richiesto",
"securityPolicyChangeWarning": "Avviso Modifica Politica Di Sicurezza",
"securityPolicyChangeDescription": "Si sta per modificare le impostazioni dei criteri di sicurezza. Dopo il salvataggio, potrebbe essere necessario autenticarsi nuovamente per conformarsi a questi aggiornamenti dei criteri. Tutti gli utenti che non sono conformi dovranno anche autenticarsi.",
"securityPolicyChangeConfirmMessage": "Confermo",
"securityPolicyChangeWarningText": "Questo influenzerà tutti gli utenti dell'organizzazione",
"authPageErrorUpdateMessage": "Si è verificato un errore durante l'aggiornamento delle impostazioni della pagina di autenticazione",
"authPageErrorUpdate": "Impossibile aggiornare la pagina di autenticazione",
"authPageUpdated": "Pagina di autenticazione aggiornata con successo",
"healthCheckNotAvailable": "Locale",
"rewritePath": "Riscrivi percorso",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Autenticazione intestazione rimossa con successo.",
"resourceErrorHeaderAuthRemove": "Impossibile rimuovere l'autenticazione dell'intestazione",
"resourceErrorHeaderAuthRemoveDescription": "Impossibile rimuovere l'autenticazione dell'intestazione per la risorsa.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Autenticazione Intestazione Abilitata",
"resourceHeaderAuthProtectionDisabled": "Autenticazione Intestazione Disabilitata",
"headerAuthRemove": "Rimuovi Autenticazione Intestazione",
"headerAuthAdd": "Aggiungi Autenticazione Intestazione",
"resourceErrorHeaderAuthSetup": "Impossibile impostare l'autenticazione dell'intestazione",
"resourceErrorHeaderAuthSetupDescription": "Impossibile impostare l'autenticazione dell'intestazione per la risorsa.",
"resourceHeaderAuthSetup": "Autenticazione intestazione impostata con successo",
"resourceHeaderAuthSetupDescription": "L'autenticazione dell'intestazione è stata impostata correttamente.",
"resourceHeaderAuthSetupTitle": "Imposta Autenticazione Intestazione",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Imposta le credenziali di autenticazione di base (nome utente e password) per proteggere questa risorsa con Autenticazione intestazione HTTP. Accedi usando il formato https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Imposta Autenticazione Intestazione",
"actionSetResourceHeaderAuth": "Imposta Autenticazione Intestazione",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"unlicensed": "Senza Licenza",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"manageClients": "Gestisci Clienti",
"manageClientsDescription": "I client sono dispositivi che possono connettersi ai tuoi siti",
"licenseTableValidUntil": "Valido Fino A",
"saasLicenseKeysSettingsTitle": "Licenze Enterprise",
"saasLicenseKeysSettingsDescription": "Genera e gestisci le chiavi di licenza Enterprise per le istanze di Pangolin self-hosted",
"sidebarEnterpriseLicenses": "Licenze",
"generateLicenseKey": "Genera Chiave Di Licenza",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Inserisci un indirizzo email valido",
"useCaseTypeRequired": "Si prega di selezionare un tipo di caso di utilizzo",
"firstNameRequired": "Il nome è obbligatorio",
"lastNameRequired": "Il cognome è obbligatorio",
"primaryUseRequired": "Descrivi il tuo uso primario",
"jobTitleRequiredBusiness": "Il titolo di lavoro è richiesto per l'uso aziendale",
"industryRequiredBusiness": "L'industria è richiesta per l'uso commerciale",
"stateProvinceRegionRequired": "Stato/Provincia/Regione è richiesta",
"postalZipCodeRequired": "Codice postale/CAP obbligatorio",
"companyNameRequiredBusiness": "Il nome dell'azienda è richiesto per l'uso aziendale",
"countryOfResidenceRequiredBusiness": "Paese di residenza è richiesto per uso professionale",
"countryRequiredPersonal": "Il paese è richiesto per uso personale",
"agreeToTermsRequired": "Devi accettare i termini",
"complianceConfirmationRequired": "È necessario confermare la conformità alla licenza commerciale Fossorial"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Uso Personale",
"description": "Per uso individuale, non commerciale, come l'apprendimento, progetti personali o sperimentazione."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Uso Aziendale",
"description": "Da utilizzare all'interno di organizzazioni, aziende o attività commerciali o generatrici di entrate."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "Email & Tipo Di Licenza",
"description": "Inserisci la tua email e scegli il tipo di licenza"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Informazioni Personali",
"description": "Raccontaci di te"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Informazioni Di Contatto",
"description": "I tuoi dati di contatto"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Termini E Genera",
"description": "Controlla e accetta i termini per generare la tua licenza"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limitsincluding use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Trasparenza Di Utilizzo",
"description": "Seleziona il livello di licenza che rispecchia accuratamente il tuo utilizzo previsto. La Licenza Personale consente l'uso gratuito del Software per le attività commerciali individuali, non commerciali o su piccola scala con entrate lorde annue inferiori a $100.000 USD. Qualsiasi uso oltre questi limiticompreso l'uso all'interno di un'azienda, organizzazione, o altro ambiente generatore di entrate — richiede una licenza Enterprise valida e il pagamento della tassa di licenza applicabile. Tutti gli utenti, siano essi personali o aziendali, devono rispettare i termini di licenza commerciale Fossorial."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Informazioni Periodo Di Prova",
"description": "Questa chiave di licenza abilita le funzionalità Enterprise per un periodo di valutazione di 7 giorni. L'accesso continuo alle funzionalità a pagamento oltre il periodo di valutazione richiede l'attivazione con una licenza personale o Enterprise valida. Per la licenza Enterprise contatta sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Stai usando Pangolin per uso personale o di affari?",
"firstName": "Nome",
"lastName": "Cognome",
"jobTitle": "Titolo Del Lavoro",
"primaryUseQuestion": "Per che cosa hai in primo luogo intenzione di usare Pangolin?",
"industryQuestion": "Qual è la sua industria?",
"prospectiveUsersQuestion": "Quanti potenziali utenti si aspettano di avere?",
"prospectiveSitesQuestion": "Quanti siti potenziali (gallerie) ci si aspetta di avere?",
"companyName": "Nome della società",
"countryOfResidence": "Paese di residenza",
"stateProvinceRegion": "Stato / Provincia / Regione",
"postalZipCode": "Codice Postale / Zip",
"companyWebsite": "Sito web dell'azienda",
"companyPhoneNumber": "Numero di telefono dell'azienda",
"country": "Paese",
"phoneNumberOptional": "Numero di telefono (facoltativo)",
"complianceConfirmation": "Confermo che le informazioni che ho fornito sono accurate e che sono in conformità con la Fossorial Commercial License. La segnalazione di informazioni inesatte o l'uso errato del prodotto è una violazione della licenza e può portare alla revoca della chiave."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Chiudi",
"previous": "Precedente",
"next": "Successivo",
"generateLicenseKey": "Genera Chiave Di Licenza"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Chiave di licenza generata con successo",
"description": "La chiave di licenza è stata generata ed è pronta per l'uso."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Impossibile generare la chiave di licenza",
"description": "Si è verificato un errore nella generazione della chiave di licenza."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Nome Istanza",
"pathMatchModalTitle": "Configura Corrispondenza Percorso",
"pathMatchModalDescription": "Impostare come le richieste in arrivo devono essere abbinate in base al loro percorso.",
"pathMatchType": "Tipo di Corrispondenza",
"pathMatchPrefix": "Prefisso",
"pathMatchExact": "Esatto",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Valore Percorso",
"clear": "Pulisci",
"saveChanges": "Salva Modifiche",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathMatchPrefixHelp": "Esempio: /api corrisponde /api, /api/users etc.",
"pathMatchExactHelp": "Esempio: /api corrisponde solo /api",
"pathMatchRegexHelp": "Esempio: ^/api/.* corrisponde /api/anything",
"pathRewriteModalTitle": "Configura La Riscrittura Percorso",
"pathRewriteModalDescription": "Trasforma il percorso corrispondente prima di inoltrarlo al bersaglio.",
"pathRewriteType": "Tipo Di Riscrittura",
"pathRewritePrefixOption": "Prefisso - Sostituisci prefisso",
"pathRewriteExactOption": "Esatto - Sostituisci l'intero percorso",
"pathRewriteRegexOption": "Regex - Sostituzione modello",
"pathRewriteStripPrefixOption": "Prefisso striscia - Rimuovi prefisso",
"pathRewriteValue": "Riscrittura Valore",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewriteDefaultPlaceholder": "/nuovo-percorso",
"pathRewritePrefixHelp": "Sostituisci il prefisso abbinato con questo valore",
"pathRewriteExactHelp": "Sostituisci l'intero percorso con questo valore quando il percorso corrisponde esattamente",
"pathRewriteRegexHelp": "Usa gruppi di acquisizione come $1, $2 per la sostituzione",
"pathRewriteStripPrefixHelp": "Lasciare vuoto per strisciare il prefisso o fornire un nuovo prefisso",
"pathRewritePrefix": "Prefisso",
"pathRewriteExact": "Esatto",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Striscia",
"pathRewriteStripLabel": "striscia",
"sidebarEnableEnterpriseLicense": "Abilita Licenza Enterprise",
"cannotbeUndone": "Questo non può essere annullato.",
"toConfirm": "per confermare",
"deleteClientQuestion": "Sei sicuro di voler rimuovere il client dal sito e dall'organizzazione?",
"clientMessageRemove": "Una volta rimosso, il client non sarà più in grado di connettersi al sito.",
"sidebarLogs": "Registri",
"request": "Richiesta",
"logs": "Registri",
"logsSettingsDescription": "Monitora i registri raccolti da questa orginizzazione",
"searchLogs": "Cerca registro...",
"action": "Azione",
"actor": "Attore",
"timestamp": "Timestamp",
"accessLogs": "Log Accesso",
"exportCsv": "Esporta CSV",
"actorId": "Id Attore",
"allowedByRule": "Consentito dalla regola",
"allowedNoAuth": "Non Consentito Auth",
"validAccessToken": "Token Di Accesso Valido",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Password Valida",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Risorsa Bloccata",
"droppedByRule": "Eliminato dalla regola",
"noSessions": "Nessuna Sessione",
"temporaryRequestToken": "Token Di Richiesta Temporaneo",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP",
"reason": "Motivo",
"requestLogs": "Log Richiesta",
"host": "Host",
"location": "Posizione",
"actionLogs": "Log Azioni",
"sidebarLogsRequest": "Log Richiesta",
"sidebarLogsAccess": "Log Accesso",
"sidebarLogsAction": "Log Azioni",
"logRetention": "Ritenzione Registro",
"logRetentionDescription": "Gestisci per quanto tempo i diversi tipi di log sono mantenuti per questa organizzazione o disabilitali",
"requestLogsDescription": "Visualizza i registri di richiesta dettagliati per le risorse in questa organizzazione",
"logRetentionRequestLabel": "Richiedi Ritenzione Log",
"logRetentionRequestDescription": "Per quanto tempo conservare i log delle richieste",
"logRetentionAccessLabel": "Ritenzione Registro Accesso",
"logRetentionAccessDescription": "Per quanto tempo conservare i log di accesso",
"logRetentionActionLabel": "Ritenzione Registro Azioni",
"logRetentionActionDescription": "Per quanto tempo conservare i log delle azioni",
"logRetentionDisabled": "Disabilitato",
"logRetention3Days": "3 giorni",
"logRetention7Days": "7 giorni",
"logRetention14Days": "14 giorni",
"logRetention30Days": "30 giorni",
"logRetention90Days": "90 giorni",
"logRetentionForever": "Per Sempre",
"actionLogsDescription": "Visualizza una cronologia delle azioni eseguite 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.",
"certResolver": "Risolutore Di Certificato",
"certResolverDescription": "Selezionare il risolutore di certificati da usare per questa risorsa.",
"selectCertResolver": "Seleziona Risolutore Di Certificato",
"enterCustomResolver": "Inserisci Risolutore Personalizzato",
"preferWildcardCert": "Preferisci Certificato Wildcard",
"unverified": "Non Verificato",
"domainSetting": "Impostazioni Dominio",
"domainSettingDescription": "Configura le impostazioni per il tuo dominio",
"preferWildcardCertDescription": "Tentativo di generare un certificato jolly (richiede un risolutore di certificati correttamente configurato).",
"recordName": "Nome Record",
"auto": "Automatico",
"TTL": "TTL",
"howToAddRecords": "Come aggiungere record",
"dnsRecord": "Record DNS",
"required": "Richiesto",
"domainSettingsUpdated": "Impostazioni dominio aggiornate con successo",
"orgOrDomainIdMissing": "Manca l'ID dell'organizzazione o del dominio",
"loadingDNSRecords": "Caricamento record DNS...",
"olmUpdateAvailableInfo": "È disponibile una versione aggiornata di Olm. Si prega di aggiornare all'ultima versione per la migliore esperienza.",
"client": "Client",
"proxyProtocol": "Impostazioni Protocollo Proxy",
"proxyProtocolDescription": "Configurare il protocollo proxy per preservare gli indirizzi IP client per i servizi TCP/UDP.",
"enableProxyProtocol": "Abilita Protocollo Proxy",
"proxyProtocolInfo": "Conserva gli indirizzi IP del client per i backend TCP/UDP",
"proxyProtocolVersion": "Versione Protocollo Proxy",
"version1": " Versione 1 (Consigliato)",
"version2": "Versione 2",
"versionDescription": "La versione 1 è testuale e ampiamente supportata. La versione 2 è binaria e più efficiente, ma meno compatibile.",
"warning": "Attenzione",
"proxyProtocolWarning": "La tua applicazione backend deve essere configurata per accettare le connessioni del protocollo proxy. Se il tuo backend non supporta il protocollo proxy, abilitando questa opzione si interromperanno tutte le connessioni. Assicurati di configurare il tuo backend per fidarti delle intestazioni del protocollo proxy da Traefik.",
"restarting": "Riavvio...",
"manual": "Manuale",
"messageSupport": "Supporto Messaggio",
"supportNotAvailableTitle": "Supporto Non Disponibile",
"supportNotAvailableDescription": "Il supporto non è disponibile in questo momento. Puoi inviare un'email a support@pangolin.net.",
"supportRequestSentTitle": "Richiesta Di Supporto Inviata",
"supportRequestSentDescription": "Il tuo messaggio è stato inviato con successo.",
"supportRequestFailedTitle": "Impossibile inviare la richiesta",
"supportRequestFailedDescription": "Si è verificato un errore durante l'invio della richiesta di supporto.",
"supportSubjectRequired": "L'oggetto è obbligatorio",
"supportSubjectMaxLength": "L'oggetto deve contenere almeno 255 caratteri",
"supportMessageRequired": "Il messaggio è obbligatorio",
"supportReplyTo": "Rispondi A",
"supportSubject": "Oggetto",
"supportSubjectPlaceholder": "Inserisci oggetto",
"supportMessage": "Messaggio",
"supportMessagePlaceholder": "Inserisci il tuo messaggio",
"supportSending": "Invio...",
"supportSend": "Invia",
"supportMessageSent": "Messaggio Inviato!",
"supportWillContact": "Saremo in contatto a breve!",
"selectLogRetention": "Seleziona ritenzione log",
"showColumns": "Mostra Colonne",
"hideColumns": "Nascondi Colonne",
"columnVisibility": "Visibilità Colonna",
"toggleColumn": "Attiva/disattiva colonna {columnName}",
"allColumns": "Tutte Le Colonne",
"defaultColumns": "Colonne Predefinite",
"customizeView": "Personalizza Vista",
"viewOptions": "Opzioni Visualizzazione",
"selectAll": "Seleziona Tutto",
"selectNone": "Seleziona Nessuno",
"selectedResources": "Risorse Selezionate",
"enableSelected": "Abilita Selezionati",
"disableSelected": "Disabilita Selezionati",
"checkSelectedStatus": "Controlla lo stato dei selezionati",
"credentials": "Credenziali",
"savecredentials": "Salva Credenziali",
"regeneratecredentials": "Ri-chiave",
"regenerateCredentials": "Rigenera e salva le tue credenziali",
"generatedcredentials": "Credenziali Generate",
"copyandsavethesecredentials": "Copia e salva queste credenziali",
"copyandsavethesecredentialsdescription": "Queste credenziali non verranno mostrate di nuovo dopo aver lasciato questa pagina. Salvarle in modo sicuro ora.",
"credentialsSaved": "Credenziali Salvate",
"credentialsSavedDescription": "Le credenziali sono state rigenerate e salvate con successo.",
"credentialsSaveError": "Errore Di Salvataggio Credenziali",
"credentialsSaveErrorDescription": "Errore durante la rigenerazione e il salvataggio delle credenziali.",
"regenerateCredentialsWarning": "Rigenerare le credenziali invaliderà quelle precedenti. Assicurarsi di aggiornare le configurazioni che utilizzano queste credenziali.",
"confirm": "Conferma",
"regenerateCredentialsConfirmation": "Sei sicuro di voler rigenerare le credenziali?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Chiave Segreta",
"featureDisabledTooltip": "Questa funzione è disponibile solo nel piano aziendale e richiede una licenza per utilizzarla.",
"niceId": "Simpatico ID",
"niceIdUpdated": "Nice ID Aggiornato",
"niceIdUpdatedSuccessfully": "Nizza Id Aggiornato Con Successo",
"niceIdUpdateError": "Errore nell'aggiornare Nice ID",
"niceIdUpdateErrorDescription": "Si è verificato un errore durante l'aggiornamento del Nice ID.",
"niceIdCannotBeEmpty": "Il Nice ID non può essere vuoto",
"enterIdentifier": "Inserisci identificatore",
"identifier": "Identifier"
}

View File

@@ -47,9 +47,8 @@
"edit": "편집",
"siteConfirmDelete": "사이트 삭제 확인",
"siteDelete": "사이트 삭제",
"siteMessageRemove": "제되면 사이트에 더 이상 접근할 수 없습니다. 사이트와 관련된 모든 리소스와 대상도 제됩니다.",
"siteMessageConfirm": "확인을 위해 아래에 사이트 이름을 입력해 주세요.",
"siteQuestionRemove": "조직에서 사이트 {selectedSite}를 제거하시겠습니까?",
"siteMessageRemove": "제되면 사이트에 더 이상 액세스할 수 없습니다. 사이트와 연결된 모든 대상도 제됩니다.",
"siteQuestionRemove": "조직에서 사이트를 제거하시겠습니까?",
"siteManageSites": "사이트 관리",
"siteDescription": "안전한 터널을 통해 네트워크에 연결할 수 있도록 허용",
"siteCreate": "사이트 생성",
@@ -96,7 +95,7 @@
"siteWgDescription": "모든 WireGuard 클라이언트를 사용하여 터널을 설정하세요. 수동 NAT 설정이 필요합니다.",
"siteWgDescriptionSaas": "모든 WireGuard 클라이언트를 사용하여 터널을 설정하세요. 수동 NAT 설정이 필요합니다. 자체 호스팅 노드에서만 작동합니다.",
"siteLocalDescription": "로컬 리소스만 사용 가능합니다. 터널링이 없습니다.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "로컬 리소스 전용. 터널링 금지. 원격 노드에서만 사용 가능합니다.",
"siteSeeAll": "모든 사이트 보기",
"siteTunnelDescription": "사이트에 연결하는 방법을 결정하세요",
"siteNewtCredentials": "Newt 자격 증명",
@@ -154,8 +153,7 @@
"protected": "보호됨",
"notProtected": "보호되지 않음",
"resourceMessageRemove": "제거되면 리소스에 더 이상 접근할 수 없습니다. 리소스와 연결된 모든 대상도 제거됩니다.",
"resourceMessageConfirm": "확인을 위해 아래에 리소스의 이름을 입력하세요.",
"resourceQuestionRemove": "조직에서 리소스 {selectedResource}를 제거하시겠습니까?",
"resourceQuestionRemove": "조직에서 리소스를 제거하시겠습니까?",
"resourceHTTP": "HTTPS 리소스",
"resourceHTTPDescription": "서브도메인 또는 기본 도메인을 사용하여 HTTPS를 통해 앱에 대한 요청을 프록시합니다.",
"resourceRaw": "원시 TCP/UDP 리소스",
@@ -181,7 +179,7 @@
"baseDomain": "기본 도메인",
"subdomnainDescription": "리소스에 접근할 수 있는 하위 도메인입니다.",
"resourceRawSettings": "TCP/UDP 설정",
"resourceRawSettingsDescription": "TCP/UDP를 통해 리소스에 접근하는 방법을 구성하세요.",
"resourceRawSettingsDescription": "리소스를 TCP/UDP를 통해 액세스하는 방법을 구성합니다. 리소스를 호스트 Pangolin 서버의 포트에 매핑하여 서버-public-ip:매핑된 포트에서 리소스에 액세스할 수 있습니다.",
"protocol": "프로토콜",
"protocolSelect": "프로토콜 선택",
"resourcePortNumber": "포트 번호",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "조직 삭제 확인",
"orgMessageRemove": "이 작업은 되돌릴 수 없으며 모든 관련 데이터를 삭제합니다.",
"orgMessageConfirm": "확인을 위해 아래에 조직 이름을 입력하십시오.",
"orgQuestionRemove": "조직 {selectedOrg}을(를) 제거하시겠습니까?",
"orgQuestionRemove": "조직을 삭제하시겠습니까?",
"orgUpdated": "조직이 업데이트되었습니다.",
"orgUpdatedDescription": "조직이 업데이트되었습니다.",
"orgErrorUpdate": "조직 업데이트에 실패했습니다.",
@@ -287,9 +285,8 @@
"apiKeysAdd": "API 키 생성",
"apiKeysErrorDelete": "API 키 삭제 오류",
"apiKeysErrorDeleteMessage": "API 키 삭제 오류",
"apiKeysQuestionRemove": "조직에서 API 키 {selectedApiKey}를 제거하시겠습니까?",
"apiKeysQuestionRemove": "조직에서 API 키를 제거하시겠습니까?",
"apiKeysMessageRemove": "삭제되면 API 키를 더 이상 사용할 수 없습니다.",
"apiKeysMessageConfirm": "확인을 위해 아래에 API 키의 이름을 입력해 주세요.",
"apiKeysDeleteConfirm": "API 키 삭제 확인",
"apiKeysDelete": "API 키 삭제",
"apiKeysManage": "API 키 관리",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "사용자 삭제 확인",
"userDeleteServer": "서버에서 사용자 삭제",
"userMessageRemove": "사용자가 모든 조직에서 제거되며 서버에서 완전히 삭제됩니다.",
"userMessageConfirm": "확인을 위해 아래에 사용자 이름을 입력하십시오.",
"userQuestionRemove": "정말로 {selectedUser}를 서버에서 영구적으로 삭제하시겠습니까?",
"userQuestionRemove": "서버에서 사용자를 영구적으로 삭제하시겠습니까?",
"licenseKey": "라이센스 키",
"valid": "유효",
"numberOfSites": "사이트 수",
@@ -339,7 +335,7 @@
"fossorialLicense": "Fossorial 상업 라이선스 및 구독 약관 보기",
"licenseMessageRemove": "이 작업은 라이센스 키와 그에 의해 부여된 모든 관련 권한을 제거합니다.",
"licenseMessageConfirm": "확인을 위해 아래에 라이센스 키를 입력하세요.",
"licenseQuestionRemove": "라이스 키 {selectedKey}를 삭제하시겠습니까?",
"licenseQuestionRemove": "라이스 키를 삭제하시겠습니까?",
"licenseKeyDelete": "라이센스 키 삭제",
"licenseKeyDeleteConfirm": "라이센스 키 삭제 확인",
"licenseTitle": "라이선스 상태 관리",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "초대를 제거하는 동안 오류가 발생했습니다.",
"inviteRemoved": "초대가 제거되었습니다.",
"inviteRemovedDescription": "{email}에 대한 초대가 삭제되었습니다.",
"inviteQuestionRemove": "초대 {email}를 제거하시겠습니까?",
"inviteQuestionRemove": "초대를 제거하시겠습니까?",
"inviteMessageRemove": "한 번 제거되면 이 초대는 더 이상 유효하지 않습니다. 나중에 사용자를 다시 초대할 수 있습니다.",
"inviteMessageConfirm": "확인을 위해 아래 초대의 이메일 주소를 입력해 주세요.",
"inviteQuestionRegenerate": "{email}에 대한 초대장을 다시 생성하시겠습니까? 이전 초대장은 취소됩니다.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "사용자를 제거하는 동안 오류가 발생했습니다.",
"userOrgRemoved": "사용자가 제거되었습니다.",
"userOrgRemovedDescription": "사용자 {email}가 조직에서 제거되었습니다.",
"userQuestionOrgRemove": "{email}을 조직에서 제거하시겠습니까?",
"userQuestionOrgRemove": "조직에서 이 사용자를 제거하시겠습니까?",
"userMessageOrgRemove": "이 사용자가 제거되면 더 이상 조직에 접근할 수 없습니다. 나중에 다시 초대할 수 있지만, 초대를 다시 수락해야 합니다.",
"userMessageOrgConfirm": "확인을 위해 아래에 사용자 이름을 입력하세요.",
"userRemoveOrgConfirm": "사용자 제거 확인",
"userRemoveOrg": "조직에서 사용자 제거",
"users": "사용자",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "서버 관리자 - 판골린",
"licenseTierProfessional": "전문 라이센스",
"licenseTierEnterprise": "기업 라이선스",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "개인 라이선스",
"licensed": "라이센스",
"yes": "예",
"no": "아니요",
@@ -742,7 +737,7 @@
"idpManageDescription": "시스템에서 ID 제공자를 보고 관리합니다",
"idpDeletedDescription": "신원 공급자가 성공적으로 삭제되었습니다",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "정말로 아이덴티티 공급자 {name}를 영구적으로 삭제하시겠습니까?",
"idpQuestionRemove": "아이덴티티 공급자를 영구적으로 삭제하시겠습니까?",
"idpMessageRemove": "이 작업은 아이덴티티 공급자와 모든 관련 구성을 제거합니다. 이 공급자를 통해 인증하는 사용자는 더 이상 로그인할 수 없습니다.",
"idpMessageConfirm": "확인을 위해 아래에 아이덴티티 제공자의 이름을 입력하세요.",
"idpConfirmDelete": "신원 제공자 삭제 확인",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "재설정 코드를 확인하려면 이메일을 확인하세요.",
"passwordNew": "새 비밀번호",
"passwordNewConfirm": "새 비밀번호 확인",
"changePassword": "비밀번호 변경",
"changePasswordDescription": "계정 비밀번호를 업데이트하십시오",
"oldPassword": "현재 비밀번호",
"newPassword": "새 비밀번호",
"confirmNewPassword": "새 비밀번호 확인",
"changePasswordError": "비밀번호 변경 실패",
"changePasswordErrorDescription": "비밀번호를 변경하는 중 오류가 발생했습니다",
"changePasswordSuccess": "비밀번호 변경 완료",
"changePasswordSuccessDescription": "비밀번호가 성공적으로 업데이트되었습니다",
"passwordExpiryRequired": "비밀번호 만료 필요",
"passwordExpiryDescription": "이 조직은 {maxDays}일마다 비밀번호 변경을 요구합니다.",
"changePasswordNow": "지금 비밀번호 변경",
"pincodeAuth": "인증 코드",
"pincodeSubmit2": "코드 제출",
"passwordResetSubmit": "재설정 요청",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "모든 사용자",
"sidebarIdentityProviders": "신원 공급자",
"sidebarLicense": "라이선스",
"sidebarClients": "Clients",
"sidebarClients": "클라이언트",
"sidebarDomains": "도메인",
"sidebarBluePrints": "청사진",
"blueprints": "청사진",
"blueprintsDescription": "선언적 구성을 적용하고 이전 실행을 봅니다",
"blueprintAdd": "청사진 추가",
"blueprintGoBack": "모든 청사진 보기",
"blueprintCreate": "청사진 생성",
"blueprintCreateDescription2": "새 청사진을 생성하고 적용하려면 아래 단계를 따르십시오",
"blueprintDetails": "청사진 세부사항",
"blueprintDetailsDescription": "적용된 청사진의 결과와 발생한 오류를 확인합니다",
"blueprintInfo": "청사진 정보",
"message": "메시지",
"blueprintContentsDescription": "인프라를 설명하는 YAML 콘텐츠를 정의하십시오",
"blueprintErrorCreateDescription": "청사진을 적용하는 중 오류가 발생했습니다",
"blueprintErrorCreate": "청사진 생성 오류",
"searchBlueprintProgress": "청사진 검색...",
"appliedAt": "적용 시점",
"source": "출처",
"contents": "콘텐츠",
"parsedContents": "구문 분석된 콘텐츠 (읽기 전용)",
"enableDockerSocket": "Docker 청사진 활성화",
"enableDockerSocketDescription": "블루프린트 레이블을 위한 Docker 소켓 레이블 수집을 활성화합니다. 소켓 경로는 Newt에 제공되어야 합니다.",
"enableDockerSocketLink": "자세히 알아보기",
@@ -1211,9 +1237,8 @@
"domainCreate": "도메인 생성",
"domainCreatedDescription": "도메인이 성공적으로 생성되었습니다",
"domainDeletedDescription": "도메인이 성공적으로 삭제되었습니다",
"domainQuestionRemove": "도메인 {domain}을(를) 계정에서 제거하시겠습니까?",
"domainQuestionRemove": "계정에서 도메인을 제거하시겠습니까?",
"domainMessageRemove": "제거되면 도메인이 더 이상 계정과 연관되지 않습니다.",
"domainMessageConfirm": "확인하려면 아래에 도메인명을 입력하세요.",
"domainConfirmDelete": "도메인 삭제 확인",
"domainDelete": "도메인 삭제",
"domain": "도메인",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "설정을 업데이트하는 동안 오류가 발생했습니다",
"sidebarCollapse": "줄이기",
"sidebarExpand": "확장하기",
"productUpdateMoreInfo": "{noOfUpdates}개의 더 많은 업데이트",
"productUpdateInfo": "{noOfUpdates}개 업데이트",
"productUpdateWhatsNew": "새로운 기능",
"productUpdateTitle": "제품 업데이트",
"productUpdateEmpty": "업데이트 없음",
"dismissAll": "모두 해제",
"pangolinUpdateAvailable": "새 버전 사용 가능",
"pangolinUpdateAvailableInfo": "버전 {version}을(를) 설치할 준비가 되었습니다",
"pangolinUpdateAvailableReleaseNotes": "릴리스 노트 보기",
"newtUpdateAvailable": "업데이트 가능",
"newtUpdateAvailableInfo": "뉴트의 새 버전이 출시되었습니다. 최상의 경험을 위해 최신 버전으로 업데이트하세요.",
"domainPickerEnterDomain": "도메인",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "무료 티어",
"billingWarningOverLimit": "경고: 하나 이상의 사용 한도를 초과했습니다. 구독을 수정하거나 사용량을 조정하기 전까지 사이트는 연결되지 않습니다.",
"billingUsageLimitsOverview": "사용 한도 개요",
"billingMonitorUsage": "설정된 한도에 대한 사용량을 모니터링합니다. 한도를 늘려야 하는 경우 support@fossorial.io로 연락하십시오.",
"billingMonitorUsage": "설정된 한도에 대한 사용량을 모니터링합니다. 한도를 늘려야 하는 경우 support@pangolin.net로 연락하십시오.",
"billingDataUsage": "데이터 사용량",
"billingOnlineTime": "사이트 온라인 시간",
"billingUsers": "활성 사용자",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "보안 키를 사용하는 데 문제가 발생했습니다. 다시 시도하세요.",
"twoFactorRequired": "보안 키를 등록하려면 이중 인증이 필요합니다.",
"twoFactor": "이중 인증",
"twoFactorAuthentication": "이중 인증",
"twoFactorDescription": "이 조직은 이중 인증을 요구합니다.",
"enableTwoFactor": "이중 인증 활성화",
"organizationSecurityPolicy": "조직 보안 정책",
"organizationSecurityPolicyDescription": "이 조직에는 접근하기 전에 준수해야 하는 보안 요구 사항이 있습니다",
"securityRequirements": "보안 요구 사항",
"allRequirementsMet": "모든 요구 사항이 충족되었습니다",
"completeRequirementsToContinue": "이 조직에 계속 접근하려면 아래 요구 사항을 완료하십시오",
"youCanNowAccessOrganization": "이제 이 조직에 접근할 수 있습니다",
"reauthenticationRequired": "세션 길이",
"reauthenticationDescription": "이 조직은 {maxDays}일마다 로그인하는 것을 요구합니다.",
"reauthenticationDescriptionHours": "이 조직은 {maxHours}시간마다 로그인하는 것을 요구합니다.",
"reauthenticateNow": "다시 로그인",
"adminEnabled2FaOnYourAccount": "관리자가 {email}에 대한 이중 인증을 활성화했습니다. 계속하려면 설정을 완료하세요.",
"securityKeyAdd": "보안 키 추가",
"securityKeyRegisterTitle": "새 보안 키 등록",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "이 리소스는 다음과 함께 사용하기 위한 것입니다.",
"resourcesTableClients": "클라이언트",
"resourcesTableAndOnlyAccessibleInternally": "클라이언트와 연결되었을 때만 내부적으로 접근 가능합니다.",
"resourcesTableNoTargets": "대상 없음",
"resourcesTableHealthy": "정상",
"resourcesTableDegraded": "저하됨",
"resourcesTableOffline": "오프라인",
"resourcesTableUnknown": "알 수 없음",
"resourcesTableNotMonitored": "모니터링되지 않음",
"editInternalResourceDialogEditClientResource": "클라이언트 리소스 수정",
"editInternalResourceDialogUpdateResourceProperties": "{resourceName}의 리소스 속성과 대상 구성을 업데이트하세요.",
"editInternalResourceDialogResourceProperties": "리소스 속성",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "ID 공급자로부터 리디렉션 URL을 받지 못했습니다.",
"autoLoginErrorGeneratingUrl": "인증 URL 생성 실패.",
"remoteExitNodeManageRemoteExitNodes": "원격 노드",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "네트워크 연결성을 확장하고 클라우드 의존도를 줄이기 위해 하나 이상의 원격 노드를 자체 호스트하십시오.",
"remoteExitNodes": "노드",
"searchRemoteExitNodes": "노드 검색...",
"remoteExitNodeAdd": "노드 추가",
"remoteExitNodeErrorDelete": "노드 삭제 오류",
"remoteExitNodeQuestionRemove": "조직에서 노드 {selectedNode}를 제거하시겠습니까?",
"remoteExitNodeQuestionRemove": "조직에서 노드를 제거하시겠습니까?",
"remoteExitNodeMessageRemove": "한 번 제거되면 더 이상 노드에 접근할 수 없습니다.",
"remoteExitNodeMessageConfirm": "확인을 위해 아래에 노드 이름을 입력해 주세요.",
"remoteExitNodeConfirmDelete": "노드 삭제 확인",
"remoteExitNodeDelete": "노드 삭제",
"sidebarRemoteExitNodes": "원격 노드",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "파일 편집: docker-compose.yml",
"emailVerificationRequired": "이메일 인증이 필요합니다. 이 단계를 완료하려면 {dashboardUrl}/auth/login 통해 다시 로그인하십시오. 그런 다음 여기로 돌아오세요.",
"twoFactorSetupRequired": "이중 인증 설정이 필요합니다. 이 단계를 완료하려면 {dashboardUrl}/auth/login 통해 다시 로그인하십시오. 그런 다음 여기로 돌아오세요.",
"additionalSecurityRequired": "추가 보안 필요",
"organizationRequiresAdditionalSteps": "이 조직은 자원에 접근하기 전에 추가 보안 단계를 요구합니다.",
"completeTheseSteps": "이 단계를 완료하십시오",
"enableTwoFactorAuthentication": "이중 인증 활성화",
"completeSecuritySteps": "보안 단계 완료",
"securitySettings": "보안 설정",
"securitySettingsDescription": "조직에 대한 보안 정책을 구성합니다",
"requireTwoFactorForAllUsers": "모든 사용자에 대해 이중 인증 요구",
"requireTwoFactorDescription": "활성화되면, 이 조직의 모든 내부 사용자는 조직에 접근하기 위해 이중 인증을 활성화해야 합니다.",
"requireTwoFactorDisabledDescription": "이 기능을 사용하려면 유효한 라이선스(Enterprise) 또는 활성 구독(SaaS)가 필요합니다.",
"requireTwoFactorCannotEnableDescription": "모든 사용자에게 강제하기 전에 계정에 대해 이중 인증을 활성화해야 합니다",
"maxSessionLength": "최대 세션 길이",
"maxSessionLengthDescription": "사용자 세션의 최대 지속 시간을 설정합니다. 이 시간이 지나면 사용자는 다시 인증해야 합니다.",
"maxSessionLengthDisabledDescription": "이 기능을 사용하려면 유효한 라이선스(Enterprise) 또는 활성 구독(SaaS)가 필요합니다.",
"selectSessionLength": "세션 길이 선택",
"unenforced": "강제되지 않음",
"1Hour": "1 시간",
"3Hours": "3 시간",
"6Hours": "6 시간",
"12Hours": "12 시간",
"1DaySession": "1 일",
"3Days": "3 일",
"7Days": "7 일",
"14Days": "14 일",
"30DaysSession": "30 일",
"90DaysSession": "90 일",
"180DaysSession": "180 일",
"passwordExpiryDays": "비밀번호 만료",
"editPasswordExpiryDescription": "사용자가 비밀번호를 변경해야 하는 날 수를 설정합니다.",
"selectPasswordExpiry": "비밀번호 만료 선택",
"30Days": "30 일",
"1Day": "1 일",
"60Days": "60 일",
"90Days": "90 일",
"180Days": "180 일",
"1Year": "1 년",
"subscriptionBadge": "구독 필요",
"securityPolicyChangeWarning": "보안 정책 변경 경고",
"securityPolicyChangeDescription": "보안 정책 설정을 변경하려고 합니다. 저장 후, 정책 업데이트를 준수하기 위해 다시 인증해야 할 수도 있습니다. 규정을 준수하지 않는 모든 사용자도 다시 인증해야 합니다.",
"securityPolicyChangeConfirmMessage": "확인합니다",
"securityPolicyChangeWarningText": "이 작업은 조직의 모든 사용자에게 영향을 미칩니다",
"authPageErrorUpdateMessage": "인증 페이지 설정을 업데이트하는 동안 오류가 발생했습니다",
"authPageErrorUpdate": "인증 페이지를 업데이트할 수 없습니다",
"authPageUpdated": "인증 페이지가 성공적으로 업데이트되었습니다",
"healthCheckNotAvailable": "로컬",
"rewritePath": "경로 재작성",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "헤더 인증이 성공적으로 제거되었습니다.",
"resourceErrorHeaderAuthRemove": "헤더 인증 제거 실패",
"resourceErrorHeaderAuthRemoveDescription": "리소스의 헤더 인증을 제거할 수 없습니다.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "헤더 인증 활성화됨",
"resourceHeaderAuthProtectionDisabled": "헤더 인증 비활성화됨",
"headerAuthRemove": "헤더 인증 삭제",
"headerAuthAdd": "헤더 인증 추가",
"resourceErrorHeaderAuthSetup": "헤더 인증 설정 실패",
"resourceErrorHeaderAuthSetupDescription": "리소스의 헤더 인증을 설정할 수 없습니다.",
"resourceHeaderAuthSetup": "헤더 인증이 성공적으로 설정되었습니다.",
"resourceHeaderAuthSetupDescription": "헤더 인증이 성공적으로 설정되었습니다.",
"resourceHeaderAuthSetupTitle": "헤더 인증 설정",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "이 리소스를 HTTP 헤더 인증으로 보호하기 위해 기본 인증 자격 증명(사용자이름 및 비밀번호)을 설정합니다. 다음과 같은 형식으로 액세스하세요 https://사용자이름:비밀번호@resource.example.com",
"resourceHeaderAuthSubmit": "헤더 인증 설정",
"actionSetResourceHeaderAuth": "헤더 인증 설정",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"enterpriseEdition": "엔터프라이즈 에디션",
"unlicensed": "라이선스 없음",
"beta": "베타",
"manageClients": "클라이언트 관리",
"manageClientsDescription": "클라이언트는 당신의 사이트에 연결할 수 있는 디바이스입니다.",
"licenseTableValidUntil": "유효 기한",
"saasLicenseKeysSettingsTitle": "엔터프라이즈 라이선스",
"saasLicenseKeysSettingsDescription": "자체 호스팅된 Pangolin 인스턴스를 위한 엔터프라이즈 라이선스 키를 생성하고 관리합니다.",
"sidebarEnterpriseLicenses": "라이선스",
"generateLicenseKey": "라이선스 키 생성",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "유효한 이메일 주소를 입력하세요",
"useCaseTypeRequired": "사용 사례 유형을 선택하세요",
"firstNameRequired": "이름은 필수입니다.",
"lastNameRequired": "성은 필수입니다.",
"primaryUseRequired": "주요 용도를 설명하세요",
"jobTitleRequiredBusiness": "사업용 직책은 필수입니다.",
"industryRequiredBusiness": "사업용 산업은 필수입니다.",
"stateProvinceRegionRequired": "주/도/지역이 필수입니다.",
"postalZipCodeRequired": "우편번호/ZIP 코드가 필수입니다.",
"companyNameRequiredBusiness": "사업용 회사 이름은 필수입니다.",
"countryOfResidenceRequiredBusiness": "사업용 거주 국가는 필수입니다.",
"countryRequiredPersonal": "개인용 국가가 필수입니다.",
"agreeToTermsRequired": "약관에 동의해야 합니다.",
"complianceConfirmationRequired": "Fossorial 상용 라이선스를 준수함을 확인해야 합니다."
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "개인 용도",
"description": "학습, 개인 프로젝트 또는 실험과 같은 개인, 비상업적 용도로 사용합니다."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "사업 용도",
"description": "조직, 회사 또는 수익 창출 활동 내에서 사용됩니다."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "이메일 및 라이선스 유형",
"description": "이메일을 입력하고 라이선스 유형을 선택하세요"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "개인 정보",
"description": "자기소개를 해주세요"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "연락처 정보",
"description": "당신의 연락처 정보"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "약관 및 생성",
"description": "라이선스를 생성하기 위해 약관을 검토하고 수락하세요"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "사용 공개",
"description": "당신의 의도된 사용에 정확히 맞는 라이선스 등급을 선택하세요. 개인 라이선스는 연간 총 수익 100,000 USD 이하의 개인, 비상업적 또는 소규모 상업 활동을 위한 소프트웨어의 무료 사용을 허용합니다. 이러한 제한을 넘는 모든 사용 — 비즈니스, 조직 또는 기타 수익 창출 환경 내에서의 사용 — 은 유효한 엔터프라이즈 라이선스 및 해당 라이선스 수수료의 지불이 필요합니다. 개인 또는 기업 사용자는 모두 Fossorial 상용 라이선스 조건을 준수해야 합니다."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "시험 기간 정보",
"description": "이 라이선스 키는 엔터프라이즈 기능을 평가판 기간 동안 7일 동안 활성화합니다. 평가 기간 이후 유료 기능에 대한 계속된 액세스는 유효한 개인 또는 엔터프라이즈 라이선스 하에서 활성화가 필요합니다. 엔터프라이즈 라이선스에 대한 정보는 sales@pangolin.net에 문의하세요."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "개인 또는 사업용으로 Pangolin을 사용하시나요?",
"firstName": "이름",
"lastName": "",
"jobTitle": "직책",
"primaryUseQuestion": "Pangolin을 주로 무엇에 사용하려고 계획하시나요?",
"industryQuestion": "당신의 산업은 무엇입니까?",
"prospectiveUsersQuestion": "예상하는 잠재적 사용자는 몇 명입니까?",
"prospectiveSitesQuestion": "예상하는 잠재적 사이트(터널)는 몇 개입니까?",
"companyName": "회사 이름",
"countryOfResidence": "거주 국가",
"stateProvinceRegion": "주 / 도 / 지역",
"postalZipCode": "우편번호 / ZIP 코드",
"companyWebsite": "회사 웹사이트",
"companyPhoneNumber": "회사 전화번호",
"country": "국가",
"phoneNumberOptional": "전화번호 (선택 항목)",
"complianceConfirmation": "제가 제공한 정보가 정확하고 Fossorial 상용 라이선스를 준수하는지 확인합니다. 부정확한 정보를 보고하거나 제품 사용을 실수로 식별하는 것은 라이선스 위반이며, 키가 취소될 수 있습니다."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "닫기",
"previous": "이전",
"next": "다음",
"generateLicenseKey": "라이선스 키 생성"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "라이선스 키가 성공적으로 생성되었습니다",
"description": "당신의 라이선스 키가 생성되었으며 사용 준비가 되었습니다."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "라이선스 키 생성에 실패했습니다",
"description": "라이선스 키를 생성하는 동안 오류가 발생했습니다."
}
}
},
"priority": "우선순위",
"priorityDescription": "우선 순위가 높은 경로가 먼저 평가됩니다. 우선 순위 = 100은 자동 정렬(시스템 결정)이 의미합니다. 수동 우선 순위를 적용하려면 다른 숫자를 사용하세요.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"instanceName": "인스턴스 이름",
"pathMatchModalTitle": "경로 매칭 설정",
"pathMatchModalDescription": "경로별로 들어오는 요청을 어떻게 매칭할지 설정합니다.",
"pathMatchType": "일치 유형",
"pathMatchPrefix": "접두사",
"pathMatchExact": "정확하게",
"pathMatchRegex": "정규 표현식",
"pathMatchValue": "경로 값",
"clear": "지우기",
"saveChanges": "변경 사항 저장",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathMatchDefaultPlaceholder": "/경로",
"pathMatchPrefixHelp": "예: /api 는 /api, /api/users 등을 매칭합니다.",
"pathMatchExactHelp": "예: /api 는 /api 만 매칭합니다.",
"pathMatchRegexHelp": ": ^/api/.* /api/anything를 매칭합니다",
"pathRewriteModalTitle": "경로 재작성 설정",
"pathRewriteModalDescription": "대상으로 전달하기 전에 매칭된 경로를 변환합니다.",
"pathRewriteType": "재작성 유형",
"pathRewritePrefixOption": "접두사 - 접두사 대체",
"pathRewriteExactOption": "정확 - 전체 경로 대체",
"pathRewriteRegexOption": "정규 표현식 - 패턴 대체",
"pathRewriteStripPrefixOption": "접두사 제거 - 접두사 삭제",
"pathRewriteValue": "재작성 값",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteDefaultPlaceholder": "/새-경로",
"pathRewritePrefixHelp": "일치하는 접두사를 이 값으로 대체합니다",
"pathRewriteExactHelp": "경로가 정확히 일치할 때 전체 경로를 이 값으로 대체합니다",
"pathRewriteRegexHelp": "$1, $2와 같은 캡처 그룹을 사용하여 대체",
"pathRewriteStripPrefixHelp": "접두사를 제거하거나 새 접두사를 제공하려면 비워 둡니다",
"pathRewritePrefix": "접두사",
"pathRewriteExact": "정확하게",
"pathRewriteRegex": "정규 표현식",
"pathRewriteStrip": "제거",
"pathRewriteStripLabel": "제거",
"sidebarEnableEnterpriseLicense": "엔터프라이즈 라이선스 활성화",
"cannotbeUndone": "이 작업은 되돌릴 수 없습니다.",
"toConfirm": "확인하려면",
"deleteClientQuestion": "고객을 사이트와 조직에서 제거하시겠습니까?",
"clientMessageRemove": "제거되면 클라이언트는 사이트에 더 이상 연결할 수 없습니다.",
"sidebarLogs": "로그",
"request": "요청",
"logs": "로그",
"logsSettingsDescription": "이 조직에서 수집된 로그를 모니터링합니다",
"searchLogs": "로그 검색...",
"action": "작업",
"actor": "행위자",
"timestamp": "타임스탬프",
"accessLogs": "접근 로그",
"exportCsv": "CSV 내보내기",
"actorId": "행위자 ID",
"allowedByRule": "룰에 의해 허용됨",
"allowedNoAuth": "인증 없음 허용됨",
"validAccessToken": "유효한 접근 토큰",
"validHeaderAuth": "유효한 헤더 인증",
"validPincode": "유효한 핀코드",
"validPassword": "유효한 비밀번호",
"validEmail": "유효한 이메일",
"validSSO": "유효한 SSO",
"resourceBlocked": "리소스 차단됨",
"droppedByRule": "룰에 의해 드롭됨",
"noSessions": "세션 없음",
"temporaryRequestToken": "임시 요청 토큰",
"noMoreAuthMethods": "유효한 인증 없음",
"ip": "IP",
"reason": "이유",
"requestLogs": "요청 로그",
"host": "호스트",
"location": "위치",
"actionLogs": "작업 로그",
"sidebarLogsRequest": "요청 로그",
"sidebarLogsAccess": "접근 로그",
"sidebarLogsAction": "작업 로그",
"logRetention": "로그 보관",
"logRetentionDescription": "다양한 유형의 로그를 이 조직에 대해 얼마나 오래 보관할지 관리하거나 비활성화합니다",
"requestLogsDescription": "이 조직의 자원에 대한 상세한 요청 로그를 봅니다",
"logRetentionRequestLabel": "요청 로그 보관",
"logRetentionRequestDescription": "요청 로그를 얼마나 오래 보관할지",
"logRetentionAccessLabel": "접근 로그 보관",
"logRetentionAccessDescription": "접근 로그를 얼마나 오래 보관할지",
"logRetentionActionLabel": "작업 로그 보관",
"logRetentionActionDescription": "작업 로그를 얼마나 오래 보관할지",
"logRetentionDisabled": "비활성화됨",
"logRetention3Days": "3 일",
"logRetention7Days": "7 일",
"logRetention14Days": "14 일",
"logRetention30Days": "30 일",
"logRetention90Days": "90 일",
"logRetentionForever": "영구",
"actionLogsDescription": "이 조직에서 수행된 작업의 기록을 봅니다",
"accessLogsDescription": "이 조직의 자원에 대한 접근 인증 요청을 확인합니다",
"licenseRequiredToUse": "이 기능을 사용하려면 Enterprise 라이선스가 필요합니다.",
"certResolver": "인증서 해결사",
"certResolverDescription": "이 리소스에 사용할 인증서 해결사를 선택하세요.",
"selectCertResolver": "인증서 해결사 선택",
"enterCustomResolver": "사용자 정의 해결사 입력",
"preferWildcardCert": "와일드카드 인증서 선호",
"unverified": "검증되지 않음",
"domainSetting": "도메인 설정",
"domainSettingDescription": "도메인에 대한 설정을 구성하세요.",
"preferWildcardCertDescription": "와일드카드 인증서를 생성하려고 시도합니다 (올바르게 구성된 인증서 해결사가 필요합니다).",
"recordName": "레코드 이름",
"auto": "자동",
"TTL": "TTL",
"howToAddRecords": "레코드 추가 방법",
"dnsRecord": "DNS 레코드",
"required": "필수",
"domainSettingsUpdated": "도메인 설정이 성공적으로 업데이트되었습니다",
"orgOrDomainIdMissing": "조직 ID 또는 도메인 ID가 누락되었습니다",
"loadingDNSRecords": "DNS 레코드를 로드하는 중...",
"olmUpdateAvailableInfo": "올름의 새 버전이 이용 가능합니다. 최상의 경험을 위해 최신 버전으로 업데이트하세요.",
"client": "클라이언트",
"proxyProtocol": "프록시 프로토콜 설정",
"proxyProtocolDescription": "프록시 프로토콜을 구성하여 TCP/UDP 서비스에 대한 클라이언트 IP 주소를 보존하십시오.",
"enableProxyProtocol": "프록시 프로토콜 활성화",
"proxyProtocolInfo": "TCP/UDP 백엔드의 클라이언트 IP 주소를 보존합니다",
"proxyProtocolVersion": "프록시 프로토콜 버전",
"version1": " 버전 1 (추천)",
"version2": "버전 2",
"versionDescription": "버전 1은 텍스트 기반으로 널리 지원됩니다. 버전 2는 이진 기반으로 더 효율적이지만 호환성이 낮습니다.",
"warning": "경고",
"proxyProtocolWarning": "백엔드 애플리케이션이 프록시 프로토콜 연결을 허용하도록 구성되어야 합니다. 백엔드가 프록시 프로토콜을 지원하지 않으면, 이를 활성화하면 모든 연결이 끊어집니다. 트래픽에서 온 프록시 프로토콜 헤더를 백엔드가 신뢰하도록 구성하십시오.",
"restarting": "재시작 중...",
"manual": "수동",
"messageSupport": "지원 메시지",
"supportNotAvailableTitle": "지원 불가",
"supportNotAvailableDescription": "현재 지원을 받을 수 없습니다. support@pangolin.net으로 이메일을 보낼 수 있습니다.",
"supportRequestSentTitle": "지원 요청 전송 완료",
"supportRequestSentDescription": "메시지가 성공적으로 전송되었습니다.",
"supportRequestFailedTitle": "요청 전송 실패",
"supportRequestFailedDescription": "지원 요청을 보내는 중 오류가 발생했습니다.",
"supportSubjectRequired": "제목은 필수입니다",
"supportSubjectMaxLength": "제목은 255자 이내여야 합니다",
"supportMessageRequired": "메시지는 필수입니다",
"supportReplyTo": "회신",
"supportSubject": "제목",
"supportSubjectPlaceholder": "제목 입력",
"supportMessage": "메시지",
"supportMessagePlaceholder": "메시지를 입력하십시오",
"supportSending": "발송 중...",
"supportSend": "보내기",
"supportMessageSent": "메시지 전송 완료!",
"supportWillContact": "곧 연락드리겠습니다!",
"selectLogRetention": "로그 보존 선택",
"showColumns": "열 표시",
"hideColumns": "열 숨기기",
"columnVisibility": "열 가시성",
"toggleColumn": "{columnName} 열 토글",
"allColumns": "모든 열",
"defaultColumns": "기본 열",
"customizeView": "보기 사용자 지정",
"viewOptions": "보기 옵션",
"selectAll": "모두 선택",
"selectNone": "선택하지 않음",
"selectedResources": "선택된 리소스",
"enableSelected": "선택된 항목 활성화",
"disableSelected": "선택된 항목 비활성화",
"checkSelectedStatus": "선택된 항목 상태 확인",
"credentials": "자격 증명",
"savecredentials": "자격 증명 저장",
"regeneratecredentials": "재생성",
"regenerateCredentials": "자격 증명을 재생성하고 저장합니다",
"generatedcredentials": "생성된 자격 증명",
"copyandsavethesecredentials": "이 자격 증명을 복사하여 저장합니다",
"copyandsavethesecredentialsdescription": "이 페이지를 떠난 후에는 자격 증명이 다시 표시되지 않습니다. 지금 안전하게 저장하십시오.",
"credentialsSaved": "자격 증명 저장됨",
"credentialsSavedDescription": "자격 증명이 성공적으로 재생성 및 저장되었습니다.",
"credentialsSaveError": "자격 증명 저장 오류",
"credentialsSaveErrorDescription": "자격 증명을 재생성하고 저장하는 동안 오류가 발생했습니다.",
"regenerateCredentialsWarning": "자격 증명을 재생성하면 이전 자격 증명이 무효화됩니다. 이 자격 증명을 사용하는 모든 구성을 업데이트하십시오.",
"confirm": "확인",
"regenerateCredentialsConfirmation": "자격 증명을 재생성하시겠습니까?",
"endpoint": "엔드포인트",
"Id": "아이디",
"SecretKey": "비밀 키",
"featureDisabledTooltip": "이 기능은 엔터프라이즈 플랜에서만 사용할 수 있으며 라이센스가 필요합니다.",
"niceId": "예쁜 ID",
"niceIdUpdated": "예쁜 ID 업데이트됨",
"niceIdUpdatedSuccessfully": "예쁜 ID가 성공적으로 업데이트되었습니다",
"niceIdUpdateError": "예쁜 ID 업데이트 오류",
"niceIdUpdateErrorDescription": "예쁜 ID를 업데이트하는 동안 오류가 발생했습니다.",
"niceIdCannotBeEmpty": "예쁜 ID는 비워둘 수 없습니다",
"enterIdentifier": "식별자 입력",
"identifier": "식별자"
}

View File

@@ -47,9 +47,8 @@
"edit": "Rediger",
"siteConfirmDelete": "Bekreft Sletting av Område",
"siteDelete": "Slett Område",
"siteMessageRemove": "Når området slettes, vil det ikke lenger være tilgjengelig. Alle ressurser og mål assosiert med området vil også bli slettet.",
"siteMessageConfirm": "For å bekrefte, vennligst skriv inn navnet i området nedenfor.",
"siteQuestionRemove": "Er du sikker på at du vil slette området {selectedSite} fra organisasjonen?",
"siteMessageRemove": "Når nettstedet er fjernet, vil det ikke lenger være tilgjengelig. Alle målene for nettstedet vil også bli fjernet.",
"siteQuestionRemove": "Er du sikker på at du vil fjerne nettstedet fra organisasjonen?",
"siteManageSites": "Administrer Områder",
"siteDescription": "Tillat tilkobling til nettverket ditt gjennom sikre tunneler",
"siteCreate": "Opprett område",
@@ -96,7 +95,7 @@
"siteWgDescription": "Bruk hvilken som helst WireGuard-klient for å etablere en tunnel. Manuell NAT-oppsett kreves.",
"siteWgDescriptionSaas": "Bruk hvilken som helst WireGuard-klient for å etablere en tunnel. Manuell NAT-oppsett er nødvendig. FUNGERER KUN PÅ SELVHOSTEDE NODER",
"siteLocalDescription": "Kun lokale ressurser. Ingen tunnelering.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Lokale ressurser. Ingen tunnelering. Bare tilgjengelig på eksterne noder.",
"siteSeeAll": "Se alle områder",
"siteTunnelDescription": "Bestem hvordan du vil koble deg til ditt område",
"siteNewtCredentials": "Newt påloggingsinformasjon",
@@ -132,7 +131,7 @@
"expireIn": "Utløper om",
"neverExpire": "Utløper aldri",
"shareExpireDescription": "Utløpstid er hvor lenge lenken vil være brukbar og gi tilgang til ressursen. Etter denne tiden vil lenken ikke lenger fungere, og brukere som brukte denne lenken vil miste tilgangen til ressursen.",
"shareSeeOnce": "Du får bare se denne lenken én gang. Pass på å kopiere den.",
"shareSeeOnce": "Du vil bare kunne se denne linken én gang. Pass på å kopiere den.",
"shareAccessHint": "Alle med denne lenken kan få tilgang til ressursen. Del forsiktig.",
"shareTokenUsage": "Se tilgangstokenbruk",
"createLink": "Opprett lenke",
@@ -154,8 +153,7 @@
"protected": "Beskyttet",
"notProtected": "Ikke beskyttet",
"resourceMessageRemove": "Når den er fjernet, vil ressursen ikke lenger være tilgjengelig. Alle mål knyttet til ressursen vil også bli fjernet.",
"resourceMessageConfirm": "For å bekrefte, skriv inn navnet på ressursen nedenfor.",
"resourceQuestionRemove": "Er du sikker på at du vil fjerne ressursen {selectedResource} fra organisasjonen?",
"resourceQuestionRemove": "Er du sikker på at du vil fjerne ressursen fra organisasjonen?",
"resourceHTTP": "HTTPS-ressurs",
"resourceHTTPDescription": "Proxy-forespørsler til appen din over HTTPS ved bruk av et underdomene eller grunndomene.",
"resourceRaw": "Rå TCP/UDP-ressurs",
@@ -181,7 +179,7 @@
"baseDomain": "Grunndomene",
"subdomnainDescription": "Underdomenet der ressursen din vil være tilgjengelig.",
"resourceRawSettings": "TCP/UDP-innstillinger",
"resourceRawSettingsDescription": "Konfigurer tilgang til ressursen din over TCP/UDP",
"resourceRawSettingsDescription": "Konfigurer hvordan din ressurs vil bli tilgjengelig over TCP/UDP. Du kartlegger ressursen til en port på vertsserveren Pangolin slik at du får tilgang til ressursene fra server-ip:mappet port.",
"protocol": "Protokoll",
"protocolSelect": "Velg en protokoll",
"resourcePortNumber": "Portnummer",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Bekreft Sletting av Organisasjon",
"orgMessageRemove": "Denne handlingen er irreversibel og vil slette alle tilknyttede data.",
"orgMessageConfirm": "For å bekrefte, vennligst skriv inn navnet på organisasjonen nedenfor.",
"orgQuestionRemove": "Er du sikker på at du vil fjerne organisasjonen {selectedOrg}?",
"orgQuestionRemove": "Er du sikker på at du vil fjerne organisasjonen?",
"orgUpdated": "Organisasjon oppdatert",
"orgUpdatedDescription": "Organisasjonen har blitt oppdatert.",
"orgErrorUpdate": "Kunne ikke oppdatere organisasjonen",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Generer API-nøkkel",
"apiKeysErrorDelete": "Feil under sletting av API-nøkkel",
"apiKeysErrorDeleteMessage": "Feil ved sletting av API-nøkkel",
"apiKeysQuestionRemove": "Er du sikker på at du vil fjerne API-nøkkelen {selectedApiKey} fra organisasjonen?",
"apiKeysQuestionRemove": "Er du sikker på at du vil fjerne API-nøkkelen fra organisasjonen?",
"apiKeysMessageRemove": "Når den er fjernet, vil API-nøkkelen ikke lenger kunne brukes.",
"apiKeysMessageConfirm": "For å bekrefte, vennligst skriv inn navnet på API-nøkkelen nedenfor.",
"apiKeysDeleteConfirm": "Bekreft sletting av API-nøkkel",
"apiKeysDelete": "Slett API-nøkkel",
"apiKeysManage": "Administrer API-nøkler",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Bekreft sletting av bruker",
"userDeleteServer": "Slett bruker fra server",
"userMessageRemove": "Brukeren vil bli fjernet fra alle organisasjoner og vil bli fullstendig fjernet fra serveren.",
"userMessageConfirm": "For å bekrefte, vennligst skriv inn navnet på brukeren nedenfor.",
"userQuestionRemove": "Er du sikker på at du vil slette {selectedUser} permanent fra serveren?",
"userQuestionRemove": "Er du sikker på at du vil slette brukeren permanent fra serveren?",
"licenseKey": "Lisensnøkkel",
"valid": "Gyldig",
"numberOfSites": "Antall områder",
@@ -339,7 +335,7 @@
"fossorialLicense": "Vis Fossorial kommersiell lisens og abonnementsvilkår",
"licenseMessageRemove": "Dette vil fjerne lisensnøkkelen og alle tilknyttede tillatelser gitt av den.",
"licenseMessageConfirm": "For å bekrefte, vennligst skriv inn lisensnøkkelen nedenfor.",
"licenseQuestionRemove": "Er du sikker på at du vil slette lisensnøkkelen {selectedKey} ?",
"licenseQuestionRemove": "Er du sikker på at du vil slette lisensnøkkelen?",
"licenseKeyDelete": "Slett Lisensnøkkel",
"licenseKeyDeleteConfirm": "Bekreft sletting av lisensnøkkel",
"licenseTitle": "Behandle lisensstatus",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Det oppstod en feil under fjerning av invitasjonen.",
"inviteRemoved": "Invitasjon fjernet",
"inviteRemovedDescription": "Invitasjonen for {email} er fjernet.",
"inviteQuestionRemove": "Er du sikker på at du vil fjerne invitasjonen {email}?",
"inviteQuestionRemove": "Er du sikker på at du vil fjerne invitasjonen?",
"inviteMessageRemove": "Når fjernet, vil denne invitasjonen ikke lenger være gyldig. Du kan alltid invitere brukeren på nytt senere.",
"inviteMessageConfirm": "For å bekrefte, vennligst tast inn invitasjonens e-postadresse nedenfor.",
"inviteQuestionRegenerate": "Er du sikker på at du vil generere invitasjonen på nytt for {email}? Dette vil ugyldiggjøre den forrige invitasjonen.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Det oppstod en feil under fjerning av brukeren.",
"userOrgRemoved": "Bruker fjernet",
"userOrgRemovedDescription": "Brukeren {email} er fjernet fra organisasjonen.",
"userQuestionOrgRemove": "Er du sikker på at du vil fjerne {email} fra organisasjonen?",
"userQuestionOrgRemove": "Er du sikker på at du vil fjerne denne brukeren fra organisasjonen?",
"userMessageOrgRemove": "Når denne brukeren er fjernet, vil de ikke lenger ha tilgang til organisasjonen. Du kan alltid invitere dem på nytt senere, men de vil måtte godta invitasjonen på nytt.",
"userMessageOrgConfirm": "For å bekrefte, vennligst skriv inn navnet på brukeren nedenfor.",
"userRemoveOrgConfirm": "Bekreft fjerning av bruker",
"userRemoveOrg": "Fjern bruker fra organisasjon",
"users": "Brukere",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Server Admin - Pangolin",
"licenseTierProfessional": "Profesjonell lisens",
"licenseTierEnterprise": "Bedriftslisens",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Personlig lisens",
"licensed": "Lisensiert",
"yes": "Ja",
"no": "Nei",
@@ -742,7 +737,7 @@
"idpManageDescription": "Vis og administrer identitetsleverandører i systemet",
"idpDeletedDescription": "Identitetsleverandør slettet vellykket",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Er du sikker på at du vil slette identitetsleverandøren {name} permanent?",
"idpQuestionRemove": "Er du sikker på at du vil slette identitetsleverandøren permanent?",
"idpMessageRemove": "Dette vil fjerne identitetsleverandøren og alle tilhørende konfigurasjoner. Brukere som autentiserer seg via denne leverandøren vil ikke lenger kunne logge inn.",
"idpMessageConfirm": "For å bekrefte, vennligst skriv inn navnet på identitetsleverandøren nedenfor.",
"idpConfirmDelete": "Bekreft Sletting av Identitetsleverandør",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Sjekk e-posten din for tilbakestillingskoden.",
"passwordNew": "Nytt passord",
"passwordNewConfirm": "Bekreft nytt passord",
"changePassword": "Endre passord",
"changePasswordDescription": "Oppdater passordet for din konto",
"oldPassword": "Nåværende passord",
"newPassword": "Nytt passord",
"confirmNewPassword": "Bekreft nytt passord",
"changePasswordError": "Kunne ikke endre passord",
"changePasswordErrorDescription": "Det oppstod en feil under endring av passordet",
"changePasswordSuccess": "Passordet er endret",
"changePasswordSuccessDescription": "Ditt passord ble oppdatert",
"passwordExpiryRequired": "Passordutløp kreves",
"passwordExpiryDescription": "Denne organisasjonen krever at du bytter passord hver {maxDays} dag.",
"changePasswordNow": "Bytt passord nå",
"pincodeAuth": "Autentiseringskode",
"pincodeSubmit2": "Send inn kode",
"passwordResetSubmit": "Be om tilbakestilling",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Alle brukere",
"sidebarIdentityProviders": "Identitetsleverandører",
"sidebarLicense": "Lisens",
"sidebarClients": "Clients",
"sidebarClients": "Klienter",
"sidebarDomains": "Domener",
"sidebarBluePrints": "Tegninger",
"blueprints": "Tegninger",
"blueprintsDescription": "Bruk deklarative konfigurasjoner og vis tidligere kjøringer",
"blueprintAdd": "Legg til blåkopi",
"blueprintGoBack": "Se alle blåkopier",
"blueprintCreate": "Opprette mal",
"blueprintCreateDescription2": "Følg trinnene nedenfor for å opprette og bruke en ny plantegning",
"blueprintDetails": "Blåkopi detaljer",
"blueprintDetailsDescription": "Se resultatet av den påførte blåkopien og alle feil som oppstod",
"blueprintInfo": "Blåkopi informasjon",
"message": "Melding",
"blueprintContentsDescription": "Definer innhold av YAML som beskriver din infrastruktur",
"blueprintErrorCreateDescription": "Det oppstod en feil da plantegningen ble lagt til",
"blueprintErrorCreate": "Feil ved opprettelse av plantegning",
"searchBlueprintProgress": "Søk etter plantegninger...",
"appliedAt": "Anvendt på",
"source": "Kilde",
"contents": "Innhold",
"parsedContents": "Parastinnhold (kun lese)",
"enableDockerSocket": "Aktiver Docker blåkopi",
"enableDockerSocketDescription": "Aktiver skraping av Docker Socket for blueprint Etiketter. Socket bane må brukes for nye.",
"enableDockerSocketLink": "Lær mer",
@@ -1211,9 +1237,8 @@
"domainCreate": "Opprett domene",
"domainCreatedDescription": "Domene ble opprettet",
"domainDeletedDescription": "Domene ble slettet",
"domainQuestionRemove": "Er du sikker på at du vil fjerne domenet {domain} fra kontoen din?",
"domainQuestionRemove": "Er du sikker på at du vil fjerne domenet fra kontoen din?",
"domainMessageRemove": "Når domenet er fjernet, vil det ikke lenger være knyttet til kontoen din.",
"domainMessageConfirm": "For å bekrefte, vennligst skriv inn domenenavnet nedenfor.",
"domainConfirmDelete": "Bekreft sletting av domene",
"domainDelete": "Slett domene",
"domain": "Domene",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "En feil oppstod under oppdatering av innstillinger",
"sidebarCollapse": "Skjul",
"sidebarExpand": "Utvid",
"productUpdateMoreInfo": "{noOfUpdates} flere oppdateringer",
"productUpdateInfo": "{noOfUpdates} oppdateringer",
"productUpdateWhatsNew": "Hva er nytt",
"productUpdateTitle": "Oppdateringer om produktet",
"productUpdateEmpty": "Ingen oppdateringer",
"dismissAll": "Avvis alle",
"pangolinUpdateAvailable": "Ny versjon tilgjengelig",
"pangolinUpdateAvailableInfo": "Versjon {version} er klar til å installere",
"pangolinUpdateAvailableReleaseNotes": "Se utgivelsnotater",
"newtUpdateAvailable": "Oppdatering tilgjengelig",
"newtUpdateAvailableInfo": "En ny versjon av Newt er tilgjengelig. Vennligst oppdater til den nyeste versjonen for den beste opplevelsen.",
"domainPickerEnterDomain": "Domene",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Gratis nivå",
"billingWarningOverLimit": "Advarsel: Du har overskredet en eller flere bruksgrenser. Nettstedene dine vil ikke koble til før du endrer abonnementet ditt eller justerer bruken.",
"billingUsageLimitsOverview": "Oversikt over bruksgrenser",
"billingMonitorUsage": "Overvåk bruken din i forhold til konfigurerte grenser. Hvis du trenger økte grenser, vennligst kontakt support@fossorial.io.",
"billingMonitorUsage": "Overvåk bruken din i forhold til konfigurerte grenser. Hvis du trenger økte grenser, vennligst kontakt support@pangolin.net.",
"billingDataUsage": "Databruk",
"billingOnlineTime": "Online tid for nettsteder",
"billingUsers": "Aktive brukere",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Det oppstod et problem med å bruke sikkerhetsnøkkelen din. Vennligst prøv igjen.",
"twoFactorRequired": "Tofaktorautentisering er påkrevd for å registrere en sikkerhetsnøkkel.",
"twoFactor": "Tofaktorautentisering",
"twoFactorAuthentication": "To-faktor autentisering",
"twoFactorDescription": "Denne organisasjonen krever to-faktor-autentisering.",
"enableTwoFactor": "Aktiver to-faktor autentisering",
"organizationSecurityPolicy": "Retningslinjer for organisasjons sikkerhet",
"organizationSecurityPolicyDescription": "Denne organisasjonen har sikkerhetskrav som må oppfylles før du får tilgang til den",
"securityRequirements": "Krav Til Sikkerhet",
"allRequirementsMet": "Alle krav er oppfylt",
"completeRequirementsToContinue": "Fullfør kravene nedenfor for å fortsette tilgangen til denne organisasjonen",
"youCanNowAccessOrganization": "Du har nå tilgang til denne organisasjonen",
"reauthenticationRequired": "Økt lengde",
"reauthenticationDescription": "Denne organisasjonen krever at du logger på alle {maxDays} dager.",
"reauthenticationDescriptionHours": "Denne organisasjonen krever at du logger inn hver {maxHours} time.",
"reauthenticateNow": "Logg inn igjen",
"adminEnabled2FaOnYourAccount": "Din administrator har aktivert tofaktorautentisering for {email}. Vennligst fullfør oppsettsprosessen for å fortsette.",
"securityKeyAdd": "Legg til sikkerhetsnøkkel",
"securityKeyRegisterTitle": "Registrer ny sikkerhetsnøkkel",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Disse ressursene er til bruk med",
"resourcesTableClients": "Klienter",
"resourcesTableAndOnlyAccessibleInternally": "og er kun tilgjengelig internt når de er koblet til med en klient.",
"resourcesTableNoTargets": "Ingen mål",
"resourcesTableHealthy": "Frisk",
"resourcesTableDegraded": "Nedgradert",
"resourcesTableOffline": "Frakoblet",
"resourcesTableUnknown": "Ukjent",
"resourcesTableNotMonitored": "Ikke overvåket",
"editInternalResourceDialogEditClientResource": "Rediger klientressurs",
"editInternalResourceDialogUpdateResourceProperties": "Oppdater ressursens egenskaper og målkonfigurasjon for {resourceName}.",
"editInternalResourceDialogResourceProperties": "Ressursegenskaper",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Ingen omdirigerings-URL mottatt fra identitetsleverandøren.",
"autoLoginErrorGeneratingUrl": "Kunne ikke generere autentiserings-URL.",
"remoteExitNodeManageRemoteExitNodes": "Eksterne Noder",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Selvbetjent én eller flere eksterne noder for å utvide nettverkstilkoblingen din og redusere avhengighet på skyen",
"remoteExitNodes": "Noder",
"searchRemoteExitNodes": "Søk noder...",
"remoteExitNodeAdd": "Legg til Node",
"remoteExitNodeErrorDelete": "Feil ved sletting av node",
"remoteExitNodeQuestionRemove": "Er du sikker på at du vil fjerne noden {selectedNode} fra organisasjonen?",
"remoteExitNodeQuestionRemove": "Er du sikker på at du vil fjerne noden fra organisasjonen?",
"remoteExitNodeMessageRemove": "Når noden er fjernet, vil ikke lenger være tilgjengelig.",
"remoteExitNodeMessageConfirm": "For å bekrefte, skriv inn navnet på noden nedenfor.",
"remoteExitNodeConfirmDelete": "Bekreft sletting av Node",
"remoteExitNodeDelete": "Slett Node",
"sidebarRemoteExitNodes": "Eksterne Noder",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Rediger fil: docker-compose.yml",
"emailVerificationRequired": "E-postbekreftelse er nødvendig. Logg inn på nytt via {dashboardUrl}/auth/login og fullfør dette trinnet. Kom deretter tilbake her.",
"twoFactorSetupRequired": "To-faktor autentiseringsoppsett er nødvendig. Vennligst logg inn igjen via {dashboardUrl}/auth/login og fullfør dette steget. Kom deretter tilbake her.",
"additionalSecurityRequired": "Ekstra sikkerhet kreves",
"organizationRequiresAdditionalSteps": "Denne organisasjonen krever ytterligere sikkerhetstrinn før du får tilgang til ressurser.",
"completeTheseSteps": "Fullfør disse trinnene",
"enableTwoFactorAuthentication": "Aktiver to-faktor autentisering",
"completeSecuritySteps": "Fullfør sikkerhetstrinnene",
"securitySettings": "Sikkerhet innstillinger",
"securitySettingsDescription": "Konfigurere sikkerhetspolicyer for din organisasjon",
"requireTwoFactorForAllUsers": "Krev to-faktor autentisering for alle brukere",
"requireTwoFactorDescription": "Når aktivert må alle interne brukere i denne organisasjonen ha to-faktorautentisering aktivert for å få tilgang til organisasjonen.",
"requireTwoFactorDisabledDescription": "Denne funksjonen krever en gyldig lisens (Enterprise) eller aktivt abonnement (SaaS)",
"requireTwoFactorCannotEnableDescription": "Du må aktivere to-faktor-autentisering for din konto før det håndheves for alle brukere",
"maxSessionLength": "Maksimal øktlengde",
"maxSessionLengthDescription": "Angi maksimal varighet for brukerøkter. Etter denne gangen må brukerne logge inn på nytt.",
"maxSessionLengthDisabledDescription": "Denne funksjonen krever en gyldig lisens (Enterprise) eller aktivt abonnement (SaaS)",
"selectSessionLength": "Velg øktlengde",
"unenforced": "Tvungen",
"1Hour": "1 time",
"3Hours": "3 timer",
"6Hours": "6 timer",
"12Hours": "12 timer",
"1DaySession": "1 dag",
"3Days": "3 dager",
"7Days": "7 dager",
"14Days": "14 dager",
"30DaysSession": "30 dager",
"90DaysSession": "90 dager",
"180DaysSession": "180 dager",
"passwordExpiryDays": "Passord utløper",
"editPasswordExpiryDescription": "Angi antall dager før brukere må endre passordet sitt.",
"selectPasswordExpiry": "Velg passordutløp",
"30Days": "30 dager",
"1Day": "1 dag",
"60Days": "60 dager",
"90Days": "90 dager",
"180Days": "180 dager",
"1Year": "1 år",
"subscriptionBadge": "Abonnement kreves",
"securityPolicyChangeWarning": "Sikkerhetsregler forandring advarsel",
"securityPolicyChangeDescription": "Du er i ferd med å endre innstillingene for sikkerhetspolicy. Etter å ha spart må du kanskje gjenopplogge deg på for å oppfylle disse policyoppdateringene. Alle brukere som ikke samsvarer vil også måtte autentisere.",
"securityPolicyChangeConfirmMessage": "Jeg bekrefter",
"securityPolicyChangeWarningText": "Dette vil påvirke alle brukere i organisasjonen",
"authPageErrorUpdateMessage": "Det oppstod en feil under oppdatering av innstillingene for godkjenningssiden",
"authPageErrorUpdate": "Kunne ikke oppdatere autoriseringssiden",
"authPageUpdated": "Godkjenningsside oppdatert",
"healthCheckNotAvailable": "Lokal",
"rewritePath": "Omskriv sti",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Topplinje autentisering fjernet.",
"resourceErrorHeaderAuthRemove": "Kunne ikke fjerne topptekst autentisering",
"resourceErrorHeaderAuthRemoveDescription": "Kunne ikke fjerne topptekst autentisering for ressursen.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Topplinje autentisering aktivert",
"resourceHeaderAuthProtectionDisabled": "Topplinje autentisering deaktivert",
"headerAuthRemove": "Fjern topptekst Auth",
"headerAuthAdd": "Legg til topptekst godkjenning",
"resourceErrorHeaderAuthSetup": "Kunne ikke sette topptekst autentisering",
"resourceErrorHeaderAuthSetupDescription": "Kunne ikke sette topplinje autentisering for ressursen.",
"resourceHeaderAuthSetup": "Header godkjenningssett var vellykket",
"resourceHeaderAuthSetupDescription": "Topplinje autentisering har blitt lagret.",
"resourceHeaderAuthSetupTitle": "Angi topptekst godkjenning",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Angi grunnleggende auth legitimasjon (brukernavn og passord) for å beskytte denne ressursen med HTTP Header autentisering. Tilgang til det ved hjelp av formatet https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Angi topptekst godkjenning",
"actionSetResourceHeaderAuth": "Angi topptekst godkjenning",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"unlicensed": "Ikke lisensiert",
"beta": "beta",
"manageClients": "Administrer klienter",
"manageClientsDescription": "Klienter er enheter som kan koble seg til nettstedet ditt",
"licenseTableValidUntil": "Gyldig til",
"saasLicenseKeysSettingsTitle": "Bedriftstillatelse Lisenser",
"saasLicenseKeysSettingsDescription": "Generer og administrer Enterprise lisensnøkler for selvbetjente Pangolin forekomster",
"sidebarEnterpriseLicenses": "Lisenser",
"generateLicenseKey": "Generer lisensnøkkel",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Vennligst skriv inn en gyldig e-postadresse",
"useCaseTypeRequired": "Vennligst velg en bruk sakstype",
"firstNameRequired": "Fornavn er påkrevd",
"lastNameRequired": "Etternavn er påkrevd",
"primaryUseRequired": "Beskriv din primære bruk",
"jobTitleRequiredBusiness": "Jobbtittel er påkrevd for forretningsbruk",
"industryRequiredBusiness": "Næringslivet må til forretningsbruk",
"stateProvinceRegionRequired": "Stat/provins/region kreves",
"postalZipCodeRequired": "Postnummer er påkrevd",
"companyNameRequiredBusiness": "Firmanavn er påkrevd for bedriftens bruk",
"countryOfResidenceRequiredBusiness": "Land som skal oppholde seg er nødvendig for bruk til forretningsdrift",
"countryRequiredPersonal": "Land er påkrevd for personlig bruk",
"agreeToTermsRequired": "Du må godta vilkårene",
"complianceConfirmationRequired": "Du må bekrefte at du overholder Fossorial Kommersiell lisens"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Personlig bruk",
"description": "For enkeltpersoner, ikke-kommersiell bruk som læring, personlige prosjekter eller eksperimentering."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Forretningsmessig bruk",
"description": "Til bruk innenfor organisasjoner eller virksomheter eller forretningsmessige inntekter eller aktiviteter."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "E-post & lisenstype",
"description": "Skriv inn e-postadressen din og velg lisenstypen din"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Personlig Informasjon",
"description": "Fortell oss om deg selv"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Kontakt Informasjon",
"description": "Dine kontaktopplysninger"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Vilkår og generere",
"description": "Se gjennom og godta vilkårene for å generere lisensen"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Bruk utlevering",
"description": "Velg lisensnivået som reflekterer nøyaktig din tiltenkte bruk. Personlige lisenser tillater fri bruk av programvare for enkelte, ikke-kommersielle eller småskala kommersielle aktiviteter, med en årlig brutto inntekt på under 100 000 amerikanske dollar. All bruk ut over disse grensene inkludert bruk innenfor en virksomhet, organisasjon eller andre inntekter miljø - krever en gyldig Enterprise lisens og betaling av gjeldende lisensavgift. Alle brukere, enten personlig eller Enterprise, må overholde de kommersielle tillatelsene på Fossorial."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Informasjon om prøveperiode",
"description": "Denne lisensnøkkelen tillater funksjoner i Enterprise for en 7-dagers evalueringsperiode. Fortsatt tilgang til betalt funksjoner utenfor evalueringsperioden krever aktivering under en gyldig Personlig eller Enterprise License. For Enterprise licensing, kontakt sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Bruker du Pangolin for personlig eller forretningsbruk?",
"firstName": "Fornavn",
"lastName": "Etternavn (Automatic Translation)",
"jobTitle": "Jobb tittel",
"primaryUseQuestion": "Hva planlegger du først og fremst å bruke Pangolin for?",
"industryQuestion": "Hva er din industri?",
"prospectiveUsersQuestion": "Hvor mange prospektive brukere forventer du å ha?",
"prospectiveSitesQuestion": "Hvor mange prospektive nettsteder (tunnels) forventer du å ha?",
"companyName": "Navn på bedrift",
"countryOfResidence": "Oppholdsland",
"stateProvinceRegion": "Fylke / Region",
"postalZipCode": "Postnummer / postnummer",
"companyWebsite": "Firmaets hjemmeside",
"companyPhoneNumber": "Firmaets telefonnummer",
"country": "Land",
"phoneNumberOptional": "Telefonnummer (valgfritt)",
"complianceConfirmation": "Jeg bekrefter at opplysningene jeg oppga er korrekte og at jeg er i samsvar med Fossorial Kommersiell Lisens. Rapportering av unøyaktig informasjon eller feilidentifisering av bruk av produktet bryter lisensen, og kan føre til at nøkkelen din blir opphevet."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Lukk",
"previous": "Forrige",
"next": "Neste",
"generateLicenseKey": "Generer lisensnøkkel"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Lisensnøkkel ble generert",
"description": "Din lisensnøkkel har blitt generert og er klar til bruk."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Kan ikke generere lisensnøkkel",
"description": "Det oppstod en feil ved generering av lisensnøkkelen."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Forekomst navn",
"pathMatchModalTitle": "Konfigurere matching av sti",
"pathMatchModalDescription": "Sett opp hvordan innkommende forespørsler skal matches basert på deres bane.",
"pathMatchType": "Trefftype",
"pathMatchPrefix": "Prefiks",
"pathMatchExact": "Nøyaktig",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Verdi for sti",
"clear": "Tøm",
"saveChanges": "Lagre endringer",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathMatchDefaultPlaceholder": "/sti",
"pathMatchPrefixHelp": "Eksempel: /api matcher /api, /api/users, etc.",
"pathMatchExactHelp": "Eksempel: /api passer bare /api",
"pathMatchRegexHelp": "Eksempel: ^/api/.* matcher /api/alt",
"pathRewriteModalTitle": "Konfigurer ferdigskriving av sti",
"pathRewriteModalDescription": "Overfør banen som passet før den videresendes til målet.",
"pathRewriteType": "Omskriv type",
"pathRewritePrefixOption": "Prefiks - erstatt prefiks",
"pathRewriteExactOption": "Eksakt - Erstatt hele banen",
"pathRewriteRegexOption": "Regex - Ekkobilde",
"pathRewriteStripPrefixOption": "Ta bort prefiks - fjern prefiks",
"pathRewriteValue": "Omskriv verdi",
"pathRewriteRegexPlaceholder": "/ny/$1",
"pathRewriteDefaultPlaceholder": "/ny sti",
"pathRewritePrefixHelp": "Erstatt det samsvarende prefikset med denne verdien",
"pathRewriteExactHelp": "Erstatt hele banen med denne verdien når stien samsvarer nøyaktig",
"pathRewriteRegexHelp": "Bruk opptaksgrupper som $1, $2 for erstatning",
"pathRewriteStripPrefixHelp": "La stå tomt for å ta opp prefiks eller legge til nytt prefiks",
"pathRewritePrefix": "Prefiks",
"pathRewriteExact": "Nøyaktig",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Stripe",
"pathRewriteStripLabel": "stripe",
"sidebarEnableEnterpriseLicense": "Aktiver Enterprise lisens",
"cannotbeUndone": "Dette kan ikke angres.",
"toConfirm": "å bekrefte",
"deleteClientQuestion": "Er du sikker på at du vil fjerne klienten fra nettstedet og organisasjonen?",
"clientMessageRemove": "Når klienten er fjernet, kan den ikke lenger koble seg til nettstedet.",
"sidebarLogs": "Logger",
"request": "Forespørsel",
"logs": "Logger",
"logsSettingsDescription": "Overvåk logger samlet fra denne orginiasjonen",
"searchLogs": "Søk i logger...",
"action": "Handling",
"actor": "Aktør",
"timestamp": "Tidsstempel",
"accessLogs": "Tilgangslogger (Automatic Translation)",
"exportCsv": "Eksportere CSV",
"actorId": "Skuespiller ID",
"allowedByRule": "Tillatt etter regel",
"allowedNoAuth": "Tillatt Ingen Auth",
"validAccessToken": "Gyldig tilgangsnøkkel",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Gyldig passord",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Ressurs blokkert",
"droppedByRule": "Legg i regelen",
"noSessions": "Ingen økter",
"temporaryRequestToken": "Midlertidig forespørsel Token",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP",
"reason": "Grunn",
"requestLogs": "Forespørselslogger (Automatic Translation)",
"host": "Vert",
"location": "Sted",
"actionLogs": "Handlingslogger",
"sidebarLogsRequest": "Forespørselslogger (Automatic Translation)",
"sidebarLogsAccess": "Tilgangslogger (Automatic Translation)",
"sidebarLogsAction": "Handlingslogger",
"logRetention": "Logg tilbaketrekning",
"logRetentionDescription": "Håndter hvor lenge ulike typer logger beholdes for denne organisasjonen, eller deaktiver dem",
"requestLogsDescription": "Se detaljerte forespørselslogger for ressurser i denne organisasjonen",
"logRetentionRequestLabel": "Be om loggoverføring",
"logRetentionRequestDescription": "Hvor lenge du vil beholde forespørselslogger",
"logRetentionAccessLabel": "Få tilgang til loggoverføring",
"logRetentionAccessDescription": "Hvor lenge du vil beholde adgangslogger",
"logRetentionActionLabel": "Handlings logg nytt",
"logRetentionActionDescription": "Hvor lenge handlingen skal lagres",
"logRetentionDisabled": "Deaktivert",
"logRetention3Days": "3 dager",
"logRetention7Days": "7 dager",
"logRetention14Days": "14 dager",
"logRetention30Days": "30 dager",
"logRetention90Days": "90 dager",
"logRetentionForever": "Alltid",
"actionLogsDescription": "Vis historikk for handlinger som er utført i denne organisasjonen",
"accessLogsDescription": "Vis autoriseringsforespørsler for ressurser i denne organisasjonen",
"licenseRequiredToUse": "En Enterprise lisens er påkrevd for å bruke denne funksjonen.",
"certResolver": "Sertifikat løser",
"certResolverDescription": "Velg sertifikatløser som skal brukes for denne ressursen.",
"selectCertResolver": "Velg sertifikatløser",
"enterCustomResolver": "Legg inn egendefinert løser",
"preferWildcardCert": "Foretrekk Wildcard sertifikat",
"unverified": "Uverifisert",
"domainSetting": "Domene innstillinger",
"domainSettingDescription": "Konfigurer innstillinger for ditt domene",
"preferWildcardCertDescription": "Forsøk på å generere et jokertegn (krever en riktig konfigurert sertifikatløsning).",
"recordName": "Lagre navn",
"auto": "Automatisk",
"TTL": "TTL",
"howToAddRecords": "Hvordan legge til poster",
"dnsRecord": "DNS registre",
"required": "Påkrevd",
"domainSettingsUpdated": "Domene innstillinger ble oppdatert",
"orgOrDomainIdMissing": "ID for organisasjon eller domene mangler",
"loadingDNSRecords": "Laster DNS-poster...",
"olmUpdateAvailableInfo": "En oppdatert versjon av Olm er tilgjengelig. Oppdater til den nyeste versjonen for å få den beste opplevelsen.",
"client": "Klient",
"proxyProtocol": "Protokoll innstillinger for Protokoll",
"proxyProtocolDescription": "Konfigurer Proxy-protokoll for å bevare klientens IP-adresser til TCP/UDP tjenester.",
"enableProxyProtocol": "Aktiver Proxy-protokoll",
"proxyProtocolInfo": "Bevar klientens IP-adresser for TCP/UDP bakover",
"proxyProtocolVersion": "Proxy protokoll versjon",
"version1": " Versjon 1 (Anbefalt)",
"version2": "Versjon 2",
"versionDescription": "Versjon 1 er tekstbasert og støttet. Versjon 2 er binært og mer effektivt, men mindre kompatibel.",
"warning": "Advarsel",
"proxyProtocolWarning": "Din backend applikasjon må være konfigurert for å godta Proxy Protokoller. Hvis din backend ikke støtter Proxy Protocol, vil aktivering av dette bryte alle tilkoblinger. Sørg for å konfigurere backend til å stole på Proxy Protokoll overskrifter fra Traefik.",
"restarting": "Restarter...",
"manual": "Manuell",
"messageSupport": "Støtte for melding",
"supportNotAvailableTitle": "Støtte ikke tilgjengelig",
"supportNotAvailableDescription": "Støtte er ikke tilgjengelig akkurat nå. Du kan sende en e-post til support@pangolin.net.",
"supportRequestSentTitle": "Supportforespørsel sendt",
"supportRequestSentDescription": "Din melding er sendt.",
"supportRequestFailedTitle": "Kunne ikke sende forespørsel",
"supportRequestFailedDescription": "En feil oppstod under sending av din forespørsel om støtte.",
"supportSubjectRequired": "Emne er påkrevd",
"supportSubjectMaxLength": "Emne må være 255 tegn eller mindre",
"supportMessageRequired": "Melding er påkrevd",
"supportReplyTo": "Svar til",
"supportSubject": "Emne",
"supportSubjectPlaceholder": "Angi emne",
"supportMessage": "Melding",
"supportMessagePlaceholder": "Skriv din melding",
"supportSending": "Sender...",
"supportSend": "Sende",
"supportMessageSent": "Melding sendt!",
"supportWillContact": "Vi kommer raskt til å ta kontakt!",
"selectLogRetention": "Velg oppbevaring av logg",
"showColumns": "Vis kolonner",
"hideColumns": "Skjul kolonner",
"columnVisibility": "Kolonne Synlighet",
"toggleColumn": "Veksle {columnName} kolonne",
"allColumns": "Alle kolonner",
"defaultColumns": "Standard kolonner",
"customizeView": "Tilpass visning",
"viewOptions": "Vis alternativer",
"selectAll": "Velg alle",
"selectNone": "Velg ingen",
"selectedResources": "Valgte ressurser",
"enableSelected": "Aktiver valgte",
"disableSelected": "Deaktiver valgte",
"checkSelectedStatus": "Kontroller status for valgte",
"credentials": "Legitimasjon",
"savecredentials": "Lagre brukeropplysninger",
"regeneratecredentials": "Ny nøkkel",
"regenerateCredentials": "Regenerer og lagre opplysningene dine",
"generatedcredentials": "Genererte brukeropplysninger",
"copyandsavethesecredentials": "Kopier og lagre disse opplysningene",
"copyandsavethesecredentialsdescription": "Disse opplysningene vil ikke bli vist igjen etter at du forlater siden. Lagre dem trygt nå.",
"credentialsSaved": "Påloggingsinformasjon lagret",
"credentialsSavedDescription": "Påloggingsinformasjonen har blitt regenerert og lagret.",
"credentialsSaveError": "Påloggingsinformasjon lagre feil",
"credentialsSaveErrorDescription": "En feil oppstod under regenerering og lagring av legitimasjon.",
"regenerateCredentialsWarning": "Regenerering av legitimasjon vil ugyldiggjøre de forrige. Sørg for at alle konfigurasjoner som bruker disse legitimasjonene.",
"confirm": "Bekreft",
"regenerateCredentialsConfirmation": "Er du sikker på at du vil regenerere legetimasjonene?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Hemmelig nøkkel",
"featureDisabledTooltip": "Denne funksjonen er bare tilgjengelig i virksomhetsplanen og krever en lisens til å bruke den.",
"niceId": "God ID",
"niceIdUpdated": "Flott ID oppdatert",
"niceIdUpdatedSuccessfully": "Id-en ble oppdatert",
"niceIdUpdateError": "Feil under oppdatering av hyggelig ID",
"niceIdUpdateErrorDescription": "Det oppstod en feil under oppdatering av Nice ID.",
"niceIdCannotBeEmpty": "God ID kan ikke være tom",
"enterIdentifier": "Angi identifikator",
"identifier": "Identifier"
}

View File

@@ -47,9 +47,8 @@
"edit": "Bewerken",
"siteConfirmDelete": "Verwijderen van site bevestigen",
"siteDelete": "Site verwijderen",
"siteMessageRemove": "Eenmaal verwijderd, zal de site niet langer toegankelijk zijn. Alle bronnen en doelen die aan de site zijn gekoppeld, zullen ook worden verwijderd.",
"siteMessageConfirm": "Typ ter bevestiging de naam van de site hieronder.",
"siteQuestionRemove": "Weet u zeker dat u de site {selectedSite} uit de organisatie wilt verwijderen?",
"siteMessageRemove": "Eenmaal verwijderd zal de site niet langer toegankelijk zijn. Alle aan de site gekoppelde doelen zullen ook worden verwijderd.",
"siteQuestionRemove": "Weet u zeker dat u de site wilt verwijderen uit de organisatie?",
"siteManageSites": "Sites beheren",
"siteDescription": "Verbindt met uw netwerk via beveiligde tunnels",
"siteCreate": "Site maken",
@@ -96,7 +95,7 @@
"siteWgDescription": "Gebruik een WireGuard client om een tunnel te bouwen. Handmatige NAT installatie vereist.",
"siteWgDescriptionSaas": "Gebruik elke WireGuard-client om een tunnel op te zetten. Handmatige NAT-instelling vereist. WERKT ALLEEN OP SELF HOSTED NODES",
"siteLocalDescription": "Alleen lokale bronnen. Geen tunneling.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Enkel lokale bronnen. Geen tunneling. Alleen beschikbaar op externe knooppunten.",
"siteSeeAll": "Alle sites bekijken",
"siteTunnelDescription": "Bepaal hoe u verbinding wilt maken met uw site",
"siteNewtCredentials": "Nieuwste aanmeldgegevens",
@@ -132,7 +131,7 @@
"expireIn": "Vervalt in",
"neverExpire": "Nooit verlopen",
"shareExpireDescription": "Vervaltijd is hoe lang de link bruikbaar is en geeft toegang tot de bron. Na deze tijd zal de link niet meer werken en zullen gebruikers die deze link hebben gebruikt de toegang tot de pagina verliezen.",
"shareSeeOnce": "Je kunt deze koppeling alleen zien. Zorg ervoor dat je het kopieert.",
"shareSeeOnce": "U kunt deze link slechts één keer zien. Zorg ervoor dat u deze kopieert.",
"shareAccessHint": "Iedereen met deze link heeft toegang tot de bron. Deel deze met zorg.",
"shareTokenUsage": "Zie Toegangstoken Gebruik",
"createLink": "Koppeling aanmaken",
@@ -154,8 +153,7 @@
"protected": "Beschermd",
"notProtected": "Niet beveiligd",
"resourceMessageRemove": "Eenmaal verwijderd, zal het bestand niet langer toegankelijk zijn. Alle doelen die gekoppeld zijn aan het hulpbron, zullen ook verwijderd worden.",
"resourceMessageConfirm": "Om te bevestigen, typ de naam van de bron hieronder.",
"resourceQuestionRemove": "Weet u zeker dat u de resource {selectedResource} uit de organisatie wilt verwijderen?",
"resourceQuestionRemove": "Weet u zeker dat u het document van de organisatie wilt verwijderen?",
"resourceHTTP": "HTTPS bron",
"resourceHTTPDescription": "Proxy verzoeken aan uw app via HTTPS via een subdomein of basisdomein.",
"resourceRaw": "TCP/UDP bron",
@@ -181,7 +179,7 @@
"baseDomain": "Basis domein",
"subdomnainDescription": "Het subdomein waar de bron toegankelijk is.",
"resourceRawSettings": "TCP/UDP instellingen",
"resourceRawSettingsDescription": "Stel in hoe je bron wordt benaderd via TCP/UDP",
"resourceRawSettingsDescription": "Stel in hoe uw bron wordt benaderd via TCP/UDP. Je gooit de bron toe aan een poort op de host-Pangolin server, zodat je de bron kan bereiken vanaf server-public-ip:mapped-port.",
"protocol": "Protocol",
"protocolSelect": "Selecteer een protocol",
"resourcePortNumber": "Nummer van poort",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Bevestig Verwijderen Organisatie",
"orgMessageRemove": "Deze actie is onomkeerbaar en zal alle bijbehorende gegevens verwijderen.",
"orgMessageConfirm": "Om te bevestigen, typ de naam van de onderstaande organisatie in.",
"orgQuestionRemove": "Weet u zeker dat u de organisatie {selectedOrg} wilt verwijderen?",
"orgQuestionRemove": "Weet u zeker dat u de organisatie wilt verwijderen?",
"orgUpdated": "Organisatie bijgewerkt",
"orgUpdatedDescription": "De organisatie is bijgewerkt.",
"orgErrorUpdate": "Bijwerken organisatie mislukt",
@@ -287,9 +285,8 @@
"apiKeysAdd": "API-sleutel genereren",
"apiKeysErrorDelete": "Fout bij verwijderen API-sleutel",
"apiKeysErrorDeleteMessage": "Fout bij verwijderen API-sleutel",
"apiKeysQuestionRemove": "Weet u zeker dat u de API-sleutel {selectedApiKey} van de organisatie wilt verwijderen?",
"apiKeysQuestionRemove": "Weet u zeker dat u de API-sleutel van de organisatie wilt verwijderen?",
"apiKeysMessageRemove": "Eenmaal verwijderd, kan de API-sleutel niet meer worden gebruikt.",
"apiKeysMessageConfirm": "Om dit te bevestigen, typt u de naam van de API-sleutel hieronder.",
"apiKeysDeleteConfirm": "Bevestig Verwijderen API-sleutel",
"apiKeysDelete": "API-sleutel verwijderen",
"apiKeysManage": "API-sleutels beheren",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Bevestig verwijderen gebruiker",
"userDeleteServer": "Gebruiker verwijderen van de server",
"userMessageRemove": "De gebruiker zal uit alle organisaties verwijderd worden en volledig verwijderd worden van de server.",
"userMessageConfirm": "Typ de naam van de gebruiker hieronder om te bevestigen.",
"userQuestionRemove": "Weet je zeker dat je {selectedUser} permanent van de server wilt verwijderen?",
"userQuestionRemove": "Weet u zeker dat u de gebruiker permanent van de server wilt verwijderen?",
"licenseKey": "Licentie sleutel",
"valid": "Geldig",
"numberOfSites": "Aantal sites",
@@ -339,7 +335,7 @@
"fossorialLicense": "Fossorial Commerciële licentie- en abonnementsvoorwaarden bekijken",
"licenseMessageRemove": "Dit zal de licentiesleutel en alle bijbehorende machtigingen verwijderen die hierdoor zijn verleend.",
"licenseMessageConfirm": "Typ de licentiesleutel hieronder om te bevestigen.",
"licenseQuestionRemove": "Weet u zeker dat u de licentiesleutel {selectedKey} wilt verwijderen?",
"licenseQuestionRemove": "Weet u zeker dat u de licentiesleutel wilt verwijderen?",
"licenseKeyDelete": "Licentiesleutel verwijderen",
"licenseKeyDeleteConfirm": "Bevestig verwijderen licentiesleutel",
"licenseTitle": "Licentiestatus beheren",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Er is een fout opgetreden tijdens het verwijderen van de uitnodiging.",
"inviteRemoved": "Uitnodiging verwijderd",
"inviteRemovedDescription": "De uitnodiging voor {email} is verwijderd.",
"inviteQuestionRemove": "Weet u zeker dat u de uitnodiging {email} wilt verwijderen?",
"inviteQuestionRemove": "Weet je zeker dat je de uitnodiging wilt verwijderen?",
"inviteMessageRemove": "Eenmaal verwijderd, zal deze uitnodiging niet meer geldig zijn. U kunt de gebruiker later altijd opnieuw uitnodigen.",
"inviteMessageConfirm": "Om dit te bevestigen, typ dan het e-mailadres van onderstaande uitnodiging.",
"inviteQuestionRegenerate": "Weet u zeker dat u de uitnodiging voor {email}opnieuw wilt genereren? Dit zal de vorige uitnodiging intrekken.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Er is een fout opgetreden tijdens het verwijderen van de gebruiker.",
"userOrgRemoved": "Gebruiker verwijderd",
"userOrgRemovedDescription": "De gebruiker {email} is verwijderd uit de organisatie.",
"userQuestionOrgRemove": "Weet u zeker dat u {email} wilt verwijderen uit de organisatie?",
"userQuestionOrgRemove": "Weet u zeker dat u deze gebruiker wilt verwijderen uit de organisatie?",
"userMessageOrgRemove": "Eenmaal verwijderd, heeft deze gebruiker geen toegang meer tot de organisatie. Je kunt ze later altijd opnieuw uitnodigen, maar ze zullen de uitnodiging opnieuw moeten accepteren.",
"userMessageOrgConfirm": "Typ om te bevestigen de naam van de gebruiker hieronder.",
"userRemoveOrgConfirm": "Bevestig verwijderen gebruiker",
"userRemoveOrg": "Gebruiker uit organisatie verwijderen",
"users": "Gebruikers",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Serverbeheer - Pangolin",
"licenseTierProfessional": "Professionele licentie",
"licenseTierEnterprise": "Enterprise Licentie",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Persoonlijke licentie",
"licensed": "Gelicentieerd",
"yes": "ja",
"no": "Neen",
@@ -742,7 +737,7 @@
"idpManageDescription": "Identiteitsaanbieders in het systeem bekijken en beheren",
"idpDeletedDescription": "Identity provider succesvol verwijderd",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Weet u zeker dat u de identiteitsprovider {name} permanent wilt verwijderen?",
"idpQuestionRemove": "Weet u zeker dat u de identiteitsprovider permanent wilt verwijderen?",
"idpMessageRemove": "Dit zal de identiteitsprovider en alle bijbehorende configuraties verwijderen. Gebruikers die via deze provider authenticeren, kunnen niet langer inloggen.",
"idpMessageConfirm": "Om dit te bevestigen, typt u de naam van onderstaande identiteitsprovider.",
"idpConfirmDelete": "Bevestig verwijderen identiteit provider",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Controleer je e-mail voor de reset code.",
"passwordNew": "Nieuw wachtwoord",
"passwordNewConfirm": "Bevestig nieuw wachtwoord",
"changePassword": "Wachtwoord wijzigen",
"changePasswordDescription": "Uw wachtwoord bijwerken",
"oldPassword": "Huidig wachtwoord",
"newPassword": "Nieuw wachtwoord",
"confirmNewPassword": "Bevestig nieuw wachtwoord",
"changePasswordError": "Wachtwoord wijzigen mislukt",
"changePasswordErrorDescription": "Er is een fout opgetreden tijdens het wijzigen van uw wachtwoord",
"changePasswordSuccess": "Wachtwoord succesvol gewijzigd",
"changePasswordSuccessDescription": "Uw wachtwoord is met succes bijgewerkt",
"passwordExpiryRequired": "Wachtwoord vervalt verplicht",
"passwordExpiryDescription": "Deze organisatie vereist dat u om de {maxDays} dagen uw wachtwoord wijzigt.",
"changePasswordNow": "Wijzig wachtwoord nu",
"pincodeAuth": "Authenticatiecode",
"pincodeSubmit2": "Code indienen",
"passwordResetSubmit": "Opnieuw instellen aanvragen",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Alle gebruikers",
"sidebarIdentityProviders": "Identiteit aanbieders",
"sidebarLicense": "Licentie",
"sidebarClients": "Clients",
"sidebarClients": "Clienten",
"sidebarDomains": "Domeinen",
"sidebarBluePrints": "Blauwdrukken",
"blueprints": "Blauwdrukken",
"blueprintsDescription": "Gebruik declaratieve configuraties en bekijk vorige uitvoeringen.",
"blueprintAdd": "Blauwdruk toevoegen",
"blueprintGoBack": "Bekijk alle Blauwdrukken",
"blueprintCreate": "Creëer blauwdruk",
"blueprintCreateDescription2": "Volg de onderstaande stappen om een nieuwe blauwdruk te maken en toe te passen",
"blueprintDetails": "Blauwdruk Details",
"blueprintDetailsDescription": "Bekijk het resultaat van de toegepaste blauwdruk en eventuele fouten",
"blueprintInfo": "Blauwdruk Informatie",
"message": "bericht",
"blueprintContentsDescription": "Definieer de YAML content die je infrastructuur beschrijft",
"blueprintErrorCreateDescription": "Er is een fout opgetreden bij het toepassen van de blauwdruk",
"blueprintErrorCreate": "Fout bij maken blauwdruk",
"searchBlueprintProgress": "Blauwdrukken zoeken...",
"appliedAt": "Toegepast op",
"source": "Bron",
"contents": "Inhoud",
"parsedContents": "Geparseerde inhoud (alleen lezen)",
"enableDockerSocket": "Schakel Docker Blauwdruk in",
"enableDockerSocketDescription": "Schakel Docker Socket label in voor blauwdruk labels. Pad naar Nieuw.",
"enableDockerSocketLink": "Meer informatie",
@@ -1211,9 +1237,8 @@
"domainCreate": "Domein aanmaken",
"domainCreatedDescription": "Domein succesvol aangemaakt",
"domainDeletedDescription": "Domein succesvol verwijderd",
"domainQuestionRemove": "Weet je zeker dat je het domein {domain} uit je account wilt verwijderen?",
"domainQuestionRemove": "Weet u zeker dat u het domein uit uw account wilt verwijderen?",
"domainMessageRemove": "Na verwijdering zal het domein niet langer aan je account gekoppeld zijn.",
"domainMessageConfirm": "Om te bevestigen, typ hieronder de domeinnaam.",
"domainConfirmDelete": "Bevestig verwijdering van domein",
"domainDelete": "Domein verwijderen",
"domain": "Domein",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Er is een fout opgetreden bij het bijwerken van instellingen",
"sidebarCollapse": "Inklappen",
"sidebarExpand": "Uitklappen",
"productUpdateMoreInfo": "Nog {noOfUpdates} updates",
"productUpdateInfo": "{noOfUpdates} updates",
"productUpdateWhatsNew": "Wat is nieuw",
"productUpdateTitle": "Update Producten",
"productUpdateEmpty": "Geen updates",
"dismissAll": "Alles afwijzen",
"pangolinUpdateAvailable": "Nieuwe versie beschikbaar",
"pangolinUpdateAvailableInfo": "Versie {version} is klaar om te installeren",
"pangolinUpdateAvailableReleaseNotes": "Bekijk release notities",
"newtUpdateAvailable": "Update beschikbaar",
"newtUpdateAvailableInfo": "Er is een nieuwe versie van Newt beschikbaar. Update naar de nieuwste versie voor de beste ervaring.",
"domainPickerEnterDomain": "Domein",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Gratis Niveau",
"billingWarningOverLimit": "Waarschuwing: U hebt een of meer gebruikslimieten overschreden. Uw sites maken geen verbinding totdat u uw abonnement aanpast of uw gebruik aanpast.",
"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@fossorial.io.",
"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",
"billingOnlineTime": "Site Online Tijd",
"billingUsers": "Actieve Gebruikers",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Er was een probleem met het gebruik van je beveiligingssleutel. Probeer het opnieuw.",
"twoFactorRequired": "Tweestapsverificatie is vereist om een beveiligingssleutel te registreren.",
"twoFactor": "Tweestapsverificatie",
"twoFactorAuthentication": "Tweestapsverificatie verificatie",
"twoFactorDescription": "Deze organisatie vereist tweestapsverificatie.",
"enableTwoFactor": "Tweestapsverificatie inschakelen",
"organizationSecurityPolicy": "Organisatie Veiligheidsbeleid",
"organizationSecurityPolicyDescription": "Deze organisatie heeft beveiligingsvereisten waaraan moet worden voldaan voordat u deze kunt openen",
"securityRequirements": "Veiligheidsvereisten",
"allRequirementsMet": "Aan alle vereisten is voldaan",
"completeRequirementsToContinue": "Voltooi de onderstaande vereisten om toegang te blijven krijgen tot deze organisatie",
"youCanNowAccessOrganization": "U heeft nu toegang tot deze organisatie",
"reauthenticationRequired": "Sessie Lengte",
"reauthenticationDescription": "Deze organisatie vereist dat u elke {maxDays} dagen inlogt.",
"reauthenticationDescriptionHours": "Deze organisatie vereist dat u elke {maxHours} uur inlogt.",
"reauthenticateNow": "Opnieuw inloggen",
"adminEnabled2FaOnYourAccount": "Je beheerder heeft tweestapsverificatie voor {email} ingeschakeld. Voltooi het instellingsproces om verder te gaan.",
"securityKeyAdd": "Beveiligingssleutel toevoegen",
"securityKeyRegisterTitle": "Nieuwe beveiligingssleutel registreren",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Deze bronnen zijn bedoeld voor gebruik met",
"resourcesTableClients": "Clienten",
"resourcesTableAndOnlyAccessibleInternally": "en zijn alleen intern toegankelijk wanneer verbonden met een client.",
"resourcesTableNoTargets": "Geen doelen",
"resourcesTableHealthy": "Gezond",
"resourcesTableDegraded": "Verminderde",
"resourcesTableOffline": "Offline",
"resourcesTableUnknown": "onbekend",
"resourcesTableNotMonitored": "Niet gecontroleerd",
"editInternalResourceDialogEditClientResource": "Bewerk clientbron",
"editInternalResourceDialogUpdateResourceProperties": "Werk de eigenschapen van de bron en doelconfiguratie bij voor {resourceName}.",
"editInternalResourceDialogResourceProperties": "Bron eigenschappen",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Geen redirect URL ontvangen van de identity provider.",
"autoLoginErrorGeneratingUrl": "Genereren van authenticatie-URL mislukt.",
"remoteExitNodeManageRemoteExitNodes": "Externe knooppunten",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Zorgt voor één of meer externe knooppunten om de netwerkverbinding uit te breiden en het vertrouwen in de cloud te verminderen",
"remoteExitNodes": "Nodes",
"searchRemoteExitNodes": "Knooppunten zoeken...",
"remoteExitNodeAdd": "Voeg node toe",
"remoteExitNodeErrorDelete": "Fout bij verwijderen node",
"remoteExitNodeQuestionRemove": "Weet u zeker dat u het node {selectedNode} uit de organisatie wilt verwijderen?",
"remoteExitNodeQuestionRemove": "Weet u zeker dat u het knooppunt uit de organisatie wilt verwijderen?",
"remoteExitNodeMessageRemove": "Eenmaal verwijderd, zal het knooppunt niet langer toegankelijk zijn.",
"remoteExitNodeMessageConfirm": "Om te bevestigen, typ de naam van het knooppunt hieronder.",
"remoteExitNodeConfirmDelete": "Bevestig verwijderen node",
"remoteExitNodeDelete": "Knoop verwijderen",
"sidebarRemoteExitNodes": "Externe knooppunten",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Bestand bewerken: docker-compose.yml",
"emailVerificationRequired": "E-mail verificatie is vereist. Log opnieuw in via {dashboardUrl}/auth/login voltooide deze stap. Kom daarna hier terug.",
"twoFactorSetupRequired": "Tweestapsverificatie instellen is vereist. Log opnieuw in via {dashboardUrl}/auth/login voltooide deze stap. Kom daarna hier terug.",
"additionalSecurityRequired": "Extra beveiliging vereist",
"organizationRequiresAdditionalSteps": "Deze organisatie vereist extra beveiligingsstappen voordat u toegang hebt tot de bronnen.",
"completeTheseSteps": "Voltooi deze stappen",
"enableTwoFactorAuthentication": "Tweestapsverificatie inschakelen",
"completeSecuritySteps": "Voltooi beveiligingsstappen",
"securitySettings": "Beveiliging instellingen",
"securitySettingsDescription": "Beveiligingsbeleid voor uw organisatie configureren",
"requireTwoFactorForAllUsers": "Authenticatie in twee stappen vereist voor alle gebruikers",
"requireTwoFactorDescription": "Wanneer ingeschakeld, moeten alle interne gebruikers in deze organisatie tweestapsverificatie ingeschakeld hebben om toegang te krijgen tot de organisatie.",
"requireTwoFactorDisabledDescription": "Deze functie vereist een geldig licentie (Enterprise) of actief abonnement (SaaS)",
"requireTwoFactorCannotEnableDescription": "U moet tweestapsverificatie inschakelen voor uw account voordat u deze voor alle gebruikers kan afdwingen",
"maxSessionLength": "Maximale sessielengte",
"maxSessionLengthDescription": "Stel de maximale duur van de gebruikerssessies in. Na deze tijd zullen gebruikers opnieuw moeten verifiëren.",
"maxSessionLengthDisabledDescription": "Deze functie vereist een geldig licentie (Enterprise) of actief abonnement (SaaS)",
"selectSessionLength": "Selecteer sessie lengte",
"unenforced": "Onafgedwongen",
"1Hour": "1 uur",
"3Hours": "3 uur",
"6Hours": "6 uur",
"12Hours": "12 uur",
"1DaySession": "1 dag",
"3Days": "3 dagen",
"7Days": "7 dagen",
"14Days": "14 dagen",
"30DaysSession": "30 dagen",
"90DaysSession": "90 dagen",
"180DaysSession": "180 dagen",
"passwordExpiryDays": "Wachtwoord verloopt",
"editPasswordExpiryDescription": "Stel het aantal dagen in voordat gebruikers verplicht zijn hun wachtwoord te wijzigen.",
"selectPasswordExpiry": "Selecteer wachtwoord vervaldatum",
"30Days": "30 dagen",
"1Day": "1 dag",
"60Days": "60 dagen",
"90Days": "90 dagen",
"180Days": "180 dagen",
"1Year": "1 jaar",
"subscriptionBadge": "Abonnement vereist",
"securityPolicyChangeWarning": "Waarschuwing wijzigen beveiligingsbeleid",
"securityPolicyChangeDescription": "U staat op het punt om de instellingen van het beveiligingsbeleid te wijzigen. Na het opslaan moet u zich opnieuw aanmelden om te voldoen aan deze beleidsupdates. Alle gebruikers die niet aan de voorwaarden voldoen, moeten zich ook opnieuw authenticeren.",
"securityPolicyChangeConfirmMessage": "Ik bevestig",
"securityPolicyChangeWarningText": "Dit heeft invloed op alle gebruikers in de organisatie",
"authPageErrorUpdateMessage": "Er is een fout opgetreden bij het bijwerken van de instellingen van de auth-pagina",
"authPageErrorUpdate": "Kan de autorisatiepagina niet bijwerken",
"authPageUpdated": "Auth-pagina succesvol bijgewerkt",
"healthCheckNotAvailable": "Lokaal",
"rewritePath": "Herschrijf Pad",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Koptekst authenticatie succesvol verwijderd.",
"resourceErrorHeaderAuthRemove": "Kan Header-authenticatie niet verwijderen",
"resourceErrorHeaderAuthRemoveDescription": "Kon header authenticatie niet verwijderen voor de bron.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Koptekst authenticatie ingeschakeld",
"resourceHeaderAuthProtectionDisabled": "Header authenticatie uitgeschakeld",
"headerAuthRemove": "Auth koptekst verwijderen",
"headerAuthAdd": "Kopsauth toevoegen",
"resourceErrorHeaderAuthSetup": "Kan Header Authenticatie niet instellen",
"resourceErrorHeaderAuthSetupDescription": "Kan geen header authenticatie instellen voor de bron.",
"resourceHeaderAuthSetup": "Header Authenticatie set succesvol",
"resourceHeaderAuthSetupDescription": "Header authenticatie is met succes ingesteld.",
"resourceHeaderAuthSetupTitle": "Header Authenticatie instellen",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Stel de basis authenticatiegegevens (gebruikersnaam en wachtwoord) in om deze bron te beschermen met HTTP Header Authenticatie. Gebruik het formaat https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Header Authenticatie instellen",
"actionSetResourceHeaderAuth": "Header Authenticatie instellen",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"unlicensed": "Ongelicentieerd",
"beta": "Bèta",
"manageClients": "Beheer Cliënten",
"manageClientsDescription": "Klanten zijn apparaten die verbinding kunnen maken met uw sites",
"licenseTableValidUntil": "Geldig tot",
"saasLicenseKeysSettingsTitle": "Enterprise Licenties",
"saasLicenseKeysSettingsDescription": "Genereer en beheer de Enterprise licentiesleutels voor zelfgehoste Pangolin instanties",
"sidebarEnterpriseLicenses": "Licenties",
"generateLicenseKey": "Licentiesleutel genereren",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Voer een geldig e-mailadres in",
"useCaseTypeRequired": "Selecteer een type voor gebruik",
"firstNameRequired": "Voornaam is vereist",
"lastNameRequired": "Achternaam is vereist",
"primaryUseRequired": "Beschrijf uw primaire gebruik",
"jobTitleRequiredBusiness": "Functitel is vereist voor business gebruik",
"industryRequiredBusiness": "Industrie is vereist voor zakelijk gebruik",
"stateProvinceRegionRequired": "Provincie/Regio is vereist",
"postalZipCodeRequired": "Postcode is vereist",
"companyNameRequiredBusiness": "Bedrijfsnaam is vereist voor zakelijk gebruik",
"countryOfResidenceRequiredBusiness": "Land van verblijf is vereist voor zakelijk gebruik",
"countryRequiredPersonal": "Land is vereist voor persoonlijk gebruik",
"agreeToTermsRequired": "U moet akkoord gaan met de voorwaarden",
"complianceConfirmationRequired": "U moet de naleving van de Fossorial Commerciële licentie bevestigen"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Persoonlijk gebruik",
"description": "Voor individueel, niet-commercieel gebruik, zoals leren, persoonlijke projecten of experimenten."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Zakelijk gebruik",
"description": "Voor gebruik binnen organisaties, bedrijven, commerciële of inkomstengenererende activiteiten."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "E-mail & Licentie Type",
"description": "Voer uw e-mailadres in en kies uw licentietype"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Persoonlijke informatie",
"description": "Vertel ons over jezelf"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Contact informatie",
"description": "Uw contactgegevens"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Voorwaarden & Genereer",
"description": "Controleer en accepteer termen om uw licentie te genereren"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Disclosure voor gebruik",
"description": "Selecteer de licentielift die precies overeenkomt met het beoogde gebruik. De Persoonlijke Licentie staat het gratis gebruik van de software toe voor individuele, niet-commerciële of kleinschalige commerciële activiteiten met jaarlijkse bruto inkomsten van minder dan $100.000 USD. Elk gebruik buiten deze grenzen - inclusief gebruik binnen een bedrijf, organisatie, of andere inkomstengenererende omgeving - vereist een geldige Enterprise-licentie en betaling van de toepasselijke licentiekosten. Alle gebruikers, Persoonlijk of Enterprise, moeten voldoen aan de Fossorial Commerciële Licentievoorwaarden."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Informatie proefperiode",
"description": "Deze licentiesleutel maakt bedrijfsfuncties mogelijk voor een evaluatieperiode van 7 dagen. Continue toegang tot betaalde functies na de evaluatieperiode vereist activering onder een geldige Persoonlijke of Enterprise License. Voor een Enterprise licentie, neem contact op met sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Gebruikt u Pangolin voor persoonlijk of zakelijk gebruik?",
"firstName": "Voornaam is vereist.",
"lastName": "Achternaam is vereist",
"jobTitle": "Job titel",
"primaryUseQuestion": "Waar bent u primair van plan Pangolin voor te gebruiken?",
"industryQuestion": "Wat is uw industrie?",
"prospectiveUsersQuestion": "Hoeveel potentiële gebruikers verwacht je te hebben?",
"prospectiveSitesQuestion": "Hoeveel potentiële sites (tunnels) verwacht je te hebben?",
"companyName": "Naam bedrijf",
"countryOfResidence": "Land van verblijf",
"stateProvinceRegion": "Staat / Provincie / Regio",
"postalZipCode": "Postcode / postcode",
"companyWebsite": "Bedrijfs website",
"companyPhoneNumber": "Bedrijfs telefoonnummer",
"country": "Land",
"phoneNumberOptional": "Telefoonnummer (optioneel)",
"complianceConfirmation": "Ik bevestig dat de door mij verstrekte informatie juist is en dat ik mij aan de Fossorial Commerciële licentie houd. Het melden van onjuiste informatie of het verkeerd identificeren van het gebruik van het product is een schending van de licentie en kan leiden tot het intrekken van uw sleutel."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Sluiten",
"previous": "named@@0",
"next": "Volgende",
"generateLicenseKey": "Licentiesleutel genereren"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Licentiesleutel succesvol gegenereerd",
"description": "Uw licentiesleutel is gegenereerd en is klaar voor gebruik."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Kan licentiesleutel niet genereren",
"description": "Fout opgetreden tijdens het genereren van de licentiesleutel."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Naam instantie",
"pathMatchModalTitle": "Configureren van overeenkomende pad",
"pathMatchModalDescription": "Stel in hoe inkomende verzoeken moeten worden gekoppeld aan hun pad.",
"pathMatchType": "Wedstrijd Type",
"pathMatchPrefix": "Voorvoegsel",
"pathMatchExact": "Exacte",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Pad waarde",
"clear": "Verwijderen",
"saveChanges": "Wijzigingen opslaan",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathMatchDefaultPlaceholder": "/Pad",
"pathMatchPrefixHelp": "Voorbeeld: /api komt overeen met /api, /api/gebruikers, etc.",
"pathMatchExactHelp": "Voorbeeld: /api matcht alleen /api",
"pathMatchRegexHelp": "Voorbeeld: ^/api/.* komt overeen met /api/any",
"pathRewriteModalTitle": "Configureer pad herschrijven",
"pathRewriteModalDescription": "Verander het overeenstemmende pad voor het doorsturen naar het doel.",
"pathRewriteType": "Herschrijf Type",
"pathRewritePrefixOption": "Voorvoegsel - prefix vervangen",
"pathRewriteExactOption": "Exacte - Vervang het gehele pad",
"pathRewriteRegexOption": "Regex - Patroon vervanging",
"pathRewriteStripPrefixOption": "Voorvoegsel verwijderen - Verwijder voorvoegsel",
"pathRewriteValue": "Herschrijf Waarde",
"pathRewriteRegexPlaceholder": "/nieuw/$1",
"pathRewriteDefaultPlaceholder": "/nieuwe-pad",
"pathRewritePrefixHelp": "Vervang de overeenkomstige prefix door deze waarde",
"pathRewriteExactHelp": "Vervang het hele pad met deze waarde wanneer het pad precies overeenkomt",
"pathRewriteRegexHelp": "Gebruik capturegroepen zoals $1, $2 voor vervanging",
"pathRewriteStripPrefixHelp": "Laat leeg om de voorvoegsel te strippen of geef een nieuw voorvoegsel",
"pathRewritePrefix": "Voorvoegsel",
"pathRewriteExact": "Exacte",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Verwijder",
"pathRewriteStripLabel": "strip",
"sidebarEnableEnterpriseLicense": "Activeer Enterprise Licentie",
"cannotbeUndone": "Dit kan niet ongedaan worden gemaakt.",
"toConfirm": "om te bevestigen",
"deleteClientQuestion": "Weet u zeker dat u de client van de site en organisatie wilt verwijderen?",
"clientMessageRemove": "Eenmaal verwijderd, kan de client geen verbinding meer maken met de site.",
"sidebarLogs": "Logboeken",
"request": "Aanvragen",
"logs": "Logboeken",
"logsSettingsDescription": "Monitor logs verzameld van deze orginiatie",
"searchLogs": "Logboeken zoeken...",
"action": "actie",
"actor": "Acteur",
"timestamp": "Artikeldatering",
"accessLogs": "Toegang tot logboek",
"exportCsv": "Exporteren als CSV",
"actorId": "Acteur ID",
"allowedByRule": "Toegestaan door regel",
"allowedNoAuth": "Toegestaan geen authenticatie",
"validAccessToken": "Geldige toegangstoken",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Geldig wachtwoord",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Bron geblokkeerd",
"droppedByRule": "Achtergelaten door regel",
"noSessions": "Geen sessies",
"temporaryRequestToken": "Tijdelijk verzoek token",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP-adres",
"reason": "Reden",
"requestLogs": "Logboeken aanvragen",
"host": "Hostnaam",
"location": "Locatie",
"actionLogs": "Actie logs",
"sidebarLogsRequest": "Logboeken aanvragen",
"sidebarLogsAccess": "Toegang tot logboek",
"sidebarLogsAction": "Actie logs",
"logRetention": "Log bewaring",
"logRetentionDescription": "Beheren hoe lang verschillende soorten logs bewaard worden voor deze organisatie of schakel ze uit",
"requestLogsDescription": "Bekijk gedetailleerde verzoeklogboeken voor resources in deze organisatie",
"logRetentionRequestLabel": "Logboekbewaring aanvragen",
"logRetentionRequestDescription": "Hoe lang de aanvraaglogboeken te behouden",
"logRetentionAccessLabel": "Toegang logboek bewaring",
"logRetentionAccessDescription": "Hoe lang de toegangslogboeken behouden blijven",
"logRetentionActionLabel": "Actie log bewaring",
"logRetentionActionDescription": "Hoe lang de action logs behouden moeten blijven",
"logRetentionDisabled": "Uitgeschakeld",
"logRetention3Days": "3 dagen",
"logRetention7Days": "7 dagen",
"logRetention14Days": "14 dagen",
"logRetention30Days": "30 dagen",
"logRetention90Days": "90 dagen",
"logRetentionForever": "Voor altijd",
"actionLogsDescription": "Bekijk een geschiedenis van acties die worden uitgevoerd in deze organisatie",
"accessLogsDescription": "Toegangsverificatieverzoeken voor resources in deze organisatie bekijken",
"licenseRequiredToUse": "Een Enterprise-licentie is vereist om deze functie te gebruiken.",
"certResolver": "Certificaat Resolver",
"certResolverDescription": "Selecteer de certificaat resolver die moet worden gebruikt voor deze resource.",
"selectCertResolver": "Certificaat Resolver selecteren",
"enterCustomResolver": "Aangepaste Oplossing invoeren",
"preferWildcardCert": "Bij voorkeur Wildcard Certificaat",
"unverified": "Ongeverifieerd",
"domainSetting": "Domein instellingen",
"domainSettingDescription": "Configureer instellingen voor uw domein",
"preferWildcardCertDescription": "Poging om een certificaat met een wildcard te genereren (vereist een correct geconfigureerde certificaatresolver).",
"recordName": "Record Naam",
"auto": "Automatisch",
"TTL": "TTL",
"howToAddRecords": "Hoe voeg ik Records toe",
"dnsRecord": "DNS Records",
"required": "vereist",
"domainSettingsUpdated": "Domeininstellingen succesvol bijgewerkt",
"orgOrDomainIdMissing": "Organisatie of domein ID ontbreekt",
"loadingDNSRecords": "DNS-records laden...",
"olmUpdateAvailableInfo": "Er is een bijgewerkte versie van Olm beschikbaar. Update alstublieft naar de nieuwste versie voor de beste ervaring.",
"client": "Klant",
"proxyProtocol": "Proxy Protocol Instellingen",
"proxyProtocolDescription": "Proxyprotocol configureren om de IP-adressen van de client voor TCP/UDP-diensten te bewaren.",
"enableProxyProtocol": "Proxy Protocol inschakelen",
"proxyProtocolInfo": "Behoud IP adressen van de client voor TCP/UDP backends",
"proxyProtocolVersion": "Proxy Protocol Versie",
"version1": " Versie 1 (Aanbevolen)",
"version2": "Versie 2",
"versionDescription": "Versie 1 is text-based en breed ondersteund. Versie 2 is binair en efficiënter maar minder compatibel.",
"warning": "Waarschuwing",
"proxyProtocolWarning": "Je backend applicatie moet worden geconfigureerd om connecties met Proxy Protocol te accepteren. Als je backend geen Proxy Protocol ondersteunt, zal het inschakelen van dit alle verbindingen verbreken. Zorg ervoor dat je je backend configureert om Proxy Protocol headers van Traefik.",
"restarting": "Herstarten...",
"manual": "Handleiding",
"messageSupport": "Bericht ondersteuning",
"supportNotAvailableTitle": "Ondersteuning niet beschikbaar",
"supportNotAvailableDescription": "Ondersteuning is momenteel niet beschikbaar. U kunt een e-mail sturen naar support@pangolin.net.",
"supportRequestSentTitle": "Ondersteuningsverzoek verzonden",
"supportRequestSentDescription": "Uw bericht is succesvol verzonden.",
"supportRequestFailedTitle": "Kon aanvraag niet verzenden",
"supportRequestFailedDescription": "Er is een fout opgetreden tijdens het verzenden van uw supportverzoek.",
"supportSubjectRequired": "Onderwerp is vereist",
"supportSubjectMaxLength": "Onderwerp moet 255 tekens of minder lang zijn",
"supportMessageRequired": "Bericht is vereist",
"supportReplyTo": "Antwoord aan",
"supportSubject": "Onderwerp",
"supportSubjectPlaceholder": "Onderwerp invoeren",
"supportMessage": "bericht",
"supportMessagePlaceholder": "Voer uw bericht in",
"supportSending": "Verzenden...",
"supportSend": "Verzenden",
"supportMessageSent": "Bericht verzonden!",
"supportWillContact": "We nemen binnenkort contact met u op!",
"selectLogRetention": "Selecteer log retentie",
"showColumns": "Kolommen weergeven",
"hideColumns": "Kolommen verbergen",
"columnVisibility": "Zichtbaarheid kolommen",
"toggleColumn": "{columnName} kolom in-/uitschakelen",
"allColumns": "Alle kolommen",
"defaultColumns": "Standaard Kolommen",
"customizeView": "Weergave aanpassen",
"viewOptions": "Bekijk opties",
"selectAll": "Alles selecteren",
"selectNone": "Niets selecteren",
"selectedResources": "Geselecteerde bronnen",
"enableSelected": "Selectie inschakelen",
"disableSelected": "Selectie uitschakelen",
"checkSelectedStatus": "Controleer de status van de geselecteerde",
"credentials": "Aanmeldgegevens",
"savecredentials": "Referenties opslaan",
"regeneratecredentials": "Hersleutel",
"regenerateCredentials": "Opnieuw genereren en opslaan van uw referenties",
"generatedcredentials": "Gegenereerde referenties",
"copyandsavethesecredentials": "Kopieer en bewaar deze inloggegevens",
"copyandsavethesecredentialsdescription": "Deze referenties worden niet meer getoond nadat u deze pagina verlaat. Sla ze nu veilig op.",
"credentialsSaved": "Referenties opgeslagen",
"credentialsSavedDescription": "Referenties werden met succes opnieuw gegenereerd en opgeslagen.",
"credentialsSaveError": "Fout bij opslaan referenties",
"credentialsSaveErrorDescription": "Er is een fout opgetreden tijdens het opnieuw genereren en opslaan van de inloggegevens.",
"regenerateCredentialsWarning": "Het opnieuw genereren van inloggegevens zal de vorige ongeldig maken. Zorg ervoor dat alle configuraties die deze inloggegevens gebruiken bijgewerkt worden.",
"confirm": "Bevestigen",
"regenerateCredentialsConfirmation": "Weet u zeker dat u de inloggegevens opnieuw wilt genereren?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Geheime sleutel",
"featureDisabledTooltip": "Deze functie is alleen beschikbaar in het bedrijfsplan en vereist een licentie om deze te gebruiken.",
"niceId": "Leuk ID",
"niceIdUpdated": "Leuke ID bijgewerkt",
"niceIdUpdatedSuccessfully": "Nice ID Updated Successfully",
"niceIdUpdateError": "Fout bij bijwerken ID Nice",
"niceIdUpdateErrorDescription": "Fout opgetreden tijdens het bijwerken van de ID van Nice.",
"niceIdCannotBeEmpty": "Nice ID mag niet leeg zijn",
"enterIdentifier": "ID invoeren",
"identifier": "Identifier"
}

View File

@@ -47,9 +47,8 @@
"edit": "Edytuj",
"siteConfirmDelete": "Potwierdź usunięcie witryny",
"siteDelete": "Usuń witrynę",
"siteMessageRemove": "Po usunięciu, witryna nie będzie już dostępna. Wszystkie zasoby i cele związane z witryną zostaną również usunięte.",
"siteMessageConfirm": "Aby potwierdzić, wpisz nazwę witryny poniżej.",
"siteQuestionRemove": "Czy na pewno chcesz usunąć stronę {selectedSite} z organizacji?",
"siteMessageRemove": "Po usunięciu witryna nie będzie już dostępna. Wszystkie cele związane z witryną zostaną również usunięte.",
"siteQuestionRemove": "Czy na pewno chcesz usunąć witrynę z organizacji?",
"siteManageSites": "Zarządzaj stronami",
"siteDescription": "Zezwalaj na połączenie z siecią przez bezpieczne tunele",
"siteCreate": "Utwórz witrynę",
@@ -96,7 +95,7 @@
"siteWgDescription": "Użyj dowolnego klienta WireGuard do utworzenia tunelu. Wymagana jest ręczna konfiguracja NAT.",
"siteWgDescriptionSaas": "Użyj dowolnego klienta WireGuard do utworzenia tunelu. Wymagana ręczna konfiguracja NAT. DZIAŁA TYLKO NA SAMODZIELNIE HOSTOWANYCH WĘZŁACH",
"siteLocalDescription": "Tylko lokalne zasoby. Brak tunelu.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Tylko zasoby lokalne. Brak tunelu. Dostępne tylko w węzłach zdalnych.",
"siteSeeAll": "Zobacz wszystkie witryny",
"siteTunnelDescription": "Określ jak chcesz połączyć się ze swoją stroną",
"siteNewtCredentials": "Aktualne dane logowania",
@@ -132,7 +131,7 @@
"expireIn": "Wygasa za",
"neverExpire": "Nigdy nie wygasa",
"shareExpireDescription": "Czas wygaśnięcia to jak długo link będzie mógł być użyty i zapewni dostęp do zasobu. Po tym czasie link nie będzie już działał, a użytkownicy, którzy użyli tego linku, utracą dostęp do zasobu.",
"shareSeeOnce": "Możesz zobaczyć tylko ten link. Upewnij się, że go skopiowało.",
"shareSeeOnce": "Możesz zobaczyć ten link tylko raz. Pamiętaj, aby go skopiować.",
"shareAccessHint": "Każdy z tym linkiem może uzyskać dostęp do zasobu. Podziel się nim ostrożnie.",
"shareTokenUsage": "Zobacz użycie tokenu dostępu",
"createLink": "Utwórz link",
@@ -154,8 +153,7 @@
"protected": "Chronione",
"notProtected": "Niechronione",
"resourceMessageRemove": "Po usunięciu, zasób nie będzie już dostępny. Wszystkie cele związane z zasobem zostaną również usunięte.",
"resourceMessageConfirm": "Aby potwierdzić, wpisz nazwę zasobu poniżej.",
"resourceQuestionRemove": "Czy na pewno chcesz usunąć zasób {selectedResource} z organizacji?",
"resourceQuestionRemove": "Czy na pewno chcesz usunąć zasób z organizacji?",
"resourceHTTP": "Zasób HTTPS",
"resourceHTTPDescription": "Proxy do Twojej aplikacji przez HTTPS, przy użyciu poddomeny lub domeny bazowej.",
"resourceRaw": "Surowy zasób TCP/UDP",
@@ -181,7 +179,7 @@
"baseDomain": "Bazowa domena",
"subdomnainDescription": "Poddomena, w której twój zasób będzie dostępny.",
"resourceRawSettings": "Ustawienia TCP/UDP",
"resourceRawSettingsDescription": "Skonfiguruj jak twój zasób będzie dostępny przez TCP/UDP",
"resourceRawSettingsDescription": "Skonfiguruj jak twój zasób będzie dostępny przez TCP/UDP. Zmapujesz zasób do portu na serwerze hosta Pangolin, dzięki czemu możesz uzyskać dostęp do zasobu z serwera-public ip:mapped-port.",
"protocol": "Protokół",
"protocolSelect": "Wybierz protokół",
"resourcePortNumber": "Numer portu",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Potwierdź usunięcie organizacji",
"orgMessageRemove": "Ta akcja jest nieodwracalna i usunie wszystkie powiązane dane.",
"orgMessageConfirm": "Aby potwierdzić, wpisz nazwę organizacji poniżej.",
"orgQuestionRemove": "Czy na pewno chcesz usunąć organizację {selectedOrg}?",
"orgQuestionRemove": "Czy na pewno chcesz usunąć organizację?",
"orgUpdated": "Organizacja zaktualizowana",
"orgUpdatedDescription": "Organizacja została zaktualizowana.",
"orgErrorUpdate": "Nie udało się zaktualizować organizacji",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Generuj klucz API",
"apiKeysErrorDelete": "Błąd podczas usuwania klucza API",
"apiKeysErrorDeleteMessage": "Błąd podczas usuwania klucza API",
"apiKeysQuestionRemove": "Czy na pewno chcesz usunąć klucz API {selectedApiKey} z organizacji?",
"apiKeysQuestionRemove": "Czy na pewno chcesz usunąć klucz API z organizacji?",
"apiKeysMessageRemove": "Po usunięciu klucz API nie będzie już mógł być używany.",
"apiKeysMessageConfirm": "Aby potwierdzić, wpisz nazwę klucza API poniżej.",
"apiKeysDeleteConfirm": "Potwierdź usunięcie klucza API",
"apiKeysDelete": "Usuń klucz API",
"apiKeysManage": "Zarządzaj kluczami API",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Potwierdź usunięcie użytkownika",
"userDeleteServer": "Usuń użytkownika z serwera",
"userMessageRemove": "Użytkownik zostanie usunięty ze wszystkich organizacji i całkowicie usunięty z serwera.",
"userMessageConfirm": "Aby potwierdzić, wpisz nazwę użytkownika poniżej.",
"userQuestionRemove": "Czy na pewno chcesz trwale usunąć {selectedUser} z serwera?",
"userQuestionRemove": "Czy na pewno chcesz trwale usunąć użytkownika z serwera?",
"licenseKey": "Klucz licencyjny",
"valid": "Prawidłowy",
"numberOfSites": "Liczba witryn",
@@ -339,7 +335,7 @@
"fossorialLicense": "Zobacz Fossorial Commercial License & Subskrypcja",
"licenseMessageRemove": "Spowoduje to usunięcie klucza licencyjnego i wszystkich przypisanych przez niego uprawnień.",
"licenseMessageConfirm": "Aby potwierdzić, wpisz klucz licencyjny poniżej.",
"licenseQuestionRemove": "Czy na pewno chcesz usunąć klucz licencyjny {selectedKey}?",
"licenseQuestionRemove": "Czy na pewno chcesz usunąć klucz licencyjny?",
"licenseKeyDelete": "Usuń klucz licencyjny",
"licenseKeyDeleteConfirm": "Potwierdź usunięcie klucza licencyjnego",
"licenseTitle": "Zarządzaj statusem licencji",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Wystąpił błąd podczas usuwania zaproszenia.",
"inviteRemoved": "Zaproszenie usunięte",
"inviteRemovedDescription": "Zaproszenie dla {email} zostało usunięte.",
"inviteQuestionRemove": "Czy na pewno chcesz usunąć zaproszenie {email}?",
"inviteQuestionRemove": "Czy na pewno chcesz usunąć zaproszenie?",
"inviteMessageRemove": "Po usunięciu to zaproszenie nie będzie już ważne. Zawsze możesz ponownie zaprosić użytkownika później.",
"inviteMessageConfirm": "Aby potwierdzić, wpisz poniżej adres email zaproszenia.",
"inviteQuestionRegenerate": "Czy na pewno chcesz ponownie wygenerować zaproszenie {email}? Spowoduje to unieważnienie poprzedniego zaproszenia.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Wystąpił błąd podczas usuwania użytkownika.",
"userOrgRemoved": "Użytkownik usunięty",
"userOrgRemovedDescription": "Użytkownik {email} został usunięty z organizacji.",
"userQuestionOrgRemove": "Czy na pewno chcesz usunąć {email} z organizacji?",
"userQuestionOrgRemove": "Czy na pewno chcesz usunąć tego użytkownika z organizacji?",
"userMessageOrgRemove": "Po usunięciu ten użytkownik nie będzie miał już dostępu do organizacji. Zawsze możesz ponownie go zaprosić później, ale będzie musiał ponownie zaakceptować zaproszenie.",
"userMessageOrgConfirm": "Aby potwierdzić, wpisz nazwę użytkownika poniżej.",
"userRemoveOrgConfirm": "Potwierdź usunięcie użytkownika",
"userRemoveOrg": "Usuń użytkownika z organizacji",
"users": "Użytkownicy",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Administrator serwera - Pangolin",
"licenseTierProfessional": "Licencja Professional",
"licenseTierEnterprise": "Licencja Enterprise",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Licencja osobista",
"licensed": "Licencjonowany",
"yes": "Tak",
"no": "Nie",
@@ -742,7 +737,7 @@
"idpManageDescription": "Wyświetl i zarządzaj dostawcami tożsamości w systemie",
"idpDeletedDescription": "Dostawca tożsamości został pomyślnie usunięty",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Czy na pewno chcesz trwale usunąć dostawcę tożsamości {name}?",
"idpQuestionRemove": "Czy na pewno chcesz trwale usunąć dostawcę tożsamości?",
"idpMessageRemove": "Spowoduje to usunięcie dostawcy tożsamości i wszystkich powiązanych konfiguracji. Użytkownicy uwierzytelniający się przez tego dostawcę nie będą mogli się już zalogować.",
"idpMessageConfirm": "Aby potwierdzić, wpisz nazwę dostawcy tożsamości poniżej.",
"idpConfirmDelete": "Potwierdź usunięcie dostawcy tożsamości",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Sprawdź swój e-mail, aby znaleźć kod resetowania.",
"passwordNew": "Nowe hasło",
"passwordNewConfirm": "Potwierdź nowe hasło",
"changePassword": "Zmień hasło",
"changePasswordDescription": "Zaktualizuj hasło do konta",
"oldPassword": "Bieżące hasło",
"newPassword": "Nowe hasło",
"confirmNewPassword": "Potwierdź nowe hasło",
"changePasswordError": "Nie udało się zmienić hasła",
"changePasswordErrorDescription": "Wystąpił błąd podczas zmiany hasła",
"changePasswordSuccess": "Hasło zostało pomyślnie zmienione",
"changePasswordSuccessDescription": "Twoje hasło zostało pomyślnie zaktualizowane",
"passwordExpiryRequired": "Wymagane hasło wygasające",
"passwordExpiryDescription": "Organizacja wymaga zmiany hasła co {maxDays} dni.",
"changePasswordNow": "Zmień hasło teraz",
"pincodeAuth": "Kod uwierzytelniający",
"pincodeSubmit2": "Wyślij kod",
"passwordResetSubmit": "Zażądaj resetowania",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Wszyscy użytkownicy",
"sidebarIdentityProviders": "Dostawcy tożsamości",
"sidebarLicense": "Licencja",
"sidebarClients": "Clients",
"sidebarClients": "Klientami",
"sidebarDomains": "Domeny",
"sidebarBluePrints": "Schematy",
"blueprints": "Schematy",
"blueprintsDescription": "Zastosuj konfiguracje deklaracyjne i wyświetl poprzednie operacje",
"blueprintAdd": "Dodaj schemat",
"blueprintGoBack": "Zobacz wszystkie schematy",
"blueprintCreate": "Utwórz schemat",
"blueprintCreateDescription2": "Wykonaj poniższe kroki, aby utworzyć i zastosować nowy schemat",
"blueprintDetails": "Szczegóły Projektu",
"blueprintDetailsDescription": "Zobacz wynik zastosowanego schematu i wszelkie błędy, które wystąpiły",
"blueprintInfo": "Informacje o projekcie",
"message": "Wiadomość",
"blueprintContentsDescription": "Zdefiniuj zawartość YAML opisującą Twoją infrastrukturę",
"blueprintErrorCreateDescription": "Wystąpił błąd podczas stosowania schematu",
"blueprintErrorCreate": "Błąd podczas tworzenia schematu",
"searchBlueprintProgress": "Szukaj schematów...",
"appliedAt": "Zastosowano",
"source": "Źródło",
"contents": "Treść",
"parsedContents": "Przetworzona zawartość (tylko do odczytu)",
"enableDockerSocket": "Włącz schemat dokera",
"enableDockerSocketDescription": "Włącz etykietowanie kieszeni dokującej dla etykiet schematów. Ścieżka do gniazda musi być dostarczona do Newt.",
"enableDockerSocketLink": "Dowiedz się więcej",
@@ -1211,9 +1237,8 @@
"domainCreate": "Utwórz domenę",
"domainCreatedDescription": "Domena utworzona pomyślnie",
"domainDeletedDescription": "Domena usunięta pomyślnie",
"domainQuestionRemove": "Czy na pewno chcesz usunąć domenę {domain} ze swojego konta?",
"domainQuestionRemove": "Czy na pewno chcesz usunąć domenę ze swojego konta?",
"domainMessageRemove": "Po usunięciu domena nie będzie już powiązana z twoim kontem.",
"domainMessageConfirm": "Aby potwierdzić, wpisz nazwę domeny poniżej.",
"domainConfirmDelete": "Potwierdź usunięcie domeny",
"domainDelete": "Usuń domenę",
"domain": "Domena",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Wystąpił błąd podczas aktualizacji ustawień",
"sidebarCollapse": "Zwiń",
"sidebarExpand": "Rozwiń",
"productUpdateMoreInfo": "{noOfUpdates} więcej aktualizacji",
"productUpdateInfo": "Aktualizacje {noOfUpdates}",
"productUpdateWhatsNew": "Co nowego",
"productUpdateTitle": "Aktualizacje produktu",
"productUpdateEmpty": "Brak aktualizacji",
"dismissAll": "Zamknij wszystkie",
"pangolinUpdateAvailable": "Dostępna jest nowa wersja",
"pangolinUpdateAvailableInfo": "Wersja {version} jest gotowa do zainstalowania",
"pangolinUpdateAvailableReleaseNotes": "Zobacz notatki o wydaniu",
"newtUpdateAvailable": "Dostępna aktualizacja",
"newtUpdateAvailableInfo": "Nowa wersja Newt jest dostępna. Prosimy o aktualizację do najnowszej wersji dla najlepszej pracy.",
"domainPickerEnterDomain": "Domena",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Darmowy pakiet",
"billingWarningOverLimit": "Ostrzeżenie: Przekroczyłeś jeden lub więcej limitów użytkowania. Twoje witryny nie połączą się, dopóki nie zmienisz subskrypcji lub nie dostosujesz 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@fossorial.io.",
"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",
"billingOnlineTime": "Czas Online Strony",
"billingUsers": "Aktywni użytkownicy",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Wystąpił problem z używaniem klucza bezpieczeństwa. Proszę spróbować ponownie.",
"twoFactorRequired": "Uwierzytelnianie dwuskładnikowe jest wymagane do zarejestrowania klucza bezpieczeństwa.",
"twoFactor": "Uwierzytelnianie dwuskładnikowe",
"twoFactorAuthentication": "Uwierzytelnianie dwuetapowe",
"twoFactorDescription": "Ta organizacja wymaga uwierzytelniania dwuskładnikowego.",
"enableTwoFactor": "Włącz uwierzytelnianie dwuetapowe",
"organizationSecurityPolicy": "Polityka bezpieczeństwa organizacji",
"organizationSecurityPolicyDescription": "Ta organizacja ma wymagania bezpieczeństwa, które muszą być spełnione, zanim będziesz mógł uzyskać dostęp do niej",
"securityRequirements": "Wymogi bezpieczeństwa",
"allRequirementsMet": "Wszystkie wymagania zostały spełnione",
"completeRequirementsToContinue": "Wypełnij poniższe wymagania, aby kontynuować dostęp do tej organizacji",
"youCanNowAccessOrganization": "Teraz możesz uzyskać dostęp do tej organizacji",
"reauthenticationRequired": "Długość sesji",
"reauthenticationDescription": "Organizacja wymaga logowania co {maxDays} dni.",
"reauthenticationDescriptionHours": "Organizacja wymaga logowania co {maxHours} godzin.",
"reauthenticateNow": "Zaloguj się ponownie",
"adminEnabled2FaOnYourAccount": "Twój administrator włączył uwierzytelnianie dwuskładnikowe dla {email}. Proszę ukończyć proces konfiguracji, aby kontynuować.",
"securityKeyAdd": "Dodaj klucz bezpieczeństwa",
"securityKeyRegisterTitle": "Zarejestruj nowy klucz bezpieczeństwa",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Te zasoby są do użytku z",
"resourcesTableClients": "Klientami",
"resourcesTableAndOnlyAccessibleInternally": "i są dostępne tylko wewnętrznie po połączeniu z klientem.",
"resourcesTableNoTargets": "Brak celów",
"resourcesTableHealthy": "Zdrowe",
"resourcesTableDegraded": "Degradacja",
"resourcesTableOffline": "Offline",
"resourcesTableUnknown": "Nieznane",
"resourcesTableNotMonitored": "Nie monitorowano",
"editInternalResourceDialogEditClientResource": "Edytuj zasób klienta",
"editInternalResourceDialogUpdateResourceProperties": "Zaktualizuj właściwości zasobu i konfigurację celu dla {resourceName}.",
"editInternalResourceDialogResourceProperties": "Właściwości zasobów",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Nie otrzymano URL przekierowania od dostawcy tożsamości.",
"autoLoginErrorGeneratingUrl": "Nie udało się wygenerować URL uwierzytelniania.",
"remoteExitNodeManageRemoteExitNodes": "Zdalne węzły",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Samodzielny host jeden lub więcej węzłów zdalnych, aby rozszerzyć łączność z siecią i zmniejszyć zależność od chmury",
"remoteExitNodes": "Węzły",
"searchRemoteExitNodes": "Szukaj węzłów...",
"remoteExitNodeAdd": "Dodaj węzeł",
"remoteExitNodeErrorDelete": "Błąd podczas usuwania węzła",
"remoteExitNodeQuestionRemove": "Czy na pewno chcesz usunąć węzeł {selectedNode} z organizacji?",
"remoteExitNodeQuestionRemove": "Czy na pewno chcesz usunąć węzeł z organizacji?",
"remoteExitNodeMessageRemove": "Po usunięciu, węzeł nie będzie już dostępny.",
"remoteExitNodeMessageConfirm": "Aby potwierdzić, wpisz nazwę węzła poniżej.",
"remoteExitNodeConfirmDelete": "Potwierdź usunięcie węzła",
"remoteExitNodeDelete": "Usuń węzeł",
"sidebarRemoteExitNodes": "Zdalne węzły",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Edytuj plik: docker-compose.yml",
"emailVerificationRequired": "Weryfikacja adresu e-mail jest wymagana. Zaloguj się ponownie przez {dashboardUrl}/auth/login zakończył ten krok. Następnie wróć tutaj.",
"twoFactorSetupRequired": "Konfiguracja uwierzytelniania dwuskładnikowego jest wymagana. Zaloguj się ponownie przez {dashboardUrl}/auth/login dokończ ten krok. Następnie wróć tutaj.",
"additionalSecurityRequired": "Wymagane dodatkowe zabezpieczenie",
"organizationRequiresAdditionalSteps": "Ta organizacja wymaga dodatkowych kroków bezpieczeństwa, zanim będziesz mógł uzyskać dostęp do zasobów.",
"completeTheseSteps": "Wykonaj te kroki",
"enableTwoFactorAuthentication": "Włącz uwierzytelnianie dwuskładnikowe",
"completeSecuritySteps": "Zakończ kroki bezpieczeństwa",
"securitySettings": "Ustawienia zabezpieczeń",
"securitySettingsDescription": "Skonfiguruj politykę bezpieczeństwa dla Twojej organizacji",
"requireTwoFactorForAllUsers": "Wymagaj uwierzytelniania dwuetapowego dla wszystkich użytkowników",
"requireTwoFactorDescription": "Po włączeniu wszyscy użytkownicy wewnętrzni w tej organizacji muszą mieć włączone uwierzytelnianie dwuskładnikowe, aby uzyskać dostęp do organizacji.",
"requireTwoFactorDisabledDescription": "Ta funkcja wymaga poprawnej licencji (Enterprise) lub aktywnej subskrypcji (SaaaS)",
"requireTwoFactorCannotEnableDescription": "Musisz włączyć uwierzytelnianie dwuskładnikowe dla swojego konta przed wymuszaniem go dla wszystkich użytkowników",
"maxSessionLength": "Maksymalna długość sesji",
"maxSessionLengthDescription": "Ustaw maksymalny czas trwania sesji użytkownika. Po tym czasie użytkownicy będą musieli ponownie uwierzytelniać.",
"maxSessionLengthDisabledDescription": "Ta funkcja wymaga poprawnej licencji (Enterprise) lub aktywnej subskrypcji (SaaaS)",
"selectSessionLength": "Wybierz długość sesji",
"unenforced": "Niewymuszony",
"1Hour": "1 godzina",
"3Hours": "3 godziny",
"6Hours": "6 godzin",
"12Hours": "12 godzin",
"1DaySession": "1 dzień",
"3Days": "3 dni",
"7Days": "7 dni",
"14Days": "14 dni",
"30DaysSession": "30 dni",
"90DaysSession": "90 dni",
"180DaysSession": "180 dni",
"passwordExpiryDays": "Hasło wygasa",
"editPasswordExpiryDescription": "Ustaw liczbę dni zanim użytkownicy będą musieli zmienić swoje hasło.",
"selectPasswordExpiry": "Wybierz wygasanie hasła",
"30Days": "30 dni",
"1Day": "1 dzień",
"60Days": "60 dni",
"90Days": "90 dni",
"180Days": "180 dni",
"1Year": "1 rok",
"subscriptionBadge": "Wymagana subskrypcja",
"securityPolicyChangeWarning": "Ostrzeżenie o zmianach w polityce bezpieczeństwa",
"securityPolicyChangeDescription": "Zamierzasz zmienić ustawienia polityki bezpieczeństwa. Po zapisaniu konieczne może być ponowne uwierzytelnienie w celu zapewnienia zgodności z tymi aktualizacjami polityki. Wszyscy użytkownicy, którzy nie są zgodni, będą również musieli ponownie uwierzytelniać.",
"securityPolicyChangeConfirmMessage": "Potwierdzam",
"securityPolicyChangeWarningText": "To wpłynie na wszystkich użytkowników w organizacji",
"authPageErrorUpdateMessage": "Wystąpił błąd podczas aktualizacji ustawień strony uwierzytelniania",
"authPageErrorUpdate": "Nie można zaktualizować strony uwierzytelniania",
"authPageUpdated": "Strona uwierzytelniania została pomyślnie zaktualizowana",
"healthCheckNotAvailable": "Lokalny",
"rewritePath": "Przepis Ścieżki",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Uwierzytelnianie nagłówka zostało pomyślnie usunięte.",
"resourceErrorHeaderAuthRemove": "Nie udało się usunąć uwierzytelniania nagłówka",
"resourceErrorHeaderAuthRemoveDescription": "Nie można usunąć uwierzytelniania nagłówka zasobu.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Uwierzytelnianie nagłówka włączone",
"resourceHeaderAuthProtectionDisabled": "Uwierzytelnianie nagłówka wyłączone",
"headerAuthRemove": "Usuń autoryzację nagłówka",
"headerAuthAdd": "Dodaj Autoryzacja nagłówka",
"resourceErrorHeaderAuthSetup": "Nie udało się ustawić uwierzytelniania nagłówka",
"resourceErrorHeaderAuthSetupDescription": "Nie można ustawić uwierzytelniania nagłówka dla zasobu.",
"resourceHeaderAuthSetup": "Uwierzytelnianie nagłówka ustawione pomyślnie",
"resourceHeaderAuthSetupDescription": "Uwierzytelnianie nagłówka zostało ustawione.",
"resourceHeaderAuthSetupTitle": "Ustaw uwierzytelnianie nagłówka",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Ustaw podstawowe dane uwierzytelniające (nazwa użytkownika i hasło), aby chronić ten zasób za pomocą uwierzytelniania nagłówka HTTP. Uzyskaj dostęp za pomocą formatu https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Ustaw uwierzytelnianie nagłówka",
"actionSetResourceHeaderAuth": "Ustaw uwierzytelnianie nagłówka",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"enterpriseEdition": "Edycja Enterprise",
"unlicensed": "Nielicencjonowane",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"manageClients": "Zarządzaj klientami",
"manageClientsDescription": "Klienci to urządzenia, które mogą łączyć się z Twoimi witrynami",
"licenseTableValidUntil": "Ważny do",
"saasLicenseKeysSettingsTitle": "Licencje przedsiębiorstwa",
"saasLicenseKeysSettingsDescription": "Generuj i zarządzaj kluczami licencyjnymi Enterprise dla samodzielnych instancji Pangolin",
"sidebarEnterpriseLicenses": "Licencje",
"generateLicenseKey": "Generuj klucz licencyjny",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Wprowadź poprawny adres e-mail",
"useCaseTypeRequired": "Proszę wybrać typ litery",
"firstNameRequired": "Imię jest wymagane",
"lastNameRequired": "Nazwisko jest wymagane",
"primaryUseRequired": "Opisz swoje podstawowe użycie",
"jobTitleRequiredBusiness": "Tytuł pracy jest wymagany do użytku służbowego",
"industryRequiredBusiness": "Przemysł jest wymagany do celów biznesowych.",
"stateProvinceRegionRequired": "Wymagany jest stan/województwo/region",
"postalZipCodeRequired": "Kod pocztowy jest wymagany",
"companyNameRequiredBusiness": "Nazwa firmy jest wymagana do użytku służbowego",
"countryOfResidenceRequiredBusiness": "Kraj zamieszkania jest wymagany do celów służbowych",
"countryRequiredPersonal": "Kraj jest wymagany do użytku osobistego",
"agreeToTermsRequired": "Musisz zaakceptować regulamin",
"complianceConfirmationRequired": "Musisz potwierdzić zgodność z Fossorial Commercial License"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Użytkowanie osobiste",
"description": "Dla celów indywidualnych, niekomercyjnych, takich jak nauka, projekty osobiste lub eksperymenty."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Wykorzystanie służbowe",
"description": "Do użytku w ramach organizacji, przedsiębiorstw lub działalności komercyjnej lub generującej dochody."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "Typ adresu e-mail i licencji",
"description": "Wprowadź swój adres e-mail i wybierz rodzaj licencji"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Informacje osobiste",
"description": "Powiedz nam o sobie"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Informacje kontaktowe",
"description": "Twoje dane kontaktowe"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Reguły i generuj",
"description": "Przejrzyj i zaakceptuj warunki generowania licencji"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Ujawnienie użycia",
"description": "Wybierz poziom licencji, który dokładnie odzwierciedla zamierzone użycie. Licencja osobista pozwala na bezpłatne wykorzystanie oprogramowania do działalności komercyjnej, o charakterze indywidualnym, niekomercyjnym lub na małą skalę, o rocznym dochodzie brutto poniżej 100 000 USD. Wszelkie zastosowania wykraczające poza te ograniczenia w tym wykorzystanie w przedsiębiorstwie, organizacja, lub inne środowisko generujące dochód wymaga ważnej licencji przedsiębiorstwa i uiszczenia stosownej opłaty licencyjnej. Wszyscy użytkownicy, niezależnie od tego, czy są prywatni czy przedsiębiorcy, muszą przestrzegać warunków licencji Fossorial Commercial License."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Informacje o okresie próbnym",
"description": "Ten klucz licencyjny umożliwia przedsiębiorstwom funkcje na 7-dniowy okres oceny. Ciągły dostęp do płatnych funkcji po zakończeniu okresu oceny wymaga aktywacji na podstawie ważnej licencji osobistej lub prywatnej. W celu uzyskania licencji przedsiębiorstwa skontaktuj się z sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Używasz Pangolin do użytku osobistego lub biznesowego?",
"firstName": "Imię",
"lastName": "Nazwisko",
"jobTitle": "Tytuł zadania",
"primaryUseQuestion": "Na co planujesz przede wszystkim stosować lek Pangolin?",
"industryQuestion": "Jaki jest twój przemysł?",
"prospectiveUsersQuestion": "Ilu potencjalnych użytkowników oczekujesz?",
"prospectiveSitesQuestion": "Ile potencjalnych stron (tuneli) oczekujesz?",
"companyName": "Nazwa firmy",
"countryOfResidence": "Kraj zamieszkania",
"stateProvinceRegion": "Województwo / Region",
"postalZipCode": "Kod pocztowy",
"companyWebsite": "Strona internetowa firmy",
"companyPhoneNumber": "Numer telefonu firmy",
"country": "Kraj",
"phoneNumberOptional": "Numer telefonu (opcjonalnie)",
"complianceConfirmation": "Potwierdzam, że podane przeze mnie informacje są dokładne i że jestem zgodny z Fossorial Commercial License. Zgłaszanie nieprawidłowych informacji lub błędne oznaczanie użycia produktu jest naruszeniem licencji i może skutkować cofnięciem klucza."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Zamknij",
"previous": "Poprzedni",
"next": "Następny",
"generateLicenseKey": "Generuj klucz licencyjny"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Klucz licencyjny wygenerowany pomyślnie",
"description": "Twój klucz licencyjny został wygenerowany i jest gotowy do użycia."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Nie udało się wygenerować klucza licencyjnego",
"description": "Wystąpił błąd podczas generowania klucza licencji."
}
}
},
"priority": "Priorytet",
"priorityDescription": "Najpierw oceniane są trasy priorytetowe. Priorytet = 100 oznacza automatyczne zamawianie (decyzje systemowe). Użyj innego numeru, aby wyegzekwować ręczny priorytet.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Nazwa instancji",
"pathMatchModalTitle": "Skonfiguruj dopasowanie ścieżki",
"pathMatchModalDescription": "Skonfiguruj sposób dopasowania przychodzących żądań na podstawie ich ścieżki.",
"pathMatchType": "Typ dopasowania",
"pathMatchPrefix": "Prefiks",
"pathMatchExact": "Dokładny",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Wartość ścieżki",
"clear": "Wyczyść",
"saveChanges": "Zapisz zmiany",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathMatchDefaultPlaceholder": "/ścieżka",
"pathMatchPrefixHelp": "Przykład: /api pasuje do /api, /api/users itp.",
"pathMatchExactHelp": "Przykład: /api pasuje tylko /api",
"pathMatchRegexHelp": "Przykład: ^/api/.* pasuje do /api/cokolwiek",
"pathRewriteModalTitle": "Konfiguruj Przepisywanie Ścieżki",
"pathRewriteModalDescription": "Przekształć dopasowaną ścieżkę przed przekierowaniem do celu.",
"pathRewriteType": "Typ przekierowania",
"pathRewritePrefixOption": "Prefiks - Zamień prefiks",
"pathRewriteExactOption": "Dokładny - Zamień całą ścieżkę",
"pathRewriteRegexOption": "Regex - zamiennik wzoru",
"pathRewriteStripPrefixOption": "Prefiks paska - Usuń prefiks",
"pathRewriteValue": "Przepisz wartość",
"pathRewriteRegexPlaceholder": "/nowy/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewritePrefixHelp": "Zastąp dopasowany prefiks tą wartością",
"pathRewriteExactHelp": "Zastąp całą ścieżkę tą wartością, gdy ścieżka dokładnie pasuje do siebie",
"pathRewriteRegexHelp": "Użyj grup przechwytywania takich jak $1, $2 do zamiany",
"pathRewriteStripPrefixHelp": "Pozostaw puste, aby usunąć prefiks lub podać nowy prefiks",
"pathRewritePrefix": "Prefiks",
"pathRewriteExact": "Dokładny",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Pasek",
"pathRewriteStripLabel": "pasek",
"sidebarEnableEnterpriseLicense": "Włącz licencję przedsiębiorstwa",
"cannotbeUndone": "Tej operacji nie można cofnąć.",
"toConfirm": "potwierdzić",
"deleteClientQuestion": "Czy na pewno chcesz usunąć klienta z witryny i organizacji?",
"clientMessageRemove": "Po usunięciu, klient nie będzie już mógł połączyć się z witryną.",
"sidebarLogs": "Logi",
"request": "Żądanie",
"logs": "Logi",
"logsSettingsDescription": "Monitoruj logi zebrane z tej orginizacji",
"searchLogs": "Szukaj dzienników...",
"action": "Akcja",
"actor": "Aktor",
"timestamp": "Znacznik czasu",
"accessLogs": "Logi dostępu",
"exportCsv": "Eksportuj CSV",
"actorId": "Identyfikator podmiotu",
"allowedByRule": "Dozwolone przez regułę",
"allowedNoAuth": "Dozwolone Brak Auth",
"validAccessToken": "Ważny token dostępu",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Prawidłowe hasło",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Zasób zablokowany",
"droppedByRule": "Upuszczone przez regułę",
"noSessions": "Brak sesji",
"temporaryRequestToken": "Tymczasowy token żądania",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP",
"reason": "Powód",
"requestLogs": "Dzienniki żądań",
"host": "Host",
"location": "Lokalizacja",
"actionLogs": "Dzienniki działań",
"sidebarLogsRequest": "Dzienniki żądań",
"sidebarLogsAccess": "Logi dostępu",
"sidebarLogsAction": "Dzienniki działań",
"logRetention": "Zachowanie dziennika",
"logRetentionDescription": "Zarządzaj jak długo różne typy logów są zachowane dla tej organizacji lub wyłącz je",
"requestLogsDescription": "Zobacz szczegółowe dzienniki żądań zasobów w tej organizacji",
"logRetentionRequestLabel": "Zachowanie dziennika żądań",
"logRetentionRequestDescription": "Jak długo zachować dzienniki żądań",
"logRetentionAccessLabel": "Zachowanie dziennika dostępu",
"logRetentionAccessDescription": "Jak długo zachować dzienniki dostępu",
"logRetentionActionLabel": "Zachowanie dziennika akcji",
"logRetentionActionDescription": "Jak długo zachować dzienniki akcji",
"logRetentionDisabled": "Wyłączone",
"logRetention3Days": "3 dni",
"logRetention7Days": "7 dni",
"logRetention14Days": "14 dni",
"logRetention30Days": "30 dni",
"logRetention90Days": "90 dni",
"logRetentionForever": "Na zawsze",
"actionLogsDescription": "Zobacz historię działań wykonywanych 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.",
"certResolver": "Rozwiązywanie certyfikatów",
"certResolverDescription": "Wybierz resolver certyfikatów do użycia dla tego zasobu.",
"selectCertResolver": "Wybierz Resolver certyfikatów",
"enterCustomResolver": "Wprowadź niestandardowy Resolver",
"preferWildcardCert": "Preferuj Certyfikat Wildcard",
"unverified": "Niezweryfikowane",
"domainSetting": "Ustawienia domeny",
"domainSettingDescription": "Skonfiguruj ustawienia domeny",
"preferWildcardCertDescription": "Próba wygenerowania certyfikatu wieloznacznego (wymaga poprawnie skonfigurowanego resolwera certyfikatów).",
"recordName": "Nazwa rekordu",
"auto": "Auto",
"TTL": "TTL",
"howToAddRecords": "Jak dodać rekordy",
"dnsRecord": "Wpisy DNS",
"required": "Wymagane",
"domainSettingsUpdated": "Ustawienia domeny zaktualizowane pomyślnie",
"orgOrDomainIdMissing": "Brakuje identyfikatora organizacji lub domeny",
"loadingDNSRecords": "Ładowanie rekordów DNS...",
"olmUpdateAvailableInfo": "Dostępna jest zaktualizowana wersja Olm. Zaktualizuj do najnowszej wersji, aby uzyskać najlepsze doświadczenia.",
"client": "Klient",
"proxyProtocol": "Ustawienia protokołu proxy",
"proxyProtocolDescription": "Skonfiguruj protokół Proxy aby zachować adresy IP klienta dla usług TCP/UDP.",
"enableProxyProtocol": "Włącz protokół proxy",
"proxyProtocolInfo": "Zachowaj adresy IP klienta dla backendów TCP/UDP",
"proxyProtocolVersion": "Wersja protokołu proxy",
"version1": " Wersja 1 (zalecane)",
"version2": "Wersja 2",
"versionDescription": "Wersja 1 jest oparta na tekście i szeroko wspierana. Wersja 2 jest binarna i bardziej efektywna, ale mniej kompatybilna.",
"warning": "Ostrzeżenie",
"proxyProtocolWarning": "Twoja aplikacja backend musi być skonfigurowana tak, aby przyjmować połączenia z protokołem proxy. Jeśli Twój backend nie obsługuje protokołu proxy, włączenie to spowoduje przerwanie wszystkich połączeń. Upewnij się, że konfiguracja twojego backendu do zaufanych nagłówków protokołu proxy z Traefik.",
"restarting": "Restartowanie...",
"manual": "Ręcznie",
"messageSupport": "Obsługa wiadomości",
"supportNotAvailableTitle": "Wsparcie niedostępne",
"supportNotAvailableDescription": "Wsparcie nie jest teraz dostępne. Możesz wysłać e-mail na adres support@pangolin.net.",
"supportRequestSentTitle": "Prośba o wsparcie wysłana",
"supportRequestSentDescription": "Wiadomość została wysłana pomyślnie.",
"supportRequestFailedTitle": "Nie udało się wysłać żądania",
"supportRequestFailedDescription": "Wystąpił błąd podczas wysyłania prośby o wsparcie.",
"supportSubjectRequired": "Temat jest wymagany",
"supportSubjectMaxLength": "Temat musi mieć 255 znaków lub mniej",
"supportMessageRequired": "Wiadomość jest wymagana",
"supportReplyTo": "Odpowiedź do",
"supportSubject": "Temat",
"supportSubjectPlaceholder": "Wprowadź temat",
"supportMessage": "Wiadomość",
"supportMessagePlaceholder": "Wprowadź swoją wiadomość",
"supportSending": "Wysyłanie...",
"supportSend": "Wyślij",
"supportMessageSent": "Wiadomość wysłana!",
"supportWillContact": "Wkrótce będziemy w kontakcie!",
"selectLogRetention": "Wybierz zatrzymanie dziennika",
"showColumns": "Pokaż kolumny",
"hideColumns": "Ukryj kolumny",
"columnVisibility": "Widoczność kolumn",
"toggleColumn": "Przełącz kolumnę {columnName}",
"allColumns": "Wszystkie kolumny",
"defaultColumns": "Kolumny domyślne",
"customizeView": "Dostosuj widok",
"viewOptions": "Opcje widoku",
"selectAll": "Zaznacz wszystko",
"selectNone": "Nie wybierz żadnego",
"selectedResources": "Wybrane Zasoby",
"enableSelected": "Włącz zaznaczone",
"disableSelected": "Wyłącz zaznaczone",
"checkSelectedStatus": "Sprawdź status zaznaczonych",
"credentials": "Dane logowania",
"savecredentials": "Zapisz dane logowania",
"regeneratecredentials": "Przycisk ponownie",
"regenerateCredentials": "Ponownie wygeneruj i zapisz swoje dane logowania",
"generatedcredentials": "Wygenerowane dane logowania",
"copyandsavethesecredentials": "Skopiuj i zapisz te dane logowania",
"copyandsavethesecredentialsdescription": "Te dane uwierzytelniające nie będą wyświetlane ponownie po opuszczeniu tej strony. Zapisz je teraz bezpiecznie.",
"credentialsSaved": "Zapisano dane logowania",
"credentialsSavedDescription": "Dane logowania zostały wygenerowane i zapisane pomyślnie.",
"credentialsSaveError": "Błąd zapisu danych logowania",
"credentialsSaveErrorDescription": "Wystąpił błąd podczas regeneracji i zapisywania poświadczeń.",
"regenerateCredentialsWarning": "Regeneracja poświadczeń spowoduje unieważnienie poprzednich poświadczeń. Upewnij się, że zaktualizowano wszystkie konfiguracje, które używają tych poświadczeń.",
"confirm": "Potwierdź",
"regenerateCredentialsConfirmation": "Czy na pewno chcesz wygenerować dane logowania?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Sekretny klucz",
"featureDisabledTooltip": "Ta funkcja jest dostępna tylko w planie przedsiębiorstwa i wymaga licencji, aby z niej korzystać.",
"niceId": "Niepoprawne ID",
"niceIdUpdated": "Zaktualizowano błędne ID",
"niceIdUpdatedSuccessfully": "Zaktualizowano błędne ID",
"niceIdUpdateError": "Błąd podczas aktualizacji Nice ID",
"niceIdUpdateErrorDescription": "Wystąpił błąd podczas aktualizowania Nicei ID.",
"niceIdCannotBeEmpty": "Niepoprawny identyfikator nie może być pusty",
"enterIdentifier": "Wprowadź identyfikator",
"identifier": "Identifier"
}

View File

@@ -47,9 +47,8 @@
"edit": "Alterar",
"siteConfirmDelete": "Confirmar que pretende apagar o site",
"siteDelete": "Excluir site",
"siteMessageRemove": "Uma vez removido, o site não estará mais acessível. Todos os recursos e alvos associados ao site também serão removidos.",
"siteMessageConfirm": "Para confirmar, por favor, digite o nome do site abaixo.",
"siteQuestionRemove": "Você tem certeza que deseja remover o site {selectedSite} da organização?",
"siteMessageRemove": "Uma vez removido, o site não estará mais acessível. Todas as metas associadas ao site também serão removidas.",
"siteQuestionRemove": "Você tem certeza que deseja remover este site da organização?",
"siteManageSites": "Gerir sites",
"siteDescription": "Permitir conectividade à sua rede através de túneis seguros",
"siteCreate": "Criar site",
@@ -96,7 +95,7 @@
"siteWgDescription": "Use qualquer cliente do WireGuard para estabelecer um túnel. Configuração manual NAT é necessária.",
"siteWgDescriptionSaas": "Use qualquer cliente WireGuard para estabelecer um túnel. Configuração manual NAT necessária. SOMENTE FUNCIONA EM NODES AUTO-HOSPEDADOS",
"siteLocalDescription": "Recursos locais apenas. Sem túneis.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Apenas recursos locais. Sem túneis. Apenas disponível em nós remotos.",
"siteSeeAll": "Ver todos os sites",
"siteTunnelDescription": "Determine como você deseja se conectar ao seu site",
"siteNewtCredentials": "Credenciais Novas",
@@ -154,8 +153,7 @@
"protected": "Protegido",
"notProtected": "Não Protegido",
"resourceMessageRemove": "Uma vez removido, o recurso não estará mais acessível. Todos os alvos associados ao recurso também serão removidos.",
"resourceMessageConfirm": "Para confirmar, por favor, digite o nome do recurso abaixo.",
"resourceQuestionRemove": "Tem certeza que deseja remover o recurso {selectedResource} da organização?",
"resourceQuestionRemove": "Você tem certeza que deseja remover o recurso da organização?",
"resourceHTTP": "Recurso HTTPS",
"resourceHTTPDescription": "O proxy solicita ao seu aplicativo via HTTPS usando um subdomínio ou domínio base.",
"resourceRaw": "Recurso TCP/UDP bruto",
@@ -181,7 +179,7 @@
"baseDomain": "Domínio Base",
"subdomnainDescription": "O subdomínio onde seu recurso estará acessível.",
"resourceRawSettings": "Configurações TCP/UDP",
"resourceRawSettingsDescription": "Configure como seu recurso será acessado sobre TCP/UDP",
"resourceRawSettingsDescription": "Configure como seu recurso será acessado sobre TCP/UDP. Você mapeia o recurso para uma porta no servidor Pangolin do hospedeiro, para que você possa acessar o recurso do server-public-ip:mapped-port.",
"protocol": "Protocolo",
"protocolSelect": "Selecione um protocolo",
"resourcePortNumber": "Número da Porta",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Confirmar que pretende apagar a organização",
"orgMessageRemove": "Esta ação é irreversível e apagará todos os dados associados.",
"orgMessageConfirm": "Para confirmar, digite o nome da organização abaixo.",
"orgQuestionRemove": "Tem certeza que deseja remover a organização {selectedOrg}?",
"orgQuestionRemove": "Você tem certeza que deseja remover esta organização?",
"orgUpdated": "Organização atualizada",
"orgUpdatedDescription": "A organização foi atualizada.",
"orgErrorUpdate": "Falha ao atualizar organização",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Gerar Chave API",
"apiKeysErrorDelete": "Erro ao apagar chave API",
"apiKeysErrorDeleteMessage": "Erro ao apagar chave API",
"apiKeysQuestionRemove": "Tem certeza que deseja remover a chave API {selectedApiKey} da organização?",
"apiKeysQuestionRemove": "Tem certeza que deseja remover a chave de API da organização?",
"apiKeysMessageRemove": "Uma vez removida, a chave API não poderá mais ser utilizada.",
"apiKeysMessageConfirm": "Para confirmar, por favor digite o nome da chave API abaixo.",
"apiKeysDeleteConfirm": "Confirmar Exclusão da Chave API",
"apiKeysDelete": "Excluir Chave API",
"apiKeysManage": "Gerir Chaves API",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Confirmar Exclusão do Usuário",
"userDeleteServer": "Excluir utilizador do servidor",
"userMessageRemove": "O utilizador será removido de todas as organizações e será completamente removido do servidor.",
"userMessageConfirm": "Para confirmar, por favor digite o nome do utilizador abaixo.",
"userQuestionRemove": "Tem certeza que deseja apagar o {selectedUser} permanentemente do servidor?",
"userQuestionRemove": "Tem certeza que deseja excluir permanentemente o usuário do servidor?",
"licenseKey": "Chave de Licença",
"valid": "Válido",
"numberOfSites": "Número de sites",
@@ -339,7 +335,7 @@
"fossorialLicense": "Ver Termos e Condições de Assinatura e Licença Fossorial",
"licenseMessageRemove": "Isto irá remover a chave da licença e todas as permissões associadas concedidas por ela.",
"licenseMessageConfirm": "Para confirmar, por favor, digite a chave de licença abaixo.",
"licenseQuestionRemove": "Tem certeza que deseja apagar a chave de licença {selectedKey}?",
"licenseQuestionRemove": "Tem certeza que deseja excluir a chave de licença?",
"licenseKeyDelete": "Excluir Chave de Licença",
"licenseKeyDeleteConfirm": "Confirmar que pretende apagar a chave de licença",
"licenseTitle": "Gerir Status da Licença",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Ocorreu um erro ao remover o convite.",
"inviteRemoved": "Convite removido",
"inviteRemovedDescription": "O convite para {email} foi removido.",
"inviteQuestionRemove": "Tem certeza de que deseja remover o convite {email}?",
"inviteQuestionRemove": "Tem certeza de que deseja remover o convite?",
"inviteMessageRemove": "Uma vez removido, este convite não será mais válido. Você sempre pode convidar o utilizador novamente mais tarde.",
"inviteMessageConfirm": "Para confirmar, digite o endereço de e-mail do convite abaixo.",
"inviteQuestionRegenerate": "Tem certeza que deseja regenerar o convite{email, plural, ='' {}, other { para #}}? Isso irá revogar o convite anterior.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Ocorreu um erro ao remover o utilizador.",
"userOrgRemoved": "Usuário removido",
"userOrgRemovedDescription": "O utilizador {email} foi removido da organização.",
"userQuestionOrgRemove": "Tem certeza que deseja remover {email} da organização?",
"userQuestionOrgRemove": "Você tem certeza que deseja remover este usuário da organização?",
"userMessageOrgRemove": "Uma vez removido, este utilizador não terá mais acesso à organização. Você sempre pode reconvidá-lo depois, mas eles precisarão aceitar o convite novamente.",
"userMessageOrgConfirm": "Para confirmar, digite o nome do utilizador abaixo.",
"userRemoveOrgConfirm": "Confirmar Remoção do Usuário",
"userRemoveOrg": "Remover Usuário da Organização",
"users": "Utilizadores",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Administrador do Servidor - Pangolin",
"licenseTierProfessional": "Licença Profissional",
"licenseTierEnterprise": "Licença Empresarial",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Licença Pessoal",
"licensed": "Licenciado",
"yes": "Sim",
"no": "Não",
@@ -742,7 +737,7 @@
"idpManageDescription": "Visualizar e gerir provedores de identidade no sistema",
"idpDeletedDescription": "Provedor de identidade eliminado com sucesso",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Tem certeza que deseja eliminar permanentemente o provedor de identidade {name}?",
"idpQuestionRemove": "Tem certeza que deseja eliminar permanentemente o provedor de identidade?",
"idpMessageRemove": "Isto irá remover o provedor de identidade e todas as configurações associadas. Os utilizadores que se autenticam através deste provedor não poderão mais fazer login.",
"idpMessageConfirm": "Para confirmar, por favor digite o nome do provedor de identidade abaixo.",
"idpConfirmDelete": "Confirmar Eliminação do Provedor de Identidade",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Verifique o seu email para obter o código de redefinição.",
"passwordNew": "Nova Palavra-passe",
"passwordNewConfirm": "Confirmar Nova Palavra-passe",
"changePassword": "Mudar a senha",
"changePasswordDescription": "Atualize a senha da sua conta",
"oldPassword": "Palavra-passe Atual",
"newPassword": "Nova Palavra-Passe",
"confirmNewPassword": "Confirme a Nova Senha",
"changePasswordError": "Falha ao alterar a senha",
"changePasswordErrorDescription": "Ocorreu um erro ao alterar sua senha",
"changePasswordSuccess": "Senha alterada com sucesso",
"changePasswordSuccessDescription": "Sua senha foi atualizada com sucesso",
"passwordExpiryRequired": "Expiração de senha necessária",
"passwordExpiryDescription": "Esta organização exige que você altere sua senha a cada {maxDays} dias.",
"changePasswordNow": "Alterar a senha agora",
"pincodeAuth": "Código do Autenticador",
"pincodeSubmit2": "Submeter Código",
"passwordResetSubmit": "Solicitar Redefinição",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Todos os utilizadores",
"sidebarIdentityProviders": "Provedores de identidade",
"sidebarLicense": "Tipo:",
"sidebarClients": "Clients",
"sidebarClients": "Clientes",
"sidebarDomains": "Domínios",
"sidebarBluePrints": "Diagramas",
"blueprints": "Diagramas",
"blueprintsDescription": "Aplicar configurações declarativas e ver execuções anteriores",
"blueprintAdd": "Adicionar Diagrama",
"blueprintGoBack": "Ver todos os Diagramas",
"blueprintCreate": "Criar Diagrama",
"blueprintCreateDescription2": "Siga as etapas abaixo para criar e aplicar um novo diagrama",
"blueprintDetails": "Detalhes do Diagrama",
"blueprintDetailsDescription": "Veja o resultado do diagrama aplicado e todos os erros que ocorreram",
"blueprintInfo": "Informação do Diagrama",
"message": "mensagem",
"blueprintContentsDescription": "Defina o conteúdo YAML descrevendo a sua infraestrutura",
"blueprintErrorCreateDescription": "Ocorreu um erro ao aplicar o diagrama",
"blueprintErrorCreate": "Erro ao criar diagrama",
"searchBlueprintProgress": "Pesquisar diagramas...",
"appliedAt": "Aplicado em",
"source": "fonte",
"contents": "Conteúdo",
"parsedContents": "Conteúdo analisado (Somente Leitura)",
"enableDockerSocket": "Habilitar o Diagrama Docker",
"enableDockerSocketDescription": "Ativar a scraping de rótulo Docker para rótulos de diagramas. Caminho de Socket deve ser fornecido para Newt.",
"enableDockerSocketLink": "Saiba mais",
@@ -1211,9 +1237,8 @@
"domainCreate": "Criar Domínio",
"domainCreatedDescription": "Domínio criado com sucesso",
"domainDeletedDescription": "Domínio deletado com sucesso",
"domainQuestionRemove": "Tem certeza de que deseja remover o domínio {domain} da sua conta?",
"domainQuestionRemove": "Tem certeza de que deseja remover o domínio da sua conta?",
"domainMessageRemove": "Uma vez removido, o domínio não estará mais associado à sua conta.",
"domainMessageConfirm": "Para confirmar, digite o nome do domínio abaixo.",
"domainConfirmDelete": "Confirmar Exclusão de Domínio",
"domainDelete": "Excluir Domínio",
"domain": "Domínio",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Ocorreu um erro ao atualizar configurações",
"sidebarCollapse": "Recolher",
"sidebarExpand": "Expandir",
"productUpdateMoreInfo": "Mais {noOfUpdates} atualizações",
"productUpdateInfo": "Atualizações {noOfUpdates}",
"productUpdateWhatsNew": "Novidades",
"productUpdateTitle": "Atualizações de Produto",
"productUpdateEmpty": "Não há atualizações",
"dismissAll": "Recusar tudo",
"pangolinUpdateAvailable": "Nova versão disponível",
"pangolinUpdateAvailableInfo": "A versão {version} está pronta para ser instalada",
"pangolinUpdateAvailableReleaseNotes": "Ver notas de lançamento",
"newtUpdateAvailable": "Nova Atualização Disponível",
"newtUpdateAvailableInfo": "Uma nova versão do Newt está disponível. Atualize para a versão mais recente para uma melhor experiência.",
"domainPickerEnterDomain": "Domínio",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Plano Gratuito",
"billingWarningOverLimit": "Aviso: Você ultrapassou um ou mais limites de uso. Seus sites não se conectarão até você modificar sua assinatura ou ajustar seu 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@fossorial.io.",
"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",
"billingOnlineTime": "Tempo Online do Site",
"billingUsers": "Usuários Ativos",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Houve um problema ao usar sua chave de segurança. Tente novamente.",
"twoFactorRequired": "A autenticação de dois fatores é necessária para registrar uma chave de segurança.",
"twoFactor": "Autenticação de Dois Fatores",
"twoFactorAuthentication": "Autenticação dupla",
"twoFactorDescription": "Esta organização requer autenticação de dois fatores.",
"enableTwoFactor": "Ativar autenticação dupla",
"organizationSecurityPolicy": "Política de Segurança da Organização",
"organizationSecurityPolicyDescription": "Esta organização tem requisitos de segurança que precisam ser cumpridos antes que você possa acessá-la",
"securityRequirements": "Requisitos De Segurança",
"allRequirementsMet": "Todos os requisitos foram cumpridos",
"completeRequirementsToContinue": "Preencha os requisitos abaixo para continuar acessando esta organização",
"youCanNowAccessOrganization": "Agora você pode acessar esta organização",
"reauthenticationRequired": "Comprimento da sessão",
"reauthenticationDescription": "Esta organização requer que você faça login a cada {maxDays} dias.",
"reauthenticationDescriptionHours": "Esta organização exige que você faça login a cada {maxHours} horas.",
"reauthenticateNow": "Iniciar sessão novamente",
"adminEnabled2FaOnYourAccount": "Seu administrador ativou a autenticação de dois fatores para {email}. Complete o processo de configuração para continuar.",
"securityKeyAdd": "Adicionar Chave de Segurança",
"securityKeyRegisterTitle": "Registrar Nova Chave de Segurança",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Esses recursos são para uso com",
"resourcesTableClients": "Clientes",
"resourcesTableAndOnlyAccessibleInternally": "e são acessíveis apenas internamente quando conectados com um cliente.",
"resourcesTableNoTargets": "Nenhum alvo",
"resourcesTableHealthy": "Saudável",
"resourcesTableDegraded": "Degradado",
"resourcesTableOffline": "Desconectado",
"resourcesTableUnknown": "Desconhecido",
"resourcesTableNotMonitored": "Não monitorado",
"editInternalResourceDialogEditClientResource": "Editar Recurso do Cliente",
"editInternalResourceDialogUpdateResourceProperties": "Atualize as propriedades do recurso e a configuração do alvo para {resourceName}.",
"editInternalResourceDialogResourceProperties": "Propriedades do Recurso",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Nenhum URL de redirecionamento recebido do provedor de identidade.",
"autoLoginErrorGeneratingUrl": "Falha ao gerar URL de autenticação.",
"remoteExitNodeManageRemoteExitNodes": "Nós remotos",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Auto-hospedar um ou mais nós remotos para estender sua conectividade de rede e reduzir a dependência da nuvem",
"remoteExitNodes": "Nós",
"searchRemoteExitNodes": "Buscar nós...",
"remoteExitNodeAdd": "Adicionar node",
"remoteExitNodeErrorDelete": "Erro ao excluir nó",
"remoteExitNodeQuestionRemove": "Tem certeza que deseja remover o nó {selectedNode} da organização?",
"remoteExitNodeQuestionRemove": "Tem certeza de que deseja remover o nó da organização?",
"remoteExitNodeMessageRemove": "Uma vez removido, o nó não estará mais acessível.",
"remoteExitNodeMessageConfirm": "Para confirmar, por favor, digite o nome do nó abaixo.",
"remoteExitNodeConfirmDelete": "Confirmar exclusão do nó",
"remoteExitNodeDelete": "Excluir nó",
"sidebarRemoteExitNodes": "Nós remotos",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Editar arquivo: docker-compose.yml",
"emailVerificationRequired": "Verificação de e-mail é necessária. Por favor, faça login novamente via {dashboardUrl}/auth/login conclui esta etapa. Em seguida, volte aqui.",
"twoFactorSetupRequired": "Configuração de autenticação de dois fatores é necessária. Por favor, entre novamente via {dashboardUrl}/auth/login conclua este passo. Em seguida, volte aqui.",
"additionalSecurityRequired": "Segurança adicional necessária",
"organizationRequiresAdditionalSteps": "Esta organização requer etapas de segurança adicionais antes que você possa acessar os recursos.",
"completeTheseSteps": "Conclua estas etapas",
"enableTwoFactorAuthentication": "Ativar autenticação de dois fatores",
"completeSecuritySteps": "Passos de segurança completos",
"securitySettings": "Configurações de Segurança",
"securitySettingsDescription": "Configurar políticas de segurança para a sua organização",
"requireTwoFactorForAllUsers": "Exigir autenticação dupla para todos os usuários",
"requireTwoFactorDescription": "Quando ativado, todos os usuários internos nesta organização devem ter a autenticação de dois fatores ativada para acessar a organização.",
"requireTwoFactorDisabledDescription": "Este recurso requer uma licença válida (Enterprise) ou assinatura ativa (SaaS)",
"requireTwoFactorCannotEnableDescription": "Você deve ativar a autenticação de dois fatores para sua conta antes de aplicá-la para todos os usuários",
"maxSessionLength": "Comprimento Máximo da Sessão",
"maxSessionLengthDescription": "Definir a duração máxima para as sessões dos usuários. Após esse tempo, os usuários precisarão autenticar novamente.",
"maxSessionLengthDisabledDescription": "Este recurso requer uma licença válida (Enterprise) ou assinatura ativa (SaaS)",
"selectSessionLength": "Selecionar duração da sessão",
"unenforced": "Inforçado",
"1Hour": "number@@0 horas",
"3Hours": "3 horas",
"6Hours": "6 horas",
"12Hours": "12 horas",
"1DaySession": "1 dia",
"3Days": "3 dias",
"7Days": "7 dias",
"14Days": "14 dias",
"30DaysSession": "30 dias",
"90DaysSession": "90 dias",
"180DaysSession": "180 dias",
"passwordExpiryDays": "Expiração da Senha",
"editPasswordExpiryDescription": "Defina o número de dias antes que os usuários sejam obrigados a mudar sua senha.",
"selectPasswordExpiry": "Selecione a senha expirada",
"30Days": "30 dias",
"1Day": "1 dia",
"60Days": "60 dias",
"90Days": "90 dias",
"180Days": "180 dias",
"1Year": "1 ano",
"subscriptionBadge": "Assinatura requerida",
"securityPolicyChangeWarning": "Aviso de Mudança da Política de Segurança",
"securityPolicyChangeDescription": "Você está prestes a alterar as configurações da política de segurança. Depois de salvar, talvez você precise se autenticar novamente para cumprir estas atualizações de política. Todos os usuários que não estiverem em conformidade também precisarão reautenticar.",
"securityPolicyChangeConfirmMessage": "Eu confirmo",
"securityPolicyChangeWarningText": "Isso afetará todos os usuários da organização",
"authPageErrorUpdateMessage": "Ocorreu um erro ao atualizar as configurações da página de autenticação",
"authPageErrorUpdate": "Não é possível atualizar a página de autenticação",
"authPageUpdated": "Página de autenticação atualizada com sucesso",
"healthCheckNotAvailable": "Localização",
"rewritePath": "Reescrever Caminho",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Autenticação de cabeçalho removida com sucesso.",
"resourceErrorHeaderAuthRemove": "Falha ao remover autenticação de cabeçalho",
"resourceErrorHeaderAuthRemoveDescription": "Não foi possível remover a autenticação do cabeçalho para o recurso.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Autenticação de Cabeçalho Habilitada",
"resourceHeaderAuthProtectionDisabled": "Autenticação de Cabeçalho Desativada",
"headerAuthRemove": "Remover autenticação de cabeçalho",
"headerAuthAdd": "Adicionar Autenticação do Cabeçalho",
"resourceErrorHeaderAuthSetup": "Falha ao definir autenticação de cabeçalho",
"resourceErrorHeaderAuthSetupDescription": "Não foi possível definir a autenticação do cabeçalho para o recurso.",
"resourceHeaderAuthSetup": "Autenticação de Cabeçalho definida com sucesso",
"resourceHeaderAuthSetupDescription": "Autenticação de cabeçalho foi definida com sucesso.",
"resourceHeaderAuthSetupTitle": "Definir autenticação de cabeçalho",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Defina as credenciais de autenticação básica (nome de usuário e senha) para proteger este recurso com a Autenticação de Cabeçalho HTTP. Acessá-lo usando o formato https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Definir autenticação de cabeçalho",
"actionSetResourceHeaderAuth": "Definir autenticação de cabeçalho",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"enterpriseEdition": "Edição Enterprise",
"unlicensed": "Sem licença",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"manageClients": "Gerenciar Clientes",
"manageClientsDescription": "Clientes são dispositivos que podem se conectar aos seus sites",
"licenseTableValidUntil": "Válido até",
"saasLicenseKeysSettingsTitle": "Licenças empresariais",
"saasLicenseKeysSettingsDescription": "Gerar e gerenciar chaves de licença Enterprise para instâncias Pangolin auto-hospedadas",
"sidebarEnterpriseLicenses": "Licenças",
"generateLicenseKey": "Gerar Chave de Licença",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Por favor, insira um endereço de e-mail válido",
"useCaseTypeRequired": "Por favor, selecione um tipo de caso de uso",
"firstNameRequired": "O primeiro nome é obrigatório",
"lastNameRequired": "Último nome é obrigatório",
"primaryUseRequired": "Descreva seu uso primário",
"jobTitleRequiredBusiness": "O título do trabalho é necessário para o uso de negócios",
"industryRequiredBusiness": "Indústria é necessária para uso de negócios",
"stateProvinceRegionRequired": "Estado/Província/Região é necessário",
"postalZipCodeRequired": "Código postal/CEP é obrigatório",
"companyNameRequiredBusiness": "O nome da empresa é necessário para uso empresarial",
"countryOfResidenceRequiredBusiness": "O país de residência é necessário para a utilização da empresa",
"countryRequiredPersonal": "País é necessário para uso pessoal",
"agreeToTermsRequired": "Você deve concordar com os termos",
"complianceConfirmationRequired": "Você deve confirmar o cumprimento da Licença Fossorial Comercial"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Uso pessoal",
"description": "Para uso individual, não comercial, como aprendizagem, projetos pessoais ou experimentação."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Uso de Negócios",
"description": "Para uso em organizações, empresas ou atividades comerciais ou geradoras de receitas."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "Tipo de Email e Licença",
"description": "Digite seu e-mail e escolha seu tipo de licença"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Informações Pessoais",
"description": "Conte-nos sobre você"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Informação do Contato",
"description": "Suas informações de contato"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Termos & Gerar",
"description": "Revise e aceite os termos para gerar a sua licença"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Divulgação de uso",
"description": "Selecione o nível de licença que reflete corretamente seu uso pretendido. A Licença Pessoal permite o uso livre do Software para atividades comerciais individuais, não comerciais ou em pequena escala com rendimento bruto anual inferior a 100.000 USD. Qualquer uso além destes limites — incluindo uso dentro de um negócio, organização, ou outro ambiente gerador de receitas — requer uma Licença Enterprise válida e o pagamento da taxa aplicável de licenciamento. Todos os usuários, pessoais ou empresariais, devem cumprir os Termos da Licença Comercial Fossorial."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Informações do Período de Avaliação",
"description": "Esta Chave de Licença permite recursos da Empresa para um período de avaliação de 7 dias. O acesso contínuo a Recursos Pagos além do período de avaliação requer ativação sob uma Licença Pessoal ou Empresarial válida. Para licenciamento Empresarial, entre em contato com sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Você está usando o Pangolin para uso pessoal ou empresarial?",
"firstName": "Primeiro nome",
"lastName": "Último Nome",
"jobTitle": "Título do Cargo",
"primaryUseQuestion": "Para que você pretende usar o Pangolin em primeiro lugar?",
"industryQuestion": "O que é a sua indústria?",
"prospectiveUsersQuestion": "Quantos usuários potenciais você espera?",
"prospectiveSitesQuestion": "Quantos sites (túneis) você espera ter?",
"companyName": "Nome Empresa",
"countryOfResidence": "País de residência",
"stateProvinceRegion": "Estado / Província / Região",
"postalZipCode": "Código Postal / Postal",
"companyWebsite": "Site da empresa",
"companyPhoneNumber": "Número de telefone empresa",
"country": "País",
"phoneNumberOptional": "Número de telefone (opcional)",
"complianceConfirmation": "Confirmo que a informação que forneci é correcta e que estou em conformidade com a Licença Comercial Fossorial. Reportar informações imprecisas ou identificar mal o uso do produto é uma violação da licença e pode resultar em sua chave ser revogada."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Fechar",
"previous": "Anterior",
"next": "Próximo",
"generateLicenseKey": "Gerar Chave de Licença"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Chave de licença gerada com sucesso",
"description": "Sua chave de licença foi gerada e está pronta para ser usada."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Falha ao gerar chave de licença",
"description": "Ocorreu um erro ao gerar a chave da licença."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Nome da Instância",
"pathMatchModalTitle": "Configurar Correspondência de Caminho",
"pathMatchModalDescription": "Configure como as solicitações de entrada devem ser correspondidas com base no caminho.",
"pathMatchType": "Tipo de Correspondência",
"pathMatchPrefix": "Prefixo",
"pathMatchExact": "Exato",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Valor do caminho",
"clear": "Limpar",
"saveChanges": "Salvar as alterações",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathMatchDefaultPlaceholder": "/caminho",
"pathMatchPrefixHelp": "Exemplo: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Exemplo: /api match only /api",
"pathMatchRegexHelp": "Exemplo: ^/api/.* Corresponde /api/anything",
"pathRewriteModalTitle": "Configurar Caminho de Reescrita",
"pathRewriteModalDescription": "Transforme o caminho correspondente antes de encaminhar para o alvo.",
"pathRewriteType": "Reescrever o tipo",
"pathRewritePrefixOption": "Prefixo - substituir prefixo",
"pathRewriteExactOption": "Exato - Substituir o caminho inteiro",
"pathRewriteRegexOption": "Regex - Substituição de padrão",
"pathRewriteStripPrefixOption": "Prefixo do Strip - Remover prefixo",
"pathRewriteValue": "Reescrever Valor",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewriteDefaultPlaceholder": "/novo-caminho",
"pathRewritePrefixHelp": "Substituir o prefixo correspondente por este valor",
"pathRewriteExactHelp": "Substitua o caminho inteiro por este valor quando o caminho corresponder exatamente",
"pathRewriteRegexHelp": "Usar grupos de captura como $1, $2 para substituição",
"pathRewriteStripPrefixHelp": "Deixe em branco para remover prefixo ou fornecer novo prefixo",
"pathRewritePrefix": "Prefixo",
"pathRewriteExact": "Exato",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Tirar",
"pathRewriteStripLabel": "faixa",
"sidebarEnableEnterpriseLicense": "Habilitar Licença Empresarial",
"cannotbeUndone": "Isso não pode ser desfeito.",
"toConfirm": "para confirmar",
"deleteClientQuestion": "Você tem certeza que deseja remover o cliente do site e da organização?",
"clientMessageRemove": "Depois de removido, o cliente não poderá mais se conectar ao site.",
"sidebarLogs": "Registros",
"request": "Pedir",
"logs": "Registros",
"logsSettingsDescription": "Monitorar logs coletados desta orginização",
"searchLogs": "Pesquisar registros...",
"action": "Acão",
"actor": "Ator",
"timestamp": "Timestamp",
"accessLogs": "Logs de Acesso",
"exportCsv": "Exportar como CSV",
"actorId": "ID do ator",
"allowedByRule": "Permitido por regra",
"allowedNoAuth": "Não Permitido Nenhuma Autenticação",
"validAccessToken": "Token de acesso válido",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Senha válida",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Recurso bloqueado",
"droppedByRule": "Derrubado pela regra",
"noSessions": "Sem Sessões",
"temporaryRequestToken": "Token de solicitação temporária",
"noMoreAuthMethods": "No Valid Auth",
"ip": "PI",
"reason": "Motivo",
"requestLogs": "Registro de pedidos",
"host": "Servidor",
"location": "Local:",
"actionLogs": "Logs de Ações",
"sidebarLogsRequest": "Registro de pedidos",
"sidebarLogsAccess": "Logs de Acesso",
"sidebarLogsAction": "Logs de Ações",
"logRetention": "Retenção de Log",
"logRetentionDescription": "Gerenciar quanto tempo os diferentes tipos de logs são mantidos para esta organização ou desativá-los",
"requestLogsDescription": "Ver registros de pedidos detalhados de recursos nesta organização",
"logRetentionRequestLabel": "Solicitar retenção de registro",
"logRetentionRequestDescription": "Por quanto tempo manter os registros de pedidos",
"logRetentionAccessLabel": "Retenção de Log de Acesso",
"logRetentionAccessDescription": "Por quanto tempo manter os registros de acesso",
"logRetentionActionLabel": "Ação de Retenção no Log",
"logRetentionActionDescription": "Por quanto tempo manter os registros de ação",
"logRetentionDisabled": "Desabilitado",
"logRetention3Days": "3 dias",
"logRetention7Days": "7 dias",
"logRetention14Days": "14 dias",
"logRetention30Days": "30 dias",
"logRetention90Days": "90 dias",
"logRetentionForever": "Permanentemente",
"actionLogsDescription": "Visualizar histórico de ações realizadas 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.",
"certResolver": "Resolvedor de Certificado",
"certResolverDescription": "Selecione o resolvedor de certificados para este recurso.",
"selectCertResolver": "Selecionar solucionador de certificado",
"enterCustomResolver": "Inserir Resolvedor Personalizado",
"preferWildcardCert": "Prefere Certificado Wildcard",
"unverified": "Não verificado",
"domainSetting": "Configurações do domínio",
"domainSettingDescription": "Configure as configurações para o seu domínio",
"preferWildcardCertDescription": "Tentativa de gerar um certificado coringa (requer um resolvedor de certificado devidamente configurado).",
"recordName": "Nome da gravação",
"auto": "Automático",
"TTL": "TTL",
"howToAddRecords": "Como adicionar registros",
"dnsRecord": "Registros DNS",
"required": "Obrigatório",
"domainSettingsUpdated": "Configurações de domínio atualizadas com sucesso",
"orgOrDomainIdMissing": "ID da organização ou domínio está faltando",
"loadingDNSRecords": "Carregando registros DNS...",
"olmUpdateAvailableInfo": "Uma versão atualizada do Olm está disponível. Atualize para a versão mais recente para ter a melhor experiência.",
"client": "Cliente",
"proxyProtocol": "Configurações de Protocolo Proxy",
"proxyProtocolDescription": "Configurar o protocolo Proxy para preservar endereços IP do cliente para serviços TCP/UDP.",
"enableProxyProtocol": "Habilitar protocolo proxy",
"proxyProtocolInfo": "Preservar endereços IP do cliente para backends TCP/UDP",
"proxyProtocolVersion": "Versão do Protocolo Proxy",
"version1": " Versão 1 (recomendado)",
"version2": "Versão 2",
"versionDescription": "A versão 1 é baseada em texto e amplamente suportada. A versão 2 é binária e mais eficiente, mas menos compatível.",
"warning": "ATENÇÃO",
"proxyProtocolWarning": "Seu aplicativo de backend deve ser configurado para aceitar conexões de protocolo de proxy. Se o seu backend não suportar o protocolo de protocolo, habilitando isso quebrará todas as conexões. Certifique-se de configurar seu backend para confiar nos cabeçalhos do protocolo proxy no Traefik.",
"restarting": "Reiniciando...",
"manual": "Manualmente",
"messageSupport": "Suporte a Mensagens",
"supportNotAvailableTitle": "Suporte Não Disponível",
"supportNotAvailableDescription": "Não está disponível no momento. Você pode enviar um e-mail para support@pangolin.net.",
"supportRequestSentTitle": "Pedido de suporte enviado",
"supportRequestSentDescription": "Sua mensagem foi enviada com sucesso.",
"supportRequestFailedTitle": "Falha ao enviar solicitação",
"supportRequestFailedDescription": "Ocorreu um erro ao enviar sua solicitação de suporte.",
"supportSubjectRequired": "Assunto é necessária",
"supportSubjectMaxLength": "O assunto deve ter 255 caracteres ou menos",
"supportMessageRequired": "A mensagem é obrigatória",
"supportReplyTo": "Responder a",
"supportSubject": "Cargo",
"supportSubjectPlaceholder": "Digite o assunto",
"supportMessage": "mensagem",
"supportMessagePlaceholder": "Digite sua mensagem",
"supportSending": "Enviando...",
"supportSend": "Mandar",
"supportMessageSent": "Mensagem enviada!",
"supportWillContact": "Entraremos em contato em breve!",
"selectLogRetention": "Selecionar retenção de log",
"showColumns": "Exibir Colunas",
"hideColumns": "Ocultar colunas",
"columnVisibility": "Visibilidade da Coluna",
"toggleColumn": "Alternar coluna {columnName}",
"allColumns": "Todas as colunas",
"defaultColumns": "Colunas padrão",
"customizeView": "Personalizar visualização",
"viewOptions": "Opções de visualização",
"selectAll": "Selecionar Todos",
"selectNone": "Não selecionar nada",
"selectedResources": "Recursos Selecionados",
"enableSelected": "Habilitar Selecionados",
"disableSelected": "Desativar Selecionados",
"checkSelectedStatus": "Status de Verificação dos Selecionados",
"credentials": "Credenciais",
"savecredentials": "Salvar Credenciais",
"regeneratecredentials": "Rechave",
"regenerateCredentials": "Regenerar e salvar suas credenciais",
"generatedcredentials": "Credenciais Geradas",
"copyandsavethesecredentials": "Copiar e salvar estas credenciais",
"copyandsavethesecredentialsdescription": "Essas credenciais não serão exibidas novamente depois que você sair desta página. Salve elas com segurança agora.",
"credentialsSaved": "Credenciais salvas",
"credentialsSavedDescription": "As credenciais foram regeneradas e salvas com sucesso.",
"credentialsSaveError": "Erro ao Salvar Credenciais",
"credentialsSaveErrorDescription": "Ocorreu um erro enquanto regenerava e salvava as credenciais.",
"regenerateCredentialsWarning": "Regenerar credenciais irá invalidar as anteriores. Certifique-se de atualizar qualquer configuração que use essas credenciais.",
"confirm": "Confirmar",
"regenerateCredentialsConfirmation": "Você tem certeza que deseja recriar as credenciais?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Chave secreta",
"featureDisabledTooltip": "Este recurso só está disponível no plano corporativo e requer que uma licença utilize.",
"niceId": "Belo ID",
"niceIdUpdated": "Bom ID atualizado",
"niceIdUpdatedSuccessfully": "Bom ID atualizado com sucesso",
"niceIdUpdateError": "Erro ao atualizar Nice ID",
"niceIdUpdateErrorDescription": "Ocorreu um erro ao atualizar a ID de Nice.",
"niceIdCannotBeEmpty": "Bom ID não pode estar vazio",
"enterIdentifier": "Inserir identificador",
"identifier": "Identifier"
}

View File

@@ -47,9 +47,8 @@
"edit": "Редактировать",
"siteConfirmDelete": "Подтвердить удаление сайта",
"siteDelete": "Удалить сайт",
"siteMessageRemove": "После удаления сайт больше не будет доступен. Все ресурсы и целевые узлы, связанные с сайтом, также будут удалены.",
"siteMessageConfirm": "Для подтверждения введите название сайта ниже.",
"siteQuestionRemove": "Вы уверены, что хотите удалить сайт {selectedSite} из организации?",
"siteMessageRemove": "После удаления сайт больше не будет доступен. Все цели, связанные с сайтом, также будут удалены.",
"siteQuestionRemove": "Вы уверены, что хотите удалить сайт из организации?",
"siteManageSites": "Управление сайтами",
"siteDescription": "Обеспечьте подключение к вашей сети через защищённые туннели",
"siteCreate": "Создать сайт",
@@ -96,7 +95,7 @@
"siteWgDescription": "Используйте любой клиент WireGuard для открытия туннеля. Требуется ручная настройка NAT.",
"siteWgDescriptionSaas": "Используйте любой клиент WireGuard для создания туннеля. Требуется ручная настройка NAT. РАБОТАЕТ ТОЛЬКО НА САМОСТОЯТЕЛЬНО РАЗМЕЩЕННЫХ УЗЛАХ",
"siteLocalDescription": "Только локальные ресурсы. Без туннелирования.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Только локальные ресурсы. Нет туннелей. Только для удаленных узлов.",
"siteSeeAll": "Просмотреть все сайты",
"siteTunnelDescription": "Выберите способ подключения к вашему сайту",
"siteNewtCredentials": "Учётные данные Newt",
@@ -132,7 +131,7 @@
"expireIn": "Срок действия",
"neverExpire": "Бессрочный доступ",
"shareExpireDescription": "Срок действия - это период, в течение которого ссылка будет работать и предоставлять доступ к ресурсу. После этого времени ссылка перестанет работать, и пользователи, использовавшие эту ссылку, потеряют доступ к ресурсу.",
"shareSeeOnce": "Вы сможете увидеть эту ссылку только один раз. Обязательно скопируйте её.",
"shareSeeOnce": "Вы сможете увидеть эту ссылку только один раз. Обязательно скопируйте ее.",
"shareAccessHint": "Любой, у кого есть эта ссылка, может получить доступ к ресурсу. Делитесь ею с осторожностью.",
"shareTokenUsage": "Посмотреть использование токена доступа",
"createLink": "Создать ссылку",
@@ -154,8 +153,7 @@
"protected": "Защищён",
"notProtected": "Не защищён",
"resourceMessageRemove": "После удаления ресурс больше не будет доступен. Все целевые узлы, связанные с ресурсом, также будут удалены.",
"resourceMessageConfirm": "Для подтверждения введите название ресурса ниже.",
"resourceQuestionRemove": "Вы действительно хотите удалить ресурс {selectedResource} из организации?",
"resourceQuestionRemove": "Вы уверены, что хотите удалить ресурс из организации?",
"resourceHTTP": "HTTPS-ресурс",
"resourceHTTPDescription": "Проксирование запросов к вашему приложению через HTTPS с использованием поддомена или базового домена.",
"resourceRaw": "Сырой TCP/UDP-ресурс",
@@ -181,7 +179,7 @@
"baseDomain": "Базовый домен",
"subdomnainDescription": "Поддомен, на котором будет доступен ресурс.",
"resourceRawSettings": "Настройки TCP/UDP",
"resourceRawSettingsDescription": "Настройте, как будет осуществляться доступ к вашему ресурсу через TCP/UDP",
"resourceRawSettingsDescription": "Настройте доступ к вашему ресурсу по TCP/UDP. Вы соотносите ресурс с портом на сервере хоста Pangolin, так что вы можете получить доступ к ресурсу с сервера server-public-ip:mapped-порта.",
"protocol": "Протокол",
"protocolSelect": "Выберите протокол",
"resourcePortNumber": "Номер порта",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Подтвердить удаление",
"orgMessageRemove": "Это действие необратимо и удалит все связанные данные.",
"orgMessageConfirm": "Для подтверждения введите название организации ниже.",
"orgQuestionRemove": "Вы действительно хотите удалить организацию {selectedOrg}?",
"orgQuestionRemove": "Вы уверены, что хотите удалить организацию?",
"orgUpdated": "Организация обновлена",
"orgUpdatedDescription": "Организация была успешно обновлена.",
"orgErrorUpdate": "Не удалось обновить организацию",
@@ -287,9 +285,8 @@
"apiKeysAdd": "Сгенерировать ключ API",
"apiKeysErrorDelete": "Ошибка при удалении ключа API",
"apiKeysErrorDeleteMessage": "Не удалось удалить ключ API",
"apiKeysQuestionRemove": "Вы действительно хотите удалить ключ API {selectedApiKey} из организации?",
"apiKeysQuestionRemove": "Вы уверены, что хотите удалить API ключ из организации?",
"apiKeysMessageRemove": "После удаления ключ API больше сможет быть использован.",
"apiKeysMessageConfirm": "Для подтверждения введите название ключа API ниже.",
"apiKeysDeleteConfirm": "Подтвердить удаление",
"apiKeysDelete": "Удаление ключа API",
"apiKeysManage": "Управление ключами API",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Подтвердить удаление",
"userDeleteServer": "Удаление пользователя с сервера",
"userMessageRemove": "Пользователь будет удалён из всех организаций и полностью удалён с сервера.",
"userMessageConfirm": "Для подтверждения введите имя пользователя ниже.",
"userQuestionRemove": "Вы действительно хотите навсегда удалить {selectedUser} с сервера?",
"userQuestionRemove": "Вы уверены, что хотите навсегда удалить пользователя с сервера?",
"licenseKey": "Лицензионный ключ",
"valid": "Действителен",
"numberOfSites": "Количество сайтов",
@@ -339,7 +335,7 @@
"fossorialLicense": "Просмотреть коммерческую лицензию Fossorial и условия подписки",
"licenseMessageRemove": "Это удалит лицензионный ключ и все связанные с ним разрешения.",
"licenseMessageConfirm": "Для подтверждения введите лицензионный ключ ниже.",
"licenseQuestionRemove": "Вы уверены, что хотите удалить лицензионный ключ {selectedKey}?",
"licenseQuestionRemove": "Вы уверены, что хотите удалить лицензионный ключ?",
"licenseKeyDelete": "Удалить лицензионный ключ",
"licenseKeyDeleteConfirm": "Подтвердить удаление лицензионного ключа",
"licenseTitle": "Управление статусом лицензии",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Произошла ошибка при удалении приглашения.",
"inviteRemoved": "Приглашение удалено",
"inviteRemovedDescription": "Приглашение для {email} было удалено.",
"inviteQuestionRemove": "Вы уверены, что хотите удалить приглашение {email}?",
"inviteQuestionRemove": "Вы уверены, что хотите удалить приглашение?",
"inviteMessageRemove": "После удаления это приглашение больше не будет действительным. Вы всегда можете пригласить пользователя заново.",
"inviteMessageConfirm": "Для подтверждения введите email адрес приглашения ниже.",
"inviteQuestionRegenerate": "Вы уверены, что хотите пересоздать приглашение для {email}? Это отзовёт предыдущее приглашение.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Произошла ошибка при удалении пользователя.",
"userOrgRemoved": "Пользователь удалён",
"userOrgRemovedDescription": "Пользователь {email} был удалён из организации.",
"userQuestionOrgRemove": "Вы уверены, что хотите удалить {email} из организации?",
"userQuestionOrgRemove": "Вы уверены, что хотите удалить этого пользователя из организации?",
"userMessageOrgRemove": "После удаления этот пользователь больше не будет иметь доступ к организации. Вы всегда можете пригласить его заново, но ему нужно будет снова принять приглашение.",
"userMessageOrgConfirm": "Для подтверждения введите имя пользователя ниже.",
"userRemoveOrgConfirm": "Подтвердить удаление пользователя",
"userRemoveOrg": "Удалить пользователя из организации",
"users": "Пользователи",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Администратор сервера - Pangolin",
"licenseTierProfessional": "Профессиональная лицензия",
"licenseTierEnterprise": "Корпоративная лицензия",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Личная лицензия",
"licensed": "Лицензировано",
"yes": "Да",
"no": "Нет",
@@ -742,7 +737,7 @@
"idpManageDescription": "Просмотр и управление поставщиками удостоверений в системе",
"idpDeletedDescription": "Поставщик удостоверений успешно удалён",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Вы уверены, что хотите навсегда удалить поставщика удостоверений {name}?",
"idpQuestionRemove": "Вы уверены, что хотите навсегда удалить поставщика удостоверений?",
"idpMessageRemove": "Это удалит поставщика удостоверений и все связанные конфигурации. Пользователи, которые аутентифицируются через этого поставщика, больше не смогут войти.",
"idpMessageConfirm": "Для подтверждения введите имя поставщика удостоверений ниже.",
"idpConfirmDelete": "Подтвердить удаление поставщика удостоверений",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "Проверьте вашу почту для получения кода сброса пароля.",
"passwordNew": "Новый пароль",
"passwordNewConfirm": "Подтвердите новый пароль",
"changePassword": "Изменить пароль",
"changePasswordDescription": "Обновить пароль учетной записи",
"oldPassword": "Текущий пароль",
"newPassword": "Новый пароль",
"confirmNewPassword": "Подтвердите новый пароль",
"changePasswordError": "Не удалось сменить пароль",
"changePasswordErrorDescription": "Произошла ошибка при смене пароля",
"changePasswordSuccess": "Пароль успешно изменен",
"changePasswordSuccessDescription": "Ваш пароль был успешно обновлен",
"passwordExpiryRequired": "Требуется срок действия пароля",
"passwordExpiryDescription": "Эта организация требует смены пароля каждые {maxDays} дней.",
"changePasswordNow": "Изменить пароль сейчас",
"pincodeAuth": "Код аутентификатора",
"pincodeSubmit2": "Отправить код",
"passwordResetSubmit": "Запросить сброс",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Все пользователи",
"sidebarIdentityProviders": "Поставщики удостоверений",
"sidebarLicense": "Лицензия",
"sidebarClients": "Clients",
"sidebarClients": "Клиенты",
"sidebarDomains": "Домены",
"sidebarBluePrints": "Чертежи",
"blueprints": "Чертежи",
"blueprintsDescription": "Применить декларирующие конфигурации и просмотреть предыдущие запуски",
"blueprintAdd": "Добавить чертёж",
"blueprintGoBack": "Посмотреть все чертежи",
"blueprintCreate": "Создать чертёж",
"blueprintCreateDescription2": "Для создания и применения нового чертежа выполните следующие шаги",
"blueprintDetails": "Детали чертежа",
"blueprintDetailsDescription": "Посмотреть результат примененного чертежа и все возникшие ошибки",
"blueprintInfo": "Информация о чертеже",
"message": "Сообщение",
"blueprintContentsDescription": "Определите содержимое YAML, описывающее вашу инфраструктуру",
"blueprintErrorCreateDescription": "Произошла ошибка при применении чертежа",
"blueprintErrorCreate": "Ошибка при создании чертежа",
"searchBlueprintProgress": "Поиск чертежей...",
"appliedAt": "Заявка на",
"source": "Источник",
"contents": "Содержание",
"parsedContents": "Переработанное содержимое (только для чтения)",
"enableDockerSocket": "Включить чертёж Docker",
"enableDockerSocketDescription": "Включить scraping ярлыка Docker Socket для ярлыков чертежей. Путь к сокету должен быть предоставлен в Newt.",
"enableDockerSocketLink": "Узнать больше",
@@ -1211,9 +1237,8 @@
"domainCreate": "Создать Домен",
"domainCreatedDescription": "Домен успешно создан",
"domainDeletedDescription": "Домен успешно удален",
"domainQuestionRemove": "Вы уверены, что хотите удалить домен {domain} из вашего аккаунта?",
"domainQuestionRemove": "Вы уверены, что хотите удалить домен из вашей учетной записи?",
"domainMessageRemove": "После удаления домен больше не будет связан с вашей учетной записью.",
"domainMessageConfirm": "Для подтверждения введите ниже имя домена.",
"domainConfirmDelete": "Подтвердить удаление домена",
"domainDelete": "Удалить Домен",
"domain": "Домен",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Произошла ошибка при обновлении настроек",
"sidebarCollapse": "Свернуть",
"sidebarExpand": "Развернуть",
"productUpdateMoreInfo": "{noOfUpdates} больше обновлений",
"productUpdateInfo": "{noOfUpdates} обновлений",
"productUpdateWhatsNew": "Что нового",
"productUpdateTitle": "Обновления продуктов",
"productUpdateEmpty": "Нет обновлений",
"dismissAll": "Отклонить все",
"pangolinUpdateAvailable": "Доступна новая версия",
"pangolinUpdateAvailableInfo": "Версия {version} готова к установке",
"pangolinUpdateAvailableReleaseNotes": "Просмотреть заметки о выпуске",
"newtUpdateAvailable": "Доступно обновление",
"newtUpdateAvailableInfo": "Доступна новая версия Newt. Пожалуйста, обновитесь до последней версии для лучшего опыта.",
"domainPickerEnterDomain": "Домен",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Бесплатный уровень",
"billingWarningOverLimit": "Предупреждение: Вы превысили одну или несколько границ использования. Ваши сайты не подключатся, пока вы не измените подписку или не скорректируете использование.",
"billingUsageLimitsOverview": "Обзор лимитов использования",
"billingMonitorUsage": "Контролируйте использование в соответствии с установленными лимитами. Если вам требуется увеличение лимитов, пожалуйста, свяжитесь с нами support@fossorial.io.",
"billingMonitorUsage": "Контролируйте использование в соответствии с установленными лимитами. Если вам требуется увеличение лимитов, пожалуйста, свяжитесь с нами support@pangolin.net.",
"billingDataUsage": "Использование данных",
"billingOnlineTime": "Время работы сайта",
"billingUsers": "Активные пользователи",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Произошла проблема при использовании вашего ключа безопасности. Пожалуйста, попробуйте еще раз.",
"twoFactorRequired": "Для регистрации ключа безопасности требуется двухфакторная аутентификация.",
"twoFactor": "Двухфакторная аутентификация",
"twoFactorAuthentication": "Двухфакторная аутентификация",
"twoFactorDescription": "Эта организация требует двухфакторной аутентификации.",
"enableTwoFactor": "Включить двухфакторную аутентификацию",
"organizationSecurityPolicy": "Политика безопасности Организации",
"organizationSecurityPolicyDescription": "У этой организации есть требования безопасности, которые должны быть выполнены, прежде чем вы сможете получить доступ к ней",
"securityRequirements": "Требования безопасности",
"allRequirementsMet": "Все требования выполнены",
"completeRequirementsToContinue": "Выполните следующие требования, чтобы продолжить доступ к этой организации",
"youCanNowAccessOrganization": "Теперь вы можете получить доступ к этой организации",
"reauthenticationRequired": "Длина сессии",
"reauthenticationDescription": "Эта организация требует входа каждый {maxDays} дней.",
"reauthenticationDescriptionHours": "Эта организация требует входа в систему каждый {maxHours} часов.",
"reauthenticateNow": "Войти снова",
"adminEnabled2FaOnYourAccount": "Ваш администратор включил двухфакторную аутентификацию для {email}. Пожалуйста, завершите процесс настройки, чтобы продолжить.",
"securityKeyAdd": "Добавить ключ безопасности",
"securityKeyRegisterTitle": "Регистрация нового ключа безопасности",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Эти ресурсы предназначены для использования с",
"resourcesTableClients": "Клиенты",
"resourcesTableAndOnlyAccessibleInternally": "и доступны только внутренне при подключении с клиентом.",
"resourcesTableNoTargets": "Нет ярлыков",
"resourcesTableHealthy": "Здоровые",
"resourcesTableDegraded": "Ухудшение",
"resourcesTableOffline": "Оффлайн",
"resourcesTableUnknown": "Неизвестен",
"resourcesTableNotMonitored": "Не отслеживается",
"editInternalResourceDialogEditClientResource": "Редактировать ресурс клиента",
"editInternalResourceDialogUpdateResourceProperties": "Обновите свойства ресурса и настройку цели для {resourceName}.",
"editInternalResourceDialogResourceProperties": "Свойства ресурса",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "URL-адрес перенаправления не получен от провайдера удостоверения.",
"autoLoginErrorGeneratingUrl": "Не удалось сгенерировать URL-адрес аутентификации.",
"remoteExitNodeManageRemoteExitNodes": "Удаленные узлы",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Самохост-один или несколько удаленных узлов для расширения сетевого подключения и уменьшения зависимости от облака",
"remoteExitNodes": "Узлы",
"searchRemoteExitNodes": "Поиск узлов...",
"remoteExitNodeAdd": "Добавить узел",
"remoteExitNodeErrorDelete": "Ошибка удаления узла",
"remoteExitNodeQuestionRemove": "Вы уверены, что хотите удалить узел {selectedNode} из организации?",
"remoteExitNodeQuestionRemove": "Вы уверены, что хотите удалить узел из организации?",
"remoteExitNodeMessageRemove": "После удаления узел больше не будет доступен.",
"remoteExitNodeMessageConfirm": "Для подтверждения введите имя узла ниже.",
"remoteExitNodeConfirmDelete": "Подтвердите удаление узла",
"remoteExitNodeDelete": "Удалить узел",
"sidebarRemoteExitNodes": "Удаленные узлы",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Редактировать файл: docker-compose.yml",
"emailVerificationRequired": "Требуется подтверждение адреса электронной почты. Пожалуйста, войдите снова через {dashboardUrl}/auth/login завершить этот шаг. Затем вернитесь сюда.",
"twoFactorSetupRequired": "Требуется настройка двухфакторной аутентификации. Пожалуйста, войдите снова через {dashboardUrl}/auth/login завершить этот шаг. Затем вернитесь сюда.",
"additionalSecurityRequired": "Требуется дополнительная безопасность",
"organizationRequiresAdditionalSteps": "Эта организация требует дополнительных шагов безопасности, прежде чем вы сможете получить доступ к ресурсам.",
"completeTheseSteps": "Выполните эти шаги",
"enableTwoFactorAuthentication": "Включить двухфакторную аутентификацию",
"completeSecuritySteps": "Пройти шаги безопасности",
"securitySettings": "Настройки безопасности",
"securitySettingsDescription": "Настройка политик безопасности для вашей организации",
"requireTwoFactorForAllUsers": "Требовать двухфакторную аутентификацию для всех пользователей",
"requireTwoFactorDescription": "Когда включено, все внутренние пользователи в этой организации должны иметь двухфакторную аутентификацию для доступа к организации.",
"requireTwoFactorDisabledDescription": "Эта функция требует действительной лицензии (Enterprise) или активной подписки (SaaS)",
"requireTwoFactorCannotEnableDescription": "Вы должны включить двухфакторную аутентификацию для вашей учетной записи, прежде чем принудительно ее применять для всех пользователей",
"maxSessionLength": "Максимальная длина сессии",
"maxSessionLengthDescription": "Установите максимальную длительность сессий пользователя. После этого времени, пользователям нужно будет пройти повторную аутентификацию.",
"maxSessionLengthDisabledDescription": "Эта функция требует действительной лицензии (Enterprise) или активной подписки (SaaS)",
"selectSessionLength": "Выберите длину сеанса",
"unenforced": "Не применено",
"1Hour": "1 час",
"3Hours": "3 часа",
"6Hours": "6 часов",
"12Hours": "12 часов",
"1DaySession": "1 день",
"3Days": "3 дня",
"7Days": "7 дней",
"14Days": "14 дней",
"30DaysSession": "30 дней",
"90DaysSession": "90 дней",
"180DaysSession": "180 дней",
"passwordExpiryDays": "Срок действия пароля",
"editPasswordExpiryDescription": "Установите количество дней, прежде чем пользователи должны изменить свой пароль.",
"selectPasswordExpiry": "Выберите срок действия пароля",
"30Days": "30 дней",
"1Day": "1 день",
"60Days": "60 дней",
"90Days": "90 дней",
"180Days": "180 дней",
"1Year": "1 год",
"subscriptionBadge": "Требуется подписка",
"securityPolicyChangeWarning": "Предупреждение об изменении политики безопасности",
"securityPolicyChangeDescription": "Вы собираетесь изменить настройки политики безопасности. После сохранения вам может потребоваться повторная аутентификация, чтобы соответствовать этим обновлениям. Все пользователи, которые не соответствуют установленным правилам, также должны пройти процедуру повторной аутентификации.",
"securityPolicyChangeConfirmMessage": "Подтверждаю",
"securityPolicyChangeWarningText": "Это повлияет на всех пользователей организации",
"authPageErrorUpdateMessage": "Произошла ошибка при обновлении настроек страницы авторизации",
"authPageErrorUpdate": "Не удалось обновить страницу авторизации",
"authPageUpdated": "Страница авторизации успешно обновлена",
"healthCheckNotAvailable": "Локальный",
"rewritePath": "Переписать путь",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Проверка подлинности заголовка успешно удалена.",
"resourceErrorHeaderAuthRemove": "Не удалось удалить аутентификацию заголовка",
"resourceErrorHeaderAuthRemoveDescription": "Не удалось удалить проверку подлинности заголовка ресурса.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Заголовок аутентификации включен",
"resourceHeaderAuthProtectionDisabled": "Проверка подлинности заголовка отключена",
"headerAuthRemove": "Удалить проверку подлинности заголовка",
"headerAuthAdd": "Добавить заголовок аутентификации",
"resourceErrorHeaderAuthSetup": "Не удалось установить аутентификацию заголовка",
"resourceErrorHeaderAuthSetupDescription": "Не удалось установить проверку подлинности заголовка ресурса.",
"resourceHeaderAuthSetup": "Проверка подлинности заголовка успешно установлена",
"resourceHeaderAuthSetupDescription": "Проверка подлинности заголовка успешно установлена.",
"resourceHeaderAuthSetupTitle": "Установить проверку подлинности заголовка",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Установите основные учетные данные авторизации (имя пользователя и пароль), чтобы защитить этот ресурс с помощью заголовка HTTP. Получите доступ к нему с помощью формата https://username:password@resource.example.com",
"resourceHeaderAuthSubmit": "Установить проверку подлинности заголовка",
"actionSetResourceHeaderAuth": "Установить проверку подлинности заголовка",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"enterpriseEdition": "Корпоративная версия",
"unlicensed": "Нелицензированный",
"beta": "Бета",
"manageClients": "Управление клиентами",
"manageClientsDescription": "Клиенты - это устройства, которые могут подключаться к вашим сайтам",
"licenseTableValidUntil": "Действителен до",
"saasLicenseKeysSettingsTitle": "Корпоративные лицензии",
"saasLicenseKeysSettingsDescription": "Генерировать и управлять лицензионными ключами Enterprise для копий Pangolin",
"sidebarEnterpriseLicenses": "Лицензии",
"generateLicenseKey": "Сгенерировать лицензионный ключ",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Пожалуйста, введите действительный адрес электронной почты",
"useCaseTypeRequired": "Пожалуйста, выберите тип варианта использования",
"firstNameRequired": "Требуется имя",
"lastNameRequired": "Требуется фамилия",
"primaryUseRequired": "Пожалуйста, опишите ваше основное использование",
"jobTitleRequiredBusiness": "Должность требуется для коммерческого использования",
"industryRequiredBusiness": "Промышленность необходима для коммерческого использования",
"stateProvinceRegionRequired": "Регион/Область обязательно",
"postalZipCodeRequired": "Почтовый индекс требуется",
"companyNameRequiredBusiness": "Название компании обязательно для бизнес-использования",
"countryOfResidenceRequiredBusiness": "Страна проживания необходима для коммерческого использования",
"countryRequiredPersonal": "Страна необходима для личного использования",
"agreeToTermsRequired": "Вы должны принять условия",
"complianceConfirmationRequired": "Вы должны подтвердить соответствие с Fossorial Commercial License"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Личное использование",
"description": "Для индивидуального, некоммерческого использования, например, обучения, личных проектов или экспериментов."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "Бизнес-использование",
"description": "Для использования в организациях, компаниях или коммерческих или приносящих доход видах деятельности."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "Email и тип лицензии",
"description": "Введите адрес электронной почты и выберите тип лицензии"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Личная информация",
"description": "Расскажите нам о себе"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "Контактная информация",
"description": "Ваши контактные данные"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Условия и Сгенерировать",
"description": "Просмотрите и примите условия для создания вашей лицензии"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Раскрытие",
"description": "Выберите уровень лицензии, который точно отражает ваше предполагаемое использование. Личная Лицензия разрешает свободное использование Программного Обеспечения для частной, некоммерческой или малой коммерческой деятельности с годовым валовым доходом до $100 000 USD. Любое использование сверх этих пределов — включая использование в бизнесе, организацию, или другой приносящей доход среде — требует действительной лицензии предприятия и уплаты соответствующей лицензионной платы. Все пользователи, будь то Личные или Предприятия, обязаны соблюдать условия коммерческой лицензии Fossoral."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Информация о пробном периоде",
"description": "Этот лицензионный ключ позволяет корпоративным функциям на 7-дневный период оценки. Для продолжения доступа к платным функциям за пределами ознакомительного периода требуется активация в рамках действующей лицензии Личного или Предприятия. Для получения лицензии свяжитесь с sales@pangolin.net."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"useCaseQuestion": "Вы используете Pangolin для личного или делового использования?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"lastName": "Фамилия",
"jobTitle": "Заголовок",
"primaryUseQuestion": "Что вы планируете использовать Панголин в первую очередь?",
"industryQuestion": "Какая у вас отрасль?",
"prospectiveUsersQuestion": "Сколько у вас потенциальных пользователей?",
"prospectiveSitesQuestion": "Сколько потенциальных сайтов (туннелей) вы ожидаете?",
"companyName": "Название компании",
"countryOfResidence": "Страна проживания",
"stateProvinceRegion": "Область / регион",
"postalZipCode": "Почтовый индекс",
"companyWebsite": "Веб-сайт компании",
"companyPhoneNumber": "Телефон компании",
"country": "Страна",
"phoneNumberOptional": "Номер телефона (необязательно)",
"complianceConfirmation": "Я подтверждаю, что информация, которую я предоставляю, является точной и что я в соответствии с коммерческой лицензии Fossorial. Сообщение о неточной информации или неправильно идентифицирующем использовании продукта является нарушением лицензии и может привести к аннулированию вашего ключа."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Закрыть",
"previous": "Предыдущий",
"next": "Следующий",
"generateLicenseKey": "Сгенерировать лицензионный ключ"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Лицензионный ключ успешно создан",
"description": "Ваш лицензионный ключ сгенерирован и готов к использованию."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Не удалось сгенерировать лицензионный ключ",
"description": "Произошла ошибка при генерации лицензионного ключа."
}
}
},
"priority": "Приоритет",
"priorityDescription": "Маршруты с более высоким приоритетом оцениваются первым. Приоритет = 100 означает автоматическое упорядочение (решение системы). Используйте другой номер для обеспечения ручного приоритета.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"instanceName": "Имя экземпляра",
"pathMatchModalTitle": "Настроить соответствие пути",
"pathMatchModalDescription": "Настройка соответствия входящих запросов на основе их пути.",
"pathMatchType": "Тип совпадения",
"pathMatchPrefix": "Префикс",
"pathMatchExact": "Точно",
"pathMatchRegex": "Регенерация",
"pathMatchValue": "Значение пути",
"clear": "Очистить",
"saveChanges": "Сохранить изменения",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathMatchDefaultPlaceholder": "/путь",
"pathMatchPrefixHelp": "Пример: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Пример: /api соответствует только /api",
"pathMatchRegexHelp": "Пример: ^/api/.* совпадает с /api/anything",
"pathRewriteModalTitle": "Настроить перезапись пути",
"pathRewriteModalDescription": "Преобразовать соответствующий путь перед пересылкой к цели.",
"pathRewriteType": "Тип перезаписи",
"pathRewritePrefixOption": "Префикс - Замена префикса",
"pathRewriteExactOption": "Точно - Заменить весь путь",
"pathRewriteRegexOption": "Regex - замена шаблона",
"pathRewriteStripPrefixOption": "Префикс вырезать - Удалить префикс",
"pathRewriteValue": "Перезаписать значение",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewritePrefixHelp": "Заменить соответствующий префикс этим значением",
"pathRewriteExactHelp": "Замените весь путь этим значением, когда путь точно соответствует",
"pathRewriteRegexHelp": "Использовать группы захвата типа $1, $2 для замены",
"pathRewriteStripPrefixHelp": "Оставьте пустым для префикса полосы или укажите новый префикс",
"pathRewritePrefix": "Префикс",
"pathRewriteExact": "Точно",
"pathRewriteRegex": "Регенерация",
"pathRewriteStrip": "Вырезать",
"pathRewriteStripLabel": "полоса",
"sidebarEnableEnterpriseLicense": "Включить корпоративную лицензию",
"cannotbeUndone": "Это действие не может быть отменено.",
"toConfirm": "для подтверждения",
"deleteClientQuestion": "Вы уверены, что хотите удалить клиента из сайта и организации?",
"clientMessageRemove": "После удаления клиент больше не сможет подключиться к сайту.",
"sidebarLogs": "Логи",
"request": "Запросить",
"logs": "Логи",
"logsSettingsDescription": "Отслеживать журналы, собранные в этой организации",
"searchLogs": "Поиск журналов...",
"action": "Действие",
"actor": "Актер",
"timestamp": "Отметка времени",
"accessLogs": "Журналы доступа",
"exportCsv": "Экспорт CSV",
"actorId": "ID актера",
"allowedByRule": "Разрешено правилом",
"allowedNoAuth": "Разрешено без авторизации",
"validAccessToken": "Действительный маркер доступа",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "Допустимый пароль",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "Ресурс заблокирован",
"droppedByRule": "Отброшено по правилам",
"noSessions": "Нет сессий",
"temporaryRequestToken": "Временный токен запроса",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP",
"reason": "Причина",
"requestLogs": "Запросить журналы",
"host": "Хост",
"location": "Местоположение",
"actionLogs": "Журнал действий",
"sidebarLogsRequest": "Запросить журналы",
"sidebarLogsAccess": "Журналы доступа",
"sidebarLogsAction": "Журнал действий",
"logRetention": "Сохранение журнала",
"logRetentionDescription": "Управление сохранением различных типов журналов для этой организации или отключение их",
"requestLogsDescription": "Просмотреть подробные журналы запроса ресурсов в этой организации",
"logRetentionRequestLabel": "Запросить сохранение журнала",
"logRetentionRequestDescription": "Как долго сохранять журналы запросов",
"logRetentionAccessLabel": "Хранение журнала доступа",
"logRetentionAccessDescription": "Как долго сохранять журналы доступа",
"logRetentionActionLabel": "Сохранение журнала действий",
"logRetentionActionDescription": "Как долго хранить журналы действий",
"logRetentionDisabled": "Отключено",
"logRetention3Days": "3 дня",
"logRetention7Days": "7 дней",
"logRetention14Days": "14 дней",
"logRetention30Days": "30 дней",
"logRetention90Days": "90 дней",
"logRetentionForever": "Всегда",
"actionLogsDescription": "Просмотр истории действий, выполненных в этой организации",
"accessLogsDescription": "Просмотр запросов авторизации доступа к ресурсам этой организации",
"licenseRequiredToUse": "Для использования этой функции требуется лицензия предприятия.",
"certResolver": "Резольвер сертификата",
"certResolverDescription": "Выберите резолвер сертификата, который будет использоваться для этого ресурса.",
"selectCertResolver": "Выберите резолвер сертификата",
"enterCustomResolver": "Введите пользовательский резолвер",
"preferWildcardCert": "Предпочитать сертификат Wildcard",
"unverified": "Не подтверждено",
"domainSetting": "Настройки домена",
"domainSettingDescription": "Настройка параметров для вашего домена",
"preferWildcardCertDescription": "Попытка создания шаблона сертификата (требуется должным образом сконфигурированный резолвер сертификата).",
"recordName": "Имя записи",
"auto": "Авто",
"TTL": "TTL",
"howToAddRecords": "Как добавить записи",
"dnsRecord": "DNS записи",
"required": "Требуется",
"domainSettingsUpdated": "Настройки домена успешно обновлены",
"orgOrDomainIdMissing": "Отсутствует организация или ID домена",
"loadingDNSRecords": "Загрузка записей DNS...",
"olmUpdateAvailableInfo": "Доступна обновленная версия Олма. Пожалуйста, обновитесь до последней версии.",
"client": "Клиент",
"proxyProtocol": "Настройки протокола прокси",
"proxyProtocolDescription": "Настроить Прокси-протокол для сохранения IP-адресов клиента для служб TCP/UDP.",
"enableProxyProtocol": "Включить Прокси Протокол",
"proxyProtocolInfo": "Сохранять IP-адреса клиента для кэша TCP/UDP",
"proxyProtocolVersion": "Версия протокола прокси",
"version1": " Версия 1 (рекомендуется)",
"version2": "Версия 2",
"versionDescription": "Версия 1 основана на тексте и широко поддерживается. Версия 2 является бинарной и более эффективной, но менее совместимой.",
"warning": "Предупреждение",
"proxyProtocolWarning": "Бэкэнд приложение должно быть сконфигурировано для принятия прокси-соединений. Если ваш бэкэнд не поддерживает Прокси-протокол, это нарушит все соединения. Обязательно настройте вашего бэкэнда на доверие заголовкам Proxy Protocol от Traefik.",
"restarting": "Перезапуск...",
"manual": "Ручной",
"messageSupport": "Поддержка сообщений",
"supportNotAvailableTitle": "Поддержка недоступна",
"supportNotAvailableDescription": "Поддержка сейчас недоступна. Вы можете отправить письмо по адресу support@pangolin.net.",
"supportRequestSentTitle": "Запрос на поддержку отправлен",
"supportRequestSentDescription": "Ваше сообщение успешно отправлено.",
"supportRequestFailedTitle": "Не удалось отправить запрос",
"supportRequestFailedDescription": "Произошла ошибка при отправке запроса поддержки.",
"supportSubjectRequired": "Необходимо ввести тему",
"supportSubjectMaxLength": "Тема должна быть 255 символов или меньше",
"supportMessageRequired": "Требуется сообщение",
"supportReplyTo": "Ответить",
"supportSubject": "Тема",
"supportSubjectPlaceholder": "Введите тему",
"supportMessage": "Сообщение",
"supportMessagePlaceholder": "Введите ваше сообщение",
"supportSending": "Отправка...",
"supportSend": "Отправить",
"supportMessageSent": "Сообщение отправлено!",
"supportWillContact": "Мы скоро свяжемся с Вами!",
"selectLogRetention": "Выберите удержание журнала",
"showColumns": "Показать колонки",
"hideColumns": "Скрыть столбцы",
"columnVisibility": "Видимость столбцов",
"toggleColumn": "Столбец {columnName}",
"allColumns": "Все колонки",
"defaultColumns": "Столбцы по умолчанию",
"customizeView": "Настроить вид",
"viewOptions": "Параметры просмотра",
"selectAll": "Выделить все",
"selectNone": "Не выбирать",
"selectedResources": "Выбранные ресурсы",
"enableSelected": "Включить выбранные",
"disableSelected": "Отключить выбранные",
"checkSelectedStatus": "Проверить статус выбранных",
"credentials": "Полномочия",
"savecredentials": "Сохранить учетные данные",
"regeneratecredentials": "Пере-ключ",
"regenerateCredentials": "Сгенерировать и сохранить ваши учетные данные",
"generatedcredentials": "Сгенерированные учетные данные",
"copyandsavethesecredentials": "Копировать и сохранить эти учетные данные",
"copyandsavethesecredentialsdescription": "Эти учетные данные не будут отображаться снова после того, как вы покинете эту страницу. Сохраните их сейчас.",
"credentialsSaved": "Учетные данные сохранены",
"credentialsSavedDescription": "Учетные данные были успешно восстановлены и сохранены.",
"credentialsSaveError": "Ошибка сохранения учетных данных",
"credentialsSaveErrorDescription": "Произошла ошибка при восстановлении и сохранении учетных данных.",
"regenerateCredentialsWarning": "Восстановление учётных данных приведет к недействительным предыдущим. Убедитесь, что все конфигурации, использующие эти учетные данные.",
"confirm": "Подтвердить",
"regenerateCredentialsConfirmation": "Вы уверены, что хотите восстановить учетные данные?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "Секретный ключ",
"featureDisabledTooltip": "Эта функция доступна только в плане предприятия и требует лицензии на ее использование.",
"niceId": "Неплохой ID",
"niceIdUpdated": "Хороший ID обновлен",
"niceIdUpdatedSuccessfully": "Неплохой ID успешно обновлен",
"niceIdUpdateError": "Ошибка обновления Nice ID",
"niceIdUpdateErrorDescription": "Произошла ошибка при обновлении Nice ID.",
"niceIdCannotBeEmpty": "Неправильный ID не может быть пустым",
"enterIdentifier": "Введите идентификатор",
"identifier": "Identifier"
}

View File

@@ -47,9 +47,8 @@
"edit": "Düzenle",
"siteConfirmDelete": "Site Silmeyi Onayla",
"siteDelete": "Siteyi Sil",
"siteMessageRemove": "Kaldırıldıktan sonra site artık erişilebilir olmayacak. Siteyle ilişkili tüm kaynaklar ve hedefler de kaldırılacaktır.",
"siteMessageConfirm": "Onaylamak için lütfen aşağıya sitenin adını yazın.",
"siteQuestionRemove": "{selectedSite} sitesini organizasyondan kaldırmak istediğinizden emin misiniz?",
"siteMessageRemove": "Kaldırıldıktan sonra site artık erişilebilir olmayacaktır. Siteyle ilişkilendirilmiş tüm hedefler de kaldırılacaktır.",
"siteQuestionRemove": "Siteyi organizasyondan kaldırmak istediğinizden emin misiniz?",
"siteManageSites": "Siteleri Yönet",
"siteDescription": "Ağınıza güvenli tüneller üzerinden bağlantı izni verin",
"siteCreate": "Site Oluştur",
@@ -96,7 +95,7 @@
"siteWgDescription": "Bir tünel oluşturmak için herhangi bir WireGuard istemcisi kullanın. Manuel NAT kurulumu gereklidir.",
"siteWgDescriptionSaas": "Bir tünel oluşturmak için herhangi bir WireGuard istemcisi kullanın. Manuel NAT kurulumu gereklidir. YALNIZCA SELF HOSTED DÜĞÜMLERDE ÇALIŞIR",
"siteLocalDescription": "Yalnızca yerel kaynaklar. Tünelleme yok.",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "Yerel kaynaklar yalnızca. Tünel oluşturma yok. Yalnızca uzak düğümlerde mevcuttur.",
"siteSeeAll": "Tüm Siteleri Gör",
"siteTunnelDescription": "Sitenize nasıl bağlanmak istediğinizi belirleyin",
"siteNewtCredentials": "Newt Kimlik Bilgileri",
@@ -154,8 +153,7 @@
"protected": "Korunan",
"notProtected": "Korunmayan",
"resourceMessageRemove": "Kaldırıldıktan sonra kaynak artık erişilebilir olmayacaktır. Kaynakla ilişkili tüm hedefler de kaldırılacaktır.",
"resourceMessageConfirm": "Onaylamak için lütfen aşağıya kaynağın adını yazın.",
"resourceQuestionRemove": "{selectedResource} kaynağını organizasyondan kaldırmak istediğinizden emin misiniz?",
"resourceQuestionRemove": "Kaynağı organizasyondan kaldırmak istediğinizden emin misiniz?",
"resourceHTTP": "HTTPS Kaynağı",
"resourceHTTPDescription": "Bir alt alan adı veya temel alan adı kullanarak uygulamanıza HTTPS üzerinden vekil istek gönderin.",
"resourceRaw": "Ham TCP/UDP Kaynağı",
@@ -181,7 +179,7 @@
"baseDomain": "Temel Alan Adı",
"subdomnainDescription": "Kaynağınızın erişilebileceği alt alan adı.",
"resourceRawSettings": "TCP/UDP Ayarları",
"resourceRawSettingsDescription": "Kaynağınıza TCP/UDP üzerinden erişimin nasıl sağlanacağını yapılandırın",
"resourceRawSettingsDescription": "Kaynağınızın TCP/UDP üzerinden nasıl erişileceğini yapılandırın. Kaynağı, sunucudan erişebilmeniz için bir ana bilgisayar Pangolin sunucusundaki bir bağlantı noktasına eşlersiniz: sunucu genel-IP: eşlenen-bağlantı-noktası.",
"protocol": "Protokol",
"protocolSelect": "Bir protokol seçin",
"resourcePortNumber": "Port Numarası",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "Organizasyon Silmeyi Onayla",
"orgMessageRemove": "Bu işlem geri alınamaz ve tüm ilişkili verileri silecektir.",
"orgMessageConfirm": "Onaylamak için lütfen aşağıya organizasyonun adını yazın.",
"orgQuestionRemove": "{selectedOrg} organizasyonunu kaldırmak istediğinizden emin misiniz?",
"orgQuestionRemove": "Organizasyondan kaldırmak istediğinizden emin misiniz?",
"orgUpdated": "Organizasyon güncellendi",
"orgUpdatedDescription": "Organizasyon güncellendi.",
"orgErrorUpdate": "Organizasyon güncellenemedi",
@@ -287,9 +285,8 @@
"apiKeysAdd": "API Anahtarı Oluştur",
"apiKeysErrorDelete": "API anahtarı silinirken bir hata oluştu",
"apiKeysErrorDeleteMessage": "API anahtarı silinirken bir hata oluştu",
"apiKeysQuestionRemove": "{selectedApiKey} API anahtarını organizasyondan kaldırmak istediğinizden emin misiniz?",
"apiKeysQuestionRemove": "API anahtarını organizasyondan kaldırmak istediğinizden emin misiniz?",
"apiKeysMessageRemove": "Kaldırıldığında, API anahtarı artık kullanılamayacaktır.",
"apiKeysMessageConfirm": "Onaylamak için lütfen aşağıya API anahtarının adını yazın.",
"apiKeysDeleteConfirm": "API Anahtarının Silinmesini Onaylayın",
"apiKeysDelete": "API Anahtarını Sil",
"apiKeysManage": "API Anahtarlarını Yönet",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "Kullanıcı Silinmesini Onayla",
"userDeleteServer": "Kullanıcıyı Sunucudan Sil",
"userMessageRemove": "Kullanıcı tüm organizasyonlardan çıkarılacak ve tamamen sunucudan kaldırılacaktır.",
"userMessageConfirm": "Onaylamak için lütfen aşağıya kullanıcının adını yazın.",
"userQuestionRemove": "{selectedUser} kullanıcısını sunucudan kalıcı olarak silmek istediğinizden emin misiniz?",
"userQuestionRemove": "Kullanıcıyı sunucudan kalıcı olarak silmek istediğinizden emin misiniz?",
"licenseKey": "Lisans Anahtarı",
"valid": "Geçerli",
"numberOfSites": "Site Sayısı",
@@ -339,7 +335,7 @@
"fossorialLicense": "Fossorial Ticari Lisans ve Abonelik Koşullarını Gör",
"licenseMessageRemove": "Bu, lisans anahtarını ve onun tarafından verilen tüm izinleri kaldıracaktır.",
"licenseMessageConfirm": "Onaylamak için lütfen aşağıya lisans anahtarını yazın.",
"licenseQuestionRemove": "{selectedKey} lisans anahtarını silmek istediğinizden emin misiniz?",
"licenseQuestionRemove": "Lisans anahtarını silmek istediğinizden emin misiniz?",
"licenseKeyDelete": "Lisans Anahtarını Sil",
"licenseKeyDeleteConfirm": "Lisans Anahtarının Silinmesini Onaylayın",
"licenseTitle": "Lisans Durumunu Yönet",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "Daveti kaldırırken bir hata oluştu.",
"inviteRemoved": "Davetiye kaldırıldı",
"inviteRemovedDescription": "{email} için olan davetiye kaldırıldı.",
"inviteQuestionRemove": "{email} davetini kaldırmak istediğinizden emin misiniz?",
"inviteQuestionRemove": "Davetiyeyi kaldırmak istediğinizden emin misiniz?",
"inviteMessageRemove": "Kaldırıldıktan sonra bu davetiye artık geçerli olmayacak. Kullanıcı tekrar davet edilebilir.",
"inviteMessageConfirm": "Onaylamak için lütfen aşağıya davetiyenin e-posta adresini yazın.",
"inviteQuestionRegenerate": "Are you sure you want to regenerate the invitation for{email, plural, ='' {}, other { for #}}? This will revoke the previous invitation.",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "Kullanıcı kaldırılırken bir hata oluştu.",
"userOrgRemoved": "Kullanıcı kaldırıldı",
"userOrgRemovedDescription": "{email} kullanıcı organizasyondan kaldırılmıştır.",
"userQuestionOrgRemove": "{email} adresini organizasyondan kaldırmak istediğinizden emin misiniz?",
"userQuestionOrgRemove": "Kullanıcıyı organizasyondan kaldırmak istediğinizden emin misiniz?",
"userMessageOrgRemove": "Kaldırıldığında, bu kullanıcı organizasyona artık erişim sağlayamayacak. Kullanıcı tekrar davet edilebilir, ancak daveti kabul etmesi gerekecek.",
"userMessageOrgConfirm": "Onaylamak için lütfen aşağıya kullanıcının adını yazın.",
"userRemoveOrgConfirm": "Kullanıcıyı Kaldırmayı Onayla",
"userRemoveOrg": "Kullanıcıyı Organizasyondan Kaldır",
"users": "Kullanıcılar",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "Sunucu Yöneticisi - Pangolin",
"licenseTierProfessional": "Profesyonel Lisans",
"licenseTierEnterprise": "Kurumsal Lisans",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "Kişisel Lisans",
"licensed": "Lisanslı",
"yes": "Evet",
"no": "Hayır",
@@ -742,7 +737,7 @@
"idpManageDescription": "Sistem içindeki kimlik sağlayıcıları görün ve yönetin",
"idpDeletedDescription": "Kimlik sağlayıcı başarıyla silindi",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "Kimlik sağlayıcıyı kalıcı olarak silmek istediğinizden emin misiniz? {name}",
"idpQuestionRemove": "Kimlik sağlayıcısını kalıcı olarak silmek istediğinizden emin misiniz?",
"idpMessageRemove": "Bu, kimlik sağlayıcıyı ve tüm ilişkili yapılandırmaları kaldıracaktır. Bu sağlayıcıdan kimlik doğrulayan kullanıcılar artık giriş yapamayacaktır.",
"idpMessageConfirm": "Onaylamak için lütfen aşağıya kimlik sağlayıcının adını yazın.",
"idpConfirmDelete": "Kimlik Sağlayıcıyı Silme Onayı",
@@ -765,7 +760,7 @@
"idpDisplayName": "Bu kimlik sağlayıcı için bir görüntü adı",
"idpAutoProvisionUsers": "Kullanıcıları Otomatik Sağla",
"idpAutoProvisionUsersDescription": "Etkinleştirildiğinde, kullanıcılar rol ve organizasyonlara eşleme yeteneğiyle birlikte sistemde otomatik olarak oluşturulacak.",
"licenseBadge": "EE",
"licenseBadge": " ",
"idpType": "Sağlayıcı Türü",
"idpTypeDescription": "Yapılandırmak istediğiniz kimlik sağlayıcısı türünü seçin",
"idpOidcConfigure": "OAuth2/OIDC Yapılandırması",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "E-posta gelen kutunuzda sıfırlama kodunu kontrol edin.",
"passwordNew": "Yeni Şifre",
"passwordNewConfirm": "Yeni Şifreyi Onayla",
"changePassword": "Parola Değiştir",
"changePasswordDescription": "Hesap şifrenizi güncelleyin",
"oldPassword": "Mevcut Şifre",
"newPassword": "Yeni Şifre",
"confirmNewPassword": "Yeni Şifreyi Onayla",
"changePasswordError": "Parola değiştirme başarısız oldu",
"changePasswordErrorDescription": "Parolanız değiştiriliyor.",
"changePasswordSuccess": "Şifre Başarıyla Değiştirildi",
"changePasswordSuccessDescription": "Parolanız başarıyla güncellendi",
"passwordExpiryRequired": "Şifre Süresi Gereklidir",
"passwordExpiryDescription": "Bu kuruluş, parolanızı {maxDays} günde bir değiştirmenizi gerektirir.",
"changePasswordNow": "Şifrenizi Şimdi Değiştirin",
"pincodeAuth": "Kimlik Doğrulama Kodu",
"pincodeSubmit2": "Kodu Gönder",
"passwordResetSubmit": "Sıfırlama İsteği",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "Tüm Kullanıcılar",
"sidebarIdentityProviders": "Kimlik Sağlayıcılar",
"sidebarLicense": "Lisans",
"sidebarClients": "Clients",
"sidebarClients": "İstemciler",
"sidebarDomains": "Alan Adları",
"sidebarBluePrints": "Planlar",
"blueprints": "Planlar",
"blueprintsDescription": "Deklaratif yapılandırmaları uygulayın ve önceki çalışmaları görüntüleyin",
"blueprintAdd": "Plan Ekle",
"blueprintGoBack": "Tüm Planları Gör",
"blueprintCreate": "Plan Oluştur",
"blueprintCreateDescription2": "Yeni bir plan oluşturup uygulamak için aşağıdaki adımları izleyin",
"blueprintDetails": "Mavi Yazılım Detayları",
"blueprintDetailsDescription": "Uygulanan mavi yazılımın sonucunu ve oluşan hataları görün",
"blueprintInfo": "Plan Bilgileri",
"message": "Mesaj",
"blueprintContentsDescription": "Altyapınızı tanımlayan YAML içeriğini tanımlayın",
"blueprintErrorCreateDescription": "Plan uygulanırken bir hata oluştu",
"blueprintErrorCreate": "Plan oluşturulurken hata oluştu",
"searchBlueprintProgress": "Planlarda ara...",
"appliedAt": "Uygulama Zamanı",
"source": "Kaynak",
"contents": "İçerik",
"parsedContents": "Verilerin Ayrıştırılmış İçeriği (Salt Okunur)",
"enableDockerSocket": "Docker Soketini Etkinleştir",
"enableDockerSocketDescription": "Plan etiketleri için Docker Socket etiket toplamasını etkinleştirin. Newt'e soket yolu sağlanmalıdır.",
"enableDockerSocketLink": "Daha fazla bilgi",
@@ -1211,9 +1237,8 @@
"domainCreate": "Alan Adı Oluştur",
"domainCreatedDescription": "Alan adı başarıyla oluşturuldu",
"domainDeletedDescription": "Alan adı başarıyla silindi",
"domainQuestionRemove": "{domain} alan adını hesabınızdan kaldırmak istediğinizden emin misiniz?",
"domainQuestionRemove": "Alan adını hesabınızdan kaldırmak istediğinizden emin misiniz?",
"domainMessageRemove": "Kaldırıldığında, alan adı hesabınızla ilişkilendirilmeyecek.",
"domainMessageConfirm": "Onaylamak için lütfen aşağıya alan adını yazın.",
"domainConfirmDelete": "Alan Adı Silinmesini Onayla",
"domainDelete": "Alan Adını Sil",
"domain": "Alan Adı",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "Ayarları güncellerken bir hata oluştu",
"sidebarCollapse": "Daralt",
"sidebarExpand": "Genişlet",
"productUpdateMoreInfo": "{noOfUpdates} daha fazla güncelleme",
"productUpdateInfo": "{noOfUpdates} güncellemeler",
"productUpdateWhatsNew": "Neler Yeni",
"productUpdateTitle": "Ürün Güncellemeleri",
"productUpdateEmpty": "Güncelleme yok",
"dismissAll": "Hepsini Kapat",
"pangolinUpdateAvailable": "Yeni sürüm mevcut",
"pangolinUpdateAvailableInfo": "Sürüm {version} yüklenmeye hazır",
"pangolinUpdateAvailableReleaseNotes": "Sürüm notlarını görüntüleyin",
"newtUpdateAvailable": "Güncelleme Mevcut",
"newtUpdateAvailableInfo": "Newt'in yeni bir versiyonu mevcut. En iyi deneyim için lütfen en son sürüme güncelleyin.",
"domainPickerEnterDomain": "Alan Adı",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "Ücretsiz Dilim",
"billingWarningOverLimit": "Uyarı: Bir veya daha fazla kullanım limitini aştınız. Aboneliğinizi değiştirmediğiniz veya kullanımı ayarlamadığınız sürece siteleriniz bağlanmayacaktır.",
"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@fossorial.io 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ı",
"billingOnlineTime": "Site Çevrimiçi Süresi",
"billingUsers": "Aktif Kullanıcılar",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "Güvenlik anahtarınızı kullanırken bir sorun oluştu. Lütfen tekrar deneyin.",
"twoFactorRequired": "Güvenlik anahtarını kaydetmek için iki faktörlü kimlik doğrulama gereklidir.",
"twoFactor": "İki Faktörlü Kimlik Doğrulama",
"twoFactorAuthentication": "İki Faktörlü Kimlik Doğrulama",
"twoFactorDescription": "Bu kuruluş iki faktörlü kimlik doğrulama gerektirir.",
"enableTwoFactor": "İki Faktörlü Kimlik Doğrulamayı Etkinleştir",
"organizationSecurityPolicy": "Kuruluş Güvenlik Politikası",
"organizationSecurityPolicyDescription": "Bu kuruluşun güvenlik gereksinimlerine erişmeden önce karşılanması gereken güvenlik gereksinimleri vardır.",
"securityRequirements": "Güvenlik Gereksinimleri",
"allRequirementsMet": "Tüm gereksinimler karşılandı",
"completeRequirementsToContinue": "Bu kuruluşa erişmeye devam etmek için aşağıdaki gereksinimleri tamamlayın",
"youCanNowAccessOrganization": "Artık bu kuruluşa erişebilirsiniz",
"reauthenticationRequired": "Oturum Süresi",
"reauthenticationDescription": "Bu kuruluş, {maxDays} günde bir oturum açmanızı gerektirir.",
"reauthenticationDescriptionHours": "Bu kuruluş, {maxHours} saatte bir oturum açmanızı gerektirir.",
"reauthenticateNow": "Tekrar Giriş Yap",
"adminEnabled2FaOnYourAccount": "Yöneticiniz {email} için iki faktörlü kimlik doğrulamayı etkinleştirdi. Devam etmek için kurulum işlemini tamamlayın.",
"securityKeyAdd": "Güvenlik Anahtarı Ekle",
"securityKeyRegisterTitle": "Yeni Güvenlik Anahtarı Kaydet",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "Bu kaynaklar ile kullanılmak için",
"resourcesTableClients": "İstemciler",
"resourcesTableAndOnlyAccessibleInternally": "veyalnızca bir istemci ile bağlandığında dahili olarak erişilebilir.",
"resourcesTableNoTargets": "Hedef yok",
"resourcesTableHealthy": "Sağlıklı",
"resourcesTableDegraded": "Düşük Performanslı",
"resourcesTableOffline": "Çevrimdışı",
"resourcesTableUnknown": "Bilinmiyor",
"resourcesTableNotMonitored": "İzlenmiyor",
"editInternalResourceDialogEditClientResource": "İstemci Kaynağı Düzenleyin",
"editInternalResourceDialogUpdateResourceProperties": "{resourceName} için kaynak özelliklerini ve hedef yapılandırmasını güncelleyin.",
"editInternalResourceDialogResourceProperties": "Kaynak Özellikleri",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "Kimlik sağlayıcıdan yönlendirme URL'si alınamadı.",
"autoLoginErrorGeneratingUrl": "Kimlik doğrulama URL'si oluşturulamadı.",
"remoteExitNodeManageRemoteExitNodes": "Uzak Düğümler",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "Kendi konum ağlarınızdan bir veya daha fazlasını barındırarak, bağlantı kurulumları için buluta bağımlılığı azaltın.",
"remoteExitNodes": "Düğümler",
"searchRemoteExitNodes": "Düğüm ara...",
"remoteExitNodeAdd": "Düğüm Ekle",
"remoteExitNodeErrorDelete": "Düğüm silinirken hata oluştu",
"remoteExitNodeQuestionRemove": "{selectedNode} düğümü organizasyondan kaldırmak istediğinizden emin misiniz?",
"remoteExitNodeQuestionRemove": "Düğümü organizasyondan kaldırmak istediğinizden emin misiniz?",
"remoteExitNodeMessageRemove": "Kaldırıldığında, düğüm artık erişilebilir olmayacaktır.",
"remoteExitNodeMessageConfirm": "Onaylamak için lütfen aşağıya düğümün adını yazın.",
"remoteExitNodeConfirmDelete": "Düğüm Silmeyi Onayla",
"remoteExitNodeDelete": "Düğümü Sil",
"sidebarRemoteExitNodes": "Uzak Düğümler",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "Dosyayı düzenle: docker-compose.yml",
"emailVerificationRequired": "E-posta doğrulaması gereklidir. Bu adımı tamamlamak için lütfen tekrar {dashboardUrl}/auth/login üzerinden oturum açın. Sonra buraya geri dönün.",
"twoFactorSetupRequired": "İki faktörlü kimlik doğrulama ayarı gereklidir. Bu adımı tamamlamak için lütfen tekrar {dashboardUrl}/auth/login üzerinden oturum açın. Sonra buraya geri dönün.",
"additionalSecurityRequired": "Ek Güvenlik Gereklidir",
"organizationRequiresAdditionalSteps": "Bu kuruluş, kaynaklara erişmeden önce ek güvenlik adımları gerektirir.",
"completeTheseSteps": "Bu adımları tamamlayın",
"enableTwoFactorAuthentication": "İki faktörlü kimlik doğrulamayı etkinleştir",
"completeSecuritySteps": "Güvenlik Adımlarını Tamamla",
"securitySettings": "Güvenlik Ayarları",
"securitySettingsDescription": "Kuruluşunuz için güvenlik politikalarını yapılandırın",
"requireTwoFactorForAllUsers": "Tüm Kullanıcılar için İki Faktörlü Kimlik Doğrulama Gerektir",
"requireTwoFactorDescription": "Etkinleştirildiğinde, bu kuruluştaki tüm dahili kullanıcıların, kuruluşa erişmek için iki faktörlü kimlik doğrulama etkinleştirilmiş olmalıdır.",
"requireTwoFactorDisabledDescription": "Bu özellik, geçerli bir lisans (Kurumsal) veya aktif bir abonelik (SaaS) gerektirir",
"requireTwoFactorCannotEnableDescription": "Tüm kullanıcılar için etkinleştirilmeden önce hesabınızda iki faktörlü kimlik doğrulamayı etkinleştirmeniz gerekir",
"maxSessionLength": "Maksimum Oturum Süresi",
"maxSessionLengthDescription": "Kullanıcı oturumları için maksimum süreyi ayarlayın. Bu süre sonra kullanıcıların tekrar kimlik doğrulaması gerekecektir.",
"maxSessionLengthDisabledDescription": "Bu özellik, geçerli bir lisans (Kurumsal) veya aktif bir abonelik (SaaS) gerektirir",
"selectSessionLength": "Oturum süresini seçin",
"unenforced": "Zorunlu Değil",
"1Hour": "1 saat",
"3Hours": "3 saat",
"6Hours": "6 saat",
"12Hours": "12 saat",
"1DaySession": "1 gün",
"3Days": "3 gün",
"7Days": "7 gün",
"14Days": "14 gün",
"30DaysSession": "30 gün",
"90DaysSession": "90 gün",
"180DaysSession": "180 gün",
"passwordExpiryDays": "Şifre Sona Ermesi",
"editPasswordExpiryDescription": "Kullanıcıların parolalarını değiştirmeleri gereken gün sayısını ayarlayın.",
"selectPasswordExpiry": "Şifre sona ermesini seçin",
"30Days": "30 gün",
"1Day": "1 gün",
"60Days": "60 gün",
"90Days": "90 gün",
"180Days": "180 gün",
"1Year": "1 yıl",
"subscriptionBadge": "Abonelik Gerekiyor",
"securityPolicyChangeWarning": "Güvenlik Politikası Değişiklik Uyarısı",
"securityPolicyChangeDescription": "Güvenlik politikası ayarlarını değiştirmek üzeresiniz. Değişiklikleri kaydettikten sonra, bu politika güncellemelerine uyum sağlamak amacıyla tekrar kimlik doğrulamanız gerekebilir. Uyum sağlamayan tüm kullanıcıların da tekrar kimlik doğrulaması gerekecektir.",
"securityPolicyChangeConfirmMessage": "Onaylıyorum",
"securityPolicyChangeWarningText": "Bu, organizasyondaki tüm kullanıcıları etkileyecektir",
"authPageErrorUpdateMessage": "Kimlik doğrulama sayfası ayarları güncellenirken bir hata oluştu.",
"authPageErrorUpdate": "Kimlik doğrulama sayfası güncellenemedi",
"authPageUpdated": "Kimlik doğrulama sayfası başarıyla güncellendi",
"healthCheckNotAvailable": "Yerel",
"rewritePath": "Yolu Yeniden Yaz",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "Başlık kimlik doğrulama başarıyla kaldırıldı.",
"resourceErrorHeaderAuthRemove": "Başlık Kimlik Doğrulama kaldırılamadı",
"resourceErrorHeaderAuthRemoveDescription": "Kaynak için başlık kimlik doğrulaması kaldırılamadı.",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "Başlık Doğrulaması Etkin",
"resourceHeaderAuthProtectionDisabled": "Başlık Doğrulaması Devre Dışı",
"headerAuthRemove": "Başlık Doğrulaması Kaldır",
"headerAuthAdd": "Başlık Doğrulaması Ekle",
"resourceErrorHeaderAuthSetup": "Başlık Kimlik Doğrulama ayarlanamadı",
"resourceErrorHeaderAuthSetupDescription": "Kaynak için başlık kimlik doğrulaması ayarlanamadı.",
"resourceHeaderAuthSetup": "Başlık Kimlik Doğrulama başarıyla ayarlandı",
"resourceHeaderAuthSetupDescription": "Başlık kimlik doğrulaması başarıyla ayarlandı.",
"resourceHeaderAuthSetupTitle": "Başlık Kimlik Doğrulama Ayarla",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "Bu kaynağı HTTP Başlık Kimlik Doğrulaması ile korumak için temel kimlik bilgilerini (kullanıcı adı ve şifre) ayarlayın. Kaynağa erişim için https://username:password@resource.example.com formatını kullanın.",
"resourceHeaderAuthSubmit": "Başlık Kimlik Doğrulama Ayarla",
"actionSetResourceHeaderAuth": "Başlık Kimlik Doğrulama Ayarla",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"enterpriseEdition": "Kurumsal Sürüm",
"unlicensed": "Lisansız",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"manageClients": "Müşteri Yönetimi",
"manageClientsDescription": "Müşteriler, sitelerinize bağlanabilen cihazlardır.",
"licenseTableValidUntil": "Geçerli İki Tarih Kadar",
"saasLicenseKeysSettingsTitle": "Kurumsal Lisanslar",
"saasLicenseKeysSettingsDescription": "Kendi barındırdığınız Pangolin örnekleri için kurumsal lisans anahtarları oluşturun ve yönetin.",
"sidebarEnterpriseLicenses": "Lisanslar",
"generateLicenseKey": "Lisans Anahtarı Oluştur",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "Lütfen geçerli bir e-posta adresi girin.",
"useCaseTypeRequired": "Lütfen bir kullanım alanı türü seçin.",
"firstNameRequired": "İsim gereklidir.",
"lastNameRequired": "Soyisim gereklidir.",
"primaryUseRequired": "Lütfen öncelikli kullanımınızııklayın.",
"jobTitleRequiredBusiness": "İş kullanımı için iş unvanı gereklidir.",
"industryRequiredBusiness": "İş kullanımı için sektör gereklidir.",
"stateProvinceRegionRequired": "Eyalet/İl/Bölge gereklidir.",
"postalZipCodeRequired": "Posta/ZIP kodu gereklidir.",
"companyNameRequiredBusiness": "İş kullanımı için şirket ismi gereklidir.",
"countryOfResidenceRequiredBusiness": "İş kullanımı için ikamet edilen ülke gereklidir.",
"countryRequiredPersonal": "Kişisel kullanım için ülke gereklidir.",
"agreeToTermsRequired": "Şartları kabul etmelisiniz.",
"complianceConfirmationRequired": "Fossorial Ticari Lisans ile uyumluluğu doğrulamalısınız."
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "Kişisel Kullanım",
"description": "Bireysel, ticari olmayan kullanım için öğrenme, kişisel projeler veya denemeler gibi."
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "İş Kullanımı",
"description": "Kuruluşlar, şirketler veya ticari veya gelir getirici faaliyetler bünyesinde kullanım için."
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "E-posta ve Lisans Türü",
"description": "E-posta adresinizi girin ve lisans türünüzü seçin."
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "Kişisel Bilgiler",
"description": "Kendinizden bahsedin."
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "İletişim Bilgileri",
"description": "İletişim detaylarınız."
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "Şartlar ve Lisans Üret",
"description": "Lisansınızı oluşturmak için şartları inceleyin ve kabul edin."
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "Kullanım Açıklaması",
"description": "Kullanım amacınızı doğru bir şekilde yansıtan lisans seviyesini seçin. Kişisel Lisans, yazılımın bireysel, ticari olmayan veya yıllık geliri 100,000 ABD Dolarının altında olan küçük ölçekli ticari faaliyetlerde ücretsiz kullanılmasına izin verir. Bu sınırların ötesinde kullanım — bir işletme, organizasyon veya diğer gelir getirici ortamlarda kullanım dahil olmak üzere — geçerli bir Kurumsal Lisans ve ilgili lisans ücretinin ödenmesini gerektirir. Tüm kullanıcılar, ister Kişisel ister Kurumsal, Fossorial Ticari Lisans Şartlarına uymalıdır."
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "Deneme Süresi Bilgileri",
"description": "Bu Lisans Anahtarı, Kurumsal özellikleri 7 günlük bir değerlendirme süresi için etkinleştirir. Değerlendirme süresi bittikten sonra, Ücretli Özelliklere devam eden erişim, geçerli bir Kişisel veya Kurumsal Lisans altında etkinleşmeyi gerektirir. Kurumsal lisanslama için sales@pangolin.net ile iletişime geçin."
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "Pangolin'i kişisel veya iş kullanımı için mi kullanıyorsunuz?",
"firstName": "İsim",
"lastName": "Soyisim",
"jobTitle": "İş Unvanı",
"primaryUseQuestion": "Pangolin'i öncelikli olarak ne amacıyla kullanmayı planlıyorsunuz?",
"industryQuestion": "Hangi sektördesiniz?",
"prospectiveUsersQuestion": "Kaç potansiyel kullanıcı öngörüyorsunuz?",
"prospectiveSitesQuestion": "Kaç potansiyel site (tünel) öngörüyorsunuz?",
"companyName": "Şirket İsmi",
"countryOfResidence": "İkamet edilen ülke",
"stateProvinceRegion": "Eyalet / İl / Bölge",
"postalZipCode": "Posta / ZIP Kodu",
"companyWebsite": "Şirket web sitesi",
"companyPhoneNumber": "Şirket telefon numarası",
"country": "Ülke",
"phoneNumberOptional": "Telefon numarası (isteğe bağlı)",
"complianceConfirmation": "Sağladığım bilgilerin doğru olduğunu ve Fossorial Ticari Lisans ile uyumlu olduğumu teyit ederim. Yanlış bilgi raporlamak veya ürün kullanımını yanlış tanımlamak lisans ihlalidir ve anahtarınızın iptal edilmesine neden olabilir."
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "Kapat",
"previous": "Önceki",
"next": "Sonraki",
"generateLicenseKey": "Lisans Anahtarı Oluştur"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "Lisans anahtarı başarıyla oluşturuldu",
"description": "Lisans anahtarınız oluşturuldu ve kullanıma hazır."
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "Lisans anahtarı oluşturulamadı",
"description": "Lisans anahtarı oluşturulurken bir hata oluştu."
}
}
},
"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.",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"instanceName": "Örnek İsmi",
"pathMatchModalTitle": "Yol Eşleşmesini Yapılandır",
"pathMatchModalDescription": "Gelen isteklerin yolu temel alarak nasıl eşleştirilmesi gerektiğini ayarlayın.",
"pathMatchType": "Eşleşme Türü",
"pathMatchPrefix": "Önek",
"pathMatchExact": "Tam",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"pathMatchValue": "Yol Değeri",
"clear": "Temizle",
"saveChanges": "Değişiklikleri Kaydet",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathMatchPrefixHelp": "Örnek: /api, /api/users vb.'ni eşleştirir.",
"pathMatchExactHelp": "Örnek: /api yalnızca /api'yi eşleştirir",
"pathMatchRegexHelp": "Örnek: ^/api/.* her şeyi eşleştirir /api/anything",
"pathRewriteModalTitle": "Yolu Yeniden Yazmayı Yapılandır",
"pathRewriteModalDescription": "Hedefe iletilmeden önce eşleşen yolu dönüştürün.",
"pathRewriteType": "Yeniden Yazma Türü",
"pathRewritePrefixOption": "Önek - Ön ek değiştirme",
"pathRewriteExactOption": "Tam - Tüm yolu değiştir",
"pathRewriteRegexOption": "Regex - Desen değiştirme",
"pathRewriteStripPrefixOption": "Ön Ek Kaldır - Ön eki sil",
"pathRewriteValue": "Yeniden Yazma Değeri",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewritePrefixHelp": "Eşleşen öneki bu değerle değiştir",
"pathRewriteExactHelp": "Yol tam olarak eşleştiğinde, yolun tamamını bu değerle değiştir",
"pathRewriteRegexHelp": "Değiştirme için $1, $2 gibi yakalama gruplarını kullan",
"pathRewriteStripPrefixHelp": "Öneki silmek veya yeni bir ön ek sağlamak için boş bırakın",
"pathRewritePrefix": "Önek",
"pathRewriteExact": "Tam",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewriteStrip": "Sil",
"pathRewriteStripLabel": "sil",
"sidebarEnableEnterpriseLicense": "Kurumsal Lisans Etkinleştir",
"cannotbeUndone": "Bu geri alınamaz.",
"toConfirm": "doğrulamak için",
"deleteClientQuestion": "Müşteriyi siteden ve organizasyondan kaldırmak istediğinizden emin misiniz?",
"clientMessageRemove": "Kaldırıldıktan sonra müşteri siteye bağlanamayacaktır.",
"sidebarLogs": "Kayıtlar",
"request": "İstek",
"logs": "Günlükler",
"logsSettingsDescription": "Bu organizasyondan toplanan günlükleri izleyin",
"searchLogs": "Günlüklerde ara...",
"action": "Eylem",
"actor": "Aktör",
"timestamp": "Zaman damgası",
"accessLogs": "Erişim Günlükleri",
"exportCsv": "CSV Dışa Aktar",
"actorId": "Aktör Kimliği",
"allowedByRule": "Kurallara Göre İzin Verildi",
"allowedNoAuth": "Kimlik Doğrulama Yok İzin Verildi",
"validAccessToken": "Geçerli Erişim Jetonu",
"validHeaderAuth": "Geçerli Başlık Doğrulama",
"validPincode": "Geçerli Pincode",
"validPassword": "Geçerli Şifre",
"validEmail": "Geçerli E-posta",
"validSSO": "Geçerli SSO",
"resourceBlocked": "Kaynak Engellendi",
"droppedByRule": "Kurallara Göre Çıkartıldı",
"noSessions": "Oturum Yok",
"temporaryRequestToken": "Geçici İstek Jetonu",
"noMoreAuthMethods": "Daha Fazla Kimlik Doğrulama Yöntemi Yok",
"ip": "IP",
"reason": "Sebep",
"requestLogs": "İstek Günlükleri",
"host": "Sunucu",
"location": "Konum",
"actionLogs": "Eylem Günlükleri",
"sidebarLogsRequest": "İstek Günlükleri",
"sidebarLogsAccess": "Erişim Günlükleri",
"sidebarLogsAction": "Eylem Günlükleri",
"logRetention": "Kayıt Saklama",
"logRetentionDescription": "Bu organizasyon için farklı türdeki günlüklerin ne kadar süre saklanacağını yönetin veya devre dışı bırakın",
"requestLogsDescription": "Bu organizasyondaki kaynaklar için ayrıntılı istek günlüklerini görüntüleyin",
"logRetentionRequestLabel": "İstek Günlüğü Saklama",
"logRetentionRequestDescription": "İstek günlüklerini ne kadar süre tutacağını belirle",
"logRetentionAccessLabel": "Erişim Günlüğü Saklama",
"logRetentionAccessDescription": "Erişim günlüklerini ne kadar süre tutacağını belirle",
"logRetentionActionLabel": "Eylem Günlüğü Saklama",
"logRetentionActionDescription": "Eylem günlüklerini ne kadar süre tutacağını belirle",
"logRetentionDisabled": "Devre Dışı",
"logRetention3Days": "3 gün",
"logRetention7Days": "7 gün",
"logRetention14Days": "14 gün",
"logRetention30Days": "30 gün",
"logRetention90Days": "90 gün",
"logRetentionForever": "Sonsuza kadar",
"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",
"licenseRequiredToUse": "Bu özelliği kullanmak için bir kurumsal lisans gereklidir.",
"certResolver": "Sertifika Çözücü",
"certResolverDescription": "Bu kaynak için kullanılacak sertifika çözücüsünü seçin.",
"selectCertResolver": "Sertifika Çözücü Seçin",
"enterCustomResolver": "Özel Çözücü Girin",
"preferWildcardCert": "Joker Sertifikayı Tercih Et",
"unverified": "Doğrulanmadı",
"domainSetting": "Alan Adı Ayarları",
"domainSettingDescription": "Alan adınız için ayarları yapılandırın",
"preferWildcardCertDescription": "Joker sertifika üretmeye çalışın (doğru yapılandırılmış bir sertifika çözücü gereklidir).",
"recordName": "Kayıt Adı",
"auto": "Otomatik",
"TTL": "TTL",
"howToAddRecords": "Kayıtları Nasıl Ekleyebilirsiniz",
"dnsRecord": "DNS Kayıtları",
"required": "Gerekli",
"domainSettingsUpdated": "Alan adına yönelik ayarlar başarıyla güncellendi",
"orgOrDomainIdMissing": "Organizasyon veya Alan Adı Kimliği eksik",
"loadingDNSRecords": "DNS kayıtları yükleniyor...",
"olmUpdateAvailableInfo": "Olm'nin güncellenmiş bir sürümü mevcut. En iyi deneyim için lütfen en son sürüme güncelleyin.",
"client": "İstemci",
"proxyProtocol": "Proxy Protokol Ayarları",
"proxyProtocolDescription": "TCP/UDP hizmetleri için istemci IP adreslerini korumak için Proxy Protokolünü yapılandırın.",
"enableProxyProtocol": "Proxy Protokolünü Etkinleştir",
"proxyProtocolInfo": "TCP/UDP arka uçları için istemci IP adreslerini koruyun",
"proxyProtocolVersion": "Proxy Protokol Versiyonu",
"version1": " Versiyon 1 (Önerilen)",
"version2": "Versiyon 2",
"versionDescription": "Versiyon 1 metin tabanlı ve yaygın olarak desteklenir. Versiyon 2 ise ikili ve daha verimlidir ama daha az uyumludur.",
"warning": "Uyarı",
"proxyProtocolWarning": "Arka uç uygulamanız, Proxy Protokol bağlantılarını kabul etmek üzere yapılandırılmalıdır. Arka ucunuz Proxy Protokolünü desteklemiyorsa, bunu etkinleştirmek tüm bağlantıları koparır. Traefik'ten gelen Proxy Protokol başlıklarına güvenecek şekilde arka ucunuzu yapılandırdığınızdan emin olun.",
"restarting": "Yeniden Başlatılıyor...",
"manual": "Manuel",
"messageSupport": "Destek Mesajı Gönder",
"supportNotAvailableTitle": "Destek Yok",
"supportNotAvailableDescription": "Destek şu anda mevcut değil. Destek'e bir e-posta gönderebilirsiniz: support@pangolin.net.",
"supportRequestSentTitle": "Destek İsteği Gönderildi",
"supportRequestSentDescription": "Mesajınız başarıyla gönderildi.",
"supportRequestFailedTitle": "İsteği Gönderme Başarısız",
"supportRequestFailedDescription": "Destek isteği gönderilirken bir hata oluştu.",
"supportSubjectRequired": "Konu gerekli",
"supportSubjectMaxLength": "Konu en fazla 255 karakter olabilir",
"supportMessageRequired": "Mesaj gerekli",
"supportReplyTo": "Yanıtla",
"supportSubject": "Konu",
"supportSubjectPlaceholder": "Konu girin",
"supportMessage": "Mesaj",
"supportMessagePlaceholder": "Mesajınızı girin",
"supportSending": "Gönderiliyor...",
"supportSend": "Gönder",
"supportMessageSent": "Mesaj Gönderildi!",
"supportWillContact": "En kısa sürede size geri döneceğiz!",
"selectLogRetention": "Kayıt saklama seç",
"showColumns": "Sütunları Göster",
"hideColumns": "Sütunları Gizle",
"columnVisibility": "Sütun Görünürlüğü",
"toggleColumn": "{columnName} sütununu aç/kapat",
"allColumns": "Tüm Sütunlar",
"defaultColumns": "Varsayılan Sütunlar",
"customizeView": "Görünümü Özelleştir",
"viewOptions": "Görünüm Seçenekleri",
"selectAll": "Tümünü Seç",
"selectNone": "Hiçbirini Seçme",
"selectedResources": "Seçilen Kaynaklar",
"enableSelected": "Seçilenleri Etkinleştir",
"disableSelected": "Seçilenleri Devre Dışı Bırak",
"checkSelectedStatus": "Seçilenlerin Durumunu Kontrol Et",
"credentials": "Kimlik Bilgileri",
"savecredentials": "Kimlik Bilgilerini Kaydet",
"regeneratecredentials": "Yeniden Anahtarla",
"regenerateCredentials": "Kimlik bilgilerinizi yeniden oluşturun ve kaydedin",
"generatedcredentials": "Oluşturulan Kimlik Bilgileri",
"copyandsavethesecredentials": "Bu kimlik bilgilerini kopyalayın ve kaydedin",
"copyandsavethesecredentialsdescription": "Bu sayfadan ayrıldıktan sonra bu kimlik bilgileri tekrar gösterilmeyecek. Onları şimdi güvenli bir şekilde saklayın.",
"credentialsSaved": "Kimlik Bilgileri Kaydedildi",
"credentialsSavedDescription": "Kimlik bilgileri başarılı bir şekilde yeniden oluşturuldu ve kaydedildi.",
"credentialsSaveError": "Kimlik Bilgileri Kayıt Hatası",
"credentialsSaveErrorDescription": "Kimlik bilgilerini yeniden oluştururken ve kaydederken bir hata oluştu.",
"regenerateCredentialsWarning": "Kimlik bilgilerini yeniden oluşturmak önceki bilgileri geçersiz kılacaktır. Bu kimlik bilgilerini kullanan tüm yapılandırmaları güncellediğinizden emin olun.",
"confirm": "Onayla",
"regenerateCredentialsConfirmation": "Kimlik bilgilerini yeniden oluşturmak istediğinizden emin misiniz?",
"endpoint": "Uç Nokta",
"Id": "Kimlik",
"SecretKey": "Gizli Anahtar",
"featureDisabledTooltip": "Bu özellik yalnızca kurumsal planda mevcuttur ve kullanmak için lisans gerektirir.",
"niceId": "Güzel Kimlik",
"niceIdUpdated": "Güzel Kimlik Güncellendi",
"niceIdUpdatedSuccessfully": "Güzel Kimlik Başarıyla Güncellendi",
"niceIdUpdateError": "Güzel Kimlik güncellenirken hata",
"niceIdUpdateErrorDescription": "Güzel Kimlik güncellenirken bir hata oluştu.",
"niceIdCannotBeEmpty": "Güzel Kimlik boş olamaz",
"enterIdentifier": "Tanımlayıcıyı girin",
"identifier": "Tanımlayıcı"
}

View File

@@ -47,9 +47,8 @@
"edit": "编辑",
"siteConfirmDelete": "确认删除站点",
"siteDelete": "删除站点",
"siteMessageRemove": "一旦除,站点将无法访问。与站点相关的所有资源和目标也将被除。",
"siteMessageConfirm": "请在下面输入站点名称以确认。",
"siteQuestionRemove": "您确定要从组织中删除 {selectedSite} 站点吗?",
"siteMessageRemove": "一旦除,站点将无法访问。与站点相关的所有目标也将被除。",
"siteQuestionRemove": "您确定要从组织中删除该站点吗?",
"siteManageSites": "管理站点",
"siteDescription": "允许通过安全隧道连接到您的网络",
"siteCreate": "创建站点",
@@ -96,7 +95,7 @@
"siteWgDescription": "使用任何 WireGuard 客户端来建立隧道。需要手动配置 NAT。",
"siteWgDescriptionSaas": "使用任何WireGuard客户端建立隧道。需要手动配置NAT。仅适用于自托管节点。",
"siteLocalDescription": "仅限本地资源。不需要隧道。",
"siteLocalDescriptionSaas": "Local resources only. No tunneling. Only available on remote nodes.",
"siteLocalDescriptionSaas": "仅本地资源。没有隧道。仅在远程节点上可用。",
"siteSeeAll": "查看所有站点",
"siteTunnelDescription": "确定如何连接到您的网站",
"siteNewtCredentials": "Newt 凭据",
@@ -132,7 +131,7 @@
"expireIn": "过期时间",
"neverExpire": "永不过期",
"shareExpireDescription": "过期时间是链接可以使用并提供对资源的访问时间。 此时间后,链接将不再工作,使用此链接的用户将失去对资源的访问。",
"shareSeeOnce": "您只能看到此链接。请确保复制它。",
"shareSeeOnce": "您只能看到一次此链接。请确保复制它。",
"shareAccessHint": "任何具有此链接的人都可以访问该资源。小心地分享它。",
"shareTokenUsage": "查看访问令牌使用情况",
"createLink": "创建链接",
@@ -154,8 +153,7 @@
"protected": "受到保护",
"notProtected": "未受到保护",
"resourceMessageRemove": "一旦删除,资源将不再可访问。与该资源相关的所有目标也将被删除。",
"resourceMessageConfirm": "请在下面输入资源名称以确认。",
"resourceQuestionRemove": "您确定要从组织中删除 {selectedResource} 吗?",
"resourceQuestionRemove": "您确定要从组织中删除资源吗?",
"resourceHTTP": "HTTPS 资源",
"resourceHTTPDescription": "使用子域或根域名通过 HTTPS 向您的应用程序提出代理请求。",
"resourceRaw": "TCP/UDP 资源",
@@ -181,7 +179,7 @@
"baseDomain": "根域名",
"subdomnainDescription": "您的资源可以访问的子域名。",
"resourceRawSettings": "TCP/UDP 设置",
"resourceRawSettingsDescription": "配置如何通过 TCP/UDP 访问您的资源",
"resourceRawSettingsDescription": "配置如何通过 TCP/UDP 访问您的资源。 您映射资源到主机Pangolin服务器上的端口这样您就可以访问服务器-公共-ip:mapped端口的资源。",
"protocol": "协议",
"protocolSelect": "选择协议",
"resourcePortNumber": "端口号",
@@ -220,7 +218,7 @@
"orgDeleteConfirm": "确认删除组织",
"orgMessageRemove": "此操作不可逆,这将删除所有相关数据。",
"orgMessageConfirm": "要确认,请在下面输入组织名称。",
"orgQuestionRemove": "确定要删除 \"{selectedOrg}\" 组织吗?",
"orgQuestionRemove": "确定要删除组织吗?",
"orgUpdated": "组织已更新",
"orgUpdatedDescription": "组织已更新。",
"orgErrorUpdate": "更新组织失败",
@@ -287,9 +285,8 @@
"apiKeysAdd": "生成 API 密钥",
"apiKeysErrorDelete": "删除 API 密钥出错",
"apiKeysErrorDeleteMessage": "删除 API 密钥出错",
"apiKeysQuestionRemove": "您确定要从组织中删除 \"{selectedApiKey}\" API密钥吗",
"apiKeysQuestionRemove": "您确定要从组织中删除 API 密钥吗?",
"apiKeysMessageRemove": "一旦删除此API密钥将无法被使用。",
"apiKeysMessageConfirm": "要确认请在下方输入API密钥名称。",
"apiKeysDeleteConfirm": "确认删除 API 密钥",
"apiKeysDelete": "删除 API 密钥",
"apiKeysManage": "管理 API 密钥",
@@ -305,8 +302,7 @@
"userDeleteConfirm": "确认删除用户",
"userDeleteServer": "从服务器删除用户",
"userMessageRemove": "该用户将被从所有组织中删除并完全从服务器中删除。",
"userMessageConfirm": "请在下面输入用户名称以确认。",
"userQuestionRemove": "您确定要从服务器中永久删除 {selectedUser} 吗?",
"userQuestionRemove": "您确定要从服务器永久删除用户吗?",
"licenseKey": "许可证密钥",
"valid": "有效",
"numberOfSites": "站点数量",
@@ -339,7 +335,7 @@
"fossorialLicense": "查看Fossorial Commercial License和订阅条款",
"licenseMessageRemove": "这将删除许可证密钥和它授予的所有相关权限。",
"licenseMessageConfirm": "要确认,请在下面输入许可证密钥。",
"licenseQuestionRemove": "您确定要删除 {selectedKey} 的邀请吗",
"licenseQuestionRemove": "您确定要删除许可证密钥",
"licenseKeyDelete": "删除许可证密钥",
"licenseKeyDeleteConfirm": "确认删除许可证密钥",
"licenseTitle": "管理许可证状态",
@@ -372,7 +368,7 @@
"inviteRemoveErrorDescription": "删除邀请时出错。",
"inviteRemoved": "邀请已删除",
"inviteRemovedDescription": "为 {email} 创建的邀请已删除",
"inviteQuestionRemove": "您确定要删除 {email} 的邀请吗?",
"inviteQuestionRemove": "您确定要删除邀请吗?",
"inviteMessageRemove": "一旦删除,这个邀请将不再有效。",
"inviteMessageConfirm": "要确认,请在下面输入邀请的电子邮件地址。",
"inviteQuestionRegenerate": "您确定要重新邀请 {email} 吗?这将会撤销掉之前的邀请",
@@ -398,9 +394,8 @@
"userErrorOrgRemoveDescription": "删除用户时出错。",
"userOrgRemoved": "用户已删除",
"userOrgRemovedDescription": "已将 {email} 从组织中移除。",
"userQuestionOrgRemove": "确定要将 {email} 从组织中移除吗?",
"userQuestionOrgRemove": "确定要从组织中删除此用户吗?",
"userMessageOrgRemove": "一旦删除,这个用户将不再能够访问组织。 你总是可以稍后重新邀请他们,但他们需要再次接受邀请。",
"userMessageOrgConfirm": "请在下面输入用户名称以确认。",
"userRemoveOrgConfirm": "确认删除用户",
"userRemoveOrg": "从组织中删除用户",
"users": "用户",
@@ -730,7 +725,7 @@
"pangolinServerAdmin": "服务器管理员 - Pangolin",
"licenseTierProfessional": "专业许可证",
"licenseTierEnterprise": "企业许可证",
"licenseTierPersonal": "Personal License",
"licenseTierPersonal": "个人许可证",
"licensed": "已授权",
"yes": "是",
"no": "否",
@@ -742,7 +737,7 @@
"idpManageDescription": "查看和管理系统中的身份提供商",
"idpDeletedDescription": "身份提供商删除成功",
"idpOidc": "OAuth2/OIDC",
"idpQuestionRemove": "确定要永久删除 \"{name}\" 这个身份提供吗?",
"idpQuestionRemove": "确定要永久删除身份提供吗?",
"idpMessageRemove": "这将删除身份提供者和所有相关的配置。通过此提供者进行身份验证的用户将无法登录。",
"idpMessageConfirm": "要确认,请在下面输入身份提供者的名称。",
"idpConfirmDelete": "确认删除身份提供商",
@@ -916,6 +911,18 @@
"passwordResetCodeDescription": "请检查您的电子邮件以获取验证码。",
"passwordNew": "新密码",
"passwordNewConfirm": "确认新密码",
"changePassword": "更改密码",
"changePasswordDescription": "更新您的帐户密码",
"oldPassword": "当前密码",
"newPassword": "新密码",
"confirmNewPassword": "确认新密码",
"changePasswordError": "更改密码失败",
"changePasswordErrorDescription": "更改您的密码时出错",
"changePasswordSuccess": "密码修改成功",
"changePasswordSuccessDescription": "您的密码已成功更新",
"passwordExpiryRequired": "需要密码过期",
"passwordExpiryDescription": "该机构要求您每 {maxDays} 天更改一次密码。",
"changePasswordNow": "现在更改密码",
"pincodeAuth": "验证器代码",
"pincodeSubmit2": "提交代码",
"passwordResetSubmit": "请求重置",
@@ -1154,8 +1161,27 @@
"sidebarAllUsers": "所有用户",
"sidebarIdentityProviders": "身份提供商",
"sidebarLicense": "证书",
"sidebarClients": "Clients",
"sidebarClients": "客户端",
"sidebarDomains": "域",
"sidebarBluePrints": "蓝图",
"blueprints": "蓝图",
"blueprintsDescription": "应用声明配置并查看先前运行的",
"blueprintAdd": "添加蓝图",
"blueprintGoBack": "查看所有蓝图",
"blueprintCreate": "创建蓝图",
"blueprintCreateDescription2": "按照下面的步骤创建和应用新的蓝图",
"blueprintDetails": "蓝图详细信息",
"blueprintDetailsDescription": "查看应用蓝图的结果和发生的任何错误",
"blueprintInfo": "蓝图信息",
"message": "留言",
"blueprintContentsDescription": "定义描述您基础设施的 YAML 内容",
"blueprintErrorCreateDescription": "应用蓝图时出错",
"blueprintErrorCreate": "创建蓝图时出错",
"searchBlueprintProgress": "搜索蓝图...",
"appliedAt": "应用于",
"source": "来源",
"contents": "目录",
"parsedContents": "解析内容 (只读)",
"enableDockerSocket": "启用 Docker 蓝图",
"enableDockerSocketDescription": "启用 Docker Socket 标签擦除蓝图标签。套接字路径必须提供给新的。",
"enableDockerSocketLink": "了解更多",
@@ -1211,9 +1237,8 @@
"domainCreate": "创建域",
"domainCreatedDescription": "域创建成功",
"domainDeletedDescription": "成功删除域",
"domainQuestionRemove": "您确定要从您的户中除域{domain}吗?",
"domainQuestionRemove": "您确定要从您的户中除域吗?",
"domainMessageRemove": "移除后,该域将不再与您的账户关联。",
"domainMessageConfirm": "要确认,请在下方输入域名。",
"domainConfirmDelete": "确认删除域",
"domainDelete": "删除域",
"domain": "域",
@@ -1254,6 +1279,15 @@
"settingsErrorUpdateDescription": "更新设置时发生错误",
"sidebarCollapse": "折叠",
"sidebarExpand": "展开",
"productUpdateMoreInfo": "{noOfUpdates} 个更新",
"productUpdateInfo": "{noOfUpdates} 个更新",
"productUpdateWhatsNew": "新功能",
"productUpdateTitle": "产品更新",
"productUpdateEmpty": "无更新",
"dismissAll": "关闭所有",
"pangolinUpdateAvailable": "新版本可用",
"pangolinUpdateAvailableInfo": "版本 {version} 已准备就绪",
"pangolinUpdateAvailableReleaseNotes": "查看发布笔记",
"newtUpdateAvailable": "更新可用",
"newtUpdateAvailableInfo": "新版本的 Newt 已可用。请更新到最新版本以获得最佳体验。",
"domainPickerEnterDomain": "域名",
@@ -1280,7 +1314,7 @@
"billingFreeTier": "免费层",
"billingWarningOverLimit": "警告:您已超出一个或多个使用限制。在您修改订阅或调整使用情况之前,您的站点将无法连接。",
"billingUsageLimitsOverview": "使用限制概览",
"billingMonitorUsage": "监控您的使用情况以对比已配置的限制。如需提高限制请联系我们 support@fossorial.io。",
"billingMonitorUsage": "监控您的使用情况以对比已配置的限制。如需提高限制请联系我们 support@pangolin.net。",
"billingDataUsage": "数据使用情况",
"billingOnlineTime": "站点在线时间",
"billingUsers": "活跃用户",
@@ -1346,6 +1380,19 @@
"securityKeyUnknownError": "使用安全密钥时出现问题。请再试一次。",
"twoFactorRequired": "注册安全密钥需要两步验证。",
"twoFactor": "两步验证",
"twoFactorAuthentication": "两步验证",
"twoFactorDescription": "这个组织需要双重身份验证。",
"enableTwoFactor": "启用两步验证",
"organizationSecurityPolicy": "组织安全政策",
"organizationSecurityPolicyDescription": "此机构拥有安全要求,您必须先满足才能访问",
"securityRequirements": "安全要求",
"allRequirementsMet": "已满足所有要求",
"completeRequirementsToContinue": "完成下面的要求以继续访问此组织",
"youCanNowAccessOrganization": "您现在可以访问此组织",
"reauthenticationRequired": "会话长度",
"reauthenticationDescription": "该机构要求您每 {maxDays} 天登录一次。",
"reauthenticationDescriptionHours": "该机构要求您每 {maxHours} 小时登录一次。",
"reauthenticateNow": "再次登录",
"adminEnabled2FaOnYourAccount": "管理员已为{email}启用两步验证。请完成设置以继续。",
"securityKeyAdd": "添加安全密钥",
"securityKeyRegisterTitle": "注册新安全密钥",
@@ -1487,6 +1534,12 @@
"resourcesTableTheseResourcesForUseWith": "这些资源供...使用",
"resourcesTableClients": "客户端",
"resourcesTableAndOnlyAccessibleInternally": "且仅在与客户端连接时可内部访问。",
"resourcesTableNoTargets": "没有目标",
"resourcesTableHealthy": "健康的",
"resourcesTableDegraded": "降级",
"resourcesTableOffline": "离线的",
"resourcesTableUnknown": "未知的",
"resourcesTableNotMonitored": "未监视的",
"editInternalResourceDialogEditClientResource": "编辑客户端资源",
"editInternalResourceDialogUpdateResourceProperties": "更新{resourceName}的资源属性和目标配置。",
"editInternalResourceDialogResourceProperties": "资源属性",
@@ -1558,14 +1611,13 @@
"autoLoginErrorNoRedirectUrl": "未从身份提供商收到重定向URL。",
"autoLoginErrorGeneratingUrl": "生成身份验证URL失败。",
"remoteExitNodeManageRemoteExitNodes": "远程节点",
"remoteExitNodeDescription": "Self-host one or more remote nodes to extend your network connectivity and reduce reliance on the cloud",
"remoteExitNodeDescription": "自我主机一个或多个远程节点来扩展您的网络连接并减少对云的依赖性",
"remoteExitNodes": "节点",
"searchRemoteExitNodes": "搜索节点...",
"remoteExitNodeAdd": "添加节点",
"remoteExitNodeErrorDelete": "删除节点时出错",
"remoteExitNodeQuestionRemove": "您确定要从组织中删除 {selectedNode} 节点吗?",
"remoteExitNodeQuestionRemove": "您确定要从组织中删除节点吗?",
"remoteExitNodeMessageRemove": "一旦删除,该节点将不再能够访问。",
"remoteExitNodeMessageConfirm": "要确认,请输入以下节点的名称。",
"remoteExitNodeConfirmDelete": "确认删除节点",
"remoteExitNodeDelete": "删除节点",
"sidebarRemoteExitNodes": "远程节点",
@@ -1733,7 +1785,49 @@
"resourceExposePortsEditFile": "编辑文件docker-compose.yml",
"emailVerificationRequired": "需要电子邮件验证。 请通过 {dashboardUrl}/auth/login 再次登录以完成此步骤。 然后,回到这里。",
"twoFactorSetupRequired": "需要设置双因素身份验证。 请通过 {dashboardUrl}/auth/login 再次登录以完成此步骤。 然后,回到这里。",
"additionalSecurityRequired": "需要额外的安全",
"organizationRequiresAdditionalSteps": "这个组织需要额外的安全步骤才能访问资源。",
"completeTheseSteps": "完成这些步骤",
"enableTwoFactorAuthentication": "启用两步验证",
"completeSecuritySteps": "完成安全步骤",
"securitySettings": "安全设置",
"securitySettingsDescription": "配置您组织的安全策略",
"requireTwoFactorForAllUsers": "所有用户需要两步验证",
"requireTwoFactorDescription": "如果启用,此组织的所有内部用户必须启用双重身份验证才能访问组织。",
"requireTwoFactorDisabledDescription": "此功能需要有效的许可证企业或活动订阅SaS",
"requireTwoFactorCannotEnableDescription": "您必须为您的帐户启用双重身份验证才能对所有用户",
"maxSessionLength": "最大会话长度",
"maxSessionLengthDescription": "设置用户会话的最长时间。此后用户需要重新验证。",
"maxSessionLengthDisabledDescription": "此功能需要有效的许可证企业或活动订阅SaS",
"selectSessionLength": "选择会话长度",
"unenforced": "未执行",
"1Hour": "1 小时",
"3Hours": "3 小时",
"6Hours": "6 小时",
"12Hours": "12 小时",
"1DaySession": "1天",
"3Days": "3 天",
"7Days": "7 天",
"14Days": "14 天",
"30DaysSession": "30 天",
"90DaysSession": "90 天",
"180DaysSession": "180天",
"passwordExpiryDays": "密码过期",
"editPasswordExpiryDescription": "设置用户需要更改密码之前的天数。",
"selectPasswordExpiry": "选择密码过期",
"30Days": "30 天",
"1Day": "1天",
"60Days": "60天",
"90Days": "90 天",
"180Days": "180天",
"1Year": "1 年",
"subscriptionBadge": "需要订阅",
"securityPolicyChangeWarning": "安全政策更改警告",
"securityPolicyChangeDescription": "您即将更改安全政策设置。保存后,您可能需要重新认证以遵守这些政策更新。 所有不符合要求的用户也需要重新认证。",
"securityPolicyChangeConfirmMessage": "我确认",
"securityPolicyChangeWarningText": "这将影响组织中的所有用户",
"authPageErrorUpdateMessage": "更新身份验证页面设置时出错",
"authPageErrorUpdate": "无法更新认证页面",
"authPageUpdated": "身份验证页面更新成功",
"healthCheckNotAvailable": "本地的",
"rewritePath": "重写路径",
@@ -1745,153 +1839,302 @@
"resourceHeaderAuthRemoveDescription": "已成功删除头部身份验证。",
"resourceErrorHeaderAuthRemove": "删除头部身份验证失败",
"resourceErrorHeaderAuthRemoveDescription": "无法删除资源的头部身份验证。",
"resourceHeaderAuthProtectionEnabled": "Header Authentication Enabled",
"resourceHeaderAuthProtectionDisabled": "Header Authentication Disabled",
"headerAuthRemove": "Remove Header Auth",
"headerAuthAdd": "Add Header Auth",
"resourceHeaderAuthProtectionEnabled": "头部认证已启用",
"resourceHeaderAuthProtectionDisabled": "头部身份验证已禁用",
"headerAuthRemove": "删除头部认证",
"headerAuthAdd": "添加页眉认证",
"resourceErrorHeaderAuthSetup": "设置页眉认证失败",
"resourceErrorHeaderAuthSetupDescription": "无法设置资源的头部身份验证。",
"resourceHeaderAuthSetup": "头部认证设置成功",
"resourceHeaderAuthSetupDescription": "头部认证已成功设置。",
"resourceHeaderAuthSetupTitle": "设置头部身份验证",
"resourceHeaderAuthSetupTitleDescription": "Set the basic auth credentials (username and password) to protect this resource with HTTP Header Authentication. Access it using the format https://username:password@resource.example.com",
"resourceHeaderAuthSetupTitleDescription": "使用HTTP 头身份验证来设置基本身份验证信息(用户名和密码)。使用 https://username:password@resource.example.com 访问它",
"resourceHeaderAuthSubmit": "设置头部身份验证",
"actionSetResourceHeaderAuth": "设置头部身份验证",
"enterpriseEdition": "Enterprise Edition",
"unlicensed": "Unlicensed",
"beta": "Beta",
"manageClients": "Manage Clients",
"manageClientsDescription": "Clients are devices that can connect to your sites",
"licenseTableValidUntil": "Valid Until",
"saasLicenseKeysSettingsTitle": "Enterprise Licenses",
"saasLicenseKeysSettingsDescription": "Generate and manage Enterprise license keys for self-hosted Pangolin instances",
"sidebarEnterpriseLicenses": "Licenses",
"generateLicenseKey": "Generate License Key",
"enterpriseEdition": "企业版",
"unlicensed": "未授权",
"beta": "测试版",
"manageClients": "管理客户端",
"manageClientsDescription": "客户端是可以连接到您的站点的设备",
"licenseTableValidUntil": "有效期至",
"saasLicenseKeysSettingsTitle": "企业许可证",
"saasLicenseKeysSettingsDescription": "为自我托管的 Pangolin 实例生成和管理企业许可证密钥",
"sidebarEnterpriseLicenses": "许可协议",
"generateLicenseKey": "生成许可证密钥",
"generateLicenseKeyForm": {
"validation": {
"emailRequired": "Please enter a valid email address",
"useCaseTypeRequired": "Please select a use case type",
"firstNameRequired": "First name is required",
"lastNameRequired": "Last name is required",
"primaryUseRequired": "Please describe your primary use",
"jobTitleRequiredBusiness": "Job title is required for business use",
"industryRequiredBusiness": "Industry is required for business use",
"stateProvinceRegionRequired": "State/Province/Region is required",
"postalZipCodeRequired": "Postal/ZIP Code is required",
"companyNameRequiredBusiness": "Company name is required for business use",
"countryOfResidenceRequiredBusiness": "Country of residence is required for business use",
"countryRequiredPersonal": "Country is required for personal use",
"agreeToTermsRequired": "You must agree to the terms",
"complianceConfirmationRequired": "You must confirm compliance with the Fossorial Commercial License"
"emailRequired": "请输入一个有效的电子邮件地址",
"useCaseTypeRequired": "请选择一个使用的案例类型",
"firstNameRequired": "必填名",
"lastNameRequired": "姓氏是必填项",
"primaryUseRequired": "请描述您的主要使用",
"jobTitleRequiredBusiness": "企业使用必须有职位头衔。",
"industryRequiredBusiness": "商业使用需要工业",
"stateProvinceRegionRequired": "州/省/地区是必填项",
"postalZipCodeRequired": "邮政编码是必需的",
"companyNameRequiredBusiness": "企业使用需要公司名称",
"countryOfResidenceRequiredBusiness": "商业使用必须是居住国",
"countryRequiredPersonal": "国家需要个人使用",
"agreeToTermsRequired": "您必须同意条款",
"complianceConfirmationRequired": "您必须确认遵守Fossorial Commercial License"
},
"useCaseOptions": {
"personal": {
"title": "Personal Use",
"description": "For individual, non-commercial use such as learning, personal projects, or experimentation."
"title": "个人使用",
"description": "个人非商业用途,如学习、个人项目或实验。"
},
"business": {
"title": "Business Use",
"description": "For use within organizations, companies, or commercial or revenue-generating activities."
"title": "商业使用",
"description": "供组织、公司或商业或创收活动使用。"
}
},
"steps": {
"emailLicenseType": {
"title": "Email & License Type",
"description": "Enter your email and choose your license type"
"title": "电子邮件和许可证类型",
"description": "输入您的电子邮件并选择您的许可证类型"
},
"personalInformation": {
"title": "Personal Information",
"description": "Tell us about yourself"
"title": "个人信息",
"description": "告诉我们自己的信息"
},
"contactInformation": {
"title": "Contact Information",
"description": "Your contact details"
"title": "联系信息",
"description": "您的联系信息"
},
"termsGenerate": {
"title": "Terms & Generate",
"description": "Review and accept terms to generate your license"
"title": "条款并生成",
"description": "审阅并接受条款生成您的许可证"
}
},
"alerts": {
"commercialUseDisclosure": {
"title": "Usage Disclosure",
"description": "Select the license tier that accurately reflects your intended use. The Personal License permits free use of the Software for individual, non-commercial or small-scale commercial activities with annual gross revenue under $100,000 USD. Any use beyond these limits — including use within a business, organization, or other revenue-generating environment — requires a valid Enterprise License and payment of the applicable licensing fee. All users, whether Personal or Enterprise, must comply with the Fossorial Commercial License Terms."
"title": "使用情况披露",
"description": "选择能准确反映您预定用途的许可等级。 个人许可证允许对个人、非商业性或小型商业活动免费使用软件,年收入毛额不到100 000美元。 超出这些限度的任何用途,包括在企业、组织内的用途。 或其他创收环境——需要有效的企业许可证和支付适用的许可证费用。 所有用户,不论是个人还是企业,都必须遵守寄养商业许可证条款。"
},
"trialPeriodInformation": {
"title": "Trial Period Information",
"description": "This License Key enables Enterprise features for a 7-day evaluation period. Continued access to Paid Features beyond the evaluation period requires activation under a valid Personal or Enterprise License. For Enterprise licensing, contact sales@fossorial.io."
"title": "试用期信息",
"description": "此许可证密钥使企业特性能够持续7天的评价。 在评估期过后继续访问付费功能需要在有效的个人或企业许可证下激活。对于企业许可证请联系Sales@pangolin.net。"
}
},
"form": {
"useCaseQuestion": "Are you using Pangolin for personal or business use?",
"firstName": "First Name",
"lastName": "Last Name",
"jobTitle": "Job Title",
"primaryUseQuestion": "What do you primarily plan to use Pangolin for?",
"industryQuestion": "What is your industry?",
"prospectiveUsersQuestion": "How many prospective users do you expect to have?",
"prospectiveSitesQuestion": "How many prospective sites (tunnels) do you expect to have?",
"companyName": "Company name",
"countryOfResidence": "Country of residence",
"stateProvinceRegion": "State / Province / Region",
"postalZipCode": "Postal / ZIP Code",
"companyWebsite": "Company website",
"companyPhoneNumber": "Company phone number",
"country": "Country",
"phoneNumberOptional": "Phone number (optional)",
"complianceConfirmation": "I confirm that I am in compliance with the Fossorial Commercial License and that reporting inaccurate information or misidentifying use of the product is a violation of the license."
"useCaseQuestion": "您是否正在使用 Pangolin 进行个人或商业使用?",
"firstName": "名字",
"lastName": "名字",
"jobTitle": "工作头衔:",
"primaryUseQuestion": "您主要计划使用 Pangolin 吗?",
"industryQuestion": "您的行业是什么?",
"prospectiveUsersQuestion": "您期望有多少预期用户?",
"prospectiveSitesQuestion": "您期望有多少站点(隧道)",
"companyName": "公司名称",
"countryOfResidence": "居住国",
"stateProvinceRegion": "州/省/地区",
"postalZipCode": "邮政编码",
"companyWebsite": "公司网站",
"companyPhoneNumber": "公司电话号码",
"country": "国家",
"phoneNumberOptional": "电话号码 (可选)",
"complianceConfirmation": "我确认我提供的资料是准确的,我遵守了寄养商业许可证。 报告不准确的信息或错误的产品使用是违反许可证的行为,可能导致您的密钥被撤销。"
},
"buttons": {
"close": "Close",
"previous": "Previous",
"next": "Next",
"generateLicenseKey": "Generate License Key"
"close": "关闭",
"previous": "上一个",
"next": "下一个",
"generateLicenseKey": "生成许可证密钥"
},
"toasts": {
"success": {
"title": "License key generated successfully",
"description": "Your license key has been generated and is ready to use."
"title": "许可证密钥生成成功",
"description": "您的许可证密钥已经生成并准备使用。"
},
"error": {
"title": "Failed to generate license key",
"description": "An error occurred while generating the license key."
"title": "生成许可证密钥失败",
"description": "生成许可证密钥时出错。"
}
}
},
"priority": "优先权",
"priorityDescription": "先评估更高优先级线路。优先级 = 100意味着自动排序(系统决定). 使用另一个数字强制执行手动优先级。",
"instanceName": "Instance Name",
"pathMatchModalTitle": "Configure Path Matching",
"pathMatchModalDescription": "Set up how incoming requests should be matched based on their path.",
"pathMatchType": "Match Type",
"pathMatchPrefix": "Prefix",
"pathMatchExact": "Exact",
"pathMatchRegex": "Regex",
"pathMatchValue": "Path Value",
"clear": "Clear",
"saveChanges": "Save Changes",
"instanceName": "实例名称",
"pathMatchModalTitle": "配置路径匹配",
"pathMatchModalDescription": "根据传入请求的路径设置匹配方式。",
"pathMatchType": "匹配类型",
"pathMatchPrefix": "前缀",
"pathMatchExact": "精准的",
"pathMatchRegex": "正则表达式",
"pathMatchValue": "路径值",
"clear": "清空",
"saveChanges": "保存更改",
"pathMatchRegexPlaceholder": "^/api/.*",
"pathMatchDefaultPlaceholder": "/path",
"pathMatchPrefixHelp": "Example: /api matches /api, /api/users, etc.",
"pathMatchExactHelp": "Example: /api matches only /api",
"pathMatchRegexHelp": "Example: ^/api/.* matches /api/anything",
"pathRewriteModalTitle": "Configure Path Rewriting",
"pathRewriteModalDescription": "Transform the matched path before forwarding to the target.",
"pathRewriteType": "Rewrite Type",
"pathRewritePrefixOption": "Prefix - Replace prefix",
"pathRewriteExactOption": "Exact - Replace entire path",
"pathRewriteRegexOption": "Regex - Pattern replacement",
"pathRewriteStripPrefixOption": "Strip Prefix - Remove prefix",
"pathRewriteValue": "Rewrite Value",
"pathMatchDefaultPlaceholder": "/路径",
"pathMatchPrefixHelp": "示例: /api 匹配/api, /api/users 等。",
"pathMatchExactHelp": "示例:/api 匹配仅限/api",
"pathMatchRegexHelp": "例如:^/api/.* 匹配/api/why",
"pathRewriteModalTitle": "配置路径重写",
"pathRewriteModalDescription": "在转发到目标之前变换匹配的路径。",
"pathRewriteType": "重写类型",
"pathRewritePrefixOption": "前缀 - 替换前缀",
"pathRewriteExactOption": "精确-替换整个路径",
"pathRewriteRegexOption": "正则表达式 - 替换模式",
"pathRewriteStripPrefixOption": "删除前缀 - 删除前缀",
"pathRewriteValue": "重写值",
"pathRewriteRegexPlaceholder": "/new/$1",
"pathRewriteDefaultPlaceholder": "/new-path",
"pathRewritePrefixHelp": "Replace the matched prefix with this value",
"pathRewriteExactHelp": "Replace the entire path with this value when the path matches exactly",
"pathRewriteRegexHelp": "Use capture groups like $1, $2 for replacement",
"pathRewriteStripPrefixHelp": "Leave empty to strip prefix or provide new prefix",
"pathRewritePrefix": "Prefix",
"pathRewriteExact": "Exact",
"pathRewriteRegex": "Regex",
"pathRewriteStrip": "Strip",
"pathRewriteStripLabel": "strip"
"pathRewritePrefixHelp": "用此值替换匹配的前缀",
"pathRewriteExactHelp": "当路径匹配时用此值替换整个路径",
"pathRewriteRegexHelp": "使用抓取组,如$1$2来替换",
"pathRewriteStripPrefixHelp": "留空以脱离前缀或提供新的前缀",
"pathRewritePrefix": "前缀",
"pathRewriteExact": "精准的",
"pathRewriteRegex": "正则表达式",
"pathRewriteStrip": "带状图",
"pathRewriteStripLabel": "条形图",
"sidebarEnableEnterpriseLicense": "启用企业许可证",
"cannotbeUndone": "无法撤消。",
"toConfirm": "确认",
"deleteClientQuestion": "您确定要从站点和组织中删除客户吗?",
"clientMessageRemove": "一旦删除,客户端将无法连接到站点。",
"sidebarLogs": "日志",
"request": "请求",
"logs": "日志",
"logsSettingsDescription": "监视从此orginization中收集的日志",
"searchLogs": "搜索日志...",
"action": "行 动",
"actor": "执行者",
"timestamp": "时间戳",
"accessLogs": "访问日志",
"exportCsv": "导出CSV",
"actorId": "执行者ID",
"allowedByRule": "根据规则允许",
"allowedNoAuth": "无认证",
"validAccessToken": "有效访问令牌",
"validHeaderAuth": "Valid header auth",
"validPincode": "Valid Pincode",
"validPassword": "有效密码",
"validEmail": "Valid email",
"validSSO": "Valid SSO",
"resourceBlocked": "资源被阻止",
"droppedByRule": "被规则删除",
"noSessions": "无会话",
"temporaryRequestToken": "临时请求令牌",
"noMoreAuthMethods": "No Valid Auth",
"ip": "IP",
"reason": "原因",
"requestLogs": "请求日志",
"host": "主机",
"location": "地点",
"actionLogs": "操作日志",
"sidebarLogsRequest": "请求日志",
"sidebarLogsAccess": "访问日志",
"sidebarLogsAction": "操作日志",
"logRetention": "日志保留",
"logRetentionDescription": "管理不同类型的日志为这个机构保留多长时间或禁用这些日志",
"requestLogsDescription": "查看此机构资源的详细请求日志",
"logRetentionRequestLabel": "请求日志保留",
"logRetentionRequestDescription": "保留请求日志的时间",
"logRetentionAccessLabel": "访问日志保留",
"logRetentionAccessDescription": "保留访问日志的时间",
"logRetentionActionLabel": "动作日志保留",
"logRetentionActionDescription": "保留操作日志的时间",
"logRetentionDisabled": "已禁用",
"logRetention3Days": "3 天",
"logRetention7Days": "7 天",
"logRetention14Days": "14 天",
"logRetention30Days": "30 天",
"logRetention90Days": "90 天",
"logRetentionForever": "永远的",
"actionLogsDescription": "查看此机构执行的操作历史",
"accessLogsDescription": "查看此机构资源的访问认证请求",
"licenseRequiredToUse": "需要企业许可证才能使用此功能。",
"certResolver": "证书解决器",
"certResolverDescription": "选择用于此资源的证书解析器。",
"selectCertResolver": "选择证书解析",
"enterCustomResolver": "输入自定义解析器",
"preferWildcardCert": "喜欢通配符证书",
"unverified": "未验证",
"domainSetting": "域设置",
"domainSettingDescription": "配置您的域的设置",
"preferWildcardCertDescription": "尝试生成通配符证书(需要正确配置的证书解析器)。",
"recordName": "记录名称",
"auto": "自动操作",
"TTL": "TTL",
"howToAddRecords": "如何添加记录",
"dnsRecord": "DNS记录",
"required": "必填",
"domainSettingsUpdated": "域设置更新成功",
"orgOrDomainIdMissing": "缺少机构或域 ID",
"loadingDNSRecords": "正在载入DNS记录...",
"olmUpdateAvailableInfo": "有最新版本的 Olm 可用。请更新到最新版本以获取最佳体验。",
"client": "客户端:",
"proxyProtocol": "代理协议设置",
"proxyProtocolDescription": "配置代理协议以保留TCP/UDP 服务的客户端IP地址。",
"enableProxyProtocol": "启用代理协议",
"proxyProtocolInfo": "为TCP/UDP 后端保留客户端IP地址",
"proxyProtocolVersion": "代理协议版本",
"version1": " 版本 1 (推荐)",
"version2": "版本 2",
"versionDescription": "版本 1 是基于文本和广泛支持的版本。版本 2 是二进制和更有效率但不那么兼容。",
"warning": "警告",
"proxyProtocolWarning": "您的后端应用程序必须配置为接受代理协议连接。如果您的后端不支持代理协议,启用这将会中断所有连接。 请务必从Traefik配置您的后端到信任代理协议标题。",
"restarting": "正在重启...",
"manual": "手动模式",
"messageSupport": "消息支持",
"supportNotAvailableTitle": "支持不可用",
"supportNotAvailableDescription": "支持现在不可用。您可以发送电子邮件到 support@pangolin.net。",
"supportRequestSentTitle": "支持请求已发送",
"supportRequestSentDescription": "您的消息已成功发送。",
"supportRequestFailedTitle": "发送请求失败",
"supportRequestFailedDescription": "发送您的支持请求时出错。",
"supportSubjectRequired": "主题是必填项",
"supportSubjectMaxLength": "主题必须是255个或更少的字符",
"supportMessageRequired": "消息是必填项",
"supportReplyTo": "回复给",
"supportSubject": "议 题",
"supportSubjectPlaceholder": "输入主题",
"supportMessage": "留言",
"supportMessagePlaceholder": "输入您的消息",
"supportSending": "正在发送...",
"supportSend": "发送",
"supportMessageSent": "消息已发送!",
"supportWillContact": "我们很快就会联系起来!",
"selectLogRetention": "选择保留日志",
"showColumns": "显示列",
"hideColumns": "隐藏列",
"columnVisibility": "列可见性",
"toggleColumn": "切换 {columnName} 列",
"allColumns": "全部列",
"defaultColumns": "默认列",
"customizeView": "自定义视图",
"viewOptions": "查看选项",
"selectAll": "选择所有",
"selectNone": "没有选择",
"selectedResources": "选定的资源",
"enableSelected": "启用选中的",
"disableSelected": "禁用选中的",
"checkSelectedStatus": "检查选中的状态",
"credentials": "全权证书",
"savecredentials": "保存证书",
"regeneratecredentials": "重置键",
"regenerateCredentials": "重新生成和保存您的凭据",
"generatedcredentials": "生成的证书",
"copyandsavethesecredentials": "复制和保存这些凭据",
"copyandsavethesecredentialsdescription": "这些凭据将不会在您离开此页面后再显示。现在安全地保存。",
"credentialsSaved": "凭据已保存",
"credentialsSavedDescription": "已成功生成和保存凭据。",
"credentialsSaveError": "证书保存错误",
"credentialsSaveErrorDescription": "更新和保存凭据时出错。",
"regenerateCredentialsWarning": "重新生成凭据将使以前的凭据失效。请确保更新使用这些凭据的任何配置。",
"confirm": "确认",
"regenerateCredentialsConfirmation": "您确定要重新生成凭据吗?",
"endpoint": "Endpoint",
"Id": "Id",
"SecretKey": "秘密密钥",
"featureDisabledTooltip": "此功能仅在企业计划中可用,需要许可证才能使用。",
"niceId": "好的 ID",
"niceIdUpdated": "好的 ID 已更新",
"niceIdUpdatedSuccessfully": "Nice ID 更新成功",
"niceIdUpdateError": "更新Nice ID时出错",
"niceIdUpdateErrorDescription": "更新Nice ID时出错。",
"niceIdCannotBeEmpty": "好的 ID 不能为空",
"enterIdentifier": "输入标识符",
"identifier": "Identifier"
}

2099
messages/zh-TW.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,15 @@
import type { NextConfig } from "next";
import createNextIntlPlugin from "next-intl/plugin";
const withNextIntl = createNextIntlPlugin();
/** @type {import("next").NextConfig} */
const nextConfig = {
const nextConfig: NextConfig = {
eslint: {
ignoreDuringBuilds: true
},
experimental: {
reactCompiler: true
},
output: "standalone"
};

11463
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -22,8 +22,8 @@
"set:oss": "echo 'export const build = \"oss\" as any;' > server/build.ts && cp tsconfig.oss.json tsconfig.json",
"set:saas": "echo 'export const build = \"saas\" as any;' > server/build.ts && cp tsconfig.saas.json tsconfig.json",
"set:enterprise": "echo 'export const build = \"enterprise\" as any;' > server/build.ts && cp tsconfig.enterprise.json tsconfig.json",
"set:sqlite": "echo 'export * from \"./sqlite\";' > server/db/index.ts",
"set:pg": "echo 'export * from \"./pg\";' > server/db/index.ts",
"set:sqlite": "echo 'export * from \"./sqlite\";\nexport const driver: \"pg\" | \"sqlite\" = \"sqlite\";' > server/db/index.ts",
"set:pg": "echo 'export * from \"./pg\";\nexport const driver: \"pg\" | \"sqlite\" = \"pg\";' > server/db/index.ts",
"next:build": "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: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",
@@ -32,41 +32,45 @@
"build:cli": "node esbuild.mjs -e cli/index.ts -o dist/cli.mjs"
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "^7.3.4",
"@aws-sdk/client-s3": "3.908.0",
"@asteasolutions/zod-to-openapi": "8.1.0",
"@aws-sdk/client-s3": "3.922.0",
"@faker-js/faker": "^10.1.0",
"@headlessui/react": "^2.2.9",
"@hookform/resolvers": "5.2.2",
"@monaco-editor/react": "^4.7.0",
"@node-rs/argon2": "^2.0.2",
"@oslojs/crypto": "1.0.1",
"@oslojs/encoding": "1.1.0",
"@radix-ui/react-avatar": "1.1.10",
"@radix-ui/react-avatar": "1.1.11",
"@radix-ui/react-checkbox": "1.3.3",
"@radix-ui/react-collapsible": "1.1.12",
"@radix-ui/react-dialog": "1.1.15",
"@radix-ui/react-dropdown-menu": "2.1.16",
"@radix-ui/react-icons": "1.3.2",
"@radix-ui/react-label": "2.1.7",
"@radix-ui/react-label": "2.1.8",
"@radix-ui/react-popover": "1.1.15",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-radio-group": "1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "2.2.6",
"@radix-ui/react-separator": "1.1.7",
"@radix-ui/react-slot": "1.2.3",
"@radix-ui/react-separator": "1.1.8",
"@radix-ui/react-slot": "1.2.4",
"@radix-ui/react-switch": "1.2.6",
"@radix-ui/react-tabs": "1.1.13",
"@radix-ui/react-toast": "1.2.15",
"@radix-ui/react-tooltip": "^1.2.8",
"@react-email/components": "0.5.6",
"@react-email/components": "0.5.7",
"@react-email/render": "^1.3.2",
"@react-email/tailwind": "1.2.2",
"@simplewebauthn/browser": "^13.2.2",
"@simplewebauthn/server": "^13.2.2",
"@tailwindcss/forms": "^0.5.10",
"@tanstack/react-query": "^5.90.6",
"@tanstack/react-table": "8.21.3",
"arctic": "^3.7.0",
"axios": "^1.12.2",
"axios": "^1.13.2",
"better-sqlite3": "11.7.0",
"canvas-confetti": "1.9.3",
"canvas-confetti": "1.9.4",
"class-variance-authority": "^0.7.1",
"clsx": "2.1.1",
"cmdk": "1.1.1",
@@ -75,89 +79,103 @@
"cookies": "^0.9.1",
"cors": "2.8.5",
"crypto-js": "^4.2.0",
"drizzle-orm": "0.44.6",
"eslint": "9.37.0",
"eslint-config-next": "15.5.4",
"d3": "^7.9.0",
"date-fns": "4.1.0",
"drizzle-orm": "0.44.7",
"eslint": "9.39.1",
"eslint-config-next": "16.0.3",
"express": "5.1.0",
"express-rate-limit": "8.1.0",
"glob": "11.0.3",
"express-rate-limit": "8.2.1",
"glob": "11.1.0",
"helmet": "8.1.0",
"http-errors": "2.0.0",
"i": "^0.3.7",
"input-otp": "1.4.2",
"ioredis": "5.8.1",
"ioredis": "5.8.2",
"jmespath": "^0.16.0",
"js-yaml": "4.1.0",
"js-yaml": "4.1.1",
"jsonwebtoken": "^9.0.2",
"lucide-react": "^0.545.0",
"maxmind": "5.0.0",
"lucide-react": "^0.552.0",
"maxmind": "5.0.1",
"moment": "2.30.1",
"next": "15.5.4",
"next-intl": "^4.3.12",
"next": "15.5.7",
"next-intl": "^4.4.0",
"next-themes": "0.4.6",
"nextjs-toploader": "^3.9.17",
"node-cache": "5.1.2",
"node-fetch": "3.3.2",
"nodemailer": "7.0.9",
"npm": "^11.6.2",
"nodemailer": "7.0.10",
"npm": "^11.6.4",
"nprogress": "^0.2.0",
"oslo": "1.2.1",
"pg": "^8.16.2",
"posthog-node": "^5.9.5",
"posthog-node": "^5.11.2",
"qrcode.react": "4.2.0",
"react": "19.2.0",
"react-dom": "19.2.0",
"react": "19.2.1",
"react-day-picker": "9.11.1",
"react-dom": "19.2.1",
"react-easy-sort": "^1.8.0",
"react-hook-form": "7.65.0",
"react-hook-form": "7.66.0",
"react-icons": "^5.5.0",
"rebuild": "0.1.2",
"recharts": "^2.15.4",
"reodotdev": "^1.0.0",
"resend": "^6.1.2",
"resend": "^6.4.2",
"semver": "^7.7.3",
"stripe": "18.2.1",
"swagger-ui-express": "^5.0.1",
"tailwind-merge": "3.3.1",
"topojson-client": "^3.1.0",
"tw-animate-css": "^1.3.8",
"uuid": "^13.0.0",
"vaul": "1.1.2",
"visionscarto-world-atlas": "^1.0.0",
"winston": "3.18.3",
"winston-daily-rotate-file": "5.0.0",
"ws": "8.18.3",
"yaml": "^2.8.1",
"yargs": "18.0.0",
"zod": "3.25.76",
"zod-validation-error": "3.5.2"
"zod": "4.1.12",
"zod-validation-error": "5.0.0"
},
"devDependencies": {
"@dotenvx/dotenvx": "1.51.0",
"@dotenvx/dotenvx": "1.51.1",
"@esbuild-plugins/tsconfig-paths": "0.1.2",
"@react-email/preview-server": "4.3.0",
"@tailwindcss/postcss": "^4.1.14",
"@react-email/preview-server": "4.3.2",
"@tailwindcss/postcss": "^4.1.17",
"@tanstack/react-query-devtools": "^5.90.2",
"@types/better-sqlite3": "7.6.12",
"@types/cookie-parser": "1.4.9",
"@types/cookie-parser": "1.4.10",
"@types/cors": "2.8.19",
"@types/crypto-js": "^4.2.2",
"@types/express": "5.0.3",
"@types/d3": "^7.4.3",
"@types/express": "5.0.5",
"@types/express-session": "^1.18.2",
"@types/jmespath": "^0.15.2",
"@types/js-yaml": "4.0.9",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "24.7.2",
"@types/nodemailer": "7.0.2",
"@types/pg": "8.15.5",
"@types/node": "24.10.1",
"@types/nodemailer": "7.0.3",
"@types/nprogress": "^0.2.3",
"@types/pg": "8.15.6",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.1",
"@types/react-dom": "19.2.2",
"@types/semver": "^7.7.1",
"@types/swagger-ui-express": "^4.1.8",
"@types/topojson-client": "^3.1.5",
"@types/ws": "8.18.1",
"@types/yargs": "17.0.33",
"drizzle-kit": "0.31.5",
"esbuild": "0.25.10",
"esbuild-node-externals": "1.18.0",
"@types/yargs": "17.0.34",
"babel-plugin-react-compiler": "^1.0.0",
"drizzle-kit": "0.31.6",
"esbuild": "0.27.0",
"esbuild-node-externals": "1.19.1",
"postcss": "^8",
"react-email": "4.3.0",
"react-email": "4.3.2",
"tailwindcss": "^4.1.4",
"tsc-alias": "1.8.16",
"tsx": "4.20.6",
"typescript": "^5",
"typescript-eslint": "^8.46.0"
"typescript-eslint": "^8.46.3"
},
"overrides": {
"emblor": {

View File

@@ -79,6 +79,12 @@ export function createApiServer() {
// Add request timeout middleware
apiServer.use(requestTimeoutMiddleware(60000)); // 60 second timeout
apiServer.use(logIncomingMiddleware);
if (build !== "oss") {
apiServer.use(`${prefix}/hybrid`, hybridRouter); // put before rate limiting because we will rate limit there separately because some of the routes are heavily used
}
if (!dev) {
apiServer.use(
rateLimit({
@@ -101,11 +107,7 @@ export function createApiServer() {
}
// API routes
apiServer.use(logIncomingMiddleware);
apiServer.use(prefix, unauthenticated);
if (build !== "oss") {
apiServer.use(`${prefix}/hybrid`, hybridRouter);
}
apiServer.use(prefix, authenticated);
// WebSocket routes

View File

@@ -19,6 +19,7 @@ export enum ActionsEnum {
getSite = "getSite",
listSites = "listSites",
updateSite = "updateSite",
reGenerateSecret = "reGenerateSecret",
createResource = "createResource",
deleteResource = "deleteResource",
getResource = "getResource",
@@ -81,7 +82,11 @@ export enum ActionsEnum {
listClients = "listClients",
getClient = "getClient",
listOrgDomains = "listOrgDomains",
getDomain = "getDomain",
updateOrgDomain = "updateOrgDomain",
getDNSRecords = "getDNSRecords",
createNewt = "createNewt",
createOlm = "createOlm",
createIdp = "createIdp",
updateIdp = "updateIdp",
deleteIdp = "deleteIdp",
@@ -116,7 +121,11 @@ export enum ActionsEnum {
updateLoginPage = "updateLoginPage",
getLoginPage = "getLoginPage",
deleteLoginPage = "deleteLoginPage",
applyBlueprint = "applyBlueprint"
listBlueprints = "listBlueprints",
getBlueprint = "getBlueprint",
applyBlueprint = "applyBlueprint",
viewLogs = "viewLogs",
exportLogs = "exportLogs"
}
export async function checkUserActionPermission(
@@ -193,7 +202,6 @@ export async function checkUserActionPermission(
.limit(1);
return roleActionPermission.length > 0;
} catch (error) {
console.error("Error checking user action permission:", error);
throw createHttpError(

View File

@@ -36,12 +36,15 @@ export async function createSession(
const sessionId = encodeHexLowerCase(
sha256(new TextEncoder().encode(token))
);
const session: Session = {
sessionId: sessionId,
userId,
expiresAt: new Date(Date.now() + SESSION_COOKIE_EXPIRES).getTime()
};
await db.insert(sessions).values(session);
const [session] = await db
.insert(sessions)
.values({
sessionId: sessionId,
userId,
expiresAt: new Date(Date.now() + SESSION_COOKIE_EXPIRES).getTime(),
issuedAt: new Date().getTime()
})
.returning();
return session;
}

View File

@@ -50,7 +50,8 @@ export async function createResourceSession(opts: {
doNotExtend: opts.doNotExtend || false,
accessTokenId: opts.accessTokenId || null,
isRequestToken: opts.isRequestToken || false,
userSessionId: opts.userSessionId || null
userSessionId: opts.userSessionId || null,
issuedAt: new Date().getTime()
};
await db.insert(resourceSessions).values(session);

View File

@@ -1,9 +1,43 @@
import { Request } from "express";
import { validateSessionToken, SESSION_COOKIE_NAME } from "@server/auth/sessions/app";
import {
validateSessionToken,
SESSION_COOKIE_NAME
} from "@server/auth/sessions/app";
export async function verifySession(req: Request) {
export async function verifySession(req: Request, forceLogin?: boolean) {
const res = await validateSessionToken(
req.cookies[SESSION_COOKIE_NAME] ?? "",
req.cookies[SESSION_COOKIE_NAME] ?? ""
);
if (!forceLogin) {
return res;
}
if (!res.session || !res.user) {
return {
session: null,
user: null
};
}
if (res.session.deviceAuthUsed) {
return {
session: null,
user: null
};
}
if (!res.session.issuedAt) {
return {
session: null,
user: null
};
}
const mins = 5 * 60 * 1000;
const now = new Date().getTime();
if (now - res.session.issuedAt > mins) {
return {
session: null,
user: null
};
}
return res;
}

View File

@@ -42,11 +42,17 @@ export async function getUniqueResourceName(orgId: string): Promise<string> {
}
const name = generateName();
const count = await db
.select({ niceId: resources.niceId, orgId: resources.orgId })
.from(resources)
.where(and(eq(resources.niceId, name), eq(resources.orgId, orgId)));
if (count.length === 0) {
const [resourceCount, siteResourceCount] = await Promise.all([
db
.select({ niceId: resources.niceId, orgId: resources.orgId })
.from(resources)
.where(and(eq(resources.niceId, name), eq(resources.orgId, orgId))),
db
.select({ niceId: siteResources.niceId, orgId: siteResources.orgId })
.from(siteResources)
.where(and(eq(siteResources.niceId, name), eq(siteResources.orgId, orgId)))
]);
if (resourceCount.length === 0 && siteResourceCount.length === 0) {
return name;
}
loops++;
@@ -61,11 +67,17 @@ export async function getUniqueSiteResourceName(orgId: string): Promise<string>
}
const name = generateName();
const count = await db
.select({ niceId: siteResources.niceId, orgId: siteResources.orgId })
.from(siteResources)
.where(and(eq(siteResources.niceId, name), eq(siteResources.orgId, orgId)));
if (count.length === 0) {
const [resourceCount, siteResourceCount] = await Promise.all([
db
.select({ niceId: resources.niceId, orgId: resources.orgId })
.from(resources)
.where(and(eq(resources.niceId, name), eq(resources.orgId, orgId))),
db
.select({ niceId: siteResources.niceId, orgId: siteResources.orgId })
.from(siteResources)
.where(and(eq(siteResources.niceId, name), eq(siteResources.orgId, orgId)))
]);
if (resourceCount.length === 0 && siteResourceCount.length === 0) {
return name;
}
loops++;

View File

@@ -13,9 +13,12 @@ function createDb() {
connection_string: process.env.POSTGRES_CONNECTION_STRING
};
if (process.env.POSTGRES_REPLICA_CONNECTION_STRINGS) {
const replicas = process.env.POSTGRES_REPLICA_CONNECTION_STRINGS.split(",").map((conn) => ({
connection_string: conn.trim()
}));
const replicas =
process.env.POSTGRES_REPLICA_CONNECTION_STRINGS.split(
","
).map((conn) => ({
connection_string: conn.trim()
}));
config.postgres.replicas = replicas;
}
} else {
@@ -40,28 +43,44 @@ function createDb() {
connectionString,
max: poolConfig?.max_connections || 20,
idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
connectionTimeoutMillis: poolConfig?.connection_timeout_ms || 5000,
connectionTimeoutMillis: poolConfig?.connection_timeout_ms || 5000
});
const replicas = [];
if (!replicaConnections.length) {
replicas.push(DrizzlePostgres(primaryPool));
replicas.push(
DrizzlePostgres(primaryPool, {
logger: process.env.NODE_ENV === "development"
})
);
} else {
for (const conn of replicaConnections) {
const replicaPool = new Pool({
connectionString: conn.connection_string,
max: poolConfig?.max_replica_connections || 20,
idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
connectionTimeoutMillis: poolConfig?.connection_timeout_ms || 5000,
connectionTimeoutMillis:
poolConfig?.connection_timeout_ms || 5000
});
replicas.push(DrizzlePostgres(replicaPool));
replicas.push(
DrizzlePostgres(replicaPool, {
logger: process.env.NODE_ENV === "development"
})
);
}
}
return withReplicas(DrizzlePostgres(primaryPool), replicas as any);
return withReplicas(
DrizzlePostgres(primaryPool, {
logger: process.env.QUERY_LOGGING === "true"
}),
replicas as any
);
}
export const db = createDb();
export default db;
export type Transaction = Parameters<Parameters<typeof db["transaction"]>[0]>[0];
export type Transaction = Parameters<
Parameters<(typeof db)["transaction"]>[0]
>[0];

View File

@@ -11,6 +11,7 @@ const runMigrations = async () => {
migrationsFolder: migrationsFolder
});
console.log("Migrations completed successfully.");
process.exit(0);
} catch (error) {
console.error("Error running migrations:", error);
process.exit(1);

View File

@@ -6,7 +6,8 @@ import {
integer,
bigint,
real,
text
text,
index
} from "drizzle-orm/pg-core";
import { InferSelectModel } from "drizzle-orm";
import { domains, orgs, targets, users, exitNodes, sessions } from "./schema";
@@ -166,6 +167,7 @@ export const remoteExitNodes = pgTable("remoteExitNode", {
secretHash: varchar("secretHash").notNull(),
dateCreated: varchar("dateCreated").notNull(),
version: varchar("version"),
secondaryVersion: varchar("secondaryVersion"), // This is to detect the new nodes after the transition to pangolin-node
exitNodeId: integer("exitNodeId").references(() => exitNodes.exitNodeId, {
onDelete: "cascade"
})
@@ -213,6 +215,43 @@ export const sessionTransferToken = pgTable("sessionTransferToken", {
expiresAt: bigint("expiresAt", { mode: "number" }).notNull()
});
export const actionAuditLog = pgTable("actionAuditLog", {
id: serial("id").primaryKey(),
timestamp: bigint("timestamp", { mode: "number" }).notNull(), // this is EPOCH time in seconds
orgId: varchar("orgId")
.notNull()
.references(() => orgs.orgId, { onDelete: "cascade" }),
actorType: varchar("actorType", { length: 50 }).notNull(),
actor: varchar("actor", { length: 255 }).notNull(),
actorId: varchar("actorId", { length: 255 }).notNull(),
action: varchar("action", { length: 100 }).notNull(),
metadata: text("metadata")
}, (table) => ([
index("idx_actionAuditLog_timestamp").on(table.timestamp),
index("idx_actionAuditLog_org_timestamp").on(table.orgId, table.timestamp)
]));
export const accessAuditLog = pgTable("accessAuditLog", {
id: serial("id").primaryKey(),
timestamp: bigint("timestamp", { mode: "number" }).notNull(), // this is EPOCH time in seconds
orgId: varchar("orgId")
.notNull()
.references(() => orgs.orgId, { onDelete: "cascade" }),
actorType: varchar("actorType", { length: 50 }),
actor: varchar("actor", { length: 255 }),
actorId: varchar("actorId", { length: 255 }),
resourceId: integer("resourceId"),
ip: varchar("ip", { length: 45 }),
type: varchar("type", { length: 100 }).notNull(),
action: boolean("action").notNull(),
location: text("location"),
userAgent: text("userAgent"),
metadata: text("metadata")
}, (table) => ([
index("idx_identityAuditLog_timestamp").on(table.timestamp),
index("idx_identityAuditLog_org_timestamp").on(table.orgId, table.timestamp)
]));
export type Limit = InferSelectModel<typeof limits>;
export type Account = InferSelectModel<typeof account>;
export type Certificate = InferSelectModel<typeof certificates>;
@@ -230,3 +269,5 @@ export type RemoteExitNodeSession = InferSelectModel<
>;
export type ExitNodeOrg = InferSelectModel<typeof exitNodeOrgs>;
export type LoginPage = InferSelectModel<typeof loginPage>;
export type ActionAuditLog = InferSelectModel<typeof actionAuditLog>;
export type AccessAuditLog = InferSelectModel<typeof accessAuditLog>;

View File

@@ -6,10 +6,12 @@ import {
integer,
bigint,
real,
text
text,
index
} from "drizzle-orm/pg-core";
import { InferSelectModel } from "drizzle-orm";
import { randomUUID } from "crypto";
import { alias } from "yargs";
export const domains = pgTable("domains", {
domainId: varchar("domainId").primaryKey(),
@@ -18,15 +20,41 @@ export const domains = pgTable("domains", {
type: varchar("type"), // "ns", "cname", "wildcard"
verified: boolean("verified").notNull().default(false),
failed: boolean("failed").notNull().default(false),
tries: integer("tries").notNull().default(0)
tries: integer("tries").notNull().default(0),
certResolver: varchar("certResolver"),
customCertResolver: varchar("customCertResolver"),
preferWildcardCert: boolean("preferWildcardCert")
});
export const dnsRecords = pgTable("dnsRecords", {
id: serial("id").primaryKey(),
domainId: varchar("domainId")
.notNull()
.references(() => domains.domainId, { onDelete: "cascade" }),
recordType: varchar("recordType").notNull(), // "NS" | "CNAME" | "A" | "TXT"
baseDomain: varchar("baseDomain"),
value: varchar("value").notNull(),
verified: boolean("verified").notNull().default(false)
});
export const orgs = pgTable("orgs", {
orgId: varchar("orgId").primaryKey(),
name: varchar("name").notNull(),
subnet: varchar("subnet"),
utilitySubnet: varchar("utilitySubnet"), // this is the subnet for utility addresses
createdAt: text("createdAt"),
settings: text("settings") // JSON blob of org-specific settings
requireTwoFactor: boolean("requireTwoFactor"),
maxSessionLengthHours: integer("maxSessionLengthHours"),
passwordExpiryDays: integer("passwordExpiryDays"),
settingsLogRetentionDaysRequest: integer("settingsLogRetentionDaysRequest") // where 0 = dont keep logs and -1 = keep forever
.notNull()
.default(7),
settingsLogRetentionDaysAccess: integer("settingsLogRetentionDaysAccess")
.notNull()
.default(0),
settingsLogRetentionDaysAction: integer("settingsLogRetentionDaysAction")
.notNull()
.default(0)
});
export const orgDomains = pgTable("orgDomains", {
@@ -62,8 +90,7 @@ export const sites = pgTable("sites", {
publicKey: varchar("publicKey"),
lastHolePunch: bigint("lastHolePunch", { mode: "number" }),
listenPort: integer("listenPort"),
dockerSocketEnabled: boolean("dockerSocketEnabled").notNull().default(true),
remoteSubnets: text("remoteSubnets") // comma-separated list of subnets that this site can access
dockerSocketEnabled: boolean("dockerSocketEnabled").notNull().default(true)
});
export const resources = pgTable("resources", {
@@ -100,9 +127,11 @@ export const resources = pgTable("resources", {
setHostHeader: varchar("setHostHeader"),
enableProxy: boolean("enableProxy").default(true),
skipToIdpId: integer("skipToIdpId").references(() => idp.idpId, {
onDelete: "cascade"
onDelete: "set null"
}),
headers: text("headers") // comma-separated list of headers to add to the request
headers: text("headers"), // comma-separated list of headers to add to the request
proxyProtocol: boolean("proxyProtocol").notNull().default(false),
proxyProtocolVersion: integer("proxyProtocolVersion").default(1)
});
export const targets = pgTable("targets", {
@@ -147,7 +176,8 @@ export const targetHealthCheck = pgTable("targetHealthCheck", {
hcFollowRedirects: boolean("hcFollowRedirects").default(true),
hcMethod: varchar("hcMethod").default("GET"),
hcStatus: integer("hcStatus"), // http code
hcHealth: text("hcHealth").default("unknown") // "unknown", "healthy", "unhealthy"
hcHealth: text("hcHealth").default("unknown"), // "unknown", "healthy", "unhealthy"
hcTlsServerName: text("hcTlsServerName"),
});
export const exitNodes = pgTable("exitNodes", {
@@ -176,11 +206,41 @@ export const siteResources = pgTable("siteResources", {
.references(() => orgs.orgId, { onDelete: "cascade" }),
niceId: varchar("niceId").notNull(),
name: varchar("name").notNull(),
protocol: varchar("protocol").notNull(),
proxyPort: integer("proxyPort").notNull(),
destinationPort: integer("destinationPort").notNull(),
destinationIp: varchar("destinationIp").notNull(),
enabled: boolean("enabled").notNull().default(true)
mode: varchar("mode").notNull(), // "host" | "cidr" | "port"
protocol: varchar("protocol"), // only for port mode
proxyPort: integer("proxyPort"), // only for port mode
destinationPort: integer("destinationPort"), // only for port mode
destination: varchar("destination").notNull(), // ip, cidr, hostname; validate against the mode
enabled: boolean("enabled").notNull().default(true),
alias: varchar("alias"),
aliasAddress: varchar("aliasAddress")
});
export const clientSiteResources = pgTable("clientSiteResources", {
clientId: integer("clientId")
.notNull()
.references(() => clients.clientId, { onDelete: "cascade" }),
siteResourceId: integer("siteResourceId")
.notNull()
.references(() => siteResources.siteResourceId, { onDelete: "cascade" })
});
export const roleSiteResources = pgTable("roleSiteResources", {
roleId: integer("roleId")
.notNull()
.references(() => roles.roleId, { onDelete: "cascade" }),
siteResourceId: integer("siteResourceId")
.notNull()
.references(() => siteResources.siteResourceId, { onDelete: "cascade" })
});
export const userSiteResources = pgTable("userSiteResources", {
userId: varchar("userId")
.notNull()
.references(() => users.userId, { onDelete: "cascade" }),
siteResourceId: integer("siteResourceId")
.notNull()
.references(() => siteResources.siteResourceId, { onDelete: "cascade" })
});
export const users = pgTable("user", {
@@ -200,7 +260,8 @@ export const users = pgTable("user", {
dateCreated: varchar("dateCreated").notNull(),
termsAcceptedTimestamp: varchar("termsAcceptedTimestamp"),
termsVersion: varchar("termsVersion"),
serverAdmin: boolean("serverAdmin").notNull().default(false)
serverAdmin: boolean("serverAdmin").notNull().default(false),
lastPasswordChange: bigint("lastPasswordChange", { mode: "number" })
});
export const newts = pgTable("newt", {
@@ -226,7 +287,9 @@ export const sessions = pgTable("session", {
userId: varchar("userId")
.notNull()
.references(() => users.userId, { onDelete: "cascade" }),
expiresAt: bigint("expiresAt", { mode: "number" }).notNull()
expiresAt: bigint("expiresAt", { mode: "number" }).notNull(),
issuedAt: bigint("issuedAt", { mode: "number" }),
deviceAuthUsed: boolean("deviceAuthUsed").notNull().default(false)
});
export const newtSessions = pgTable("newtSession", {
@@ -443,7 +506,8 @@ export const resourceSessions = pgTable("resourceSessions", {
{
onDelete: "cascade"
}
)
),
issuedAt: bigint("issuedAt", { mode: "number" })
});
export const resourceWhitelist = pgTable("resourceWhitelist", {
@@ -567,7 +631,7 @@ export const idpOrg = pgTable("idpOrg", {
});
export const clients = pgTable("clients", {
clientId: serial("id").primaryKey(),
clientId: serial("clientId").primaryKey(),
orgId: varchar("orgId")
.references(() => orgs.orgId, {
onDelete: "cascade"
@@ -576,6 +640,11 @@ export const clients = pgTable("clients", {
exitNodeId: integer("exitNode").references(() => exitNodes.exitNodeId, {
onDelete: "set null"
}),
userId: text("userId").references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade"
}),
olmId: text("olmId"), // to lock it to a specific olm optionally
name: varchar("name").notNull(),
pubKey: varchar("pubKey"),
subnet: varchar("subnet").notNull(),
@@ -590,23 +659,40 @@ export const clients = pgTable("clients", {
maxConnections: integer("maxConnections")
});
export const clientSites = pgTable("clientSites", {
clientId: integer("clientId")
.notNull()
.references(() => clients.clientId, { onDelete: "cascade" }),
siteId: integer("siteId")
.notNull()
.references(() => sites.siteId, { onDelete: "cascade" }),
isRelayed: boolean("isRelayed").notNull().default(false),
endpoint: varchar("endpoint")
});
export const clientSitesAssociationsCache = pgTable(
"clientSitesAssociationsCache",
{
clientId: integer("clientId") // not a foreign key here so after its deleted the rebuild function can delete it and send the message
.notNull(),
siteId: integer("siteId").notNull(),
isRelayed: boolean("isRelayed").notNull().default(false),
endpoint: varchar("endpoint"),
publicKey: varchar("publicKey") // this will act as the session's public key for hole punching so we can track when it changes
}
);
export const clientSiteResourcesAssociationsCache = pgTable(
"clientSiteResourcesAssociationsCache",
{
clientId: integer("clientId") // not a foreign key here so after its deleted the rebuild function can delete it and send the message
.notNull(),
siteResourceId: integer("siteResourceId").notNull()
}
);
export const olms = pgTable("olms", {
olmId: varchar("id").primaryKey(),
secretHash: varchar("secretHash").notNull(),
dateCreated: varchar("dateCreated").notNull(),
version: text("version"),
agent: text("agent"),
name: varchar("name"),
clientId: integer("clientId").references(() => clients.clientId, {
// we will switch this depending on the current org it wants to connect to
onDelete: "set null"
}),
userId: text("userId").references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade"
})
});
@@ -671,6 +757,72 @@ export const setupTokens = pgTable("setupTokens", {
dateUsed: varchar("dateUsed")
});
// Blueprint runs
export const blueprints = pgTable("blueprints", {
blueprintId: serial("blueprintId").primaryKey(),
orgId: text("orgId")
.references(() => orgs.orgId, {
onDelete: "cascade"
})
.notNull(),
name: varchar("name").notNull(),
source: varchar("source").notNull(),
createdAt: integer("createdAt").notNull(),
succeeded: boolean("succeeded").notNull(),
contents: text("contents").notNull(),
message: text("message")
});
export const requestAuditLog = pgTable(
"requestAuditLog",
{
id: serial("id").primaryKey(),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: text("orgId").references(() => orgs.orgId, {
onDelete: "cascade"
}),
action: boolean("action").notNull(),
reason: integer("reason").notNull(),
actorType: text("actorType"),
actor: text("actor"),
actorId: text("actorId"),
resourceId: integer("resourceId"),
ip: text("ip"),
location: text("location"),
userAgent: text("userAgent"),
metadata: text("metadata"),
headers: text("headers"), // JSON blob
query: text("query"), // JSON blob
originalRequestURL: text("originalRequestURL"),
scheme: text("scheme"),
host: text("host"),
path: text("path"),
method: text("method"),
tls: boolean("tls")
},
(table) => [
index("idx_requestAuditLog_timestamp").on(table.timestamp),
index("idx_requestAuditLog_org_timestamp").on(
table.orgId,
table.timestamp
)
]
);
export const deviceWebAuthCodes = pgTable("deviceWebAuthCodes", {
codeId: serial("codeId").primaryKey(),
code: text("code").notNull().unique(),
ip: text("ip"),
city: text("city"),
deviceName: text("deviceName"),
applicationName: text("applicationName").notNull(),
expiresAt: bigint("expiresAt", { mode: "number" }).notNull(),
createdAt: bigint("createdAt", { mode: "number" }).notNull(),
verified: boolean("verified").notNull().default(false),
userId: varchar("userId").references(() => users.userId, {
onDelete: "cascade"
})
});
export type Org = InferSelectModel<typeof orgs>;
export type User = InferSelectModel<typeof users>;
export type Site = InferSelectModel<typeof sites>;
@@ -711,7 +863,7 @@ export type ApiKey = InferSelectModel<typeof apiKeys>;
export type ApiKeyAction = InferSelectModel<typeof apiKeyActions>;
export type ApiKeyOrg = InferSelectModel<typeof apiKeyOrg>;
export type Client = InferSelectModel<typeof clients>;
export type ClientSite = InferSelectModel<typeof clientSites>;
export type ClientSite = InferSelectModel<typeof clientSitesAssociationsCache>;
export type Olm = InferSelectModel<typeof olms>;
export type OlmSession = InferSelectModel<typeof olmSessions>;
export type UserClient = InferSelectModel<typeof userClients>;
@@ -722,3 +874,9 @@ export type SetupToken = InferSelectModel<typeof setupTokens>;
export type HostMeta = InferSelectModel<typeof hostMeta>;
export type TargetHealthCheck = InferSelectModel<typeof targetHealthCheck>;
export type IdpOidcConfig = InferSelectModel<typeof idpOidcConfig>;
export type Blueprint = InferSelectModel<typeof blueprints>;
export type LicenseKey = InferSelectModel<typeof licenseKey>;
export type SecurityKey = InferSelectModel<typeof securityKeys>;
export type WebauthnChallenge = InferSelectModel<typeof webauthnChallenge>;
export type DeviceWebAuthCode = InferSelectModel<typeof deviceWebAuthCodes>;
export type RequestAuditLog = InferSelectModel<typeof requestAuditLog>;

View File

@@ -1,4 +1,4 @@
import { db, loginPage, LoginPage, loginPageOrg } from "@server/db";
import { db, loginPage, LoginPage, loginPageOrg, Org, orgs } from "@server/db";
import {
Resource,
ResourcePassword,
@@ -23,6 +23,7 @@ export type ResourceWithAuth = {
pincode: ResourcePincode | null;
password: ResourcePassword | null;
headerAuth: ResourceHeaderAuth | null;
org: Org;
};
export type UserSessionWithUser = {
@@ -51,6 +52,10 @@ export async function getResourceByDomain(
resourceHeaderAuth,
eq(resourceHeaderAuth.resourceId, resources.resourceId)
)
.innerJoin(
orgs,
eq(orgs.orgId, resources.orgId)
)
.where(eq(resources.fullDomain, domain))
.limit(1);
@@ -62,7 +67,8 @@ export async function getResourceByDomain(
resource: result.resources,
pincode: result.resourcePincode,
password: result.resourcePassword,
headerAuth: result.resourceHeaderAuth
headerAuth: result.resourceHeaderAuth,
org: result.orgs
};
}

View File

@@ -13,12 +13,16 @@ bootstrapVolume();
function createDb() {
const sqlite = new Database(location);
return DrizzleSqlite(sqlite, { schema });
return DrizzleSqlite(sqlite, {
schema
});
}
export const db = createDb();
export default db;
export type Transaction = Parameters<Parameters<typeof db["transaction"]>[0]>[0];
export type Transaction = Parameters<
Parameters<(typeof db)["transaction"]>[0]
>[0];
function checkFileExists(filePath: string): boolean {
try {

View File

@@ -2,10 +2,12 @@ import {
sqliteTable,
integer,
text,
real
real,
index
} from "drizzle-orm/sqlite-core";
import { InferSelectModel } from "drizzle-orm";
import { domains, orgs, targets, users, exitNodes, sessions } from "./schema";
import { metadata } from "@app/app/[orgId]/settings/layout";
export const certificates = sqliteTable("certificates", {
certId: integer("certId").primaryKey({ autoIncrement: true }),
@@ -160,6 +162,7 @@ export const remoteExitNodes = sqliteTable("remoteExitNode", {
secretHash: text("secretHash").notNull(),
dateCreated: text("dateCreated").notNull(),
version: text("version"),
secondaryVersion: text("secondaryVersion"), // This is to detect the new nodes after the transition to pangolin-node
exitNodeId: integer("exitNodeId").references(() => exitNodes.exitNodeId, {
onDelete: "cascade"
})
@@ -207,6 +210,43 @@ export const sessionTransferToken = sqliteTable("sessionTransferToken", {
expiresAt: integer("expiresAt").notNull()
});
export const actionAuditLog = sqliteTable("actionAuditLog", {
id: integer("id").primaryKey({ autoIncrement: true }),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: text("orgId")
.notNull()
.references(() => orgs.orgId, { onDelete: "cascade" }),
actorType: text("actorType").notNull(),
actor: text("actor").notNull(),
actorId: text("actorId").notNull(),
action: text("action").notNull(),
metadata: text("metadata")
}, (table) => ([
index("idx_actionAuditLog_timestamp").on(table.timestamp),
index("idx_actionAuditLog_org_timestamp").on(table.orgId, table.timestamp)
]));
export const accessAuditLog = sqliteTable("accessAuditLog", {
id: integer("id").primaryKey({ autoIncrement: true }),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: text("orgId")
.notNull()
.references(() => orgs.orgId, { onDelete: "cascade" }),
actorType: text("actorType"),
actor: text("actor"),
actorId: text("actorId"),
resourceId: integer("resourceId"),
ip: text("ip"),
location: text("location"),
type: text("type").notNull(),
action: integer("action", { mode: "boolean" }).notNull(),
userAgent: text("userAgent"),
metadata: text("metadata")
}, (table) => ([
index("idx_identityAuditLog_timestamp").on(table.timestamp),
index("idx_identityAuditLog_org_timestamp").on(table.orgId, table.timestamp)
]));
export type Limit = InferSelectModel<typeof limits>;
export type Account = InferSelectModel<typeof account>;
export type Certificate = InferSelectModel<typeof certificates>;
@@ -224,3 +264,5 @@ export type RemoteExitNodeSession = InferSelectModel<
>;
export type ExitNodeOrg = InferSelectModel<typeof exitNodeOrgs>;
export type LoginPage = InferSelectModel<typeof loginPage>;
export type ActionAuditLog = InferSelectModel<typeof actionAuditLog>;
export type AccessAuditLog = InferSelectModel<typeof accessAuditLog>;

View File

@@ -1,6 +1,7 @@
import { randomUUID } from "crypto";
import { InferSelectModel } from "drizzle-orm";
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
import { sqliteTable, text, integer, index } from "drizzle-orm/sqlite-core";
import { no } from "zod/v4/locales";
export const domains = sqliteTable("domains", {
domainId: text("domainId").primaryKey(),
@@ -11,15 +12,41 @@ export const domains = sqliteTable("domains", {
type: text("type"), // "ns", "cname", "wildcard"
verified: integer("verified", { mode: "boolean" }).notNull().default(false),
failed: integer("failed", { mode: "boolean" }).notNull().default(false),
tries: integer("tries").notNull().default(0)
tries: integer("tries").notNull().default(0),
certResolver: text("certResolver"),
preferWildcardCert: integer("preferWildcardCert", { mode: "boolean" })
});
export const dnsRecords = sqliteTable("dnsRecords", {
id: integer("id").primaryKey({ autoIncrement: true }),
domainId: text("domainId")
.notNull()
.references(() => domains.domainId, { onDelete: "cascade" }),
recordType: text("recordType").notNull(), // "NS" | "CNAME" | "A" | "TXT"
baseDomain: text("baseDomain"),
value: text("value").notNull(),
verified: integer("verified", { mode: "boolean" }).notNull().default(false)
});
export const orgs = sqliteTable("orgs", {
orgId: text("orgId").primaryKey(),
name: text("name").notNull(),
subnet: text("subnet"),
utilitySubnet: text("utilitySubnet"), // this is the subnet for utility addresses
createdAt: text("createdAt"),
settings: text("settings") // JSON blob of org-specific settings
requireTwoFactor: integer("requireTwoFactor", { mode: "boolean" }),
maxSessionLengthHours: integer("maxSessionLengthHours"), // hours
passwordExpiryDays: integer("passwordExpiryDays"), // days
settingsLogRetentionDaysRequest: integer("settingsLogRetentionDaysRequest") // where 0 = dont keep logs and -1 = keep forever
.notNull()
.default(7),
settingsLogRetentionDaysAccess: integer("settingsLogRetentionDaysAccess")
.notNull()
.default(0),
settingsLogRetentionDaysAction: integer("settingsLogRetentionDaysAction")
.notNull()
.default(0)
});
export const userDomains = sqliteTable("userDomains", {
@@ -68,8 +95,7 @@ export const sites = sqliteTable("sites", {
listenPort: integer("listenPort"),
dockerSocketEnabled: integer("dockerSocketEnabled", { mode: "boolean" })
.notNull()
.default(true),
remoteSubnets: text("remoteSubnets") // comma-separated list of subnets that this site can access
.default(true)
});
export const resources = sqliteTable("resources", {
@@ -112,9 +138,13 @@ export const resources = sqliteTable("resources", {
setHostHeader: text("setHostHeader"),
enableProxy: integer("enableProxy", { mode: "boolean" }).default(true),
skipToIdpId: integer("skipToIdpId").references(() => idp.idpId, {
onDelete: "cascade"
onDelete: "set null"
}),
headers: text("headers") // comma-separated list of headers to add to the request
headers: text("headers"), // comma-separated list of headers to add to the request
proxyProtocol: integer("proxyProtocol", { mode: "boolean" })
.notNull()
.default(false),
proxyProtocolVersion: integer("proxyProtocolVersion").default(1)
});
export const targets = sqliteTable("targets", {
@@ -142,11 +172,15 @@ export const targets = sqliteTable("targets", {
});
export const targetHealthCheck = sqliteTable("targetHealthCheck", {
targetHealthCheckId: integer("targetHealthCheckId").primaryKey({ autoIncrement: true }),
targetHealthCheckId: integer("targetHealthCheckId").primaryKey({
autoIncrement: true
}),
targetId: integer("targetId")
.notNull()
.references(() => targets.targetId, { onDelete: "cascade" }),
hcEnabled: integer("hcEnabled", { mode: "boolean" }).notNull().default(false),
hcEnabled: integer("hcEnabled", { mode: "boolean" })
.notNull()
.default(false),
hcPath: text("hcPath"),
hcScheme: text("hcScheme"),
hcMode: text("hcMode").default("http"),
@@ -156,10 +190,13 @@ export const targetHealthCheck = sqliteTable("targetHealthCheck", {
hcUnhealthyInterval: integer("hcUnhealthyInterval").default(30), // in seconds
hcTimeout: integer("hcTimeout").default(5), // in seconds
hcHeaders: text("hcHeaders"),
hcFollowRedirects: integer("hcFollowRedirects", { mode: "boolean" }).default(true),
hcFollowRedirects: integer("hcFollowRedirects", {
mode: "boolean"
}).default(true),
hcMethod: text("hcMethod").default("GET"),
hcStatus: integer("hcStatus"), // http code
hcHealth: text("hcHealth").default("unknown") // "unknown", "healthy", "unhealthy"
hcHealth: text("hcHealth").default("unknown"), // "unknown", "healthy", "unhealthy"
hcTlsServerName: text("hcTlsServerName"),
});
export const exitNodes = sqliteTable("exitNodes", {
@@ -190,11 +227,41 @@ export const siteResources = sqliteTable("siteResources", {
.references(() => orgs.orgId, { onDelete: "cascade" }),
niceId: text("niceId").notNull(),
name: text("name").notNull(),
protocol: text("protocol").notNull(),
proxyPort: integer("proxyPort").notNull(),
destinationPort: integer("destinationPort").notNull(),
destinationIp: text("destinationIp").notNull(),
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true)
mode: text("mode").notNull(), // "host" | "cidr" | "port"
protocol: text("protocol"), // only for port mode
proxyPort: integer("proxyPort"), // only for port mode
destinationPort: integer("destinationPort"), // only for port mode
destination: text("destination").notNull(), // ip, cidr, hostname
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
alias: text("alias"),
aliasAddress: text("aliasAddress")
});
export const clientSiteResources = sqliteTable("clientSiteResources", {
clientId: integer("clientId")
.notNull()
.references(() => clients.clientId, { onDelete: "cascade" }),
siteResourceId: integer("siteResourceId")
.notNull()
.references(() => siteResources.siteResourceId, { onDelete: "cascade" })
});
export const roleSiteResources = sqliteTable("roleSiteResources", {
roleId: integer("roleId")
.notNull()
.references(() => roles.roleId, { onDelete: "cascade" }),
siteResourceId: integer("siteResourceId")
.notNull()
.references(() => siteResources.siteResourceId, { onDelete: "cascade" })
});
export const userSiteResources = sqliteTable("userSiteResources", {
userId: text("userId")
.notNull()
.references(() => users.userId, { onDelete: "cascade" }),
siteResourceId: integer("siteResourceId")
.notNull()
.references(() => siteResources.siteResourceId, { onDelete: "cascade" })
});
export const users = sqliteTable("user", {
@@ -222,7 +289,8 @@ export const users = sqliteTable("user", {
termsVersion: text("termsVersion"),
serverAdmin: integer("serverAdmin", { mode: "boolean" })
.notNull()
.default(false)
.default(false),
lastPasswordChange: integer("lastPasswordChange")
});
export const securityKeys = sqliteTable("webauthnCredentials", {
@@ -269,7 +337,7 @@ export const newts = sqliteTable("newt", {
});
export const clients = sqliteTable("clients", {
clientId: integer("id").primaryKey({ autoIncrement: true }),
clientId: integer("clientId").primaryKey({ autoIncrement: true }),
orgId: text("orgId")
.references(() => orgs.orgId, {
onDelete: "cascade"
@@ -278,8 +346,14 @@ export const clients = sqliteTable("clients", {
exitNodeId: integer("exitNode").references(() => exitNodes.exitNodeId, {
onDelete: "set null"
}),
userId: text("userId").references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade"
}),
name: text("name").notNull(),
pubKey: text("pubKey"),
olmId: text("olmId"), // to lock it to a specific olm optionally
subnet: text("subnet").notNull(),
megabytesIn: integer("bytesIn"),
megabytesOut: integer("bytesOut"),
@@ -291,25 +365,42 @@ export const clients = sqliteTable("clients", {
lastHolePunch: integer("lastHolePunch")
});
export const clientSites = sqliteTable("clientSites", {
clientId: integer("clientId")
.notNull()
.references(() => clients.clientId, { onDelete: "cascade" }),
siteId: integer("siteId")
.notNull()
.references(() => sites.siteId, { onDelete: "cascade" }),
isRelayed: integer("isRelayed", { mode: "boolean" })
.notNull()
.default(false),
endpoint: text("endpoint")
});
export const clientSitesAssociationsCache = sqliteTable(
"clientSitesAssociationsCache",
{
clientId: integer("clientId") // not a foreign key here so after its deleted the rebuild function can delete it and send the message
.notNull(),
siteId: integer("siteId").notNull(),
isRelayed: integer("isRelayed", { mode: "boolean" })
.notNull()
.default(false),
endpoint: text("endpoint"),
publicKey: text("publicKey") // this will act as the session's public key for hole punching so we can track when it changes
}
);
export const clientSiteResourcesAssociationsCache = sqliteTable(
"clientSiteResourcesAssociationsCache",
{
clientId: integer("clientId") // not a foreign key here so after its deleted the rebuild function can delete it and send the message
.notNull(),
siteResourceId: integer("siteResourceId").notNull()
}
);
export const olms = sqliteTable("olms", {
olmId: text("id").primaryKey(),
secretHash: text("secretHash").notNull(),
dateCreated: text("dateCreated").notNull(),
version: text("version"),
agent: text("agent"),
name: text("name"),
clientId: integer("clientId").references(() => clients.clientId, {
// we will switch this depending on the current org it wants to connect to
onDelete: "set null"
}),
userId: text("userId").references(() => users.userId, {
// optionally tied to a user and in this case delete when the user deletes
onDelete: "cascade"
})
});
@@ -327,7 +418,11 @@ export const sessions = sqliteTable("session", {
userId: text("userId")
.notNull()
.references(() => users.userId, { onDelete: "cascade" }),
expiresAt: integer("expiresAt").notNull()
expiresAt: integer("expiresAt").notNull(),
issuedAt: integer("issuedAt"),
deviceAuthUsed: integer("deviceAuthUsed", { mode: "boolean" })
.notNull()
.default(false)
});
export const newtSessions = sqliteTable("newtSession", {
@@ -577,7 +672,8 @@ export const resourceSessions = sqliteTable("resourceSessions", {
{
onDelete: "cascade"
}
)
),
issuedAt: integer("issuedAt")
});
export const resourceWhitelist = sqliteTable("resourceWhitelist", {
@@ -710,6 +806,74 @@ export const idpOrg = sqliteTable("idpOrg", {
orgMapping: text("orgMapping")
});
// Blueprint runs
export const blueprints = sqliteTable("blueprints", {
blueprintId: integer("blueprintId").primaryKey({
autoIncrement: true
}),
orgId: text("orgId")
.references(() => orgs.orgId, {
onDelete: "cascade"
})
.notNull(),
name: text("name").notNull(),
source: text("source").notNull(),
createdAt: integer("createdAt").notNull(),
succeeded: integer("succeeded", { mode: "boolean" }).notNull(),
contents: text("contents").notNull(),
message: text("message")
});
export const requestAuditLog = sqliteTable(
"requestAuditLog",
{
id: integer("id").primaryKey({ autoIncrement: true }),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: text("orgId").references(() => orgs.orgId, {
onDelete: "cascade"
}),
action: integer("action", { mode: "boolean" }).notNull(),
reason: integer("reason").notNull(),
actorType: text("actorType"),
actor: text("actor"),
actorId: text("actorId"),
resourceId: integer("resourceId"),
ip: text("ip"),
location: text("location"),
userAgent: text("userAgent"),
metadata: text("metadata"),
headers: text("headers"), // JSON blob
query: text("query"), // JSON blob
originalRequestURL: text("originalRequestURL"),
scheme: text("scheme"),
host: text("host"),
path: text("path"),
method: text("method"),
tls: integer("tls", { mode: "boolean" })
},
(table) => [
index("idx_requestAuditLog_timestamp").on(table.timestamp),
index("idx_requestAuditLog_org_timestamp").on(
table.orgId,
table.timestamp
)
]
);
export const deviceWebAuthCodes = sqliteTable("deviceWebAuthCodes", {
codeId: integer("codeId").primaryKey({ autoIncrement: true }),
code: text("code").notNull().unique(),
ip: text("ip"),
city: text("city"),
deviceName: text("deviceName"),
applicationName: text("applicationName").notNull(),
expiresAt: integer("expiresAt").notNull(),
createdAt: integer("createdAt").notNull(),
verified: integer("verified", { mode: "boolean" }).notNull().default(false),
userId: text("userId").references(() => users.userId, {
onDelete: "cascade"
})
});
export type Org = InferSelectModel<typeof orgs>;
export type User = InferSelectModel<typeof users>;
export type Site = InferSelectModel<typeof sites>;
@@ -746,8 +910,9 @@ export type ResourceWhitelist = InferSelectModel<typeof resourceWhitelist>;
export type VersionMigration = InferSelectModel<typeof versionMigrations>;
export type ResourceRule = InferSelectModel<typeof resourceRules>;
export type Domain = InferSelectModel<typeof domains>;
export type DnsRecord = InferSelectModel<typeof dnsRecords>;
export type Client = InferSelectModel<typeof clients>;
export type ClientSite = InferSelectModel<typeof clientSites>;
export type ClientSite = InferSelectModel<typeof clientSitesAssociationsCache>;
export type RoleClient = InferSelectModel<typeof roleClients>;
export type UserClient = InferSelectModel<typeof userClients>;
export type SupporterKey = InferSelectModel<typeof supporterKey>;
@@ -761,3 +926,9 @@ export type SetupToken = InferSelectModel<typeof setupTokens>;
export type HostMeta = InferSelectModel<typeof hostMeta>;
export type TargetHealthCheck = InferSelectModel<typeof targetHealthCheck>;
export type IdpOidcConfig = InferSelectModel<typeof idpOidcConfig>;
export type Blueprint = InferSelectModel<typeof blueprints>;
export type LicenseKey = InferSelectModel<typeof licenseKey>;
export type SecurityKey = InferSelectModel<typeof securityKeys>;
export type WebauthnChallenge = InferSelectModel<typeof webauthnChallenge>;
export type RequestAuditLog = InferSelectModel<typeof requestAuditLog>;
export type DeviceWebAuthCode = InferSelectModel<typeof deviceWebAuthCodes>;

View File

@@ -0,0 +1,56 @@
import React from "react";
import { Body, Head, Html, Preview, Tailwind } from "@react-email/components";
import { themeColors } from "./lib/theme";
import {
EmailContainer,
EmailGreeting,
EmailLetterHead,
EmailText
} from "./components/Email";
interface SupportEmailProps {
email: string;
username: string;
subject: string;
body: string;
}
export const SupportEmail = ({
username,
email,
body,
subject
}: SupportEmailProps) => {
const previewText = subject;
return (
<Html>
<Head />
<Preview>{previewText}</Preview>
<Tailwind config={themeColors}>
<Body className="font-sans bg-gray-50">
<EmailContainer>
<EmailLetterHead />
<EmailGreeting>Hi support,</EmailGreeting>
<EmailText>
You have received a new support request from{" "}
<strong>{username}</strong> ({email}).
</EmailText>
<EmailText>
<strong>Subject:</strong> {subject}
</EmailText>
<EmailText>
<strong>Message:</strong> {body}
</EmailText>
</EmailContainer>
</Body>
</Tailwind>
</Html>
);
};
export default SupportEmail;

View File

@@ -88,7 +88,7 @@ export const WelcomeQuickStart = ({
To learn how to use Newt, including more
installation methods, visit the{" "}
<a
href="https://docs.digpangolin.com/manage/sites/install-site"
href="https://docs.pangolin.net/manage/sites/install-site"
className="underline"
>
docs

View File

@@ -89,7 +89,7 @@ export function EmailFooter({ children }: { children: React.ReactNode }) {
<p className="text-xs text-gray-400 mt-4">
For any questions or support, please contact us at:
<br />
support@fossorial.io
support@pangolin.net
</p>
<p className="text-xs text-gray-300 text-center mt-4">
&copy; {new Date().getFullYear()} Fossorial, Inc. All

View File

@@ -5,21 +5,24 @@ import { runSetupFunctions } from "./setup";
import { createApiServer } from "./apiServer";
import { createNextServer } from "./nextServer";
import { createInternalServer } from "./internalServer";
import { createIntegrationApiServer } from "./integrationApiServer";
import {
ApiKey,
ApiKeyOrg,
RemoteExitNode,
Session,
SiteResource,
User,
UserOrg
} from "@server/db";
import { createIntegrationApiServer } from "./integrationApiServer";
import config from "@server/lib/config";
import { setHostMeta } from "@server/lib/hostMeta";
import { initTelemetryClient } from "./lib/telemetry.js";
import { TraefikConfigManager } from "./lib/traefik/TraefikConfigManager.js";
import { initTelemetryClient } from "@server/lib/telemetry";
import { TraefikConfigManager } from "@server/lib/traefik/TraefikConfigManager";
import { initCleanup } from "#dynamic/cleanup";
import license from "#dynamic/license/license";
import { initLogCleanupInterval } from "@server/lib/cleanupLogs";
import { fetchServerIp } from "@server/lib/serverIpService";
async function startServers() {
await setHostMeta();
@@ -31,14 +34,17 @@ async function startServers() {
await runSetupFunctions();
await fetchServerIp();
initTelemetryClient();
initLogCleanupInterval();
// Start all servers
const apiServer = createApiServer();
const internalServer = createInternalServer();
let nextServer;
nextServer = await createNextServer();
const nextServer = await createNextServer();
if (config.getRawConfig().traefik.file_mode) {
const monitor = new TraefikConfigManager();
await monitor.start();
@@ -72,6 +78,8 @@ declare global {
userOrgId?: string;
userOrgIds?: string[];
remoteExitNode?: RemoteExitNode;
siteResource?: SiteResource;
orgPolicyAllowed?: boolean;
}
}
}

View File

@@ -1,8 +1,8 @@
export async function getOrgTierData(
orgId: string
): Promise<{ tier: string | null; active: boolean }> {
let tier = null;
let active = false;
const tier = null;
const active = false;
return { tier, active };
}

View File

@@ -1,5 +1,4 @@
import { eq, sql, and } from "drizzle-orm";
import NodeCache from "node-cache";
import { v4 as uuidv4 } from "uuid";
import { PutObjectCommand } from "@aws-sdk/client-s3";
import * as fs from "fs/promises";
@@ -20,6 +19,7 @@ import logger from "@server/logger";
import { sendToClient } from "#dynamic/routers/ws";
import { build } from "@server/build";
import { s3Client } from "@server/lib/s3";
import cache from "@server/lib/cache";
interface StripeEvent {
identifier?: string;
@@ -43,7 +43,6 @@ export function noop() {
}
export class UsageService {
private cache: NodeCache;
private bucketName: string | undefined;
private currentEventFile: string | null = null;
private currentFileStartTime: number = 0;
@@ -51,7 +50,6 @@ export class UsageService {
private uploadingFiles: Set<string> = new Set();
constructor() {
this.cache = new NodeCache({ stdTTL: 300 }); // 5 minute TTL
if (noop()) {
return;
}
@@ -399,7 +397,7 @@ export class UsageService {
featureId: FeatureId
): Promise<string | null> {
const cacheKey = `customer_${orgId}_${featureId}`;
const cached = this.cache.get<string>(cacheKey);
const cached = cache.get<string>(cacheKey);
if (cached) {
return cached;
@@ -422,7 +420,7 @@ export class UsageService {
const customerId = customer.customerId;
// Cache the result
this.cache.set(cacheKey, customerId);
cache.set(cacheKey, customerId, 300); // 5 minute TTL
return customerId;
} catch (error) {
@@ -612,7 +610,8 @@ export class UsageService {
public async getUsage(
orgId: string,
featureId: FeatureId
featureId: FeatureId,
trx: Transaction | typeof db = db
): Promise<Usage | null> {
if (noop()) {
return null;
@@ -621,7 +620,7 @@ export class UsageService {
const usageId = `${orgId}-${featureId}`;
try {
const [result] = await db
const [result] = await trx
.select()
.from(usage)
.where(eq(usage.usageId, usageId))
@@ -635,7 +634,7 @@ export class UsageService {
const meterId = getFeatureMeterId(featureId);
try {
const [newUsage] = await db
const [newUsage] = await trx
.insert(usage)
.values({
usageId,
@@ -652,7 +651,7 @@ export class UsageService {
return newUsage;
} else {
// Record was created by another process, fetch it
const [existingUsage] = await db
const [existingUsage] = await trx
.select()
.from(usage)
.where(eq(usage.usageId, usageId))
@@ -665,7 +664,7 @@ export class UsageService {
`Insert failed for ${orgId}/${featureId}, attempting to fetch existing record:`,
insertError
);
const [existingUsage] = await db
const [existingUsage] = await trx
.select()
.from(usage)
.where(eq(usage.usageId, usageId))
@@ -699,10 +698,6 @@ export class UsageService {
await this.uploadFileToS3();
}
public clearCache(): void {
this.cache.flushAll();
}
/**
* Scan the events directory for files older than 1 minute and upload them if not empty.
*/
@@ -812,7 +807,8 @@ export class UsageService {
orgId: string,
kickSites = false,
featureId?: FeatureId,
usage?: Usage
usage?: Usage,
trx: Transaction | typeof db = db
): Promise<boolean> {
if (noop()) {
return false;
@@ -825,7 +821,7 @@ export class UsageService {
let orgLimits: Limit[] = [];
if (featureId) {
// Get all limits set for this organization
orgLimits = await db
orgLimits = await trx
.select()
.from(limits)
.where(
@@ -836,7 +832,7 @@ export class UsageService {
);
} else {
// Get all limits set for this organization
orgLimits = await db
orgLimits = await trx
.select()
.from(limits)
.where(eq(limits.orgId, orgId));
@@ -855,7 +851,8 @@ export class UsageService {
} else {
currentUsage = await this.getUsage(
orgId,
limit.featureId as FeatureId
limit.featureId as FeatureId,
trx
);
}
@@ -890,7 +887,7 @@ export class UsageService {
);
// Get all sites for this organization
const orgSites = await db
const orgSites = await trx
.select()
.from(sites)
.where(eq(sites.orgId, orgId));
@@ -902,7 +899,7 @@ export class UsageService {
// Send termination messages to newt sites
for (const site of orgSites) {
if (site.type === "newt") {
const [newt] = await db
const [newt] = await trx
.select()
.from(newts)
.where(eq(newts.siteId, site.siteId))
@@ -917,7 +914,7 @@ export class UsageService {
};
// Don't await to prevent blocking
sendToClient(newt.newtId, payload).catch(
await sendToClient(newt.newtId, payload).catch(
(error: any) => {
logger.error(
`Failed to send termination message to newt ${newt.newtId}:`,

View File

@@ -1,22 +1,35 @@
import { db, newts, Target } from "@server/db";
import { db, newts, blueprints, Blueprint } from "@server/db";
import { Config, ConfigSchema } from "./types";
import { ProxyResourcesResults, updateProxyResources } from "./proxyResources";
import { fromError } from "zod-validation-error";
import logger from "@server/logger";
import { resources, targets, sites } from "@server/db";
import { eq, and, asc, or, ne, count, isNotNull } from "drizzle-orm";
import { sites } from "@server/db";
import { eq, and, isNotNull } from "drizzle-orm";
import { addTargets as addProxyTargets } from "@server/routers/newt/targets";
import { addTargets as addClientTargets } from "@server/routers/client/targets";
import {
ClientResourcesResults,
updateClientResources
} from "./clientResources";
import { BlueprintSource } from "@server/routers/blueprints/types";
import { stringify as stringifyYaml } from "yaml";
import { faker } from "@faker-js/faker";
export async function applyBlueprint(
orgId: string,
configData: unknown,
siteId?: number
): Promise<void> {
type ApplyBlueprintArgs = {
orgId: string;
configData: unknown;
name?: string;
siteId?: number;
source?: BlueprintSource;
};
export async function applyBlueprint({
orgId,
configData,
siteId,
name,
source = "API"
}: ApplyBlueprintArgs): Promise<Blueprint> {
// Validate the input data
const validationResult = ConfigSchema.safeParse(configData);
if (!validationResult.success) {
@@ -24,6 +37,9 @@ export async function applyBlueprint(
}
const config: Config = validationResult.data;
let blueprintSucceeded: boolean = false;
let blueprintMessage: string;
let error: any | null = null;
try {
let proxyResourcesResults: ProxyResourcesResults = [];
@@ -106,24 +122,54 @@ export async function applyBlueprint(
)
.limit(1);
if (site) {
logger.debug(
`Updating client resource ${result.resource.siteResourceId} on site ${site.sites.siteId}`
);
logger.debug(
`Updating client resource ${result.resource.siteResourceId} on site ${site.sites.siteId}`
);
await addClientTargets(
site.newt.newtId,
result.resource.destinationIp,
result.resource.destinationPort,
result.resource.protocol,
result.resource.proxyPort
);
}
// await addClientTargets(
// site.newt.newtId,
// result.resource.destination,
// result.resource.destinationPort,
// result.resource.protocol,
// result.resource.proxyPort
// );
}
} catch (error) {
logger.error(`Failed to update database from config: ${error}`);
throw error;
blueprintSucceeded = true;
blueprintMessage = "Blueprint applied successfully";
} catch (err) {
blueprintSucceeded = false;
blueprintMessage = `Blueprint applied with errors: ${err}`;
logger.error(blueprintMessage);
error = err;
}
let blueprint: Blueprint | null = null;
await db.transaction(async (trx) => {
const newBlueprint = await trx
.insert(blueprints)
.values({
orgId,
name:
name ??
`${faker.word.adjective()} ${faker.word.adjective()} ${faker.word.noun()}`,
contents: stringifyYaml(configData),
createdAt: Math.floor(Date.now() / 1000),
succeeded: blueprintSucceeded,
message: blueprintMessage,
source
})
.returning();
blueprint = newBlueprint[0];
});
if (!blueprint || (source !== "UI" && !blueprintSucceeded)) {
// ^^^^^^^^^^^^^^^ The UI considers a failed blueprint as a valid response
throw error ?? "Unknown Server Error";
}
return blueprint;
}
// await updateDatabaseFromConfig("org_i21aifypnlyxur2", {
@@ -139,8 +185,8 @@ export async function applyBlueprint(
// password: "sadfasdfadsf",
// "sso-enabled": true,
// "sso-roles": ["Member"],
// "sso-users": ["owen@fossorial.io"],
// "whitelist-users": ["owen@fossorial.io"]
// "sso-users": ["owen@pangolin.net"],
// "whitelist-users": ["owen@pangolin.net"]
// },
// targets: [
// {

View File

@@ -29,15 +29,29 @@ export async function applyNewtDockerBlueprint(
logger.debug(`Received Docker blueprint: ${JSON.stringify(blueprint)}`);
// make sure this is not an empty object
if (isEmptyObject(blueprint)) {
return;
}
if (isEmptyObject(blueprint["proxy-resources"]) && isEmptyObject(blueprint["client-resources"])) {
return;
}
// Update the blueprint in the database
await applyBlueprint(site.orgId, blueprint, site.siteId);
await applyBlueprint({
orgId: site.orgId,
configData: blueprint,
siteId: site.siteId,
source: "NEWT"
});
} catch (error) {
logger.error(`Failed to update database from config: ${error}`);
await sendToClient(newtId, {
type: "newt/blueprint/results",
data: {
success: false,
message: `Failed to update database from config: ${error}`
message: `Failed to apply blueprint from config: ${error}`
}
});
return;
@@ -51,3 +65,10 @@ export async function applyNewtDockerBlueprint(
}
});
}
function isEmptyObject(obj: any) {
if (obj === null || obj === undefined) {
return true;
}
return Object.keys(obj).length === 0 && obj.constructor === Object;
}

View File

@@ -75,8 +75,9 @@ export async function updateClientResources(
.set({
name: resourceData.name || resourceNiceId,
siteId: site.siteId,
mode: "port",
proxyPort: resourceData["proxy-port"]!,
destinationIp: resourceData.hostname,
destination: resourceData.hostname,
destinationPort: resourceData["internal-port"],
protocol: resourceData.protocol
})
@@ -98,8 +99,9 @@ export async function updateClientResources(
siteId: site.siteId,
niceId: resourceNiceId,
name: resourceData.name || resourceNiceId,
mode: "port",
proxyPort: resourceData["proxy-port"]!,
destinationIp: resourceData.hostname,
destination: resourceData.hostname,
destinationPort: resourceData["internal-port"],
protocol: resourceData.protocol
})

View File

@@ -87,8 +87,8 @@ export function convertValue(value: string): any {
// "resources.resource-nice-id.auth.password": "sadfasdfadsf",
// "resources.resource-nice-id.auth.sso-enabled": "true",
// "resources.resource-nice-id.auth.sso-roles[0]": "Member",
// "resources.resource-nice-id.auth.sso-users[0]": "owen@fossorial.io",
// "resources.resource-nice-id.auth.whitelist-users[0]": "owen@fossorial.io",
// "resources.resource-nice-id.auth.sso-users[0]": "owen@pangolin.net",
// "resources.resource-nice-id.auth.whitelist-users[0]": "owen@pangolin.net",
// "resources.resource-nice-id.targets[0].hostname": "localhost",
// "resources.resource-nice-id.targets[0].method": "http",
// "resources.resource-nice-id.targets[0].port": "8000",

View File

@@ -30,6 +30,7 @@ import { pickPort } from "@server/routers/target/helpers";
import { resourcePassword } from "@server/db";
import { hashPassword } from "@server/auth/password";
import { isValidCIDR, isValidIP, isValidUrlGlobPattern } from "../validators";
import { get } from "http";
export type ProxyResourcesResults = {
proxyResource: Resource;
@@ -114,7 +115,12 @@ export async function updateProxyResources(
internalPort: internalPortToCreate,
path: targetData.path,
pathMatchType: targetData["path-match"],
rewritePath: targetData.rewritePath,
rewritePath:
targetData.rewritePath ||
targetData["rewrite-path"] ||
(targetData["rewrite-match"] === "stripPrefix"
? "/"
: undefined),
rewritePathType: targetData["rewrite-match"],
priority: targetData.priority
})
@@ -139,10 +145,14 @@ export async function updateProxyResources(
hcHostname: healthcheckData?.hostname,
hcPort: healthcheckData?.port,
hcInterval: healthcheckData?.interval,
hcUnhealthyInterval: healthcheckData?.unhealthyInterval,
hcUnhealthyInterval:
healthcheckData?.unhealthyInterval ||
healthcheckData?.["unhealthy-interval"],
hcTimeout: healthcheckData?.timeout,
hcHeaders: hcHeaders,
hcFollowRedirects: healthcheckData?.followRedirects,
hcFollowRedirects:
healthcheckData?.followRedirects ||
healthcheckData?.["follow-redirects"],
hcMethod: healthcheckData?.method,
hcStatus: healthcheckData?.status,
hcHealth: "unknown"
@@ -211,6 +221,7 @@ export async function updateProxyResources(
domainId: domain ? domain.domainId : null,
enabled: resourceEnabled,
sso: resourceData.auth?.["sso-enabled"] || false,
skipToIdpId: resourceData.auth?.["auto-login-idp"] || null,
ssl: resourceSsl,
setHostHeader: resourceData["host-header"] || null,
tlsServerName: resourceData["tls-server-name"] || null,
@@ -392,7 +403,12 @@ export async function updateProxyResources(
enabled: targetData.enabled,
path: targetData.path,
pathMatchType: targetData["path-match"],
rewritePath: targetData.rewritePath,
rewritePath:
targetData.rewritePath ||
targetData["rewrite-path"] ||
(targetData["rewrite-match"] === "stripPrefix"
? "/"
: undefined),
rewritePathType: targetData["rewrite-match"],
priority: targetData.priority
})
@@ -452,10 +468,13 @@ export async function updateProxyResources(
hcPort: healthcheckData?.port,
hcInterval: healthcheckData?.interval,
hcUnhealthyInterval:
healthcheckData?.unhealthyInterval,
healthcheckData?.unhealthyInterval ||
healthcheckData?.["unhealthy-interval"],
hcTimeout: healthcheckData?.timeout,
hcHeaders: hcHeaders,
hcFollowRedirects: healthcheckData?.followRedirects,
hcFollowRedirects:
healthcheckData?.followRedirects ||
healthcheckData?.["follow-redirects"],
hcMethod: healthcheckData?.method,
hcStatus: healthcheckData?.status
})
@@ -527,7 +546,7 @@ export async function updateProxyResources(
if (
existingRule.action !== getRuleAction(rule.action) ||
existingRule.match !== rule.match.toUpperCase() ||
existingRule.value !== rule.value
existingRule.value !== getRuleValue(rule.match.toUpperCase(), rule.value)
) {
validateRule(rule);
await trx
@@ -535,7 +554,7 @@ export async function updateProxyResources(
.set({
action: getRuleAction(rule.action),
match: rule.match.toUpperCase(),
value: rule.value
value: getRuleValue(rule.match.toUpperCase(), rule.value),
})
.where(
eq(resourceRules.ruleId, existingRule.ruleId)
@@ -547,7 +566,7 @@ export async function updateProxyResources(
resourceId: existingResource.resourceId,
action: getRuleAction(rule.action),
match: rule.match.toUpperCase(),
value: rule.value,
value: getRuleValue(rule.match.toUpperCase(), rule.value),
priority: index + 1 // start priorities at 1
});
}
@@ -592,6 +611,7 @@ export async function updateProxyResources(
domainId: domain ? domain.domainId : null,
enabled: resourceEnabled,
sso: resourceData.auth?.["sso-enabled"] || false,
skipToIdpId: resourceData.auth?.["auto-login-idp"] || null,
setHostHeader: resourceData["host-header"] || null,
tlsServerName: resourceData["tls-server-name"] || null,
ssl: resourceSsl,
@@ -705,7 +725,7 @@ export async function updateProxyResources(
resourceId: newResource.resourceId,
action: getRuleAction(rule.action),
match: rule.match.toUpperCase(),
value: rule.value,
value: getRuleValue(rule.match.toUpperCase(), rule.value),
priority: index + 1 // start priorities at 1
});
}
@@ -735,6 +755,14 @@ function getRuleAction(input: string) {
return action;
}
function getRuleValue(match: string, value: string) {
// if the match is a country, uppercase the value
if (match == "COUNTRY") {
return value.toUpperCase();
}
return value;
}
function validateRule(rule: any) {
if (rule.match === "cidr") {
if (!isValidCIDR(rule.value)) {
@@ -763,10 +791,6 @@ async function syncRoleResources(
.where(eq(roleResources.resourceId, resourceId));
for (const roleName of ssoRoles) {
if (roleName === "Admin") {
continue; // never add admin access
}
const [role] = await trx
.select()
.from(roles)
@@ -777,6 +801,10 @@ async function syncRoleResources(
throw new Error(`Role not found: ${roleName} in org ${orgId}`);
}
if (role.isAdmin) {
continue; // never add admin access
}
const existingRoleResource = existingRoleResources.find(
(rr) => rr.roleId === role.roleId
);

View File

@@ -7,18 +7,20 @@ export const SiteSchema = z.object({
export const TargetHealthCheckSchema = z.object({
hostname: z.string(),
port: z.number().int().min(1).max(65535),
port: z.int().min(1).max(65535),
enabled: z.boolean().optional().default(true),
path: z.string().optional(),
scheme: z.string().optional(),
mode: z.string().default("http"),
interval: z.number().int().default(30),
unhealthyInterval: z.number().int().default(30),
timeout: z.number().int().default(5),
interval: z.int().default(30),
"unhealthy-interval": z.int().default(30),
unhealthyInterval: z.int().optional(), // deprecated alias
timeout: z.int().default(5),
headers: z.array(z.object({ name: z.string(), value: z.string() })).nullable().optional().default(null),
followRedirects: z.boolean().default(true),
"follow-redirects": z.boolean().default(true),
followRedirects: z.boolean().optional(), // deprecated alias
method: z.string().default("GET"),
status: z.number().int().optional()
status: z.int().optional()
});
// Schema for individual target within a resource
@@ -26,15 +28,16 @@ export const TargetSchema = z.object({
site: z.string().optional(),
method: z.enum(["http", "https", "h2c"]).optional(),
hostname: z.string(),
port: z.number().int().min(1).max(65535),
port: z.int().min(1).max(65535),
enabled: z.boolean().optional().default(true),
"internal-port": z.number().int().min(1).max(65535).optional(),
"internal-port": z.int().min(1).max(65535).optional(),
path: z.string().optional(),
"path-match": z.enum(["exact", "prefix", "regex"]).optional().nullable(),
healthcheck: TargetHealthCheckSchema.optional(),
rewritePath: z.string().optional(),
rewritePath: z.string().optional(), // deprecated alias
"rewrite-path": z.string().optional(),
"rewrite-match": z.enum(["exact", "prefix", "regex", "stripPrefix"]).optional().nullable(),
priority: z.number().int().min(1).max(1000).optional().default(100)
priority: z.int().min(1).max(1000).optional().default(100)
});
export type TargetData = z.infer<typeof TargetSchema>;
@@ -52,10 +55,11 @@ export const AuthSchema = z.object({
.optional()
.default([])
.refine((roles) => !roles.includes("Admin"), {
message: "Admin role cannot be included in sso-roles"
error: "Admin role cannot be included in sso-roles"
}),
"sso-users": z.array(z.string().email()).optional().default([]),
"whitelist-users": z.array(z.string().email()).optional().default([]),
"sso-users": z.array(z.email()).optional().default([]),
"whitelist-users": z.array(z.email()).optional().default([]),
"auto-login-idp": z.int().positive().optional(),
});
export const RuleSchema = z.object({
@@ -76,7 +80,7 @@ export const ResourceSchema = z
protocol: z.enum(["http", "tcp", "udp"]).optional(),
ssl: z.boolean().optional(),
"full-domain": z.string().optional(),
"proxy-port": z.number().int().min(1).max(65535).optional(),
"proxy-port": z.int().min(1).max(65535).optional(),
enabled: z.boolean().optional(),
targets: z.array(TargetSchema.nullable()).optional().default([]),
auth: AuthSchema.optional(),
@@ -97,9 +101,8 @@ export const ResourceSchema = z
);
},
{
message:
"Resource must either be targets-only (only 'targets' field) or have both 'name' and 'protocol' fields at a minimum",
path: ["name", "protocol"]
path: ["name", "protocol"],
error: "Resource must either be targets-only (only 'targets' field) or have both 'name' and 'protocol' fields at a minimum"
}
)
.refine(
@@ -114,6 +117,20 @@ export const ResourceSchema = z
(target) => target == null || target.method !== undefined
);
}
return true;
},
{
path: ["targets"],
error: "When protocol is 'http', all targets must have a 'method' field"
}
)
.refine(
(resource) => {
if (isTargetsOnlyResource(resource)) {
return true;
}
// If protocol is tcp or udp, no target should have method field
if (resource.protocol === "tcp" || resource.protocol === "udp") {
return resource.targets.every(
@@ -122,19 +139,9 @@ export const ResourceSchema = z
}
return true;
},
(resource) => {
if (resource.protocol === "http") {
return {
message:
"When protocol is 'http', all targets must have a 'method' field",
path: ["targets"]
};
}
return {
message:
"When protocol is 'tcp' or 'udp', targets must not have a 'method' field",
path: ["targets"]
};
{
path: ["targets"],
error: "When protocol is 'tcp' or 'udp', targets must not have a 'method' field"
}
)
.refine(
@@ -153,9 +160,8 @@ export const ResourceSchema = z
return true;
},
{
message:
"When protocol is 'http', a 'full-domain' must be provided",
path: ["full-domain"]
path: ["full-domain"],
error: "When protocol is 'http', a 'full-domain' must be provided"
}
)
.refine(
@@ -171,9 +177,8 @@ export const ResourceSchema = z
return true;
},
{
message:
"When protocol is 'tcp' or 'udp', 'proxy-port' must be provided",
path: ["proxy-port", "exit-node"]
path: ["proxy-port", "exit-node"],
error: "When protocol is 'tcp' or 'udp', 'proxy-port' must be provided"
}
)
.refine(
@@ -190,9 +195,8 @@ export const ResourceSchema = z
return true;
},
{
message:
"When protocol is 'tcp' or 'udp', 'auth' must not be provided",
path: ["auth"]
path: ["auth"],
error: "When protocol is 'tcp' or 'udp', 'auth' must not be provided"
}
);
@@ -213,36 +217,12 @@ export const ClientResourceSchema = z.object({
// Schema for the entire configuration object
export const ConfigSchema = z
.object({
"proxy-resources": z.record(z.string(), ResourceSchema).optional().default({}),
"client-resources": z.record(z.string(), ClientResourceSchema).optional().default({}),
sites: z.record(z.string(), SiteSchema).optional().default({})
"proxy-resources": z.record(z.string(), ResourceSchema).optional().prefault({}),
"client-resources": z.record(z.string(), ClientResourceSchema).optional().prefault({}),
sites: z.record(z.string(), SiteSchema).optional().prefault({})
})
.refine(
// Enforce the full-domain uniqueness across resources in the same stack
(config) => {
// Extract all full-domain values with their resource keys
const fullDomainMap = new Map<string, string[]>();
Object.entries(config["proxy-resources"]).forEach(
([resourceKey, resource]) => {
const fullDomain = resource["full-domain"];
if (fullDomain) {
// Only process if full-domain is defined
if (!fullDomainMap.has(fullDomain)) {
fullDomainMap.set(fullDomain, []);
}
fullDomainMap.get(fullDomain)!.push(resourceKey);
}
}
);
// Find duplicates
const duplicates = Array.from(fullDomainMap.entries()).filter(
([_, resourceKeys]) => resourceKeys.length > 1
);
return duplicates.length === 0;
},
(config) => {
// Extract duplicates for error message
const fullDomainMap = new Map<string, string[]>();
@@ -268,90 +248,54 @@ export const ConfigSchema = z
)
.join("; ");
return {
message: `Duplicate 'full-domain' values found: ${duplicates}`,
path: ["resources"]
};
if (duplicates.length !== 0) {
return {
path: ["resources"],
error: `Duplicate 'full-domain' values found: ${duplicates}`
};
}
}
)
.refine(
// Enforce proxy-port uniqueness within proxy-resources
(config) => {
const proxyPortMap = new Map<number, string[]>();
Object.entries(config["proxy-resources"]).forEach(
([resourceKey, resource]) => {
const proxyPort = resource["proxy-port"];
if (proxyPort !== undefined) {
if (!proxyPortMap.has(proxyPort)) {
proxyPortMap.set(proxyPort, []);
}
proxyPortMap.get(proxyPort)!.push(resourceKey);
}
}
);
// Find duplicates
const duplicates = Array.from(proxyPortMap.entries()).filter(
([_, resourceKeys]) => resourceKeys.length > 1
);
return duplicates.length === 0;
},
// Enforce proxy-port uniqueness within proxy-resources per protocol
(config) => {
// Extract duplicates for error message
const proxyPortMap = new Map<number, string[]>();
const protocolPortMap = new Map<string, string[]>();
Object.entries(config["proxy-resources"]).forEach(
([resourceKey, resource]) => {
const proxyPort = resource["proxy-port"];
if (proxyPort !== undefined) {
if (!proxyPortMap.has(proxyPort)) {
proxyPortMap.set(proxyPort, []);
const protocol = resource.protocol;
if (proxyPort !== undefined && protocol !== undefined) {
const key = `${protocol}:${proxyPort}`;
if (!protocolPortMap.has(key)) {
protocolPortMap.set(key, []);
}
proxyPortMap.get(proxyPort)!.push(resourceKey);
protocolPortMap.get(key)!.push(resourceKey);
}
}
);
const duplicates = Array.from(proxyPortMap.entries())
const duplicates = Array.from(protocolPortMap.entries())
.filter(([_, resourceKeys]) => resourceKeys.length > 1)
.map(
([proxyPort, resourceKeys]) =>
`port ${proxyPort} used by proxy-resources: ${resourceKeys.join(", ")}`
([protocolPort, resourceKeys]) => {
const [protocol, port] = protocolPort.split(':');
return `${protocol.toUpperCase()} port ${port} used by proxy-resources: ${resourceKeys.join(", ")}`;
}
)
.join("; ");
return {
message: `Duplicate 'proxy-port' values found in proxy-resources: ${duplicates}`,
path: ["proxy-resources"]
};
if (duplicates.length !== 0) {
return {
path: ["proxy-resources"],
error: `Duplicate 'proxy-port' values found in proxy-resources: ${duplicates}`
};
}
}
)
.refine(
// Enforce proxy-port uniqueness within client-resources
(config) => {
const proxyPortMap = new Map<number, string[]>();
Object.entries(config["client-resources"]).forEach(
([resourceKey, resource]) => {
const proxyPort = resource["proxy-port"];
if (proxyPort !== undefined) {
if (!proxyPortMap.has(proxyPort)) {
proxyPortMap.set(proxyPort, []);
}
proxyPortMap.get(proxyPort)!.push(resourceKey);
}
}
);
// Find duplicates
const duplicates = Array.from(proxyPortMap.entries()).filter(
([_, resourceKeys]) => resourceKeys.length > 1
);
return duplicates.length === 0;
},
(config) => {
// Extract duplicates for error message
const proxyPortMap = new Map<number, string[]>();
@@ -376,10 +320,12 @@ export const ConfigSchema = z
)
.join("; ");
return {
message: `Duplicate 'proxy-port' values found in client-resources: ${duplicates}`,
path: ["client-resources"]
};
if (duplicates.length !== 0) {
return {
path: ["client-resources"],
error: `Duplicate 'proxy-port' values found in client-resources: ${duplicates}`
};
}
}
);

5
server/lib/cache.ts Normal file
View File

@@ -0,0 +1,5 @@
import NodeCache from "node-cache";
export const cache = new NodeCache({ stdTTL: 3600, checkperiod: 120 });
export default cache;

View File

@@ -0,0 +1,286 @@
import {
clients,
db,
olms,
orgs,
roleClients,
roles,
userClients,
userOrgs,
Transaction
} 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";
export async function calculateUserClientsForOrgs(
userId: string,
trx?: Transaction
): Promise<void> {
const execute = async (transaction: Transaction) => {
// Get all OLMs for this user
const userOlms = await transaction
.select()
.from(olms)
.where(eq(olms.userId, userId));
if (userOlms.length === 0) {
// No OLMs for this user, but we should still clean up any orphaned clients
await cleanupOrphanedClients(userId, transaction);
return;
}
// Get all user orgs
const allUserOrgs = await transaction
.select()
.from(userOrgs)
.where(eq(userOrgs.userId, userId));
const userOrgIds = allUserOrgs.map((uo) => uo.orgId);
// For each OLM, ensure there's a client in each org the user is in
for (const olm of userOlms) {
for (const userOrg of allUserOrgs) {
const orgId = userOrg.orgId;
const [org] = await transaction
.select()
.from(orgs)
.where(eq(orgs.orgId, orgId));
if (!org) {
logger.warn(
`Skipping org ${orgId} for OLM ${olm.olmId} (user ${userId}): org not found`
);
continue;
}
if (!org.subnet) {
logger.warn(
`Skipping org ${orgId} for OLM ${olm.olmId} (user ${userId}): org has no subnet configured`
);
continue;
}
// Get admin role for this org (needed for access grants)
const [adminRole] = await transaction
.select()
.from(roles)
.where(and(eq(roles.isAdmin, true), eq(roles.orgId, orgId)))
.limit(1);
if (!adminRole) {
logger.warn(
`Skipping org ${orgId} for OLM ${olm.olmId} (user ${userId}): no admin role found`
);
continue;
}
// Check if a client already exists for this OLM+user+org combination
const [existingClient] = await transaction
.select()
.from(clients)
.where(
and(
eq(clients.userId, userId),
eq(clients.orgId, orgId),
eq(clients.olmId, olm.olmId)
)
)
.limit(1);
if (existingClient) {
// Ensure admin role has access to the client
const [existingRoleClient] = await transaction
.select()
.from(roleClients)
.where(
and(
eq(roleClients.roleId, adminRole.roleId),
eq(
roleClients.clientId,
existingClient.clientId
)
)
)
.limit(1);
if (!existingRoleClient) {
await transaction.insert(roleClients).values({
roleId: adminRole.roleId,
clientId: existingClient.clientId
});
logger.debug(
`Granted admin role access to existing client ${existingClient.clientId} for OLM ${olm.olmId} in org ${orgId} (user ${userId})`
);
}
// Ensure user has access to the client
const [existingUserClient] = await transaction
.select()
.from(userClients)
.where(
and(
eq(userClients.userId, userId),
eq(
userClients.clientId,
existingClient.clientId
)
)
)
.limit(1);
if (!existingUserClient) {
await transaction.insert(userClients).values({
userId,
clientId: existingClient.clientId
});
logger.debug(
`Granted user access to existing client ${existingClient.clientId} for OLM ${olm.olmId} in org ${orgId} (user ${userId})`
);
}
logger.debug(
`Client already exists for OLM ${olm.olmId} in org ${orgId} (user ${userId}), skipping creation`
);
continue;
}
// Get exit nodes for this org
const exitNodesList = await listExitNodes(orgId);
if (exitNodesList.length === 0) {
logger.warn(
`Skipping org ${orgId} for OLM ${olm.olmId} (user ${userId}): no exit nodes found`
);
continue;
}
const randomExitNode =
exitNodesList[
Math.floor(Math.random() * exitNodesList.length)
];
// Get next available subnet
const newSubnet = await getNextAvailableClientSubnet(orgId);
if (!newSubnet) {
logger.warn(
`Skipping org ${orgId} for OLM ${olm.olmId} (user ${userId}): no available subnet found`
);
continue;
}
const subnet = newSubnet.split("/")[0];
const updatedSubnet = `${subnet}/${org.subnet.split("/")[1]}`;
// Create the client
const [newClient] = await transaction
.insert(clients)
.values({
userId,
orgId: userOrg.orgId,
exitNodeId: randomExitNode.exitNodeId,
name: olm.name || "User Client",
subnet: updatedSubnet,
olmId: olm.olmId,
type: "olm"
})
.returning();
await rebuildClientAssociationsFromClient(
newClient,
transaction
);
// Grant admin role access to the client
await transaction.insert(roleClients).values({
roleId: adminRole.roleId,
clientId: newClient.clientId
});
// Grant user access to the client
await transaction.insert(userClients).values({
userId,
clientId: newClient.clientId
});
logger.debug(
`Created client for OLM ${olm.olmId} in org ${orgId} (user ${userId}) with access granted to admin role and user`
);
}
}
// Clean up clients in orgs the user is no longer in
await cleanupOrphanedClients(userId, transaction, userOrgIds);
};
if (trx) {
// Use provided transaction
await execute(trx);
} else {
// Create new transaction
await db.transaction(async (transaction) => {
await execute(transaction);
});
}
}
async function cleanupOrphanedClients(
userId: string,
trx: Transaction,
userOrgIds: string[] = []
): Promise<void> {
// Find all OLM clients for this user that should be deleted
// If userOrgIds is empty, delete all OLM clients (user has no orgs)
// If userOrgIds has values, delete clients in orgs they're not in
const clientsToDelete = await trx
.select({ clientId: clients.clientId })
.from(clients)
.where(
userOrgIds.length > 0
? and(
eq(clients.userId, userId),
notInArray(clients.orgId, userOrgIds)
)
: and(eq(clients.userId, userId))
);
if (clientsToDelete.length > 0) {
const deletedClients = await trx
.delete(clients)
.where(
userOrgIds.length > 0
? and(
eq(clients.userId, userId),
notInArray(clients.orgId, userOrgIds)
)
: and(eq(clients.userId, userId))
)
.returning();
// Rebuild associations for each deleted client to clean up related data
for (const deletedClient of deletedClients) {
await rebuildClientAssociationsFromClient(deletedClient, trx);
if (deletedClient.olmId) {
await sendTerminateClient(
deletedClient.clientId,
deletedClient.olmId
);
}
}
if (userOrgIds.length === 0) {
logger.debug(
`Deleted all ${clientsToDelete.length} OLM client(s) for user ${userId} (user has no orgs)`
);
} else {
logger.debug(
`Deleted ${clientsToDelete.length} orphaned OLM client(s) for user ${userId} in orgs they're no longer in`
);
}
}
}

View File

@@ -0,0 +1,41 @@
import { Org, ResourceSession, Session, User } from "@server/db";
export type CheckOrgAccessPolicyProps = {
orgId?: string;
org?: Org;
userId?: string;
user?: User;
sessionId?: string;
session?: Session;
};
export type CheckOrgAccessPolicyResult = {
allowed: boolean;
error?: string;
policies?: {
requiredTwoFactor?: boolean;
maxSessionLength?: {
compliant: boolean;
maxSessionLengthHours: number;
sessionAgeHours: number;
};
passwordAge?: {
compliant: boolean;
maxPasswordAgeDays: number;
passwordAgeDays: number;
};
};
};
export async function enforceResourceSessionLength(
resourceSession: ResourceSession,
org: Org
): Promise<{ valid: boolean; error?: string }> {
return { valid: true };
}
export async function checkOrgAccessPolicy(
props: CheckOrgAccessPolicyProps
): Promise<CheckOrgAccessPolicyResult> {
return { allowed: true };
}

62
server/lib/cleanupLogs.ts Normal file
View File

@@ -0,0 +1,62 @@
import { db, orgs } from "@server/db";
import { cleanUpOldLogs as cleanUpOldAccessLogs } from "#dynamic/lib/logAccessAudit";
import { cleanUpOldLogs as cleanUpOldActionLogs } from "#dynamic/middlewares/logActionAudit";
import { cleanUpOldLogs as cleanUpOldRequestLogs } from "@server/routers/badger/logRequestAudit";
import { gt, or } from "drizzle-orm";
export function initLogCleanupInterval() {
return setInterval(
async () => {
const orgsToClean = await db
.select({
orgId: orgs.orgId,
settingsLogRetentionDaysAction:
orgs.settingsLogRetentionDaysAction,
settingsLogRetentionDaysAccess:
orgs.settingsLogRetentionDaysAccess,
settingsLogRetentionDaysRequest:
orgs.settingsLogRetentionDaysRequest
})
.from(orgs)
.where(
or(
gt(orgs.settingsLogRetentionDaysAction, 0),
gt(orgs.settingsLogRetentionDaysAccess, 0),
gt(orgs.settingsLogRetentionDaysRequest, 0)
)
);
for (const org of orgsToClean) {
const {
orgId,
settingsLogRetentionDaysAction,
settingsLogRetentionDaysAccess,
settingsLogRetentionDaysRequest
} = org;
if (settingsLogRetentionDaysAction > 0) {
await cleanUpOldActionLogs(
orgId,
settingsLogRetentionDaysRequest
);
}
if (settingsLogRetentionDaysAccess > 0) {
await cleanUpOldAccessLogs(
orgId,
settingsLogRetentionDaysRequest
);
}
if (settingsLogRetentionDaysRequest > 0) {
await cleanUpOldRequestLogs(
orgId,
settingsLogRetentionDaysRequest
);
}
}
},
// 3 * 60 * 60 * 1000
60 * 1000 // for testing
); // every 3 hours
}

View File

@@ -85,7 +85,13 @@ export class Config {
? "true"
: "false";
process.env.FLAGS_ENABLE_CLIENTS = parsedConfig.flags?.enable_clients
process.env.PRODUCT_UPDATES_NOTIFICATION_ENABLED = parsedConfig.app
.notifications.product_updates
? "true"
: "false";
process.env.NEW_RELEASES_NOTIFICATION_ENABLED = parsedConfig.app
.notifications.new_releases
? "true"
: "false";
@@ -158,7 +164,7 @@ export class Config {
try {
const response = await fetch(
"https://api.fossorial.io/api/v1/license/validate",
`https://api.fossorial.io/api/v1/license/validate`,
{
method: "POST",
headers: {

View File

@@ -2,7 +2,7 @@ import path from "path";
import { fileURLToPath } from "url";
// This is a placeholder value replaced by the build process
export const APP_VERSION = "1.11.0";
export const APP_VERSION = "1.12.3";
export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME);

View File

@@ -18,6 +18,7 @@ import { defaultRoleAllowedActions } from "@server/routers/role";
import { FeatureId, limitsService, sandboxLimitSet } from "@server/lib/billing";
import { createCustomer } from "#dynamic/lib/billing";
import { usageService } from "@server/lib/billing/usageService";
import config from "@server/lib/config";
export async function createUserAccountOrg(
userId: string,
@@ -76,6 +77,8 @@ export async function createUserAccountOrg(
.from(domains)
.where(eq(domains.configManaged, true));
const utilitySubnet = config.getRawConfig().orgs.utility_subnet_group;
const newOrg = await trx
.insert(orgs)
.values({
@@ -83,6 +86,7 @@ export async function createUserAccountOrg(
name,
// subnet
subnet: "100.90.128.0/24", // TODO: this should not be hardcoded - or can it be the same in all orgs?
utilitySubnet: utilitySubnet,
createdAt: new Date().toISOString()
})
.returning();

View File

@@ -1,4 +1,4 @@
import { db, exitNodes } from "@server/db";
import { db, exitNodes, Transaction } from "@server/db";
import logger from "@server/logger";
import { ExitNodePingResult } from "@server/routers/newt";
import { eq } from "drizzle-orm";
@@ -59,7 +59,11 @@ export function selectBestExitNode(
return pingResults[0];
}
export async function checkExitNodeOrg(exitNodeId: number, orgId: string) {
export async function checkExitNodeOrg(
exitNodeId: number,
orgId: string,
trx?: Transaction | typeof db
): Promise<boolean> {
return false;
}

View File

@@ -6,7 +6,7 @@ export async function getCountryCodeForIp(
): Promise<string | undefined> {
try {
if (!maxmindLookup) {
logger.warn(
logger.debug(
"MaxMind DB path not configured, cannot perform GeoIP lookup"
);
return;

View File

@@ -1,7 +1,15 @@
import { db } from "@server/db";
import {
clientSitesAssociationsCache,
db,
SiteResource,
siteResources,
Transaction
} from "@server/db";
import { clients, orgs, sites } from "@server/db";
import { and, eq, isNotNull } from "drizzle-orm";
import config from "@server/lib/config";
import z from "zod";
import logger from "@server/logger";
interface IPRange {
start: bigint;
@@ -279,6 +287,56 @@ export async function getNextAvailableClientSubnet(
return subnet;
}
export async function getNextAvailableAliasAddress(
orgId: string
): Promise<string> {
const [org] = await db.select().from(orgs).where(eq(orgs.orgId, orgId));
if (!org) {
throw new Error(`Organization with ID ${orgId} not found`);
}
if (!org.subnet) {
throw new Error(`Organization with ID ${orgId} has no subnet defined`);
}
if (!org.utilitySubnet) {
throw new Error(
`Organization with ID ${orgId} has no utility subnet defined`
);
}
const existingAddresses = await db
.select({
aliasAddress: siteResources.aliasAddress
})
.from(siteResources)
.where(
and(
isNotNull(siteResources.aliasAddress),
eq(siteResources.orgId, orgId)
)
);
const addresses = [
...existingAddresses.map(
(site) => `${site.aliasAddress?.split("/")[0]}/32`
),
// reserve a /29 for the dns server and other stuff
`${org.utilitySubnet.split("/")[0]}/29`
].filter((address) => address !== null) as string[];
let subnet = findNextAvailableCidr(addresses, 32, org.utilitySubnet);
if (!subnet) {
throw new Error("No available subnets remaining in space");
}
// remove the cidr
subnet = subnet.split("/")[0];
return subnet;
}
export async function getNextAvailableOrgSubnet(): Promise<string> {
const existingAddresses = await db
.select({
@@ -300,3 +358,113 @@ export async function getNextAvailableOrgSubnet(): Promise<string> {
return subnet;
}
export function generateRemoteSubnets(allSiteResources: SiteResource[]): string[] {
const remoteSubnets = allSiteResources
.filter((sr) => {
if (sr.mode === "cidr") return true;
if (sr.mode === "host") {
// check if its a valid IP using zod
const ipSchema = z.union([z.ipv4(), z.ipv6()]);
const parseResult = ipSchema.safeParse(sr.destination);
return parseResult.success;
}
return false;
})
.map((sr) => {
if (sr.mode === "cidr") return sr.destination;
if (sr.mode === "host") {
return `${sr.destination}/32`;
}
return ""; // This should never be reached due to filtering, but satisfies TypeScript
})
.filter((subnet) => subnet !== ""); // Remove empty strings just to be safe
// remove duplicates
return Array.from(new Set(remoteSubnets));
}
export type Alias = { alias: string | null; aliasAddress: string | null };
export function generateAliasConfig(allSiteResources: SiteResource[]): Alias[] {
let aliasConfigs = allSiteResources
.filter((sr) => sr.alias && sr.aliasAddress && sr.mode == "host")
.map((sr) => ({
alias: sr.alias,
aliasAddress: sr.aliasAddress
}));
return aliasConfigs;
}
export type SubnetProxyTarget = {
sourcePrefix: string; // must be a cidr
destPrefix: string; // must be a cidr
rewriteTo?: string; // must be a cidr
portRange?: {
min: number;
max: number;
}[];
};
export function generateSubnetProxyTargets(
siteResource: SiteResource,
clients: {
clientId: number;
pubKey: string | null;
subnet: string | null;
}[]
): SubnetProxyTarget[] {
const targets: SubnetProxyTarget[] = [];
if (clients.length === 0) {
logger.debug(
`No clients have access to site resource ${siteResource.siteResourceId}, skipping target generation.`
);
return [];
}
for (const clientSite of clients) {
if (!clientSite.subnet) {
logger.debug(
`Client ${clientSite.clientId} has no subnet, skipping for site resource ${siteResource.siteResourceId}.`
);
continue;
}
const clientPrefix = `${clientSite.subnet.split("/")[0]}/32`;
if (siteResource.mode == "host") {
let destination = siteResource.destination;
// check if this is a valid ip
const ipSchema = z.union([z.ipv4(), z.ipv6()]);
if (ipSchema.safeParse(destination).success) {
destination = `${destination}/32`;
targets.push({
sourcePrefix: clientPrefix,
destPrefix: destination
});
}
if (siteResource.alias && siteResource.aliasAddress) {
// also push a match for the alias address
targets.push({
sourcePrefix: clientPrefix,
destPrefix: `${siteResource.aliasAddress}/32`,
rewriteTo: destination
});
}
} else if (siteResource.mode == "cidr") {
targets.push({
sourcePrefix: clientPrefix,
destPrefix: siteResource.destination
});
}
}
// print a nice representation of the targets
// logger.debug(
// `Generated subnet proxy targets for: ${JSON.stringify(targets, null, 2)}`
// );
return targets;
}

111
server/lib/lock.ts Normal file
View File

@@ -0,0 +1,111 @@
export class LockManager {
/**
* Acquire a distributed lock using Redis SET with NX and PX options
* @param lockKey - Unique identifier for the lock
* @param ttlMs - Time to live in milliseconds
* @returns Promise<boolean> - true if lock acquired, false otherwise
*/
async acquireLock(
lockKey: string,
ttlMs: number = 30000
): Promise<boolean> {
return true;
}
/**
* Release a lock using Lua script to ensure atomicity
* @param lockKey - Unique identifier for the lock
*/
async releaseLock(lockKey: string): Promise<void> {}
/**
* Force release a lock regardless of owner (use with caution)
* @param lockKey - Unique identifier for the lock
*/
async forceReleaseLock(lockKey: string): Promise<void> {}
/**
* Check if a lock exists and get its info
* @param lockKey - Unique identifier for the lock
* @returns Promise<{exists: boolean, ownedByMe: boolean, ttl: number}>
*/
async getLockInfo(lockKey: string): Promise<{
exists: boolean;
ownedByMe: boolean;
ttl: number;
owner?: string;
}> {
return { exists: true, ownedByMe: true, ttl: 0 };
}
/**
* Extend the TTL of an existing lock owned by this worker
* @param lockKey - Unique identifier for the lock
* @param ttlMs - New TTL in milliseconds
* @returns Promise<boolean> - true if extended successfully
*/
async extendLock(lockKey: string, ttlMs: number): Promise<boolean> {
return true;
}
/**
* Attempt to acquire lock with retries and exponential backoff
* @param lockKey - Unique identifier for the lock
* @param ttlMs - Time to live in milliseconds
* @param maxRetries - Maximum number of retry attempts
* @param baseDelayMs - Base delay between retries in milliseconds
* @returns Promise<boolean> - true if lock acquired
*/
async acquireLockWithRetry(
lockKey: string,
ttlMs: number = 30000,
maxRetries: number = 5,
baseDelayMs: number = 100
): Promise<boolean> {
return true;
}
/**
* Execute a function while holding a lock
* @param lockKey - Unique identifier for the lock
* @param fn - Function to execute while holding the lock
* @param ttlMs - Lock TTL in milliseconds
* @returns Promise<T> - Result of the executed function
*/
async withLock<T>(
lockKey: string,
fn: () => Promise<T>,
ttlMs: number = 30000
): Promise<T> {
const acquired = await this.acquireLock(lockKey, ttlMs);
if (!acquired) {
throw new Error(`Failed to acquire lock: ${lockKey}`);
}
try {
return await fn();
} finally {
await this.releaseLock(lockKey);
}
}
/**
* Clean up expired locks - Redis handles this automatically, but this method
* can be used to get statistics about locks
* @returns Promise<{activeLocksCount: number, locksOwnedByMe: number}>
*/
async getLockStatistics(): Promise<{
activeLocksCount: number;
locksOwnedByMe: number;
}> {
return { activeLocksCount: 0, locksOwnedByMe: 0 };
}
/**
* Close the Redis connection
*/
async disconnect(): Promise<void> {}
}
export const lockManager = new LockManager();

View File

@@ -0,0 +1,17 @@
export async function cleanUpOldLogs(orgId: string, retentionDays: number) {
return;
}
export async function logAccessAudit(data: {
action: boolean;
type: string;
orgId: string;
resourceId?: number;
user?: { username: string; userId: string };
apiKey?: { name: string | null; apiKeyId: string };
metadata?: any;
userAgent?: string;
requestIp?: string;
}) {
return;
}

View File

@@ -14,10 +14,8 @@ export const configSchema = z
.object({
app: z
.object({
dashboard_url: z
.string()
.url()
.pipe(z.string().url())
dashboard_url: z.url()
.pipe(z.url())
.transform((url) => url.toLowerCase())
.optional(),
log_level: z
@@ -31,7 +29,14 @@ export const configSchema = z
anonymous_usage: z.boolean().optional().default(true)
})
.optional()
.default({})
.prefault({}),
notifications: z
.object({
product_updates: z.boolean().optional().default(true),
new_releases: z.boolean().optional().default(true)
})
.optional()
.prefault({})
})
.optional()
.default({
@@ -40,6 +45,10 @@ export const configSchema = z
log_failed_attempts: false,
telemetry: {
anonymous_usage: true
},
notifications: {
product_updates: true,
new_releases: true
}
}),
domains: z
@@ -50,7 +59,7 @@ export const configSchema = z
.string()
.nonempty("base_domain must not be empty")
.transform((url) => url.toLowerCase()),
cert_resolver: z.string().optional().default("letsencrypt"),
cert_resolver: z.string().optional(), // null falls back to traefik.cert_resolver
prefer_wildcard_cert: z.boolean().optional().default(false)
})
)
@@ -96,7 +105,7 @@ export const configSchema = z
token: z.string().optional().default("P-Access-Token")
})
.optional()
.default({}),
.prefault({}),
resource_session_request_param: z
.string()
.optional()
@@ -121,7 +130,7 @@ export const configSchema = z
credentials: z.boolean().optional()
})
.optional(),
trust_proxy: z.number().int().gte(0).optional().default(1),
trust_proxy: z.int().gte(0).optional().default(1),
secret: z.string().pipe(z.string().min(8)).optional(),
maxmind_db_path: z.string().optional()
})
@@ -178,7 +187,7 @@ export const configSchema = z
.default(5000)
})
.optional()
.default({})
.prefault({})
})
.optional(),
traefik: z
@@ -204,10 +213,14 @@ export const configSchema = z
.optional()
.default(["newt", "wireguard", "local"]),
allow_raw_resources: z.boolean().optional().default(true),
file_mode: z.boolean().optional().default(false)
file_mode: z.boolean().optional().default(false),
pp_transport_prefix: z
.string()
.optional()
.default("pp-transport-v")
})
.optional()
.default({}),
.prefault({}),
gerbil: z
.object({
exit_node_name: z.string().optional(),
@@ -216,6 +229,11 @@ export const configSchema = z
.default(51820)
.transform(stoi)
.pipe(portSchema),
clients_start_port: portSchema
.optional()
.default(21820)
.transform(stoi)
.pipe(portSchema),
base_endpoint: z
.string()
.optional()
@@ -232,16 +250,18 @@ export const configSchema = z
.default(30)
})
.optional()
.default({}),
.prefault({}),
orgs: z
.object({
block_size: z.number().positive().gt(0).optional().default(24),
subnet_group: z.string().optional().default("100.90.128.0/24")
subnet_group: z.string().optional().default("100.90.128.0/24"),
utility_subnet_group: z.string().optional().default("100.96.128.0/24") //just hardcode this for now as well
})
.optional()
.default({
block_size: 24,
subnet_group: "100.90.128.0/24"
subnet_group: "100.90.128.0/24",
utility_subnet_group: "100.96.128.0/24"
}),
rate_limits: z
.object({
@@ -261,7 +281,7 @@ export const configSchema = z
.default(500)
})
.optional()
.default({}),
.prefault({}),
auth: z
.object({
window_minutes: z
@@ -278,10 +298,10 @@ export const configSchema = z
.default(500)
})
.optional()
.default({})
.prefault({})
})
.optional()
.default({}),
.prefault({}),
email: z
.object({
smtp_host: z.string().optional(),
@@ -293,7 +313,7 @@ export const configSchema = z
.transform(getEnvOrYaml("EMAIL_SMTP_PASS")),
smtp_secure: z.boolean().optional(),
smtp_tls_reject_unauthorized: z.boolean().optional(),
no_reply: z.string().email().optional()
no_reply: z.email().optional()
})
.optional(),
flags: z
@@ -305,8 +325,7 @@ export const configSchema = z
enable_integration_api: z.boolean().optional(),
disable_local_sites: z.boolean().optional(),
disable_basic_wireguard_sites: z.boolean().optional(),
disable_config_managed_domains: z.boolean().optional(),
enable_clients: z.boolean().optional().default(true)
disable_config_managed_domains: z.boolean().optional()
})
.optional(),
dns: z
@@ -314,14 +333,18 @@ export const configSchema = z
nameservers: z
.array(z.string().optional().optional())
.optional()
.default(["ns1.fossorial.io", "ns2.fossorial.io"]),
cname_extension: z.string().optional().default("fossorial.io")
.default([
"ns1.pangolin.net",
"ns2.pangolin.net",
"ns3.pangolin.net"
]),
cname_extension: z
.string()
.optional()
.default("cname.pangolin.net")
})
.optional()
.default({
nameservers: ["ns1.fossorial.io", "ns2.fossorial.io"],
cname_extension: "fossorial.io"
})
.prefault({})
})
.refine(
(data) => {
@@ -336,7 +359,7 @@ export const configSchema = z
return true;
},
{
message: "At least one domain must be defined"
error: "At least one domain must be defined"
}
)
.refine(
@@ -351,7 +374,7 @@ export const configSchema = z
);
},
{
message: "Server secret must be defined"
error: "Server secret must be defined"
}
)
.refine(
@@ -363,7 +386,7 @@ export const configSchema = z
);
},
{
message: "Dashboard URL must be defined"
error: "Dashboard URL must be defined"
}
);
@@ -392,7 +415,7 @@ export function readConfigFile() {
if (!environment) {
throw new Error(
"No configuration file found. Please create one. https://docs.digpangolin.com/self-host/advanced/config-file"
"No configuration file found. Please create one. https://docs.pangolin.net/self-host/advanced/config-file"
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
export enum AudienceIds {
General = "",
Subscribed = "",
Churned = ""
SignUps = "",
Subscribed = "",
Churned = "",
Newsletter = ""
}
let resend;
@@ -12,4 +13,4 @@ export async function moveEmailToAudience(
audienceId: AudienceIds
) {
return;
}
}

View File

@@ -0,0 +1,29 @@
import logger from "@server/logger";
import axios from "axios";
let serverIp: string | null = null;
const services = [
"https://checkip.amazonaws.com",
"https://ifconfig.io/ip",
"https://api.ipify.org",
];
export async function fetchServerIp() {
for (const url of services) {
try {
const response = await axios.get(url, { timeout: 5000 });
serverIp = response.data.trim();
logger.debug("Detected public IP: " + serverIp);
return;
} catch (err: any) {
console.warn(`Failed to fetch server IP from ${url}: ${err.message || err.code}`);
}
}
console.error("All attempts to fetch server IP failed.");
}
export function getServerIp() {
return serverIp;
}

View File

@@ -4,7 +4,7 @@ import { getHostMeta } from "./hostMeta";
import logger from "@server/logger";
import { apiKeys, db, roles } from "@server/db";
import { sites, users, orgs, resources, clients, idp } from "@server/db";
import { eq, count, notInArray } from "drizzle-orm";
import { eq, count, notInArray, and } from "drizzle-orm";
import { APP_VERSION } from "./consts";
import crypto from "crypto";
import { UserType } from "@server/types/UserTypes";
@@ -33,7 +33,7 @@ class TelemetryClient {
this.client = new PostHog(
"phc_QYuATSSZt6onzssWcYJbXLzQwnunIpdGGDTYhzK3VjX",
{
host: "https://digpangolin.com/relay-O7yI"
host: "https://pangolin.net/relay-O7yI"
}
);
@@ -48,11 +48,11 @@ class TelemetryClient {
this.startAnalyticsInterval();
logger.info(
"Pangolin now gathers anonymous usage data to help us better understand how the software is used and guide future improvements and feature development. You can find more details, including instructions for opting out of this anonymous data collection, at: https://docs.digpangolin.com/telemetry"
"Pangolin now gathers anonymous usage data to help us better understand how the software is used and guide future improvements and feature development. You can find more details, including instructions for opting out of this anonymous data collection, at: https://docs.pangolin.net/telemetry"
);
} else if (!this.enabled) {
logger.info(
"Analytics usage statistics collection is disabled. If you enable this, you can help us make Pangolin better for everyone. Learn more at: https://docs.digpangolin.com/telemetry"
"Analytics usage statistics collection is disabled. If you enable this, you can help us make Pangolin better for everyone. Learn more at: https://docs.pangolin.net/telemetry"
);
}
}
@@ -113,7 +113,12 @@ class TelemetryClient {
const [customRoles] = await db
.select({ count: count() })
.from(roles)
.where(notInArray(roles.name, ["Admin", "Member"]));
.where(
and(
eq(roles.isAdmin, false),
notInArray(roles.name, ["Member"])
)
);
const adminUsers = await db
.select({ email: users.email })
@@ -188,7 +193,7 @@ class TelemetryClient {
license_tier: licenseStatus.tier || "unknown"
}
};
logger.debug("Sending enterprise startup telemtry payload:", {
logger.debug("Sending enterprise startup telemetry payload:", {
payload
});
// this.client.capture(payload);
@@ -200,10 +205,7 @@ class TelemetryClient {
event: "supporter_status",
properties: {
valid: stats.supporterStatus.valid,
tier: stats.supporterStatus.tier,
github_username: stats.supporterStatus.githubUsername
? this.anon(stats.supporterStatus.githubUsername)
: "None"
tier: stats.supporterStatus.tier
}
});
}
@@ -217,21 +219,6 @@ class TelemetryClient {
install_timestamp: hostMeta.createdAt
}
});
for (const email of stats.adminUsers) {
// There should only be on admin user, but just in case
if (email) {
this.client.capture({
distinctId: this.anon(email),
event: "admin_user",
properties: {
host_id: hostMeta.hostMetaId,
app_version: stats.appVersion,
hashed_email: this.anon(email)
}
});
}
}
}
private async collectAndSendAnalytics() {
@@ -262,19 +249,38 @@ class TelemetryClient {
num_clients: stats.numClients,
num_identity_providers: stats.numIdentityProviders,
num_sites_online: stats.numSitesOnline,
resources: stats.resources.map((r) => ({
name: this.anon(r.name),
sso_enabled: r.sso,
protocol: r.protocol,
http_enabled: r.http
})),
sites: stats.sites.map((s) => ({
site_name: this.anon(s.siteName),
megabytes_in: s.megabytesIn,
megabytes_out: s.megabytesOut,
type: s.type,
online: s.online
})),
num_resources_sso_enabled: stats.resources.filter(
(r) => r.sso
).length,
num_resources_non_http: stats.resources.filter(
(r) => !r.http
).length,
num_newt_sites: stats.sites.filter((s) => s.type === "newt")
.length,
num_local_sites: stats.sites.filter(
(s) => s.type === "local"
).length,
num_wg_sites: stats.sites.filter(
(s) => s.type === "wireguard"
).length,
avg_megabytes_in:
stats.sites.length > 0
? Math.round(
stats.sites.reduce(
(sum, s) => sum + (s.megabytesIn ?? 0),
0
) / stats.sites.length
)
: 0,
avg_megabytes_out:
stats.sites.length > 0
? Math.round(
stats.sites.reduce(
(sum, s) => sum + (s.megabytesOut ?? 0),
0
) / stats.sites.length
)
: 0,
num_api_keys: stats.numApiKeys,
num_custom_roles: stats.numCustomRoles
}

View File

@@ -309,10 +309,7 @@ export class TraefikConfigManager {
this.lastActiveDomains = new Set(domains);
}
if (
process.env.USE_PANGOLIN_DNS === "true" &&
build != "oss"
) {
if (process.env.USE_PANGOLIN_DNS === "true" && build != "oss") {
// Scan current local certificate state
this.lastLocalCertificateState =
await this.scanLocalCertificateState();
@@ -450,7 +447,8 @@ export class TraefikConfigManager {
currentExitNode,
config.getRawConfig().traefik.site_types,
build == "oss", // filter out the namespace domains in open source
build != "oss" // generate the login pages on the cloud and hybrid
build != "oss", // generate the login pages on the cloud and hybrid,
build == "saas" ? false : config.getRawConfig().traefik.allow_raw_resources // dont allow raw resources on saas otherwise use config
);
const domains = new Set<string>();
@@ -502,6 +500,25 @@ export class TraefikConfigManager {
};
}
// tcp:
// serversTransports:
// pp-transport-v1:
// proxyProtocol:
// version: 1
// pp-transport-v2:
// proxyProtocol:
// version: 2
if (build != "saas") {
// add the serversTransports section if not present
if (traefikConfig.tcp && !traefikConfig.tcp.serversTransports) {
traefikConfig.tcp.serversTransports = {
"pp-transport-v1": { proxyProtocol: { version: 1 } },
"pp-transport-v2": { proxyProtocol: { version: 2 } }
};
}
}
return { domains, traefikConfig };
} catch (error) {
// pull data out of the axios error to log

View File

@@ -1,4 +1,4 @@
import { db, targetHealthCheck } from "@server/db";
import { db, targetHealthCheck, domains } from "@server/db";
import {
and,
eq,
@@ -23,7 +23,8 @@ export async function getTraefikConfig(
exitNodeId: number,
siteTypes: string[],
filterOutNamespaceDomains = false,
generateLoginPageRouters = false
generateLoginPageRouters = false,
allowRawResources = true
): Promise<any> {
// Define extended target type with site information
type TargetWithSite = Target & {
@@ -56,6 +57,8 @@ export async function getTraefikConfig(
setHostHeader: resources.setHostHeader,
enableProxy: resources.enableProxy,
headers: resources.headers,
proxyProtocol: resources.proxyProtocol,
proxyProtocolVersion: resources.proxyProtocolVersion,
// Target fields
targetId: targets.targetId,
targetEnabled: targets.enabled,
@@ -75,11 +78,15 @@ export async function getTraefikConfig(
siteType: sites.type,
siteOnline: sites.online,
subnet: sites.subnet,
exitNodeId: sites.exitNodeId
exitNodeId: sites.exitNodeId,
// Domain cert resolver fields
domainCertResolver: domains.certResolver,
preferWildcardCert: domains.preferWildcardCert
})
.from(sites)
.innerJoin(targets, eq(targets.siteId, sites.siteId))
.innerJoin(resources, eq(resources.resourceId, targets.resourceId))
.leftJoin(domains, eq(domains.domainId, resources.domainId))
.leftJoin(
targetHealthCheck,
eq(targetHealthCheck.targetId, targets.targetId)
@@ -92,7 +99,8 @@ export async function getTraefikConfig(
eq(sites.exitNodeId, exitNodeId),
and(
isNull(sites.exitNodeId),
sql`(${siteTypes.includes("local") ? 1 : 0} = 1)` // only allow local sites if "local" is in siteTypes
sql`(${siteTypes.includes("local") ? 1 : 0} = 1)`, // only allow local sites if "local" is in siteTypes
eq(sites.type, "local")
)
),
or(
@@ -100,7 +108,7 @@ export async function getTraefikConfig(
isNull(targetHealthCheck.hcHealth) // Include targets with no health check record
),
inArray(sites.type, siteTypes),
config.getRawConfig().traefik.allow_raw_resources
allowRawResources
? isNotNull(resources.http) // ignore the http check if allow_raw_resources is true
: eq(resources.http, true)
)
@@ -163,11 +171,16 @@ export async function getTraefikConfig(
enableProxy: row.enableProxy,
targets: [],
headers: row.headers,
proxyProtocol: row.proxyProtocol,
proxyProtocolVersion: row.proxyProtocolVersion ?? 1,
path: row.path, // the targets will all have the same path
pathMatchType: row.pathMatchType, // the targets will all have the same pathMatchType
rewritePath: row.rewritePath,
rewritePathType: row.rewritePathType,
priority: priority // may be null, we fallback later
priority: priority,
// Store domain cert resolver fields
domainCertResolver: row.domainCertResolver,
preferWildcardCert: row.preferWildcardCert
});
}
@@ -246,21 +259,35 @@ export async function getTraefikConfig(
wildCard = resource.fullDomain;
}
const configDomain = config.getDomain(resource.domainId);
const globalDefaultResolver =
config.getRawConfig().traefik.cert_resolver;
const globalDefaultPreferWildcard =
config.getRawConfig().traefik.prefer_wildcard_cert;
let certResolver: string, preferWildcardCert: boolean;
if (!configDomain) {
certResolver = config.getRawConfig().traefik.cert_resolver;
preferWildcardCert =
config.getRawConfig().traefik.prefer_wildcard_cert;
const domainCertResolver = resource.domainCertResolver;
const preferWildcardCert = resource.preferWildcardCert;
let resolverName: string | undefined;
let preferWildcard: boolean | undefined;
// Handle both letsencrypt & custom cases
if (domainCertResolver) {
resolverName = domainCertResolver.trim();
} else {
certResolver = configDomain.cert_resolver;
preferWildcardCert = configDomain.prefer_wildcard_cert;
resolverName = globalDefaultResolver;
}
if (
preferWildcardCert !== undefined &&
preferWildcardCert !== null
) {
preferWildcard = preferWildcardCert;
} else {
preferWildcard = globalDefaultPreferWildcard;
}
const tls = {
certResolver: certResolver,
...(preferWildcardCert
certResolver: resolverName,
...(preferWildcard
? {
domains: [
{
@@ -318,9 +345,9 @@ export async function getTraefikConfig(
routerMiddlewares.push(rewriteMiddlewareName);
}
logger.debug(
`Created path rewrite middleware ${rewriteMiddlewareName}: ${resource.pathMatchType}(${resource.path}) -> ${resource.rewritePathType}(${resource.rewritePath})`
);
// logger.debug(
// `Created path rewrite middleware ${rewriteMiddlewareName}: ${resource.pathMatchType}(${resource.path}) -> ${resource.rewritePathType}(${resource.rewritePath})`
// );
} catch (error) {
logger.error(
`Failed to create path rewrite middleware for resource ${resource.resourceId}: ${error}`
@@ -561,6 +588,8 @@ export async function getTraefikConfig(
...(protocol === "tcp" ? { rule: "HostSNI(`*`)" } : {})
};
const ppPrefix = config.getRawConfig().traefik.pp_transport_prefix;
config_output[protocol].services[serviceName] = {
loadBalancer: {
servers: (() => {
@@ -614,6 +643,11 @@ export async function getTraefikConfig(
}
});
})(),
...(resource.proxyProtocol && protocol == "tcp"
? {
serversTransport: `${ppPrefix}${resource.proxyProtocolVersion || 1}@file` // TODO: does @file here cause issues?
}
: {}),
...(resource.stickySession
? {
sticky: {

View File

@@ -1,11 +1,12 @@
import z from "zod";
import ipaddr from "ipaddr.js";
export function isValidCIDR(cidr: string): boolean {
return z.string().cidr().safeParse(cidr).success;
return z.cidrv4().safeParse(cidr).success || z.cidrv6().safeParse(cidr).success;
}
export function isValidIP(ip: string): boolean {
return z.string().ip().safeParse(ip).success;
return z.ipv4().safeParse(ip).success || z.ipv6().safeParse(ip).success;
}
export function isValidUrlGlobPattern(pattern: string): boolean {
@@ -68,11 +69,11 @@ export function isUrlValid(url: string | undefined) {
if (!url) return true; // the link is optional in the schema so if it's empty it's valid
var pattern = new RegExp(
"^(https?:\\/\\/)?" + // protocol
"((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name
"((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address
"(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path
"(\\?[;&a-z\\d%_.~+=-]*)?" + // query string
"(\\#[-a-z\\d_]*)?$",
"((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name
"((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address
"(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path
"(\\?[;&a-z\\d%_.~+=-]*)?" + // query string
"(\\#[-a-z\\d_]*)?$",
"i"
);
return !!pattern.test(url);
@@ -83,12 +84,15 @@ export function isTargetValid(value: string | undefined) {
const DOMAIN_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_])?)*$/;
const IPV4_REGEX =
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
const IPV6_REGEX = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$/i;
// const IPV4_REGEX =
// /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
// const IPV6_REGEX = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$/i;
if (IPV4_REGEX.test(value) || IPV6_REGEX.test(value)) {
return true;
try {
const addr = ipaddr.parse(value);
return addr.kind() === "ipv4" || addr.kind() === "ipv6";
} catch {
// fall through to domain regex check
}
return DOMAIN_REGEX.test(value);
@@ -169,10 +173,10 @@ export function isSecondLevelDomain(domain: string): boolean {
}
const trimmedDomain = domain.trim().toLowerCase();
// Split into parts
const parts = trimmedDomain.split('.');
// Should have exactly 2 parts for a second-level domain (e.g., "example.com")
if (parts.length !== 2) {
return false;

View File

@@ -40,6 +40,10 @@ export class License {
public setServerSecret(secret: string) {
this.serverSecret = secret;
}
public async isUnlocked() {
return false;
}
}
await setHostMeta();

View File

@@ -11,6 +11,7 @@ export * from "./verifyRoleAccess";
export * from "./verifyUserAccess";
export * from "./verifyAdmin";
export * from "./verifySetResourceUsers";
export * from "./verifySetResourceClients";
export * from "./verifyUserInRole";
export * from "./verifyAccessTokenAccess";
export * from "./requestTimeout";
@@ -24,6 +25,7 @@ export * from "./integration";
export * from "./verifyUserHasAction";
export * from "./verifyApiKeyAccess";
export * from "./verifyDomainAccess";
export * from "./verifyClientsEnabled";
export * from "./verifyUserIsOrgOwner";
export * from "./verifySiteResourceAccess";
export * from "./logActionAudit";
export * from "./verifyOlmAccess";

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