Compare commits

...

35 Commits

Author SHA1 Message Date
dependabot[bot]
ea4848c7c6 web: bump postcss from 8.5.8 to 8.5.10 in /web (#21819)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.8 to 8.5.10.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.8...8.5.10)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-25 11:28:06 +02:00
dependabot[bot]
2fd9a09055 web: bump brace-expansion from 1.1.13 to 1.1.14 (#21820)
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.13 to 1.1.14.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.13...v1.1.14)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.14
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-25 11:27:27 +02:00
dependabot[bot]
b07b71f528 web: bump postcss from 8.5.8 to 8.5.10 (#21821)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.8 to 8.5.10.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.8...8.5.10)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-25 11:27:09 +02:00
Jens L.
c058363180 website/docs: improve social login docs titles (#21816)
* website/docs: improve social login docs titles

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* sigh twitter

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2026-04-24 17:40:27 +02:00
Sai Asish Y
b5a92b783f providers/oauth2: require client_secret on device_code exchange for confidential clients (#21700)
* providers/oauth2: require client_secret on device_code exchange for confidential clients

TokenParams.__post_init__ only ran the client_secret check for the
authorization_code and refresh_token grant types:

	if self.grant_type in [GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_REFRESH_TOKEN]:
		if self.provider.client_type == ClientTypes.CONFIDENTIAL and not compare_digest(
			self.provider.client_secret, self.client_secret,
		):
			raise TokenError("invalid_client")

The device_code path (__post_init_device_code) then looked up the
DeviceToken solely by device_code and issued an access token if one
matched. A caller that knows the client_id and has stolen a
device_code (e.g. via the standard phishing flow: attacker starts
device authorization, sends user_code to a victim, victim completes
authorization, attacker redeems the device_code) did not have to
prove ownership of the confidential client.

RFC 6749 Section 2.3.1 requires confidential clients to authenticate
to the token endpoint, and RFC 8628 Section 3.4 inherits that: the
device_code is bearer-shaped but not a substitute for client
credentials. Keycloak and Okta both enforce client_secret on the
device token exchange for confidential clients; we didn't.

Add GRANT_TYPE_DEVICE_CODE to the list so the existing compare_digest
check runs for it too. Public clients are unaffected (the guard is
gated on ClientTypes.CONFIDENTIAL). client_credentials/password keep
their own client-auth path in __post_init_client_credentials, which
also enforces the secret (and supports client assertion).

Fixes #20828

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>

* Apply suggestion from @BeryJu

Signed-off-by: Jens L. <jens@beryju.org>

* update tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
Signed-off-by: Jens L. <jens@beryju.org>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: SAY-5 <SAY-5@users.noreply.github.com>
Co-authored-by: Jens L. <jens@beryju.org>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2026-04-24 17:23:36 +02:00
Marc 'risson' Schmitt
a4c60ece8b lifecycle/container: allow cross-compilation from arm64 to amd64 (#21817)
Co-authored-by: João C. Fernandes <jfernandes@cloudflare.com>
2026-04-24 17:00:46 +02:00
Jens L.
d1d38edb50 enterprise/endpoints/connectors: Fleet conditional access stage (#20978)
* rework mtls stage to be more modular

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* sync fleet conditional access CA to authentik

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* save host uuid

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* initial stage impl

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add fixtures & tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add lookup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate to parsing mobileconfig

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* directly use stage_invalid

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add more test

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* test team mapping

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix endpoint test

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* cleanup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* Add document for this. Update sidebar.

* Doc improvement

* Add note about Fleet licensing

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* re-fix tests after mtls traefik encoding change

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* Add info about fleet and device config. Add link from fleet connector doc.

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2026-04-24 16:17:00 +02:00
Jens L.
c6ee7b6881 core: complete rework to oobe and setup experience (#21753)
* initial

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use same startup template

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix check not working

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* unrelated: fix inspector auth

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update docs

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* ensure oobe flow can only accessed via correct url

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* set setup flag when applying bootstrap blueprint when env is set

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add system visibility to flags to make them non-editable

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* set setup flag for e2e tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests and linting

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make github lint happy

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make tests have less assumptions

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* Update docs

* include more heuristics in migration

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add management command to set any flag

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate worker command to signal

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* improved api for setting flags

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* short circuit

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2026-04-24 14:47:05 +02:00
dependabot[bot]
0459568a96 core: bump github.com/Azure/go-ntlmssp from 0.1.0 to 0.1.1 in the go_modules group across 1 directory (#21807)
core: bump github.com/Azure/go-ntlmssp

Bumps the go_modules group with 1 update in the / directory: [github.com/Azure/go-ntlmssp](https://github.com/Azure/go-ntlmssp).


Updates `github.com/Azure/go-ntlmssp` from 0.1.0 to 0.1.1
- [Release notes](https://github.com/Azure/go-ntlmssp/releases)
- [Commits](https://github.com/Azure/go-ntlmssp/compare/v0.1.0...v0.1.1)

---
updated-dependencies:
- dependency-name: github.com/Azure/go-ntlmssp
  dependency-version: 0.1.1
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:57 +01:00
dependabot[bot]
aa746e7585 lifecycle/aws: bump aws-cdk from 2.1118.3 to 2.1118.4 in /lifecycle/aws (#21808)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1118.3 to 2.1118.4.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1118.4/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1118.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:53 +01:00
dependabot[bot]
a4dcf097b3 core: bump pydantic from 2.13.2 to 2.13.3 (#21809)
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.13.2 to 2.13.3.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.13.2...v2.13.3)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.13.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:48 +01:00
dependabot[bot]
c2ecff559c web: bump @sentry/browser from 10.48.0 to 10.49.0 in /web in the sentry group across 1 directory (#21810)
web: bump @sentry/browser in /web in the sentry group across 1 directory

Bumps the sentry group with 1 update in the /web directory: [@sentry/browser](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/browser` from 10.48.0 to 10.49.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.48.0...10.49.0)

---
updated-dependencies:
- dependency-name: "@sentry/browser"
  dependency-version: 10.49.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:43 +01:00
dependabot[bot]
c20ecb48f8 core: bump cachetools from 7.0.5 to 7.0.6 (#21811)
Bumps [cachetools](https://github.com/tkem/cachetools) from 7.0.5 to 7.0.6.
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v7.0.5...v7.0.6)

---
updated-dependencies:
- dependency-name: cachetools
  dependency-version: 7.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:39 +01:00
dependabot[bot]
34a50ad46e ci: bump calibreapp/image-actions from 4f7260f5dbd809ec86d03721c1ad71b8a841d3e0 to e2cc8db5d49c849e00844dfebf01438318e96fa2 (#21812)
ci: bump calibreapp/image-actions

Bumps [calibreapp/image-actions](https://github.com/calibreapp/image-actions) from 4f7260f5dbd809ec86d03721c1ad71b8a841d3e0 to e2cc8db5d49c849e00844dfebf01438318e96fa2.
- [Release notes](https://github.com/calibreapp/image-actions/releases)
- [Commits](4f7260f5db...e2cc8db5d4)

---
updated-dependencies:
- dependency-name: calibreapp/image-actions
  dependency-version: e2cc8db5d49c849e00844dfebf01438318e96fa2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:34 +01:00
dependabot[bot]
99410f3775 web: bump @patternfly/elements from 4.3.1 to 4.4.0 in /web (#21813)
Bumps [@patternfly/elements](https://github.com/patternfly/patternfly-elements/tree/HEAD/elements) from 4.3.1 to 4.4.0.
- [Release notes](https://github.com/patternfly/patternfly-elements/releases)
- [Changelog](https://github.com/patternfly/patternfly-elements/blob/main/elements/CHANGELOG.md)
- [Commits](https://github.com/patternfly/patternfly-elements/commits/@patternfly/elements@4.4.0/elements)

---
updated-dependencies:
- dependency-name: "@patternfly/elements"
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:30 +01:00
dependabot[bot]
86de4955aa ci: bump taiki-e/install-action from 2.75.18 to 2.75.19 in /.github/actions/setup (#21814)
ci: bump taiki-e/install-action in /.github/actions/setup

Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.75.18 to 2.75.19.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](055f5df8c3...5f57d6cb7c)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.75.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-24 11:39:26 +01:00
dependabot[bot]
bea9b23555 lifecycle/aws: bump aws-cdk from 2.1118.2 to 2.1118.3 in /lifecycle/aws (#21801)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 18:09:55 +02:00
dependabot[bot]
9820ee1d67 core: bump rustls from 0.23.38 to 0.23.39 (#21802)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 14:18:04 +00:00
Marc 'risson' Schmitt
1379637389 ci: add rustls and aws-lc ecosystem crates to delay ignore list (#21800) 2026-04-23 13:42:25 +00:00
Dominic R
39e6c41566 admin/files: sign custom-domain S3 URLs for the final host (#21704) 2026-04-23 15:23:05 +02:00
Sai Asish Y
92a2d26c86 core: survive the empty-queryset race in chunked_queryset (#21666) 2026-04-23 15:21:57 +02:00
Simonyi Gergő
0f8d8c81d7 core: simplify boolean (#21790) 2026-04-23 14:47:23 +02:00
Sai Asish Y
cce646b132 providers/oauth2: clip device authorization scope against the provider's ScopeMapping set (#21701)
* providers/oauth2: clip device authorization scope against the provider's ScopeMapping set

DeviceView.parse_request stored the raw request scope straight onto the
DeviceToken:

	self.scopes = self.request.POST.get("scope", "").split(" ")
	...
	token = DeviceToken.objects.create(..., _scope=" ".join(self.scopes))

The token-exchange side then reads those scopes back directly:

	if SCOPE_OFFLINE_ACCESS in self.params.device_code.scope:
		refresh_token = RefreshToken(...)
		...

so a caller that adds offline_access to the device authorization
request body gets a refresh_token at the exchange, even when the
provider has no offline_access ScopeMapping configured. Every other
grant type clips scope against ScopeMapping for the provider inside
TokenParams.__check_scopes, but the device authorization endpoint
runs before TokenParams is ever constructed, so the clip never
happens for the device flow.

Combined with #20828 (missing client_secret verification on device
code exchange for confidential clients, now being fixed separately)
and the lack of per-app opt-out for the device flow, this gives any
caller that knows the client_id a path to an offline refresh token
against any OIDC application the deployment exposes.

Intersect the requested scope set with the provider's ScopeMapping
names before we ever persist the DeviceToken. offline_access that is
not configured is silently dropped, matching __check_scopes on the
other grant types. Configured offline_access still flows through
unchanged.

Fixes #20825

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>

* rework and add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: SAY-5 <SAY-5@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2026-04-23 13:44:44 +02:00
dependabot[bot]
6d274d1e3d core: bump library/nginx from 3acc8b9 to 6e23479 in /website (#21794)
Bumps library/nginx from `3acc8b9` to `6e23479`.

---
updated-dependencies:
- dependency-name: library/nginx
  dependency-version: 1.29-trixie
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 11:20:09 +02:00
dependabot[bot]
8d5489e441 core: bump library/node from b272ff1 to 74ff139 in /website (#21795)
Bumps library/node from `b272ff1` to `74ff139`.

---
updated-dependencies:
- dependency-name: library/node
  dependency-version: 25.9.0-trixie
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 11:19:56 +02:00
dependabot[bot]
8ea9a48017 core: bump library/golang from cd8540d to 982ae92 in /lifecycle/container (#21793)
core: bump library/golang in /lifecycle/container

Bumps library/golang from `cd8540d` to `982ae92`.

---
updated-dependencies:
- dependency-name: library/golang
  dependency-version: 1.26.2-trixie
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 10:19:37 +01:00
Sai Asish Y
c6b5869b48 stages/user_write: refuse to write id/pk claims onto the user model (#21667)
* stages/user_write: refuse to write id/pk claims onto the user model

When an enrollment or source flow maps IdP-supplied attributes onto the
User model, update_user walks each key and, if the user already has an
attribute by that name, calls setattr(user, key, value) unconditionally.
"id" is always present on the User model (it is the Django PK), so a
SAML assertion that ships an "id" claim, e.g. a hex string from
mocksaml, was written straight into the PK field. Django then rejected
the save:

  ValueError: Field 'id' expected a number but got '<hex>'.

The log surfaced as "Failed to save user" and the enrollment flow
silently failed for every incoming user.

Treat "id" and "pk" the same way the existing "groups" entry is
treated: add them to disallowed_user_attributes so the walker logs and
skips them. IdP attributes can still be stored on user.attributes via
the dotted/underscored forms (e.g. attributes.id), which go through
write_attribute and land in the JSONField safely.

Added a regression test covering both id and pk in the prompt context.

Fixes #21580

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>

* fix lint

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: SAY-5 <SAY-5@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2026-04-23 11:03:12 +02:00
authentik-automation[bot]
e4971f9aa5 core, web: update translations (#21785)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2026-04-23 10:39:13 +02:00
Dominic R
028ec05a8b website: Merge branch (#21684)
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2026-04-23 01:46:10 +00:00
Ryan Pesek
b4c9ac57e0 core/applications: Optimize list applications when only_with_launch_url=true (#20428)
* Performance optimizations for the application list API endpoint when only_with_launch_url=true

* lint

---------

Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2026-04-23 03:15:16 +02:00
Dewi Roberts
80b93e1fbc website/docs: add authorization header info to all proxy configs (#21664)
Add authorization header info to all proxy configs
2026-04-23 02:35:02 +02:00
dependabot[bot]
dff6b48f53 web: bump @xmldom/xmldom from 0.8.12 to 0.8.13 in /web (#21784)
Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.8.12 to 0.8.13.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xmldom/xmldom/compare/0.8.12...0.8.13)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-version: 0.8.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 02:33:20 +02:00
gp-somni-labs
79473341d6 internal/outpost: serialize websocket writes to prevent panic (#21728)
The outpost API controller shares a single *websocket.Conn across
multiple goroutines: the event-handler loop, the 10s health ticker
(SendEventHello), the shutdown path (WriteMessage close), initEvent
writing the hello frame on (re)connect, and RAC session handlers that
also invoke SendEventHello. gorilla/websocket explicitly documents that
concurrent WriteMessage/WriteJSON calls are unsafe and will panic with
"concurrent write to websocket connection", which takes the outpost
(and embedded-outpost authentik-server) pod down.

Fix by adding a sync.Mutex on APIController guarding every write path
on eventConn (initEvent hello, Shutdown close message, SendEventHello).
Reads (ReadJSON in startEventHandler) are left unsynchronized as
gorilla permits a single concurrent reader alongside a writer.

Minimal, localized change: no API changes, no behavior changes, writes
are already infrequent so lock contention is negligible.

Refs #11090

Co-authored-by: curiosity <curiosity@somni.dev>
2026-04-23 02:33:10 +02:00
dependabot[bot]
99f9682d61 core: bump rand from 0.8.5 to 0.8.6 in the cargo group across 1 directory (#21783)
core: bump rand in the cargo group across 1 directory

Bumps the cargo group with 1 update in the / directory: [rand](https://github.com/rust-random/rand).


Updates `rand` from 0.8.5 to 0.8.6
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/0.8.6/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.8.6)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.8.6
  dependency-type: indirect
  dependency-group: cargo
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-23 02:02:24 +02:00
Bapuji Koraganti
987f367d7b web: merge MFA devices and tokens into unified Credentials tab (#21705)
* web: merge MFA devices and tokens into unified Credentials tab

Combines the separate "MFA Devices" and "Tokens and App passwords"
tabs into a single "Credentials" tab on the user settings page,
so users can manage all credentials from one place.

Fixes #21637

Signed-off-by: Bapuji Koraganti <bapuk.2008@gmail.com>

* add card title

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Bapuji Koraganti <bapuk.2008@gmail.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2026-04-23 02:02:00 +02:00
118 changed files with 4163 additions and 1716 deletions

View File

@@ -64,7 +64,7 @@ runs:
rustflags: ""
- name: Setup rust dependencies
if: ${{ contains(inputs.dependencies, 'rust') }}
uses: taiki-e/install-action@055f5df8c3f65ea01cd41e9dc855becd88953486 # v2
uses: taiki-e/install-action@5f57d6cb7cd20b14a8a27f522884c4bc8a187458 # v2
with:
tool: cargo-deny cargo-machete cargo-llvm-cov nextest
- name: Setup node (web)

View File

@@ -67,6 +67,12 @@ updates:
semver-major-days: 14
semver-patch-days: 3
exclude:
- aws-lc-fips-sys
- aws-lc-rs
- aws-lc-sys
- rustls
- rustls-pki-types
- rustls-platform-verifier
- rustls-webpki
- package-ecosystem: rust-toolchain

View File

@@ -38,7 +38,7 @@ jobs:
token: ${{ steps.generate_token.outputs.token }}
- name: Compress images
id: compress
uses: calibreapp/image-actions@4f7260f5dbd809ec86d03721c1ad71b8a841d3e0 # main
uses: calibreapp/image-actions@e2cc8db5d49c849e00844dfebf01438318e96fa2 # main
with:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
compressOnly: ${{ github.event_name != 'pull_request' }}

14
Cargo.lock generated
View File

@@ -1981,7 +1981,7 @@ dependencies = [
"num-integer",
"num-iter",
"num-traits",
"rand 0.8.5",
"rand 0.8.6",
"smallvec",
"zeroize",
]
@@ -2502,9 +2502,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
version = "0.8.5"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
dependencies = [
"libc",
"rand_chacha 0.3.1",
@@ -2737,9 +2737,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.38"
version = "0.23.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21"
checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e"
dependencies = [
"aws-lc-rs",
"log",
@@ -3315,7 +3315,7 @@ dependencies = [
"memchr",
"once_cell",
"percent-encoding",
"rand 0.8.5",
"rand 0.8.6",
"rsa",
"serde",
"sha1",
@@ -3356,7 +3356,7 @@ dependencies = [
"md-5",
"memchr",
"once_cell",
"rand 0.8.5",
"rand 0.8.6",
"serde",
"serde_json",
"sha2",

View File

@@ -58,7 +58,7 @@ reqwest-middleware = { version = "= 0.5.1", features = [
"query",
"rustls",
] }
rustls = { version = "= 0.23.38", features = ["fips"] }
rustls = { version = "= 0.23.39", features = ["fips"] }
sentry = { version = "= 0.47.0", default-features = false, features = [
"backtrace",
"contexts",

View File

@@ -1,7 +1,7 @@
from collections.abc import Generator, Iterator
from contextlib import contextmanager
from tempfile import SpooledTemporaryFile
from urllib.parse import urlsplit
from urllib.parse import urlsplit, urlunsplit
import boto3
from botocore.config import Config
@@ -164,16 +164,19 @@ class S3Backend(ManageableBackend):
)
def _file_url(name: str, request: HttpRequest | None) -> str:
client = self.client
params = {
"Bucket": self.bucket_name,
"Key": f"{self.base_path}/{name}",
}
url = self.client.generate_presigned_url(
"get_object",
Params=params,
ExpiresIn=expires_in,
HttpMethod="GET",
operation_name = "GetObject"
operation_model = client.meta.service_model.operation_model(operation_name)
request_dict = client._convert_to_request_dict(
params,
operation_model,
endpoint_url=client.meta.endpoint_url,
context={"is_presign_request": True},
)
# Support custom domain for S3-compatible storage (so not AWS)
@@ -183,9 +186,8 @@ class S3Backend(ManageableBackend):
CONFIG.get(f"storage.{self.name}.custom_domain", None),
)
if custom_domain:
parsed = urlsplit(url)
scheme = "https" if use_https else "http"
path = parsed.path
path = request_dict["url_path"]
# When using path-style addressing, the presigned URL contains the bucket
# name in the path (e.g., /bucket-name/key). Since custom_domain must
@@ -200,9 +202,22 @@ class S3Backend(ManageableBackend):
if not path.startswith("/"):
path = f"/{path}"
url = f"{scheme}://{custom_domain}{path}?{parsed.query}"
custom_base = urlsplit(f"{scheme}://{custom_domain}")
return url
# Sign the final public URL instead of signing the internal S3 endpoint and
# rewriting it afterwards. Presigned SigV4 URLs include the host header in the
# canonical request, so post-sign host changes break strict backends like RustFS.
public_path = f"{custom_base.path.rstrip('/')}{path}" if custom_base.path else path
request_dict["url_path"] = public_path
request_dict["url"] = urlunsplit(
(custom_base.scheme, custom_base.netloc, public_path, "", "")
)
return client._request_signer.generate_presigned_url(
request_dict,
operation_name,
expires_in=expires_in,
)
if use_cache:
return self._cache_get_or_set(name, request, _file_url, expires_in)

View File

@@ -1,4 +1,5 @@
from unittest import skipUnless
from urllib.parse import parse_qs, urlsplit
from botocore.exceptions import UnsupportedSignatureVersionError
from django.test import TestCase
@@ -168,6 +169,44 @@ class TestS3Backend(FileTestS3BackendMixin, TestCase):
f"URL: {url}",
)
@CONFIG.patch("storage.s3.secure_urls", False)
@CONFIG.patch("storage.s3.addressing_style", "path")
def test_file_url_custom_domain_resigns_for_custom_host(self):
"""Test presigned URLs are signed for the custom domain host.
Host-changing custom domains must produce a signature query string for
the public host, not reuse the internal endpoint signature.
"""
bucket_name = self.media_s3_bucket_name
key_name = "application-icons/test.svg"
custom_domain = f"files.example.test:8020/{bucket_name}"
endpoint_signed_url = self.media_s3_backend.client.generate_presigned_url(
"get_object",
Params={
"Bucket": bucket_name,
"Key": f"{self.media_s3_backend.base_path}/{key_name}",
},
ExpiresIn=900,
HttpMethod="GET",
)
with CONFIG.patch("storage.media.s3.custom_domain", custom_domain):
custom_url = self.media_s3_backend.file_url(key_name, use_cache=False)
endpoint_parts = urlsplit(endpoint_signed_url)
custom_parts = urlsplit(custom_url)
self.assertEqual(custom_parts.scheme, "http")
self.assertEqual(custom_parts.netloc, "files.example.test:8020")
self.assertEqual(parse_qs(custom_parts.query)["X-Amz-SignedHeaders"], ["host"])
self.assertNotEqual(
custom_parts.query,
endpoint_parts.query,
"Custom-domain URLs must be signed for the public host, not reuse the endpoint "
"signature query string.",
)
def test_themed_urls_without_theme_variable(self):
"""Test themed_urls returns None when filename has no %(theme)s"""
result = self.media_s3_backend.themed_urls("logo.png")

View File

@@ -1,5 +1,6 @@
"""Apply blueprint from commandline"""
from argparse import ArgumentParser
from sys import exit as sys_exit
from django.core.management.base import BaseCommand, no_translations
@@ -31,5 +32,5 @@ class Command(BaseCommand):
sys_exit(1)
importer.apply()
def add_arguments(self, parser):
def add_arguments(self, parser: ArgumentParser):
parser.add_argument("blueprints", nargs="+", type=str)

View File

@@ -4,7 +4,7 @@ from collections.abc import Iterator
from copy import copy
from django.core.cache import cache
from django.db.models import Case, QuerySet
from django.db.models import Case, Q, QuerySet
from django.db.models.expressions import When
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext as _
@@ -36,9 +36,13 @@ from authentik.rbac.filters import ObjectFilter
LOGGER = get_logger()
def user_app_cache_key(user_pk: str, page_number: int | None = None) -> str:
def user_app_cache_key(
user_pk: str, page_number: int | None = None, only_with_launch_url: bool = False
) -> str:
"""Cache key where application list for user is saved"""
key = f"{CACHE_PREFIX}app_access/{user_pk}"
if only_with_launch_url:
key += "/launch"
if page_number:
key += f"/{page_number}"
return key
@@ -274,11 +278,19 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
if superuser_full_list and request.user.is_superuser:
return super().list(request)
only_with_launch_url = str(
request.query_params.get("only_with_launch_url", "false")
).lower()
only_with_launch_url = (
str(request.query_params.get("only_with_launch_url", "false")).lower()
) == "true"
queryset = self._filter_queryset_for_list(self.get_queryset())
if only_with_launch_url:
# Pre-filter at DB level to skip expensive per-app policy evaluation
# for apps that can never appear in the launcher:
# - No meta_launch_url AND no provider: no possible launch URL
# - meta_launch_url="blank://blank": documented convention to hide from launcher
queryset = queryset.exclude(
Q(meta_launch_url="", provider__isnull=True) | Q(meta_launch_url="blank://blank")
)
paginator: Pagination = self.paginator
paginated_apps = paginator.paginate_queryset(queryset, request)
@@ -295,7 +307,6 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
except ValueError as exc:
raise ValidationError from exc
allowed_applications = self._get_allowed_applications(paginated_apps, user=for_user)
allowed_applications = self._expand_applications(allowed_applications)
serializer = self.get_serializer(allowed_applications, many=True)
return self.get_paginated_response(serializer.data)
@@ -305,19 +316,26 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
allowed_applications = self._get_allowed_applications(paginated_apps)
if should_cache:
allowed_applications = cache.get(
user_app_cache_key(self.request.user.pk, paginator.page.number)
user_app_cache_key(
self.request.user.pk, paginator.page.number, only_with_launch_url
)
)
if not allowed_applications:
if allowed_applications:
# Re-fetch cached applications since pickled instances lose prefetched
# relationships, causing N+1 queries during serialization
allowed_applications = self._expand_applications(allowed_applications)
else:
LOGGER.debug("Caching allowed application list", page=paginator.page.number)
allowed_applications = self._get_allowed_applications(paginated_apps)
cache.set(
user_app_cache_key(self.request.user.pk, paginator.page.number),
user_app_cache_key(
self.request.user.pk, paginator.page.number, only_with_launch_url
),
allowed_applications,
timeout=86400,
)
allowed_applications = self._expand_applications(allowed_applications)
if only_with_launch_url == "true":
if only_with_launch_url:
allowed_applications = self._filter_applications_with_launch_url(allowed_applications)
serializer = self.get_serializer(allowed_applications, many=True)

View File

@@ -7,6 +7,12 @@ from authentik.tasks.schedules.common import ScheduleSpec
from authentik.tenants.flags import Flag
class Setup(Flag[bool], key="setup"):
default = False
visibility = "system"
class AppAccessWithoutBindings(Flag[bool], key="core_default_app_access"):
default = True
@@ -26,6 +32,10 @@ class AuthentikCoreConfig(ManagedAppConfig):
mountpoint = ""
default = True
def import_related(self):
super().import_related()
self.import_module("authentik.core.setup.signals")
@ManagedAppConfig.reconcile_tenant
def source_inbuilt(self):
"""Reconcile inbuilt source"""

View File

@@ -0,0 +1,61 @@
# Generated by Django 5.2.13 on 2026-04-21 18:49
from django.apps.registry import Apps
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db import migrations
def check_is_already_setup(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from django.conf import settings
from authentik.flows.models import FlowAuthenticationRequirement
VersionHistory = apps.get_model("authentik_admin", "VersionHistory")
Flow = apps.get_model("authentik_flows", "Flow")
User = apps.get_model("authentik_core", "User")
db_alias = schema_editor.connection.alias
# Upgrading from a previous version
if not settings.TEST and VersionHistory.objects.using(db_alias).count() > 1:
return True
# OOBE flow sets itself to this authentication requirement once finished
if (
Flow.objects.using(db_alias)
.filter(
slug="initial-setup", authentication=FlowAuthenticationRequirement.REQUIRE_SUPERUSER
)
.exists()
):
return True
# non-akadmin and non-guardian anonymous user exist
if (
User.objects.using(db_alias)
.exclude(username="akadmin")
.exclude(username="AnonymousUser")
.exists()
):
return True
return False
def update_setup_flag(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from authentik.core.apps import Setup
from authentik.tenants.utils import get_current_tenant
is_already_setup = check_is_already_setup(apps, schema_editor)
if is_already_setup:
tenant = get_current_tenant()
tenant.flags[Setup().key] = True
tenant.save()
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0057_remove_user_groups_remove_user_user_permissions_and_more"),
# 0024_flow_authentication adds the `authentication` field.
("authentik_flows", "0024_flow_authentication"),
]
operations = [migrations.RunPython(update_setup_flag, migrations.RunPython.noop)]

View File

@@ -790,9 +790,13 @@ class Application(SerializerModel, PolicyBindingModel):
def get_provider(self) -> Provider | None:
"""Get casted provider instance. Needs Application queryset with_provider"""
if hasattr(self, "_cached_provider"):
return self._cached_provider
if not self.provider:
self._cached_provider = None
return None
return get_deepest_child(self.provider)
self._cached_provider = get_deepest_child(self.provider)
return self._cached_provider
def backchannel_provider_for[T: Provider](self, provider_type: type[T], **kwargs) -> T | None:
"""Get Backchannel provider for a specific type"""

View File

View File

@@ -0,0 +1,38 @@
from os import getenv
from django.dispatch import receiver
from structlog.stdlib import get_logger
from authentik.blueprints.models import BlueprintInstance
from authentik.blueprints.v1.importer import Importer
from authentik.core.apps import Setup
from authentik.root.signals import post_startup
from authentik.tenants.models import Tenant
BOOTSTRAP_BLUEPRINT = "system/bootstrap.yaml"
LOGGER = get_logger()
@receiver(post_startup)
def post_startup_setup_bootstrap(sender, **_):
if not getenv("AUTHENTIK_BOOTSTRAP_PASSWORD") and not getenv("AUTHENTIK_BOOTSTRAP_TOKEN"):
return
LOGGER.info("Configuring authentik through bootstrap environment variables")
content = BlueprintInstance(path=BOOTSTRAP_BLUEPRINT).retrieve()
# If we have bootstrap credentials set, run bootstrap tasks outside of main server
# sync, so that we can sure the first start actually has working bootstrap
# credentials
for tenant in Tenant.objects.filter(ready=True):
if Setup.get(tenant=tenant):
LOGGER.info("Tenant is already setup, skipping", tenant=tenant.schema_name)
continue
with tenant:
importer = Importer.from_string(content)
valid, logs = importer.validate()
if not valid:
LOGGER.warning("Blueprint invalid", tenant=tenant.schema_name)
for log in logs:
log.log()
importer.apply()
Setup.set(True, tenant=tenant)

View File

@@ -0,0 +1,80 @@
from functools import lru_cache
from http import HTTPMethod, HTTPStatus
from django.contrib.staticfiles import finders
from django.db import transaction
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.views import View
from structlog.stdlib import get_logger
from authentik.blueprints.models import BlueprintInstance
from authentik.core.apps import Setup
from authentik.flows.models import Flow, FlowAuthenticationRequirement, in_memory_stage
from authentik.flows.planner import FlowPlanner
from authentik.flows.stage import StageView
LOGGER = get_logger()
FLOW_CONTEXT_START_BY = "goauthentik.io/core/setup/started-by"
@lru_cache
def read_static(path: str) -> str | None:
result = finders.find(path)
if not result:
return None
with open(result, encoding="utf8") as _file:
return _file.read()
class SetupView(View):
setup_flow_slug = "initial-setup"
def dispatch(self, request: HttpRequest, *args, **kwargs):
if request.method != HTTPMethod.HEAD and Setup.get():
return redirect(reverse("authentik_core:root-redirect"))
return super().dispatch(request, *args, **kwargs)
def head(self, request: HttpRequest, *args, **kwargs):
if Setup.get():
return HttpResponse(status=HTTPStatus.SERVICE_UNAVAILABLE)
if not Flow.objects.filter(slug=self.setup_flow_slug).exists():
return HttpResponse(status=HTTPStatus.SERVICE_UNAVAILABLE)
return HttpResponse(status=HTTPStatus.OK)
def get(self, request: HttpRequest):
flow = Flow.objects.filter(slug=self.setup_flow_slug).first()
if not flow:
LOGGER.info("Setup flow does not exist yet, waiting for worker to finish")
return HttpResponse(
read_static("dist/standalone/loading/startup.html"),
status=HTTPStatus.SERVICE_UNAVAILABLE,
)
planner = FlowPlanner(flow)
plan = planner.plan(request, {FLOW_CONTEXT_START_BY: "setup"})
plan.append_stage(in_memory_stage(PostSetupStageView))
return plan.to_redirect(request, flow)
class PostSetupStageView(StageView):
"""Run post-setup tasks"""
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
"""Wrapper when this stage gets hit with a post request"""
return self.get(request, *args, **kwargs)
def get(self, requeset: HttpRequest, *args, **kwargs):
with transaction.atomic():
# Remember we're setup
Setup.set(True)
# Disable OOBE Blueprints
BlueprintInstance.objects.filter(
**{"metadata__labels__blueprints.goauthentik.io/system-oobe": "true"}
).update(enabled=False)
# Make flow inaccessible
Flow.objects.filter(slug="initial-setup").update(
authentication=FlowAuthenticationRequirement.REQUIRE_SUPERUSER
)
return self.executor.stage_ok()

View File

@@ -4,6 +4,7 @@ from django.test import TestCase
from django.urls import reverse
from authentik.brands.models import Brand
from authentik.core.apps import Setup
from authentik.core.models import Application, UserTypes
from authentik.core.tests.utils import create_test_brand, create_test_user
@@ -12,6 +13,7 @@ class TestInterfaceRedirects(TestCase):
"""Test RootRedirectView and BrandDefaultRedirectView redirect logic by user type"""
def setUp(self):
Setup.set(True)
self.app = Application.objects.create(name="test-app", slug="test-app")
self.brand: Brand = create_test_brand(default_application=self.app)

View File

@@ -0,0 +1,156 @@
from http import HTTPStatus
from os import environ
from django.urls import reverse
from authentik.blueprints.tests import apply_blueprint
from authentik.core.apps import Setup
from authentik.core.models import Token, TokenIntents, User
from authentik.flows.models import Flow
from authentik.flows.tests import FlowTestCase
from authentik.lib.generators import generate_id
from authentik.root.signals import post_startup, pre_startup
from authentik.tenants.flags import patch_flag
class TestSetup(FlowTestCase):
def tearDown(self):
environ.pop("AUTHENTIK_BOOTSTRAP_PASSWORD", None)
environ.pop("AUTHENTIK_BOOTSTRAP_TOKEN", None)
@patch_flag(Setup, True)
def test_setup(self):
"""Test existing instance"""
res = self.client.get(reverse("authentik_core:root-redirect"))
self.assertEqual(res.status_code, HTTPStatus.FOUND)
self.assertRedirects(
res,
reverse("authentik_flows:default-authentication") + "?next=/",
fetch_redirect_response=False,
)
res = self.client.head(reverse("authentik_core:setup"))
self.assertEqual(res.status_code, HTTPStatus.SERVICE_UNAVAILABLE)
res = self.client.get(reverse("authentik_core:setup"))
self.assertEqual(res.status_code, HTTPStatus.FOUND)
self.assertRedirects(
res,
reverse("authentik_core:root-redirect"),
fetch_redirect_response=False,
)
@patch_flag(Setup, False)
def test_not_setup_no_flow(self):
"""Test case on initial startup; setup flag is not set and oobe flow does
not exist yet"""
Flow.objects.filter(slug="initial-setup").delete()
res = self.client.get(reverse("authentik_core:root-redirect"))
self.assertEqual(res.status_code, HTTPStatus.FOUND)
self.assertRedirects(res, reverse("authentik_core:setup"), fetch_redirect_response=False)
# Flow does not exist, hence 503
res = self.client.get(reverse("authentik_core:setup"))
self.assertEqual(res.status_code, HTTPStatus.SERVICE_UNAVAILABLE)
res = self.client.head(reverse("authentik_core:setup"))
self.assertEqual(res.status_code, HTTPStatus.SERVICE_UNAVAILABLE)
@patch_flag(Setup, False)
@apply_blueprint("default/flow-oobe.yaml")
def test_not_setup(self):
"""Test case for when worker comes up, and has created flow"""
res = self.client.get(reverse("authentik_core:root-redirect"))
self.assertEqual(res.status_code, HTTPStatus.FOUND)
self.assertRedirects(res, reverse("authentik_core:setup"), fetch_redirect_response=False)
# Flow does not exist, hence 503
res = self.client.head(reverse("authentik_core:setup"))
self.assertEqual(res.status_code, HTTPStatus.OK)
res = self.client.get(reverse("authentik_core:setup"))
self.assertEqual(res.status_code, HTTPStatus.FOUND)
self.assertRedirects(
res,
reverse("authentik_core:if-flow", kwargs={"flow_slug": "initial-setup"}),
fetch_redirect_response=False,
)
@apply_blueprint("default/flow-oobe.yaml")
@apply_blueprint("system/bootstrap.yaml")
def test_setup_flow_full(self):
"""Test full setup flow"""
Setup.set(False)
res = self.client.get(reverse("authentik_core:setup"))
self.assertEqual(res.status_code, HTTPStatus.FOUND)
self.assertRedirects(
res,
reverse("authentik_core:if-flow", kwargs={"flow_slug": "initial-setup"}),
fetch_redirect_response=False,
)
res = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": "initial-setup"}),
)
self.assertEqual(res.status_code, HTTPStatus.OK)
self.assertStageResponse(res, component="ak-stage-prompt")
pw = generate_id()
res = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": "initial-setup"}),
{
"email": f"{generate_id()}@t.goauthentik.io",
"password": pw,
"password_repeat": pw,
"component": "ak-stage-prompt",
},
)
self.assertEqual(res.status_code, HTTPStatus.FOUND)
res = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": "initial-setup"}),
)
self.assertEqual(res.status_code, HTTPStatus.FOUND)
res = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": "initial-setup"}),
)
self.assertEqual(res.status_code, HTTPStatus.FOUND)
res = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": "initial-setup"}),
)
self.assertEqual(res.status_code, HTTPStatus.OK)
self.assertTrue(Setup.get())
user = User.objects.get(username="akadmin")
self.assertTrue(user.check_password(pw))
@patch_flag(Setup, False)
@apply_blueprint("default/flow-oobe.yaml")
@apply_blueprint("system/bootstrap.yaml")
def test_setup_flow_direct(self):
"""Test setup flow, directly accessing the flow"""
res = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": "initial-setup"})
)
self.assertStageResponse(
res,
component="ak-stage-access-denied",
error_message="Access the authentik setup by navigating to http://testserver/",
)
def test_setup_bootstrap_env(self):
"""Test setup with env vars"""
User.objects.filter(username="akadmin").delete()
Setup.set(False)
environ["AUTHENTIK_BOOTSTRAP_PASSWORD"] = generate_id()
environ["AUTHENTIK_BOOTSTRAP_TOKEN"] = generate_id()
pre_startup.send(sender=self)
post_startup.send(sender=self)
self.assertTrue(Setup.get())
user = User.objects.get(username="akadmin")
self.assertTrue(user.check_password(environ["AUTHENTIK_BOOTSTRAP_PASSWORD"]))
token = Token.objects.filter(identifier="authentik-bootstrap-token").first()
self.assertEqual(token.intent, TokenIntents.INTENT_API)
self.assertEqual(token.key, environ["AUTHENTIK_BOOTSTRAP_TOKEN"])

View File

@@ -1,7 +1,6 @@
"""authentik URL Configuration"""
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.urls import path
from authentik.core.api.application_entitlements import ApplicationEntitlementViewSet
@@ -19,6 +18,7 @@ from authentik.core.api.sources import (
from authentik.core.api.tokens import TokenViewSet
from authentik.core.api.transactional_applications import TransactionalApplicationView
from authentik.core.api.users import UserViewSet
from authentik.core.setup.views import SetupView
from authentik.core.views.apps import RedirectToAppLaunch
from authentik.core.views.debug import AccessDeniedView
from authentik.core.views.interface import (
@@ -35,7 +35,7 @@ from authentik.tenants.channels import TenantsAwareMiddleware
urlpatterns = [
path(
"",
login_required(RootRedirectView.as_view()),
RootRedirectView.as_view(),
name="root-redirect",
),
path(
@@ -62,6 +62,11 @@ urlpatterns = [
FlowInterfaceView.as_view(),
name="if-flow",
),
path(
"setup",
SetupView.as_view(),
name="setup",
),
# Fallback for WS
path("ws/outpost/<uuid:pk>/", InterfaceView.as_view(template_name="if/admin.html")),
path(

View File

@@ -3,6 +3,7 @@
from json import dumps
from typing import Any
from django.contrib.auth.mixins import AccessMixin
from django.http import HttpRequest
from django.http.response import HttpResponse
from django.shortcuts import redirect
@@ -14,12 +15,13 @@ from authentik.admin.tasks import LOCAL_VERSION
from authentik.api.v3.config import ConfigView
from authentik.brands.api import CurrentBrandSerializer
from authentik.brands.models import Brand
from authentik.core.apps import Setup
from authentik.core.models import UserTypes
from authentik.lib.config import CONFIG
from authentik.policies.denied import AccessDeniedResponse
class RootRedirectView(RedirectView):
class RootRedirectView(AccessMixin, RedirectView):
"""Root redirect view, redirect to brand's default application if set"""
pattern_name = "authentik_core:if-user"
@@ -40,6 +42,10 @@ class RootRedirectView(RedirectView):
return None
def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
if not Setup.get():
return redirect("authentik_core:setup")
if not request.user.is_authenticated:
return self.handle_no_permission()
if redirect_response := RootRedirectView().redirect_to_app(request):
return redirect_response
return super().dispatch(request, *args, **kwargs)

View File

@@ -1,10 +1,12 @@
from unittest.mock import PropertyMock, patch
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.tests.utils import create_test_admin_user
from authentik.endpoints.connectors.agent.models import AgentConnector
from authentik.endpoints.controller import BaseController
from authentik.endpoints.models import StageMode
from authentik.enterprise.endpoints.connectors.fleet.models import FleetConnector
from authentik.lib.generators import generate_id
@@ -25,16 +27,22 @@ class TestAPI(APITestCase):
)
self.assertEqual(res.status_code, 201)
def test_endpoint_stage_fleet(self):
connector = FleetConnector.objects.create(name=generate_id())
res = self.client.post(
reverse("authentik_api:stages-endpoint-list"),
data={
"name": generate_id(),
"connector": str(connector.pk),
"mode": StageMode.REQUIRED,
},
)
def test_endpoint_stage_agent_no_stage(self):
connector = AgentConnector.objects.create(name=generate_id())
class controller(BaseController):
def capabilities(self):
return []
with patch.object(AgentConnector, "controller", PropertyMock(return_value=controller)):
res = self.client.post(
reverse("authentik_api:stages-endpoint-list"),
data={
"name": generate_id(),
"connector": str(connector.pk),
"mode": StageMode.REQUIRED,
},
)
self.assertEqual(res.status_code, 400)
self.assertJSONEqual(
res.content, {"connector": ["Selected connector is not compatible with this stage."]}

View File

@@ -1,11 +1,15 @@
import re
from plistlib import loads
from typing import Any
from cryptography.hazmat.primitives import serialization
from cryptography.x509 import load_der_x509_certificate
from django.db import transaction
from requests import RequestException
from rest_framework.exceptions import ValidationError
from authentik.core.models import User
from authentik.crypto.models import CertificateKeyPair
from authentik.endpoints.controller import BaseController, Capabilities, ConnectorSyncException
from authentik.endpoints.facts import (
DeviceFacts,
@@ -44,7 +48,7 @@ class FleetController(BaseController[DBC]):
return "fleetdm.com"
def capabilities(self) -> list[Capabilities]:
return [Capabilities.ENROLL_AUTOMATIC_API]
return [Capabilities.STAGE_ENDPOINTS, Capabilities.ENROLL_AUTOMATIC_API]
def _url(self, path: str) -> str:
return f"{self.connector.url}{path}"
@@ -76,8 +80,44 @@ class FleetController(BaseController[DBC]):
except RequestException as exc:
raise ConnectorSyncException(exc) from exc
@property
def mtls_ca_managed(self) -> str:
return f"goauthentik.io/endpoints/connectors/fleet/{self.connector.pk}"
def _sync_mtls_ca(self):
"""Sync conditional access Root CA for mTLS"""
try:
# Fleet doesn't have an API to just get the Conditional Access Root CA Cert (yet),
# hence we fetch the apple config profile and extract it
res = self._session.get(self._url("/api/v1/fleet/conditional_access/idp/apple/profile"))
res.raise_for_status()
profile = loads(res.text).get("PayloadContent", [])
raw_cert = None
for payload in profile:
if payload.get("PayloadIdentifier", "") != "com.fleetdm.conditional-access-ca":
continue
raw_cert = payload.get("PayloadContent")
if not raw_cert:
raise ConnectorSyncException("Failed to get conditional acccess CA")
except RequestException as exc:
raise ConnectorSyncException(exc) from exc
cert = load_der_x509_certificate(raw_cert)
CertificateKeyPair.objects.update_or_create(
managed=self.mtls_ca_managed,
defaults={
"name": f"Fleet Endpoint connector {self.connector.name}",
"certificate_data": cert.public_bytes(
encoding=serialization.Encoding.PEM,
).decode("utf-8"),
},
)
@transaction.atomic
def sync_endpoints(self) -> None:
try:
self._sync_mtls_ca()
except ConnectorSyncException as exc:
self.logger.warning("Failed to sync conditional access CA", exc=exc)
for host in self._paginate_hosts():
serial = host["hardware_serial"]
device, _ = Device.objects.get_or_create(
@@ -198,6 +238,8 @@ class FleetController(BaseController[DBC]):
for policy in host.get("policies", [])
],
"agent_version": fleet_version,
# Host UUID is required for conditional access matching
"uuid": host.get("uuid", "").lower(),
},
},
}

View File

@@ -51,6 +51,12 @@ class FleetConnector(Connector):
def component(self) -> str:
return "ak-endpoints-connector-fleet-form"
@property
def stage(self):
from authentik.enterprise.endpoints.connectors.fleet.stage import FleetStageView
return FleetStageView
class Meta:
verbose_name = _("Fleet Connector")
verbose_name_plural = _("Fleet Connectors")

View File

@@ -0,0 +1,51 @@
from cryptography.x509 import (
Certificate,
Extension,
SubjectAlternativeName,
UniformResourceIdentifier,
)
from rest_framework.exceptions import PermissionDenied
from authentik.crypto.models import CertificateKeyPair, fingerprint_sha256
from authentik.endpoints.models import Device, EndpointStage, StageMode
from authentik.enterprise.endpoints.connectors.fleet.models import FleetConnector
from authentik.enterprise.stages.mtls.stage import PLAN_CONTEXT_CERTIFICATE, MTLSStageView
from authentik.flows.planner import PLAN_CONTEXT_DEVICE
FLEET_CONDITIONAL_ACCESS_URI_PREFIX = "urn:device:apple:uuid:"
class FleetStageView(MTLSStageView):
def get_authorities(self):
stage: EndpointStage = self.executor.current_stage
connector = FleetConnector.objects.filter(pk=stage.connector_id).first()
controller = connector.controller(connector)
kp = CertificateKeyPair.objects.filter(managed=controller.mtls_ca_managed).first()
return [kp] if kp else None
def lookup_device(self, cert: Certificate, mode: StageMode):
san_ext: Extension[SubjectAlternativeName] = cert.extensions.get_extension_for_oid(
SubjectAlternativeName.oid
)
raw_values = san_ext.value.get_values_for_type(UniformResourceIdentifier)
values = [x.removeprefix(FLEET_CONDITIONAL_ACCESS_URI_PREFIX).lower() for x in raw_values]
self.logger.debug("Looking for devices with uuid", fleet_device_uuid=values)
device = Device.objects.filter(
**{"deviceconnection__devicefactsnapshot__data__vendor__fleetdm.com__uuid__in": values}
).first()
if not device and mode == StageMode.REQUIRED:
raise PermissionDenied("Failed to find device")
self.executor.plan.context[PLAN_CONTEXT_DEVICE] = device
self.executor.plan.context[PLAN_CONTEXT_CERTIFICATE] = self._cert_to_dict(cert)
return self.executor.stage_ok()
def dispatch(self, request, *args, **kwargs):
stage: EndpointStage = self.executor.current_stage
try:
cert = self.get_cert(stage.mode)
if not cert:
return self.executor.stage_ok()
self.logger.debug("Received certificate", cert=fingerprint_sha256(cert))
return self.lookup_device(cert, stage.mode)
except PermissionDenied as exc:
return self.executor.stage_invalid(error_message=exc.detail)

View File

@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIIDwDCCAqigAwIBAgIBBDANBgkqhkiG9w0BAQsFADBpMQkwBwYDVQQGEwAxJDAi
BgNVBAoTG0xvY2FsIGNlcnRpZmljYXRlIGF1dGhvcml0eTEQMA4GA1UECxMHU0NF
UCBDQTEkMCIGA1UEAxMbRmxlZXQgY29uZGl0aW9uYWwgYWNjZXNzIENBMB4XDTI2
MDMxODExMTc1NFoXDTI3MDQyMDExMjc1NFowLDEqMCgGA1UEAxMhRmxlZXQgY29u
ZGl0aW9uYWwgYWNjZXNzIGZvciBPa3RhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA3xuKxQQ8JSA4qCJ6RfOB7tbQurhwXiaJSLUDG7R5ncdRcd9LH/9y
5ZyI5kQACOwfICHmv02zR4/CrurfzXabo3CCpvcMdS7JI/FzP1GIIZ5RsR7oPFC6
JJg3m5BHuoHsUtCD7w0D52WiE7XVfbw47h2ChKmGMhkSrBvQnp3dHFEt8ntbl1/q
zCSuQaLeR2sQFurBDVBdinEgsvb1YHaYHi4tdFx5joG64Q/nJXyA2OM4hO9uBF+G
c4UVTzubx5sxwONcPhC9H+eLMpF1VHeU9gAGBlruVusUEYDmlqYQuA+bW5fTr4Zd
ZmJ5e+CzzUBYHduAML9a5S+1jbxSPZFBSwIDAQABo4GvMIGsMA4GA1UdDwEB/wQE
AwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUPrc1+LvbR9WoJIWZ
7YQa/3IX2w8wHwYDVR0jBBgwFoAUfl92kU2qcH4e+hypez4kEnqMbk4wRQYDVR0R
BD4wPIY6dXJuOmRldmljZTphcHBsZTp1dWlkOjVCRjQyMkQ2LTZFQUItNTE1Ni1B
QzVBLTlFQURDOTUyNDcxMzANBgkqhkiG9w0BAQsFAAOCAQEAGfxJ/u4271tnUUTB
J39YU6z2Ciav+9G3BtbvxBXI57Po7zCE6Z1sVkvYq6Xd0CcItPWRjbSPEy78ZzS0
By+gPy5fkKc8HHJ5I1wK890xbLBUS1P4EbdVBzI9ggouEa3B2asE10asnzLoKE4C
0FYWQwrzCsso8yxsJj1S8RKtd6MMbCis/9OQSC8om2tu6cLO+OftVn5DHtNWFidw
tAl/oHn2cZPUfZGpJGrHNZlp5w1c1dYfQeiPayoQIbsF+8eMV424G76z/8UPhMBs
R23LByv4TlUOPAGn2TRa2WtLIXs7FgqXRIFW4CjsPsEpXSVNlkYcn/VHY7Jl13zz
CRQ1Pg==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<!-- Trusted CA certificate -->
<dict>
<key>PayloadCertificateFileName</key>
<string>conditional_access_ca.der</string>
<key>PayloadContent</key>
<data>MIIDjzCCAnegAwIBAgIBATANBgkqhkiG9w0BAQsFADBpMQkwBwYDVQQGEwAxJDAiBgNVBAoTG0xvY2FsIGNlcnRpZmljYXRlIGF1dGhvcml0eTEQMA4GA1UECxMHU0NFUCBDQTEkMCIGA1UEAxMbRmxlZXQgY29uZGl0aW9uYWwgYWNjZXNzIENBMB4XDTI1MTIwOTEyMjI1MVoXDTM1MTIwOTEyMjI1MVowaTEJMAcGA1UEBhMAMSQwIgYDVQQKExtMb2NhbCBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkxEDAOBgNVBAsTB1NDRVAgQ0ExJDAiBgNVBAMTG0ZsZWV0IGNvbmRpdGlvbmFsIGFjY2VzcyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANrgCcpzQci2UhH+Dn0eHopnnbx3HbMabMCHXm6xteMVFLrdQJDTFrZCQzcexUgbpPJ0az6mn4szo+E3stn0y2PPWsiAiVhFwp5M9HwNg18rPgDmITv2pM3l/hlEsfggjq6TEVO2gRcq4NujEGagcYX6kp6nWxh6bbRngQ/hlK6mXItWV3x0G9eTcbFObwZhbuC2dNbccytdqbVEIpBjp6fftQnQwAaUVjoyZBFlf1C1cDV4+1jpaVsIj11U1olA33GJCHcZQ4CJEsgh8yiSsvkH5RNf94CGINB5ixsMfppjSXV/vNkWDKEfmUXW2q4ft7KK/L/SRq8QSB4VqTAp2GsCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH5fdpFNqnB+HvocqXs+JBJ6jG5OMA0GCSqGSIb3DQEBCwUAA4IBAQAJr4bTGlrANoHStu4Y+OXjGbEQjZOe546Bcln4eWrEB16eaVzfKuZgjJYdcOmp36/v34QY/OCXEIsixrBU5aW/Sr53IK6UQSZV3O3xbBc4Aert7AbeJ4NVGZyelfVQo/5G0qM6k9p0+zpIZqNAzFbhcSPIzuE7ig2OGsFoQU+bXhzk09bsZ+u4BXibzVNfMuMG+DHNv0PRjll272nEPI3bGwHF5tdrnfJG6e9t+qK9j9UqmSlBknHQJNeU5o8IDcmWYjWtOuBzecYsg8pZzXabJqlHTBIz/h7waRe7jtrK+XopK3jghRf9JTL+i0Y8NbVjoNkIoS3xMeRhnNbR9lw1</data>
<key>PayloadDescription</key>
<string>Fleet conditional access CA certificate</string>
<key>PayloadDisplayName</key>
<string>Fleet conditional access CA</string>
<key>PayloadIdentifier</key>
<string>com.fleetdm.conditional-access-ca</string>
<key>PayloadType</key>
<string>com.apple.security.root</string>
<key>PayloadUUID</key>
<string>ef1b2231-ad80-5511-9893-1f9838295147</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>Configures SCEP enrollment for Okta conditional access</string>
<key>PayloadDisplayName</key>
<string>Fleet conditional access for Okta</string>
<key>PayloadIdentifier</key>
<string>com.fleetdm.conditional-access-okta</string>
<key>PayloadOrganization</key>
<string>Fleet Device Management</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadScope</key>
<string>User</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>6fa509a3-feca-56f7-a283-d6a81c733ed2</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

View File

@@ -1,27 +1,27 @@
{
"created_at": "2025-06-25T22:21:35Z",
"updated_at": "2025-12-20T11:42:09Z",
"created_at": "2026-02-18T16:31:34Z",
"updated_at": "2026-03-18T11:29:18Z",
"software": null,
"software_updated_at": "2025-10-22T02:24:25Z",
"id": 1,
"detail_updated_at": "2025-10-23T23:30:31Z",
"label_updated_at": "2025-10-23T23:30:31Z",
"policy_updated_at": "2025-10-23T23:02:11Z",
"last_enrolled_at": "2025-06-25T22:21:37Z",
"seen_time": "2025-10-23T23:59:08Z",
"software_updated_at": "2026-03-18T11:29:17Z",
"id": 19,
"detail_updated_at": "2026-03-18T11:29:18Z",
"label_updated_at": "2026-03-18T11:29:18Z",
"policy_updated_at": "2026-03-18T11:29:18Z",
"last_enrolled_at": "2026-02-18T16:31:45Z",
"seen_time": "2026-03-18T11:31:34Z",
"refetch_requested": false,
"hostname": "jens-mac-vm.local",
"uuid": "C8B98348-A0A6-5838-A321-57B59D788269",
"uuid": "5BF422D6-6EAB-5156-AC5A-9EADC9524713",
"platform": "darwin",
"osquery_version": "5.19.0",
"osquery_version": "5.21.0",
"orbit_version": null,
"fleet_desktop_version": null,
"scripts_enabled": null,
"os_version": "macOS 26.0.1",
"build": "25A362",
"os_version": "macOS 26.3",
"build": "25D125",
"platform_like": "darwin",
"code_name": "",
"uptime": 256356000000000,
"uptime": 653014000000000,
"memory": 4294967296,
"cpu_type": "arm64e",
"cpu_subtype": "ARM64E",
@@ -31,38 +31,41 @@
"hardware_vendor": "Apple Inc.",
"hardware_model": "VirtualMac2,1",
"hardware_version": "",
"hardware_serial": "Z5DDF07GK6",
"hardware_serial": "ZV35VFDD50",
"computer_name": "jens-mac-vm",
"timezone": null,
"public_ip": "92.116.179.252",
"primary_ip": "192.168.85.3",
"primary_mac": "e6:9d:21:c2:2f:19",
"primary_ip": "192.168.64.7",
"primary_mac": "5e:72:1c:89:98:29",
"distributed_interval": 10,
"config_tls_refresh": 60,
"logger_tls_period": 10,
"team_id": 2,
"team_id": 5,
"pack_stats": null,
"team_name": "prod",
"gigs_disk_space_available": 23.82,
"percent_disk_space_available": 37,
"team_name": "dev",
"gigs_disk_space_available": 16.52,
"percent_disk_space_available": 26,
"gigs_total_disk_space": 62.83,
"gigs_all_disk_space": null,
"issues": {
"failing_policies_count": 1,
"critical_vulnerabilities_count": 2,
"total_issues_count": 3
"critical_vulnerabilities_count": 0,
"total_issues_count": 1
},
"device_mapping": null,
"mdm": {
"enrollment_status": "On (manual)",
"dep_profile_error": false,
"server_url": "https://fleet.beryjuio-home.k8s.beryju.io/mdm/apple/mdm",
"server_url": "https://fleet.beryjuio-prod.k8s.beryju.io/mdm/apple/mdm",
"name": "Fleet",
"encryption_key_available": false,
"connected_to_fleet": true
},
"refetch_critical_queries_until": null,
"last_restarted_at": "2025-10-21T00:17:55Z",
"status": "offline",
"last_restarted_at": "2026-03-10T22:05:44.00887Z",
"status": "online",
"display_text": "jens-mac-vm.local",
"display_name": "jens-mac-vm"
"display_name": "jens-mac-vm",
"fleet_id": 5,
"fleet_name": "dev"
}

View File

@@ -21,12 +21,19 @@ TEST_HOST = {"hosts": [TEST_HOST_UBUNTU, TEST_HOST_MACOS, TEST_HOST_WINDOWS, TES
class TestFleetConnector(APITestCase):
def setUp(self):
self.connector = FleetConnector.objects.create(
name=generate_id(), url="http://localhost", token=generate_id()
name=generate_id(),
url="http://localhost",
token=generate_id(),
map_teams_access_group=True,
)
def test_sync(self):
controller = self.connector.controller(self.connector)
with Mocker() as mock:
mock.get(
"http://localhost/api/v1/fleet/conditional_access/idp/apple/profile",
text=load_fixture("fixtures/cond_acc_profile.mobileconfig"),
)
mock.get(
"http://localhost/api/v1/fleet/hosts?order_key=hardware_serial&page=0&per_page=50&device_mapping=true&populate_software=true&populate_users=true",
json=TEST_HOST,
@@ -40,6 +47,9 @@ class TestFleetConnector(APITestCase):
identifier="VMware-56 4d 4a 5a b0 22 7b d7-9b a5 0b dc 8f f2 3b 60"
).first()
self.assertIsNotNone(device)
group = device.access_group
self.assertIsNotNone(group)
self.assertEqual(group.name, "prod")
self.assertEqual(
device.cached_facts.data,
{
@@ -50,7 +60,13 @@ class TestFleetConnector(APITestCase):
"version": "24.04.3 LTS",
},
"disks": [],
"vendor": {"fleetdm.com": {"policies": [], "agent_version": ""}},
"vendor": {
"fleetdm.com": {
"policies": [],
"agent_version": "",
"uuid": "5a4a4d56-22b0-d77b-9ba5-0bdc8ff23b60",
}
},
"network": {"hostname": "ubuntu-desktop", "interfaces": []},
"hardware": {
"model": "VMware20,1",
@@ -72,6 +88,10 @@ class TestFleetConnector(APITestCase):
self.connector.save()
controller = self.connector.controller(self.connector)
with Mocker() as mock:
mock.get(
"http://localhost/api/v1/fleet/conditional_access/idp/apple/profile",
text=load_fixture("fixtures/cond_acc_profile.mobileconfig"),
)
mock.get(
"http://localhost/api/v1/fleet/hosts?order_key=hardware_serial&page=0&per_page=50&device_mapping=true&populate_software=true&populate_users=true",
json=TEST_HOST,
@@ -81,11 +101,13 @@ class TestFleetConnector(APITestCase):
json={"hosts": []},
)
controller.sync_endpoints()
self.assertEqual(mock.call_count, 2)
self.assertEqual(mock.call_count, 3)
self.assertEqual(mock.request_history[0].method, "GET")
self.assertEqual(mock.request_history[0].headers["foo"], "bar")
self.assertEqual(mock.request_history[1].method, "GET")
self.assertEqual(mock.request_history[1].headers["foo"], "bar")
self.assertEqual(mock.request_history[2].method, "GET")
self.assertEqual(mock.request_history[2].headers["foo"], "bar")
def test_map_host_linux(self):
controller = self.connector.controller(self.connector)
@@ -128,6 +150,6 @@ class TestFleetConnector(APITestCase):
"arch": "arm64e",
"family": OSFamily.macOS,
"name": "macOS",
"version": "26.0.1",
"version": "26.3",
},
)

View File

@@ -0,0 +1,84 @@
from json import loads
from ssl import PEM_FOOTER, PEM_HEADER
from django.urls import reverse
from requests_mock import Mocker
from authentik.core.tests.utils import (
create_test_flow,
)
from authentik.endpoints.models import Device, EndpointStage, StageMode
from authentik.enterprise.endpoints.connectors.fleet.models import FleetConnector
from authentik.enterprise.stages.mtls.stage import PLAN_CONTEXT_CERTIFICATE
from authentik.flows.models import FlowDesignation, FlowStageBinding
from authentik.flows.planner import PLAN_CONTEXT_DEVICE
from authentik.flows.tests import FlowTestCase
from authentik.lib.generators import generate_id
from authentik.lib.tests.utils import load_fixture
class FleetConnectorStageTests(FlowTestCase):
def setUp(self):
super().setUp()
self.connector = FleetConnector.objects.create(
name=generate_id(), url="http://localhost", token=generate_id()
)
controller = self.connector.controller(self.connector)
with Mocker() as mock:
mock.get(
"http://localhost/api/v1/fleet/conditional_access/idp/apple/profile",
text=load_fixture("fixtures/cond_acc_profile.mobileconfig"),
)
mock.get(
"http://localhost/api/v1/fleet/hosts?order_key=hardware_serial&page=0&per_page=50&device_mapping=true&populate_software=true&populate_users=true",
json={"hosts": [loads(load_fixture("fixtures/host_macos.json"))]},
)
mock.get(
"http://localhost/api/v1/fleet/hosts?order_key=hardware_serial&page=1&per_page=50&device_mapping=true&populate_software=true&populate_users=true",
json={"hosts": []},
)
controller.sync_endpoints()
self.flow = create_test_flow(FlowDesignation.AUTHENTICATION)
self.stage = EndpointStage.objects.create(
name=generate_id(),
mode=StageMode.REQUIRED,
connector=self.connector,
)
self.binding = FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=0)
self.host_cert = load_fixture("fixtures/cond_acc_host.pem")
def _format_traefik(self, cert: str | None = None):
cert = cert if cert else self.host_cert
return cert.replace(PEM_HEADER, "").replace(PEM_FOOTER, "").replace("\n", "")
def test_assoc(self):
dev = Device.objects.get(identifier="ZV35VFDD50")
with self.assertFlowFinishes() as plan:
res = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
headers={"X-Forwarded-TLS-Client-Cert": self._format_traefik()},
)
self.assertEqual(res.status_code, 200)
plan = plan()
self.assertEqual(plan.context[PLAN_CONTEXT_DEVICE], dev)
self.assertEqual(
plan.context[PLAN_CONTEXT_CERTIFICATE]["subject"],
"CN=Fleet conditional access for Okta",
)
def test_assoc_not_found(self):
dev = Device.objects.get(identifier="ZV35VFDD50")
dev.delete()
with self.assertFlowFinishes() as plan:
res = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
headers={"X-Forwarded-TLS-Client-Cert": self._format_traefik()},
)
self.assertEqual(res.status_code, 200)
self.assertStageResponse(res, self.flow, component="ak-stage-access-denied")
plan = plan()
self.assertNotIn(PLAN_CONTEXT_DEVICE, plan.context)

View File

@@ -15,6 +15,7 @@ from cryptography.x509 import (
)
from cryptography.x509.verification import PolicyBuilder, Store, VerificationError
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import PermissionDenied
from authentik.brands.models import Brand
from authentik.core.models import User
@@ -25,7 +26,6 @@ from authentik.enterprise.stages.mtls.models import (
MutualTLSStage,
UserAttributes,
)
from authentik.flows.challenge import AccessDeniedChallenge
from authentik.flows.models import FlowDesignation
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView
@@ -217,8 +217,7 @@ class MTLSStageView(ChallengeStageView):
return None
return str(_cert_attr[0])
def dispatch(self, request, *args, **kwargs):
stage: MutualTLSStage = self.executor.current_stage
def get_cert(self, mode: StageMode):
certs = [
*self._parse_cert_xfcc(),
*self._parse_cert_nginx(),
@@ -228,21 +227,26 @@ class MTLSStageView(ChallengeStageView):
authorities = self.get_authorities()
if not authorities:
self.logger.warning("No Certificate authority found")
if stage.mode == StageMode.OPTIONAL:
return self.executor.stage_ok()
if stage.mode == StageMode.REQUIRED:
return super().dispatch(request, *args, **kwargs)
if mode == StageMode.OPTIONAL:
return None
if mode == StageMode.REQUIRED:
raise PermissionDenied("Unknown error")
cert = self.validate_cert(authorities, certs)
if not cert and stage.mode == StageMode.REQUIRED:
if not cert and mode == StageMode.REQUIRED:
self.logger.warning("Client certificate required but no certificates given")
return super().dispatch(
request,
*args,
error_message=_("Certificate required but no certificate was given."),
**kwargs,
)
if not cert and stage.mode == StageMode.OPTIONAL:
raise PermissionDenied(str(_("Certificate required but no certificate was given.")))
if not cert and mode == StageMode.OPTIONAL:
self.logger.info("No certificate given, continuing")
return None
return cert
def dispatch(self, request, *args, **kwargs):
stage: MutualTLSStage = self.executor.current_stage
try:
cert = self.get_cert(stage.mode)
except PermissionDenied as exc:
return self.executor.stage_invalid(error_message=exc.detail)
if not cert:
return self.executor.stage_ok()
self.logger.debug("Received certificate", cert=fingerprint_sha256(cert))
existing_user = self.check_if_user(cert)
@@ -251,15 +255,5 @@ class MTLSStageView(ChallengeStageView):
elif existing_user:
self.auth_user(existing_user, cert)
else:
return super().dispatch(
request, *args, error_message=_("No user found for certificate."), **kwargs
)
return self.executor.stage_invalid(_("No user found for certificate."))
return self.executor.stage_ok()
def get_challenge(self, *args, error_message: str | None = None, **kwargs):
return AccessDeniedChallenge(
data={
"component": "ak-stage-access-denied",
"error_message": str(error_message or "Unknown error"),
}
)

View File

@@ -71,7 +71,11 @@ class FlowInspectorView(APIView):
flow: Flow
_logger: BoundLogger
permission_classes = [IsAuthenticated]
def get_permissions(self):
if settings.DEBUG:
return []
return [IsAuthenticated()]
def setup(self, request: HttpRequest, flow_slug: str):
super().setup(request, flow_slug=flow_slug)

View File

@@ -14,7 +14,16 @@ def chunked_queryset[T: Model](queryset: QuerySet[T], chunk_size: int = 1_000) -
def get_chunks(qs: QuerySet) -> Generator[QuerySet[T]]:
qs = qs.order_by("pk")
pks = qs.values_list("pk", flat=True)
start_pk = pks[0]
# The outer queryset.exists() guard can race with a concurrent
# transaction that deletes the last matching row (or with a
# different isolation-level snapshot), so by the time this
# generator starts iterating the queryset may be empty and
# pks[0] would raise IndexError and crash the caller. Using
# .first() returns None on an empty queryset, which we bail
# out on cleanly. See goauthentik/authentik#21643.
start_pk = pks.first()
if start_pk is None:
return
while True:
try:
end_pk = pks.filter(pk__gte=start_pk)[chunk_size]

View File

@@ -6,10 +6,11 @@ from urllib.parse import quote
from django.urls import reverse
from authentik.blueprints.tests import apply_blueprint
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_flow
from authentik.lib.generators import generate_id
from authentik.providers.oauth2.models import OAuth2Provider
from authentik.providers.oauth2.models import DeviceToken, OAuth2Provider, ScopeMapping
from authentik.providers.oauth2.tests.utils import OAuthTestCase
@@ -110,3 +111,57 @@ class TesOAuth2DeviceBackchannel(OAuthTestCase):
self.assertEqual(res.status_code, 200)
body = loads(res.content.decode())
self.assertEqual(body["expires_in"], 60)
@apply_blueprint("system/providers-oauth2.yaml")
def test_backchannel_scopes(self):
"""Test backchannel"""
self.provider.property_mappings.set(
ScopeMapping.objects.filter(
managed__in=[
"goauthentik.io/providers/oauth2/scope-openid",
"goauthentik.io/providers/oauth2/scope-email",
"goauthentik.io/providers/oauth2/scope-profile",
]
)
)
creds = b64encode(f"{self.provider.client_id}:".encode()).decode()
res = self.client.post(
reverse("authentik_providers_oauth2:device"),
HTTP_AUTHORIZATION=f"Basic {creds}",
data={"scope": "openid email"},
)
self.assertEqual(res.status_code, 200)
body = loads(res.content.decode())
self.assertEqual(body["expires_in"], 60)
token = DeviceToken.objects.filter(device_code=body["device_code"]).first()
self.assertIsNotNone(token)
self.assertEqual(len(token.scope), 2)
self.assertIn("openid", token.scope)
self.assertIn("email", token.scope)
@apply_blueprint("system/providers-oauth2.yaml")
def test_backchannel_scopes_extra(self):
"""Test backchannel"""
self.provider.property_mappings.set(
ScopeMapping.objects.filter(
managed__in=[
"goauthentik.io/providers/oauth2/scope-openid",
"goauthentik.io/providers/oauth2/scope-email",
"goauthentik.io/providers/oauth2/scope-profile",
]
)
)
creds = b64encode(f"{self.provider.client_id}:".encode()).decode()
res = self.client.post(
reverse("authentik_providers_oauth2:device"),
HTTP_AUTHORIZATION=f"Basic {creds}",
data={"scope": "openid email foo"},
)
self.assertEqual(res.status_code, 200)
body = loads(res.content.decode())
self.assertEqual(body["expires_in"], 60)
token = DeviceToken.objects.filter(device_code=body["device_code"]).first()
self.assertIsNotNone(token)
self.assertEqual(len(token.scope), 2)
self.assertIn("openid", token.scope)
self.assertIn("email", token.scope)

View File

@@ -48,6 +48,7 @@ class TestTokenDeviceCode(OAuthTestCase):
reverse("authentik_providers_oauth2:token"),
data={
"client_id": self.provider.client_id,
"client_secret": self.provider.client_secret,
"grant_type": GRANT_TYPE_DEVICE_CODE,
},
)
@@ -66,6 +67,7 @@ class TestTokenDeviceCode(OAuthTestCase):
reverse("authentik_providers_oauth2:token"),
data={
"client_id": self.provider.client_id,
"client_secret": self.provider.client_secret,
"grant_type": GRANT_TYPE_DEVICE_CODE,
"device_code": device_token.device_code,
},
@@ -74,6 +76,26 @@ class TestTokenDeviceCode(OAuthTestCase):
body = loads(res.content.decode())
self.assertEqual(body["error"], "authorization_pending")
def test_code_no_auth(self):
"""Test code with user"""
device_token = DeviceToken.objects.create(
provider=self.provider,
user_code=generate_code_fixed_length(),
device_code=generate_id(),
user=self.user,
)
res = self.client.post(
reverse("authentik_providers_oauth2:token"),
data={
"client_id": self.provider.client_id,
"grant_type": GRANT_TYPE_DEVICE_CODE,
"device_code": device_token.device_code,
},
)
self.assertEqual(res.status_code, 400)
body = loads(res.content.decode())
self.assertEqual(body["error"], "invalid_client")
def test_code(self):
"""Test code with user"""
device_token = DeviceToken.objects.create(
@@ -86,6 +108,7 @@ class TestTokenDeviceCode(OAuthTestCase):
reverse("authentik_providers_oauth2:token"),
data={
"client_id": self.provider.client_id,
"client_secret": self.provider.client_secret,
"grant_type": GRANT_TYPE_DEVICE_CODE,
"device_code": device_token.device_code,
},
@@ -105,6 +128,7 @@ class TestTokenDeviceCode(OAuthTestCase):
reverse("authentik_providers_oauth2:token"),
data={
"client_id": self.provider.client_id,
"client_secret": self.provider.client_secret,
"grant_type": GRANT_TYPE_DEVICE_CODE,
"device_code": device_token.device_code,
"scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} invalid",

View File

@@ -15,7 +15,7 @@ from authentik.core.models import Application
from authentik.lib.config import CONFIG
from authentik.lib.utils.time import timedelta_from_string
from authentik.providers.oauth2.errors import DeviceCodeError
from authentik.providers.oauth2.models import DeviceToken, OAuth2Provider
from authentik.providers.oauth2.models import DeviceToken, OAuth2Provider, ScopeMapping
from authentik.providers.oauth2.utils import TokenResponse, extract_client_auth
from authentik.providers.oauth2.views.device_init import QS_KEY_CODE
@@ -28,7 +28,7 @@ class DeviceView(View):
client_id: str
provider: OAuth2Provider
scopes: list[str] = []
scopes: set[str] = []
def parse_request(self):
"""Parse incoming request"""
@@ -44,7 +44,21 @@ class DeviceView(View):
raise DeviceCodeError("invalid_client") from None
self.provider = provider
self.client_id = client_id
self.scopes = self.request.POST.get("scope", "").split(" ")
scopes_to_check = set(self.request.POST.get("scope", "").split())
default_scope_names = set(
ScopeMapping.objects.filter(provider__in=[self.provider]).values_list(
"scope_name", flat=True
)
)
self.scopes = scopes_to_check
if not scopes_to_check.issubset(default_scope_names):
LOGGER.info(
"Application requested scopes not configured, setting to overlap",
scope_allowed=default_scope_names,
scope_given=self.scopes,
)
self.scopes = self.scopes.intersection(default_scope_names)
def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
throttle = AnonRateThrottle()

View File

@@ -165,7 +165,15 @@ class TokenParams:
raise TokenError("invalid_grant")
def __post_init__(self, raw_code: str, raw_token: str, request: HttpRequest):
if self.grant_type in [GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_REFRESH_TOKEN]:
# Confidential clients MUST authenticate to the token endpoint per
# RFC 6749 §2.3.1. The device code grant (RFC 8628 §3.4) inherits
# that requirement - the device_code alone is not a substitute for
# client credentials.
if self.grant_type in [
GRANT_TYPE_AUTHORIZATION_CODE,
GRANT_TYPE_REFRESH_TOKEN,
GRANT_TYPE_DEVICE_CODE,
]:
if self.provider.client_type == ClientTypes.CONFIDENTIAL and not compare_digest(
self.provider.client_secret, self.client_secret
):

View File

@@ -1,5 +1,7 @@
"""authentik recovery create_admin_group"""
from argparse import ArgumentParser
from django.utils.translation import gettext as _
from authentik.core.models import User
@@ -12,7 +14,7 @@ class Command(TenantCommand):
help = _("Create admin group if the default group gets deleted.")
def add_arguments(self, parser):
def add_arguments(self, parser: ArgumentParser):
parser.add_argument("user", action="store", help="User to add to the admin group.")
def handle_per_tenant(self, *args, **options):

View File

@@ -36,6 +36,14 @@ class UserWriteStageView(StageView):
super().__init__(executor, **kwargs)
self.disallowed_user_attributes = [
"groups",
# Block attribute writes that would otherwise land on the model's
# primary key. An IdP that returns an `id` claim (mocksaml is one
# example) used to crash the enrollment flow with
# ValueError: Field 'id' expected a number but got '<hex>'
# because hasattr(user, "id") is true and setattr(user, "id", ...)
# was taken unchecked. See #21580.
"id",
"pk",
]
@staticmethod

View File

@@ -315,6 +315,34 @@ class TestUserWriteStage(FlowTestCase):
component="ak-stage-access-denied",
)
def test_user_update_ignores_id_from_idp(self):
"""IdP-supplied `id`/`pk` attributes must not land on the model
primary key and crash user save (#21580)."""
existing = User.objects.create(username="unittest", email="test@goauthentik.io")
original_pk = existing.pk
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
plan.context[PLAN_CONTEXT_PENDING_USER] = existing
plan.context[PLAN_CONTEXT_PROMPT] = {
"username": "idp-user",
# Hex string from a SAML IdP; would previously crash with
# ValueError: Field 'id' expected a number but got '<hex>'.
"id": "1dda9fb491dc01bd24d2423ba2f22ae561f56ddf2376b29a11c80281d21201f9",
"pk": "also-not-an-int",
}
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
user = User.objects.get(username="idp-user")
self.assertEqual(user.pk, original_pk)
def test_write_attribute(self):
"""Test write_attribute"""
user = create_test_admin_user()

View File

@@ -19,19 +19,32 @@ from authentik.tenants.models import Tenant
class FlagJSONField(JSONDictField):
def to_representation(self, value: dict) -> dict:
"""Exclude any system flags that aren't modifiable"""
new_value = value.copy()
for flag in Flag.available(exclude_system=False):
_flag = flag()
if _flag.visibility == "system":
new_value.pop(_flag.key, None)
return super().to_representation(new_value)
def run_validators(self, value: dict):
super().run_validators(value)
for flag in Flag.available():
for flag in Flag.available(exclude_system=False):
_flag = flag()
if _flag.key in value:
flag_value = value.get(_flag.key)
flag_type = get_args(_flag.__orig_bases__[0])[0]
if flag_value and not isinstance(flag_value, flag_type):
raise ValidationError(
_("Value for flag {flag_key} needs to be of type {type}.").format(
flag_key=_flag.key, type=flag_type.__name__
)
if _flag.key not in value:
continue
if _flag.visibility == "system":
value.pop(_flag.key, None)
continue
flag_value = value.get(_flag.key)
flag_type = get_args(_flag.__orig_bases__[0])[0]
if flag_value and not isinstance(flag_value, flag_type):
raise ValidationError(
_("Value for flag {flag_key} needs to be of type {type}.").format(
flag_key=_flag.key, type=flag_type.__name__
)
)
class FlagsJSONExtension(OpenApiSerializerFieldExtension):

View File

@@ -4,6 +4,7 @@ from functools import wraps
from typing import TYPE_CHECKING, Any, Literal
from django.db import DatabaseError, InternalError, ProgrammingError
from django.db.models import F, Func, JSONField, Value
from authentik.lib.utils.reflection import all_subclasses
@@ -13,7 +14,9 @@ if TYPE_CHECKING:
class Flag[T]:
default: T | None = None
visibility: Literal["none"] | Literal["public"] | Literal["authenticated"] = "none"
visibility: (
Literal["none"] | Literal["public"] | Literal["authenticated"] | Literal["system"]
) = "none"
description: str | None = None
def __init_subclass__(cls, key: str, **kwargs):
@@ -24,12 +27,15 @@ class Flag[T]:
return self.__key
@classmethod
def get(cls) -> T | None:
def get(cls, tenant: Tenant | None = None) -> T | None:
from authentik.tenants.utils import get_current_tenant
if not tenant:
tenant = get_current_tenant(["flags"])
flags = {}
try:
flags: dict[str, Any] = get_current_tenant(["flags"]).flags
flags: dict[str, Any] = tenant.flags
except DatabaseError, ProgrammingError, InternalError:
pass
value = flags.get(cls.__key, None)
@@ -37,20 +43,38 @@ class Flag[T]:
return cls().get_default()
return value
@classmethod
def set(cls, value: T, tenant: Tenant | None = None) -> T | None:
from authentik.tenants.models import Tenant
from authentik.tenants.utils import get_current_tenant
if not tenant:
tenant = get_current_tenant()
Tenant.objects.filter(pk=tenant.pk).update(
flags=Func(
F("flags"),
Value([cls.__key]),
Value(value, JSONField()),
function="jsonb_set",
)
)
def get_default(self) -> T | None:
return self.default
@staticmethod
def available(
visibility: Literal["none"] | Literal["public"] | Literal["authenticated"] | None = None,
exclude_system=True,
):
flags = all_subclasses(Flag)
if visibility:
for flag in flags:
if flag.visibility == visibility:
yield flag
else:
yield from flags
for flag in flags:
if visibility and flag.visibility != visibility:
continue
if exclude_system and flag.visibility == "system":
continue
yield flag
def patch_flag[T](flag: Flag[T], value: T):

View File

@@ -0,0 +1,19 @@
from argparse import ArgumentParser
from typing import Any
from authentik.tenants.management import TenantCommand
from authentik.tenants.utils import get_current_tenant
class Command(TenantCommand):
def add_arguments(self, parser: ArgumentParser):
parser.add_argument("flag_key", type=str)
parser.add_argument("flag_value", type=str)
def handle(self, *, flag_key: str, flag_value: Any, **options):
tenant = get_current_tenant()
val = flag_value.lower() == "true"
tenant.flags[flag_key] = val
tenant.save()
self.stdout.write(f"Set flag '{flag_key}' to {val}.")

View File

@@ -1,10 +1,12 @@
"""Test Settings API"""
from django.core.management import call_command
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.tests.utils import create_test_admin_user
from authentik.tenants.flags import Flag
from authentik.tenants.utils import get_current_tenant
class TestLocalSettingsAPI(APITestCase):
@@ -13,11 +15,19 @@ class TestLocalSettingsAPI(APITestCase):
def setUp(self):
super().setUp()
self.local_admin = create_test_admin_user()
self.tenant = get_current_tenant()
def tearDown(self):
super().tearDown()
self.tenant.flags = {}
self.tenant.save()
def test_settings_flags(self):
"""Test settings API"""
self.tenant.flags = {}
self.tenant.save()
class TestFlag(Flag[bool], key="tenants_test_flag"):
class _TestFlag(Flag[bool], key="tenants_test_flag_bool"):
default = False
visibility = "public"
@@ -26,15 +36,19 @@ class TestLocalSettingsAPI(APITestCase):
response = self.client.patch(
reverse("authentik_api:tenant_settings"),
data={
"flags": {"tenants_test_flag": True},
"flags": {"tenants_test_flag_bool": True},
},
)
self.assertEqual(response.status_code, 200)
self.tenant.refresh_from_db()
self.assertEqual(self.tenant.flags["tenants_test_flag_bool"], True)
def test_settings_flags_incorrect(self):
"""Test settings API"""
self.tenant.flags = {}
self.tenant.save()
class TestFlag(Flag[bool], key="tenants_test_flag"):
class _TestFlag(Flag[bool], key="tenants_test_flag_incorrect"):
default = False
visibility = "public"
@@ -43,11 +57,44 @@ class TestLocalSettingsAPI(APITestCase):
response = self.client.patch(
reverse("authentik_api:tenant_settings"),
data={
"flags": {"tenants_test_flag": 123},
"flags": {"tenants_test_flag_incorrect": 123},
},
)
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(
response.content,
{"flags": ["Value for flag tenants_test_flag needs to be of type bool."]},
{"flags": ["Value for flag tenants_test_flag_incorrect needs to be of type bool."]},
)
self.tenant.refresh_from_db()
self.assertEqual(self.tenant.flags, {})
def test_settings_flags_system(self):
"""Test settings API"""
self.tenant.flags = {}
self.tenant.save()
class _TestFlag(Flag[bool], key="tenants_test_flag_sys"):
default = False
visibility = "system"
self.client.force_login(self.local_admin)
response = self.client.patch(
reverse("authentik_api:tenant_settings"),
data={
"flags": {"tenants_test_flag_sys": 123},
},
)
print(response.content)
self.assertEqual(response.status_code, 200)
self.tenant.refresh_from_db()
self.assertEqual(self.tenant.flags, {})
def test_command(self):
self.tenant.flags = {}
self.tenant.save()
call_command("set_flag", "foo", "true")
self.tenant.refresh_from_db()
self.assertTrue(self.tenant.flags["foo"])

View File

@@ -1,4 +1,7 @@
metadata:
labels:
blueprints.goauthentik.io/system-oobe: "true"
blueprints.goauthentik.io/system: "true"
name: Default - Out-of-box-experience flow
version: 1
entries:
@@ -75,23 +78,20 @@ entries:
- attrs:
expression: |
# This policy ensures that the setup flow can only be
# executed when the admin user doesn''t have a password set
# executed when the admin user doesn't have a password set
akadmin = ak_user_by(username="akadmin")
return not akadmin.has_usable_password()
# Ensure flow was started correctly
started_by = context.get("goauthentik.io/core/setup/started-by")
if started_by != "setup":
setup_url = request.http_request.build_absolute_uri("/")
ak_message(f"Access the authentik setup by navigating to {setup_url}")
return False
return akadmin is None or not akadmin.has_usable_password()
id: policy-default-oobe-password-usable
identifiers:
name: default-oobe-password-usable
model: authentik_policies_expression.expressionpolicy
- attrs:
expression: |
# This policy ensures that the setup flow can only be
# used one time
from authentik.flows.models import Flow, FlowAuthenticationRequirement
Flow.objects.filter(slug="initial-setup").update(
authentication=FlowAuthenticationRequirement.REQUIRE_SUPERUSER,
)
return True
id: policy-default-oobe-flow-set-authentication
- state: absent
identifiers:
name: default-oobe-flow-set-authentication
model: authentik_policies_expression.expressionpolicy
@@ -154,8 +154,3 @@ entries:
policy: !KeyOf policy-default-oobe-prefill-user
target: !KeyOf binding-password-write
model: authentik_policies.policybinding
- identifiers:
order: 0
policy: !KeyOf policy-default-oobe-flow-set-authentication
target: !KeyOf binding-login
model: authentik_policies.policybinding

2
go.mod
View File

@@ -40,7 +40,7 @@ require (
)
require (
github.com/Azure/go-ntlmssp v0.1.0 // indirect
github.com/Azure/go-ntlmssp v0.1.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect

4
go.sum
View File

@@ -2,8 +2,8 @@ beryju.io/ldap v0.2.1 h1:rhTAP2CXqrKZy/UycLC/aPSSBMcgJMzooKqk3TwVFxY=
beryju.io/ldap v0.2.1/go.mod h1:GJSw3pVOON/3+L5att3Eysmj7j0GmjLvA6/WNmPajD4=
beryju.io/radius-eap v0.1.0 h1:5M3HwkzH3nIEBcKDA2z5+sb4nCY3WdKL/SDDKTBvoqw=
beryju.io/radius-eap v0.1.0/go.mod h1:yYtO59iyoLNEepdyp1gZ0i1tGdjPbrR2M/v5yOz7Fkc=
github.com/Azure/go-ntlmssp v0.1.0 h1:DjFo6YtWzNqNvQdrwEyr/e4nhU3vRiwenz5QX7sFz+A=
github.com/Azure/go-ntlmssp v0.1.0/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk=
github.com/Azure/go-ntlmssp v0.1.1 h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw=
github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk=
github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI=
github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/avast/retry-go/v4 v4.7.0 h1:yjDs35SlGvKwRNSykujfjdMxMhMQQM0TnIjJaHB+Zio=

View File

@@ -11,6 +11,7 @@ import (
"os"
"os/signal"
"runtime"
"sync"
"syscall"
"time"
@@ -45,6 +46,7 @@ type APIController struct {
reloadOffset time.Duration
eventConn *websocket.Conn
eventConnMu sync.Mutex
lastWsReconnect time.Time
wsIsReconnecting bool
eventHandlers []EventHandler

View File

@@ -77,7 +77,12 @@ func (ac *APIController) initEvent(outpostUUID string, attempt int) error {
Instruction: EventKindHello,
Args: ac.getEventPingArgs(),
}
// Serialize this write against concurrent SendEventHello callers (health
// ticker, RAC handlers) sharing the same *websocket.Conn. Gorilla's Conn
// does not permit concurrent writes.
ac.eventConnMu.Lock()
err = ws.WriteJSON(msg)
ac.eventConnMu.Unlock()
if err != nil {
ac.logger.WithField("logger", "authentik.outpost.events").WithError(err).Warning("Failed to hello to authentik")
return err
@@ -91,7 +96,9 @@ func (ac *APIController) initEvent(outpostUUID string, attempt int) error {
func (ac *APIController) Shutdown() {
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
ac.eventConnMu.Lock()
err := ac.eventConn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
ac.eventConnMu.Unlock()
if err != nil {
ac.logger.WithError(err).Warning("failed to write close message")
return
@@ -252,6 +259,10 @@ func (a *APIController) SendEventHello(args map[string]any) error {
Instruction: EventKindHello,
Args: allArgs,
}
// Gorilla *websocket.Conn does not permit concurrent writes. This method
// is invoked from the health ticker and from RAC session handlers.
a.eventConnMu.Lock()
err := a.eventConn.WriteJSON(aliveMsg)
a.eventConnMu.Unlock()
return err
}

View File

@@ -84,12 +84,6 @@ if [[ "$1" == "server" ]]; then
elif [[ "$1" == "worker" ]]; then
set_mode "worker"
shift
# If we have bootstrap credentials set, run bootstrap tasks outside of main server
# sync, so that we can sure the first start actually has working bootstrap
# credentials
if [[ -n "${AUTHENTIK_BOOTSTRAP_PASSWORD}" || -n "${AUTHENTIK_BOOTSTRAP_TOKEN}" ]]; then
python -m manage apply_blueprint system/bootstrap.yaml || true
fi
check_if_root "python -m manage worker --pid-file ${TMPDIR}/authentik-worker.pid $@"
elif [[ "$1" == "bash" ]]; then
/bin/bash

View File

@@ -9,7 +9,7 @@
"version": "0.0.0",
"license": "MIT",
"devDependencies": {
"aws-cdk": "^2.1118.2",
"aws-cdk": "^2.1118.4",
"cross-env": "^10.1.0"
},
"engines": {
@@ -25,9 +25,9 @@
"license": "MIT"
},
"node_modules/aws-cdk": {
"version": "2.1118.2",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1118.2.tgz",
"integrity": "sha512-jHuShSx0JI14enDz2Hk2Qe0LYTDPzLyF2nBhWCvoXyRCpz31sI3XsCh4KO5ZXKfw9ET0bHvDTVnMZQPBpswg8A==",
"version": "2.1118.4",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1118.4.tgz",
"integrity": "sha512-wJfRQdvb+FJ2cni059mYdmjhfwhMskP+PAB59BL9jhon+jYtjy8X3pbj3uzHgAOJwNhh6jGkP8xq36Cffccbbw==",
"dev": true,
"license": "Apache-2.0",
"bin": {

View File

@@ -7,7 +7,7 @@
"aws-cfn": "cross-env CI=false cdk synth --version-reporting=false > template.yaml"
},
"devDependencies": {
"aws-cdk": "^2.1118.2",
"aws-cdk": "^2.1118.4",
"cross-env": "^10.1.0"
},
"engines": {

View File

@@ -29,7 +29,7 @@ RUN npm run build && \
npm run build:sfe
# Stage 2: Build go proxy
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:cd8540d626ab35272a8f5ef829c5e5f189ce1dfbf467c123320c191c69c23245 AS go-builder
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:982ae929f9a74083a242c6e25d19d7d9ed78c6e97fab639a119e90707ba819e2 AS go-builder
ARG TARGETOS
ARG TARGETARCH
@@ -42,8 +42,9 @@ WORKDIR /go/src/goauthentik.io
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt \
dpkg --add-architecture arm64 && \
dpkg --add-architecture amd64 && \
apt-get update && \
apt-get install -y --no-install-recommends crossbuild-essential-arm64 gcc-aarch64-linux-gnu
apt-get install -y --no-install-recommends crossbuild-essential-arm64 gcc-aarch64-linux-gnu crossbuild-essential-amd64 gcc-x86-64-linux-gnu
RUN --mount=type=bind,target=/go/src/goauthentik.io/go.mod,src=./go.mod \
--mount=type=bind,target=/go/src/goauthentik.io/go.sum,src=./go.sum \
@@ -62,7 +63,8 @@ COPY ./packages/client-go /go/src/goauthentik.io/packages/client-go
RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
--mount=type=cache,id=go-build-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/go-build \
if [ "$TARGETARCH" = "arm64" ]; then export CC=aarch64-linux-gnu-gcc && export CC_FOR_TARGET=gcc-aarch64-linux-gnu; fi && \
if [ "$TARGETARCH" = "arm64" ] && [ "$(uname -m)" != "aarch64" ]; then export CC=aarch64-linux-gnu-gcc && export CC_FOR_TARGET=gcc-aarch64-linux-gnu; fi && \
if [ "$TARGETARCH" = "amd64" ] && [ "$(uname -m)" != "x86_64" ]; then export CC=x86_64-linux-gnu-gcc; fi && \
CGO_ENABLED=1 GOFIPS140=latest GOARM="${TARGETVARIANT#v}" \
go build -o /go/authentik ./cmd/server

View File

@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
# Stage 1: Build
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:cd8540d626ab35272a8f5ef829c5e5f189ce1dfbf467c123320c191c69c23245 AS builder
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:982ae929f9a74083a242c6e25d19d7d9ed78c6e97fab639a119e90707ba819e2 AS builder
ARG TARGETOS
ARG TARGETARCH

View File

@@ -21,7 +21,7 @@ COPY web .
RUN npm run build-proxy
# Stage 2: Build
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:cd8540d626ab35272a8f5ef829c5e5f189ce1dfbf467c123320c191c69c23245 AS builder
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:982ae929f9a74083a242c6e25d19d7d9ed78c6e97fab639a119e90707ba819e2 AS builder
ARG TARGETOS
ARG TARGETARCH

View File

@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
# Stage 1: Build
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:cd8540d626ab35272a8f5ef829c5e5f189ce1dfbf467c123320c191c69c23245 AS builder
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:982ae929f9a74083a242c6e25d19d7d9ed78c6e97fab639a119e90707ba819e2 AS builder
ARG TARGETOS
ARG TARGETARCH

View File

@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
# Stage 1: Build
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:cd8540d626ab35272a8f5ef829c5e5f189ce1dfbf467c123320c191c69c23245 AS builder
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.26.2-trixie@sha256:982ae929f9a74083a242c6e25d19d7d9ed78c6e97fab639a119e90707ba819e2 AS builder
ARG TARGETOS
ARG TARGETARCH

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-22 00:20+0000\n"
"POT-Creation-Date: 2026-04-23 00:25+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1579,6 +1579,10 @@ msgstr ""
msgid "Flow Tokens"
msgstr ""
#: authentik/flows/planner.py
msgid "This link is invalid or has expired. Please request a new one."
msgstr ""
#: authentik/flows/views/executor.py
msgid "Invalid next URL"
msgstr ""

View File

@@ -4,3 +4,4 @@ Yubi
Yubikey
Yubikeys
mycorp
mocksaml

12
package-lock.json generated
View File

@@ -1843,9 +1843,9 @@
}
},
"node_modules/brace-expansion": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
"integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
"integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -5373,9 +5373,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
"integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
"funding": [
{
"type": "opencollective",

View File

@@ -7,7 +7,7 @@ requires-python = "==3.14.*"
dependencies = [
"ak-guardian==3.2.0",
"argon2-cffi==25.1.0",
"cachetools==7.0.5",
"cachetools==7.0.6",
"channels==4.3.2",
"cryptography==46.0.7",
"dacite==1.9.2",
@@ -50,7 +50,7 @@ dependencies = [
"paramiko==4.0.0",
"psycopg[c,pool]==3.3.3",
"pydantic-scim==0.0.8",
"pydantic==2.13.2",
"pydantic==2.13.3",
"pyjwt==2.11.0",
"pyrad==2.5.4",
"python-kadmin-rs==0.7.0",

View File

@@ -6,6 +6,7 @@ from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from dramatiq import get_broker
from structlog.stdlib import get_logger
from authentik.core.apps import Setup
from authentik.core.models import User
from authentik.core.tests.utils import create_test_admin_user
from authentik.tasks.test import use_test_broker
@@ -27,6 +28,7 @@ class E2ETestMixin(DockerTestCase):
self.wait_timeout = 60
self.logger = get_logger()
self.user = create_test_admin_user()
Setup.set(True)
super().setUp()
@classmethod

80
uv.lock generated
View File

@@ -316,7 +316,7 @@ dev = [
requires-dist = [
{ name = "ak-guardian", editable = "packages/ak-guardian" },
{ name = "argon2-cffi", specifier = "==25.1.0" },
{ name = "cachetools", specifier = "==7.0.5" },
{ name = "cachetools", specifier = "==7.0.6" },
{ name = "channels", specifier = "==4.3.2" },
{ name = "cryptography", specifier = "==46.0.7" },
{ name = "dacite", specifier = "==1.9.2" },
@@ -358,7 +358,7 @@ requires-dist = [
{ name = "packaging", specifier = "==26.1" },
{ name = "paramiko", specifier = "==4.0.0" },
{ name = "psycopg", extras = ["c", "pool"], specifier = "==3.3.3" },
{ name = "pydantic", specifier = "==2.13.2" },
{ name = "pydantic", specifier = "==2.13.3" },
{ name = "pydantic-scim", specifier = "==0.0.8" },
{ name = "pyjwt", specifier = "==2.11.0" },
{ name = "pyrad", specifier = "==2.5.4" },
@@ -688,11 +688,11 @@ wheels = [
[[package]]
name = "cachetools"
version = "7.0.5"
version = "7.0.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/af/dd/57fe3fdb6e65b25a5987fd2cdc7e22db0aef508b91634d2e57d22928d41b/cachetools-7.0.5.tar.gz", hash = "sha256:0cd042c24377200c1dcd225f8b7b12b0ca53cc2c961b43757e774ebe190fd990", size = 37367, upload-time = "2026-03-09T20:51:29.451Z" }
sdist = { url = "https://files.pythonhosted.org/packages/76/7b/1755ed2c6bfabd1d98b37ae73152f8dcf94aa40fee119d163c19ed484704/cachetools-7.0.6.tar.gz", hash = "sha256:e5d524d36d65703a87243a26ff08ad84f73352adbeafb1cde81e207b456aaf24", size = 37526, upload-time = "2026-04-20T19:02:23.289Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/06/f3/39cf3367b8107baa44f861dc802cbf16263c945b62d8265d36034fc07bea/cachetools-7.0.5-py3-none-any.whl", hash = "sha256:46bc8ebefbe485407621d0a4264b23c080cedd913921bad7ac3ed2f26c183114", size = 13918, upload-time = "2026-03-09T20:51:27.33Z" },
{ url = "https://files.pythonhosted.org/packages/fe/c4/cf76242a5da1410917107ff14551764aa405a5fd10cd10cf9a5ca8fa77f4/cachetools-7.0.6-py3-none-any.whl", hash = "sha256:4e94956cfdd3086f12042cdd29318f5ced3893014f7d0d059bf3ead3f85b7f8b", size = 13976, upload-time = "2026-04-20T19:02:21.187Z" },
]
[[package]]
@@ -2824,7 +2824,7 @@ wheels = [
[[package]]
name = "pydantic"
version = "2.13.2"
version = "2.13.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "annotated-types" },
@@ -2832,9 +2832,9 @@ dependencies = [
{ name = "typing-extensions" },
{ name = "typing-inspection" },
]
sdist = { url = "https://files.pythonhosted.org/packages/09/e5/06d23afac9973109d1e3c8ad38e1547a12e860610e327c05ee686827dc37/pydantic-2.13.2.tar.gz", hash = "sha256:b418196607e61081c3226dcd4f0672f2a194828abb9109e9cfb84026564df2d1", size = 843836, upload-time = "2026-04-17T09:31:59.636Z" }
sdist = { url = "https://files.pythonhosted.org/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/ca/b45c378e6e8d0b90577288b533e04e95b7afd61bb1d51b6c263176435489/pydantic-2.13.2-py3-none-any.whl", hash = "sha256:a525087f4c03d7e7456a3de89b64cd693d2229933bb1068b9af6befd5563694e", size = 471947, upload-time = "2026-04-17T09:31:57.541Z" },
{ url = "https://files.pythonhosted.org/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" },
]
[package.optional-dependencies]
@@ -2844,43 +2844,43 @@ email = [
[[package]]
name = "pydantic-core"
version = "2.46.2"
version = "2.46.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/43/bb/4742f05b739b2478459bb16fa8470549518c802e06ddcf3f106c5081315e/pydantic_core-2.46.2.tar.gz", hash = "sha256:37bb079f9ee3f1a519392b73fda2a96379b31f2013c6b467fe693e7f2987f596", size = 471269, upload-time = "2026-04-17T09:10:07.017Z" }
sdist = { url = "https://files.pythonhosted.org/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d0/96/a50ccb6b539ae780f73cea74905468777680e30c6c3bdf714b9d4c116ea0/pydantic_core-2.46.2-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:4f59b45f3ef8650c0c736a57f59031d47ed9df4c0a64e83796849d7d14863a2d", size = 2097111, upload-time = "2026-04-17T09:10:49.617Z" },
{ url = "https://files.pythonhosted.org/packages/34/5f/fdead7b3afa822ab6e5a18ee0ecffd54937de1877c01ed13a342e0fb3f07/pydantic_core-2.46.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3a075a29ebef752784a91532a1a85be6b234ccffec0a9d7978a92696387c3da6", size = 1951904, upload-time = "2026-04-17T09:12:32.062Z" },
{ url = "https://files.pythonhosted.org/packages/95/e0/1c5d547e550cdab1bec737492aa08865337af6fe7fc9b96f7f45f17d9519/pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d12d786e30c04a9d307c5d7080bf720d9bac7f1668191d8e37633a9562749e2", size = 1978667, upload-time = "2026-04-17T09:11:35.589Z" },
{ url = "https://files.pythonhosted.org/packages/0e/cb/665ce629e218c8228302cb94beff4f6531082a2c87d3ecc3d5e63a26f392/pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0d5e6d6343b0b5dcacb3503b5de90022968da8ed0ab9ab39d3eda71c20cbf84e", size = 2046721, upload-time = "2026-04-17T09:11:47.725Z" },
{ url = "https://files.pythonhosted.org/packages/77/e9/6cb2cf60f54c1472bbdfce19d957553b43dbba79d1d7b2930a195c594785/pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:233eebac0999b6b9ba76eb56f3ec8fce13164aa16b6d2225a36a79e0f95b5973", size = 2228483, upload-time = "2026-04-17T09:12:08.837Z" },
{ url = "https://files.pythonhosted.org/packages/0d/2a/93e018dd5571f781ebaeda8c0cf65398489d5bee9b1f484df0b6149b43b9/pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cc0eee720dd2f14f3b7c349469402b99ad81a174ab49d3533974529e9d93992", size = 2294663, upload-time = "2026-04-17T09:12:52.053Z" },
{ url = "https://files.pythonhosted.org/packages/5e/4f/49e57ca55c770c93d9bb046666a54949b42e3c9099a0c5fe94557873fe30/pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83ee76bf2c9910513dbc19e7d82367131fa7508dedd6186a462393071cc11059", size = 2098742, upload-time = "2026-04-17T09:13:45.472Z" },
{ url = "https://files.pythonhosted.org/packages/c6/b0/6e46b5cd3332af665f794b8cdeea206618a8630bd9e7bcc36864518fce81/pydantic_core-2.46.2-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:d61db38eb4ee5192f0c261b7f2d38e420b554df8912245e3546aee5c45e2fd78", size = 2125922, upload-time = "2026-04-17T09:12:54.304Z" },
{ url = "https://files.pythonhosted.org/packages/06/d1/40850c81585be443a2abfdf7f795f8fae831baf8e2f9b2133c8246ac671c/pydantic_core-2.46.2-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8f09a713d17bcd55da8ab02ebd9110c5246a49c44182af213b5212800af8bc83", size = 2183000, upload-time = "2026-04-17T09:10:59.027Z" },
{ url = "https://files.pythonhosted.org/packages/04/af/8493d7dfa03ebb7866909e577c6aa65ea0de7377b86023cc51d0c8e11db3/pydantic_core-2.46.2-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:30cacc5fb696e64b8ef6fd31d9549d394dd7d52760db072eecb98e37e3af1677", size = 2180335, upload-time = "2026-04-17T09:12:57.01Z" },
{ url = "https://files.pythonhosted.org/packages/72/5b/1f6a344c4ffdf284da41c6067b82d5ebcbd11ce1b515ae4b662d4adb6f61/pydantic_core-2.46.2-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:7ccfb105fcfe91a22bbb5563ad3dc124bc1aa75bfd2e53a780ab05f78cdf6108", size = 2330002, upload-time = "2026-04-17T09:12:02.958Z" },
{ url = "https://files.pythonhosted.org/packages/25/ff/9a694126c12d6d2f48a0cafa6f8eef88ef0d8825600e18d03ff2e896c3b2/pydantic_core-2.46.2-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:13ffef637dc8370c249e5b26bd18e9a80a4fca3d809618c44e18ec834a7ca7a8", size = 2359920, upload-time = "2026-04-17T09:10:27.764Z" },
{ url = "https://files.pythonhosted.org/packages/51/c8/3a35c763d68a9cb2675eb10ef242cf66c5d4701b28ae12e688d67d2c180e/pydantic_core-2.46.2-cp314-cp314-win32.whl", hash = "sha256:1b0ab6d756ca2704a938e6c31b53f290c2f9c10d3914235410302a149de1a83e", size = 1953701, upload-time = "2026-04-17T09:13:30.021Z" },
{ url = "https://files.pythonhosted.org/packages/1a/6a/f2726a780365f7dfd89d62036f984f7acb99978c60c5e1fa7c0cb898ed11/pydantic_core-2.46.2-cp314-cp314-win_amd64.whl", hash = "sha256:99ebade8c9ada4df975372d8dd25883daa0e379a05f1cd0c99aa0c04368d01a6", size = 2071867, upload-time = "2026-04-17T09:10:39.205Z" },
{ url = "https://files.pythonhosted.org/packages/e1/79/76baacb9feba3d7c399b245ca1a29c74ea0db04ea693811374827eec2290/pydantic_core-2.46.2-cp314-cp314-win_arm64.whl", hash = "sha256:de87422197cf7f83db91d89c86a21660d749b3cd76cd8a45d115b8e675670f02", size = 2017252, upload-time = "2026-04-17T09:10:26.175Z" },
{ url = "https://files.pythonhosted.org/packages/f1/3b/77c26938f817668d9ad9bab1a905cb23f11d9a3d4bf724d429b3e55a8eaf/pydantic_core-2.46.2-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:236f22b4a206b5b61db955396b7cf9e2e1ff77f372efe9570128ccfcd6a525eb", size = 2094545, upload-time = "2026-04-17T09:12:19.339Z" },
{ url = "https://files.pythonhosted.org/packages/fe/de/42c13f590e3c260966aa49bcdb1674774f975467c49abd51191e502bea28/pydantic_core-2.46.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c2012f64d2cd7cca50f49f22445aa5a88691ac2b4498ee0a9a977f8ca4f7289f", size = 1933953, upload-time = "2026-04-17T09:09:55.889Z" },
{ url = "https://files.pythonhosted.org/packages/4e/84/ebe3ebb3e2d8db656937cfa6f97f544cb7132f2307a4a7dfdcd0ea102a12/pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d07d6c63106d3a9c9a333e2636f9c82c703b1a9e3b079299e58747964e4fdb72", size = 1974435, upload-time = "2026-04-17T09:10:12.371Z" },
{ url = "https://files.pythonhosted.org/packages/b9/15/0bf51ca6709477cd4ef86148b6d7844f3308f029eac361dd0383f1e17b1a/pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c326a2b4b85e959d9a1fc3a11f32f84611b6ec07c053e1828a860edf8d068208", size = 2031113, upload-time = "2026-04-17T09:10:00.752Z" },
{ url = "https://files.pythonhosted.org/packages/02/ae/b7b5af9b79db036d9e61a44c481c17a213dc8fc4b8b71fe6875a72fc778b/pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac8a65e798f2462552c00d2e013d532c94d646729dda98458beaf51f9ec7b120", size = 2236325, upload-time = "2026-04-17T09:10:33.227Z" },
{ url = "https://files.pythonhosted.org/packages/a6/ae/ecef7477b5a03d4a499708f7e75d2836452ebb70b776c2d64612b334f57a/pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a3c2bc1cc8164bedbc160b7bb1e8cc1e8b9c27f69ae4f9ae2b976cdae02b2dd", size = 2278135, upload-time = "2026-04-17T09:10:23.287Z" },
{ url = "https://files.pythonhosted.org/packages/db/e4/2f9d82faa47af6c39fc3f120145fd915971e1e0cb6b55b494fad9fdf8275/pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e69aa5e10b7e8b1bb4a6888650fd12fcbf11d396ca11d4a44de1450875702830", size = 2109071, upload-time = "2026-04-17T09:11:06.149Z" },
{ url = "https://files.pythonhosted.org/packages/f1/9c/677cf10873fbd0b116575ab7b97c90482b21564f8a8040beb18edef7a577/pydantic_core-2.46.2-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:4e6df5c3301e65fb42bc5338bf9a1027a02b0a31dc7f54c33775229af474daf0", size = 2106028, upload-time = "2026-04-17T09:10:51.525Z" },
{ url = "https://files.pythonhosted.org/packages/d6/53/6a06183544daba51c059123a2064a99039df25f115a06bdb26f2ea177038/pydantic_core-2.46.2-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c2f6e32548ac8d559b47944effcf8ae4d81c161f6b6c885edc53bc08b8f192d", size = 2164816, upload-time = "2026-04-17T09:11:56.187Z" },
{ url = "https://files.pythonhosted.org/packages/57/6f/10fcdd9e3eca66fc828eef0f6f5850f2dd3bca2c59e6e041fb8bc3da39be/pydantic_core-2.46.2-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:b089a81c58e6ea0485562bbbbbca4f65c0549521606d5ef27fba217aac9b665a", size = 2166130, upload-time = "2026-04-17T09:10:03.804Z" },
{ url = "https://files.pythonhosted.org/packages/29/83/92d3fd0e0156cad2e3cb5c26de73794af78ac9fa0c22ab666e566dd67061/pydantic_core-2.46.2-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:7f700a6d6f64112ae9193709b84303bbab84424ad4b47d0253301aabce9dfc70", size = 2316605, upload-time = "2026-04-17T09:12:45.249Z" },
{ url = "https://files.pythonhosted.org/packages/97/f1/facffdb970981068219582e499b8d0871ed163ffcc6b347de5c412669e4c/pydantic_core-2.46.2-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:67db6814beaa5fefe91101ec7eb9efda613795767be96f7cf58b1ca8c9ca9972", size = 2358385, upload-time = "2026-04-17T09:09:54.657Z" },
{ url = "https://files.pythonhosted.org/packages/8b/a1/b8160b2f22b2199467bc68581a4ed380643c16b348a27d6165c6c242d694/pydantic_core-2.46.2-cp314-cp314t-win32.whl", hash = "sha256:32fbc7447be8e3be99bf7869f7066308f16be55b61f9882c2cefc7931f5c7664", size = 1942373, upload-time = "2026-04-17T09:12:59.594Z" },
{ url = "https://files.pythonhosted.org/packages/0d/90/db89acabe5b150e11d1b59fe3d947dda2ef6abbfef5c82f056ff63802f5d/pydantic_core-2.46.2-cp314-cp314t-win_amd64.whl", hash = "sha256:b317a2b97019c0b95ce99f4f901ae383f40132da6706cdf1731066a73394c25c", size = 2052078, upload-time = "2026-04-17T09:10:19.96Z" },
{ url = "https://files.pythonhosted.org/packages/97/32/e19b83ceb07a3f1bb21798407790bbc9a31740158fd132b94139cb84e16c/pydantic_core-2.46.2-cp314-cp314t-win_arm64.whl", hash = "sha256:7dcb9d40930dfad7ab6b20bcc6ca9d2b030b0f347a0cd9909b54bd53ead521b1", size = 2016941, upload-time = "2026-04-17T09:12:34.447Z" },
{ url = "https://files.pythonhosted.org/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" },
{ url = "https://files.pythonhosted.org/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" },
{ url = "https://files.pythonhosted.org/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" },
{ url = "https://files.pythonhosted.org/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" },
{ url = "https://files.pythonhosted.org/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" },
{ url = "https://files.pythonhosted.org/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" },
{ url = "https://files.pythonhosted.org/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" },
{ url = "https://files.pythonhosted.org/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" },
{ url = "https://files.pythonhosted.org/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" },
{ url = "https://files.pythonhosted.org/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" },
{ url = "https://files.pythonhosted.org/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" },
{ url = "https://files.pythonhosted.org/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" },
{ url = "https://files.pythonhosted.org/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" },
{ url = "https://files.pythonhosted.org/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" },
{ url = "https://files.pythonhosted.org/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" },
{ url = "https://files.pythonhosted.org/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" },
{ url = "https://files.pythonhosted.org/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" },
{ url = "https://files.pythonhosted.org/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" },
{ url = "https://files.pythonhosted.org/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" },
{ url = "https://files.pythonhosted.org/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" },
{ url = "https://files.pythonhosted.org/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" },
{ url = "https://files.pythonhosted.org/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" },
{ url = "https://files.pythonhosted.org/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" },
{ url = "https://files.pythonhosted.org/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" },
{ url = "https://files.pythonhosted.org/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" },
{ url = "https://files.pythonhosted.org/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" },
{ url = "https://files.pythonhosted.org/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" },
{ url = "https://files.pythonhosted.org/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" },
{ url = "https://files.pythonhosted.org/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" },
{ url = "https://files.pythonhosted.org/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" },
]
[[package]]

88
web/package-lock.json generated
View File

@@ -40,10 +40,10 @@
"@open-wc/lit-helpers": "^0.7.0",
"@openlayers-elements/core": "^0.4.0",
"@openlayers-elements/maps": "^0.4.0",
"@patternfly/elements": "^4.3.1",
"@patternfly/elements": "^4.4.0",
"@patternfly/patternfly": "^4.224.2",
"@playwright/test": "^1.59.1",
"@sentry/browser": "^10.48.0",
"@sentry/browser": "^10.49.0",
"@storybook/addon-docs": "^10.3.5",
"@storybook/addon-links": "^10.3.5",
"@storybook/web-components": "^10.3.5",
@@ -2825,14 +2825,14 @@
}
},
"node_modules/@patternfly/elements": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@patternfly/elements/-/elements-4.3.1.tgz",
"integrity": "sha512-MRVwxcam+ACyy+0Xy5igPr+LcSVRbX422NGPE4I7WRuwAEhRBA3BayyLi8mNVKXpLLZbk8EtJ17kM30PcMziMw==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@patternfly/elements/-/elements-4.4.0.tgz",
"integrity": "sha512-ShLDYMYEWdhmYDd1XUVj41IfwEmWEXXvHEscVTuga1M9KWMXRJQgf+9jio/2Od5dNh4PAshyH0f19fHFU9EAsA==",
"license": "MIT",
"dependencies": {
"@lit/context": "^1.1.6",
"@patternfly/icons": "^1.0.3",
"@patternfly/pfe-core": "^5.0.6",
"@patternfly/pfe-core": "^5.0.8",
"lit": "^3.3.2",
"tslib": "^2.8.1"
}
@@ -2850,9 +2850,9 @@
"license": "MIT"
},
"node_modules/@patternfly/pfe-core": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/@patternfly/pfe-core/-/pfe-core-5.0.7.tgz",
"integrity": "sha512-cOIyW2k+l/H2592BQ00Bc0kfJClBCRiDDmeEYvhumHAKzgJiQIsVQ81GpNpOgtlibV5KTn3FxrSMadGEpEl/fg==",
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/@patternfly/pfe-core/-/pfe-core-5.0.8.tgz",
"integrity": "sha512-gH+gC8+lwLQ5OxcQsmJOSHNHqQgoa+VboM4LlI63N+jnDPmB7E9EZ7VzJc8C4qTPbCIfQp+o1ObjmKyNw/b9TA==",
"license": "MIT",
"dependencies": {
"@lit/context": "^1.1.6",
@@ -3591,75 +3591,75 @@
"license": "MIT"
},
"node_modules/@sentry-internal/browser-utils": {
"version": "10.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.48.0.tgz",
"integrity": "sha512-SCiTLBXzugFKxev6NoKYBIhQoDk0gUh0AVVVepCBqfCJiWBG01Zvv0R5tCVohr4cWRllkQ8mlBdNQd/I7s9tdA==",
"version": "10.49.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.49.0.tgz",
"integrity": "sha512-n0QRx0Ysx6mPfIydTkz7VP0FmwM+/EqMZiRqdsU3aTYsngE9GmEDV0OL1bAy6a8N/C1xf9vntkuAtj6N/8Z51w==",
"license": "MIT",
"dependencies": {
"@sentry/core": "10.48.0"
"@sentry/core": "10.49.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/feedback": {
"version": "10.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.48.0.tgz",
"integrity": "sha512-tGkEyOM1HDS9qebDphUMEnyk3qq/50AnuTBiFmMJyjNzowylVGmRRk0sr3xkmbVHCDXQCiYnDmSVlJ2x4SDMrQ==",
"version": "10.49.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.49.0.tgz",
"integrity": "sha512-JNsUBGv0faCFE7MeZUH99Y9lU9qq3LBALbLxpE1x7ngNrQnVYRlcFgdqaD/btNBKr8awjYL8gmcSkHBWskGqLQ==",
"license": "MIT",
"dependencies": {
"@sentry/core": "10.48.0"
"@sentry/core": "10.49.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay": {
"version": "10.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.48.0.tgz",
"integrity": "sha512-sevRTePfuk4PNuz9KAKpmTZEomAU0aLXyIhOwA0OnUDdxPhkY8kq5lwDbuxTHv6DQUjUX3YgFbY45VH1JEqHKA==",
"version": "10.49.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.49.0.tgz",
"integrity": "sha512-IEy4lwHVMiRE3JAcn+kFKjsTgalDOCSTf20SoFd+nkt6rN/k1RDyr4xpdfF//Kj3UdeTmbuibYjK5H/FLhhnGg==",
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "10.48.0",
"@sentry/core": "10.48.0"
"@sentry-internal/browser-utils": "10.49.0",
"@sentry/core": "10.49.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
"version": "10.48.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.48.0.tgz",
"integrity": "sha512-9nWuN2z4O+iwbTfuYV5ZmngBgJU/ZxfOo47A5RJP3Nu/kl59aJ1lUhILYOKyeNOIC/JyeERmpIcTxnlPXQzZ3Q==",
"version": "10.49.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.49.0.tgz",
"integrity": "sha512-7D/NrgH1Qwx5trDYaaTSSJmCb1yVQQLqFG4G/S9x2ltzl9876lSGJL8UeW8ReNQgF3CDAcwbmm/9aXaVSBUNZA==",
"license": "MIT",
"dependencies": {
"@sentry-internal/replay": "10.48.0",
"@sentry/core": "10.48.0"
"@sentry-internal/replay": "10.49.0",
"@sentry/core": "10.49.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry/browser": {
"version": "10.48.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.48.0.tgz",
"integrity": "sha512-4jt2zX2ExgFcNe2x+W+/k81fmDUsOrquGtt028CiGuDuma6kEsWBI4JbooT1jhj2T+eeUxe3YGbM23Zhh7Ghhw==",
"version": "10.49.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.49.0.tgz",
"integrity": "sha512-bGCHc+wK2Dx67YoSbmtlt04alqWfQ+dasD/GVipVOq50gvw/BBIDHTEWRJEjACl+LrvszeY54V+24p8z4IgysA==",
"license": "MIT",
"dependencies": {
"@sentry-internal/browser-utils": "10.48.0",
"@sentry-internal/feedback": "10.48.0",
"@sentry-internal/replay": "10.48.0",
"@sentry-internal/replay-canvas": "10.48.0",
"@sentry/core": "10.48.0"
"@sentry-internal/browser-utils": "10.49.0",
"@sentry-internal/feedback": "10.49.0",
"@sentry-internal/replay": "10.49.0",
"@sentry-internal/replay-canvas": "10.49.0",
"@sentry/core": "10.49.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry/core": {
"version": "10.48.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.48.0.tgz",
"integrity": "sha512-h8F+fXVwYC9ro5ZaO8V+v3vqc0awlXHGblEAuVxSGgh4IV/oFX+QVzXeDTTrFOFS6v/Vn5vAyu240eJrJAS6/g==",
"version": "10.49.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.49.0.tgz",
"integrity": "sha512-UaFeum3LUM1mB0d67jvKnqId1yWQjyqmaDV6kWngG03x+jqXb08tJdGpSoxjXZe13jFBbiBL/wKDDYIK7rCK4g==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -6151,9 +6151,9 @@
}
},
"node_modules/@xmldom/xmldom": {
"version": "0.8.12",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.12.tgz",
"integrity": "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==",
"version": "0.8.13",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz",
"integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@@ -14810,9 +14810,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
"integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
"funding": [
{
"type": "opencollective",

View File

@@ -116,10 +116,10 @@
"@open-wc/lit-helpers": "^0.7.0",
"@openlayers-elements/core": "^0.4.0",
"@openlayers-elements/maps": "^0.4.0",
"@patternfly/elements": "^4.3.1",
"@patternfly/elements": "^4.4.0",
"@patternfly/patternfly": "^4.224.2",
"@playwright/test": "^1.59.1",
"@sentry/browser": "^10.48.0",
"@sentry/browser": "^10.49.0",
"@storybook/addon-docs": "^10.3.5",
"@storybook/addon-links": "^10.3.5",
"@storybook/web-components": "^10.3.5",

View File

@@ -130,17 +130,30 @@ export class UserSettingsPage extends WithSession(AKElement) {
</div>
</div>
<div
id="page-mfa"
id="page-credentials"
role="tabpanel"
tabindex="0"
slot="page-mfa"
aria-label=${msg("MFA Devices")}
slot="page-credentials"
aria-label=${msg("Credentials")}
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
<div class="pf-c-card">
<ak-user-settings-mfa
.userSettings=${this.userSettings}
></ak-user-settings-mfa>
<div class="pf-l-stack pf-m-gutter">
<div class="pf-l-stack__item">
<div class="pf-c-card">
<div class="pf-c-card__title">${msg("MFA Devices")}</div>
<ak-user-settings-mfa
.userSettings=${this.userSettings}
></ak-user-settings-mfa>
</div>
</div>
<div class="pf-l-stack__item">
<div class="pf-c-card">
<div class="pf-c-card__title">
${msg("Tokens and App passwords")}
</div>
<ak-user-token-list></ak-user-token-list>
</div>
</div>
</div>
</div>
<div
@@ -163,18 +176,6 @@ export class UserSettingsPage extends WithSession(AKElement) {
></ak-user-settings-source>
</div>
</div>
<div
id="page-tokens"
role="tabpanel"
tabindex="0"
slot="page-tokens"
aria-label=${msg("Tokens and App passwords")}
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
<div class="pf-c-card">
<ak-user-token-list></ak-user-token-list>
</div>
</div>
</ak-tabs>
</div>
</div>`;

View File

@@ -85,7 +85,7 @@ export class MFADevicesPage extends Table<Device> {
role="menuitem"
href="${ifDefined(stage.configureUrl)}${AndNext(
`${globalAK().api.relBase}if/user/#/settings;${JSON.stringify({
page: "page-mfa",
page: "page-credentials",
})}`,
)}"
class="pf-c-dropdown__menu-item"

View File

@@ -923,24 +923,8 @@
<source>Not used by any other object.</source>
<target>Není používáno žádným jiným objektem.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>objekt bude SMAZÁN</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>připojení bude smazáno</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>reference bude obnovena na výchozí hodnotu</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>reference bude nastavena na prázdnou hodnotu</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -961,12 +945,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>Úspěšně smazáno <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Nepodařio se smazat
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Smazat
@@ -1353,17 +1331,17 @@
<target>Konfigurovat vazby</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Zásada
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Skupina
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Uživatel
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2610,18 +2588,6 @@
<source>Don't show this message again.</source>
<target>Tuto zprávu již nezobrazovat.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Nápověda, 'Nový průvodce aplikací', je aktuálně skryta</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Obnovení průvodce aplikací</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Vytvořit pomocí průvodce</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Poskytovatel byl úspěšně importován.</target>
@@ -2777,11 +2743,6 @@
<source>Provider not assigned to any application.</source>
<target>Poskytovatel není přiřazen žádné aplikaci.</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Aktualizovat
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Synchronizace úspěšně spuštěna.</target>
@@ -3613,14 +3574,6 @@ neprojde, když jedna nebo obě z vybraných možností jsou rovny nebo nad prah
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Vytvořit a svázat zásadu</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>Navázat existující <x id="0" equiv-text="${this.allowedTypesLabel}"/></target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>Aktuálně vybraný policy engine je <x id="0" equiv-text="${policyEngineMode.label}"/>:</target>
@@ -5232,30 +5185,6 @@ neprojde, když jedna nebo obě z vybraných možností jsou rovny nebo nad prah
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Platné 360 dní, po kterých se heslo automaticky změní. Heslo můžete zkopírovat ze seznamu tokenů.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Následující objekty používají <x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>spojovací objekt bude smazán</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>Úspěšně aktualizováno <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Nepodařilo se aktualizovat
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
<target>Zosobňuji uživatele...</target>
@@ -8791,9 +8720,6 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10443,12 +10369,6 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10898,6 +10818,156 @@ Vazby na skupiny/uživatele jsou kontrolovány vůči uživateli události.</tar
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -930,24 +930,8 @@
<source>Not used by any other object.</source>
<target>Von keinem anderen Objekt verwendet.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>Objekt wird GELÖSCHT</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>Verbindung wird gelöscht</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>Referenz wird auf den Standardwert zurückgesetzt</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>Referenz wird auf einen leeren Wert gesetzt</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -968,12 +952,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>Erfolgreich <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/> gelöscht</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Fehler beim Löschen
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Lösche
@@ -1364,17 +1342,17 @@
<target>Bindings konfigurieren</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Richtlinie
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Gruppe
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Benutzer
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2635,18 +2613,6 @@
<source>Don't show this message again.</source>
<target>Diese Meldung nicht mehr anzeigen.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Ein Hinweis, der „Assistent für neue Anwendungen“ ist derzeit ausgeblendet</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Hinweis für Anwendungsassistent wiederherstellen</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Mit Assistent erstellen</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Provider erfolgreich importiert.</target>
@@ -2803,11 +2769,6 @@
<source>Provider not assigned to any application.</source>
<target>Provider ist keiner Anwendung zugewiesen.</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Aktualisiere
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Synchronisation erfolgreich ausgelöst.</target>
@@ -3638,14 +3599,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Richtlinie erstellen und binden</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>Vorhandenes <x id="0" equiv-text="${this.allowedTypesLabel}"/> verknüpfen</target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>Der aktuell ausgewählte Modus der Richtlinien-Engine ist <x id="0" equiv-text="${policyEngineMode.label}"/>:</target>
@@ -5257,31 +5210,6 @@ Hier können nur Policies verwendet werden, da der Zugriff geprüft wird, bevor
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Gültig für 360 Tage, danach rotiert das Passwort automatisch. Sie können das Passwort aus der Token-Liste kopieren.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Die folgenden Objekte verwenden
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>Verbindungsobjekt wird gelöscht</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target><x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/> erfolgreich aktualisiert</target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Aktualisieren von
<x id="0" equiv-text="${this.objectLabel}"/>fehlgeschlagen:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
<target>Benutzer wird imitiert …</target>
@@ -8825,9 +8753,6 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10477,12 +10402,6 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10932,6 +10851,156 @@ Bindings zu Gruppen/Benutzern werden mit dem Benutzer des Ereignisses abgegliche
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -701,20 +701,8 @@
<trans-unit id="se09ab93d69f7f45b">
<source>Not used by any other object.</source>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
<source>Delete</source>
@@ -728,9 +716,6 @@
<trans-unit id="se33b158a1ec02a09">
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
@@ -1035,13 +1020,13 @@
<source>Configure Bindings</source>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
</trans-unit>
<trans-unit id="sc387b20e6d629087">
<source>Configure Policy/User/Group Bindings</source>
@@ -2009,15 +1994,6 @@
<trans-unit id="s71c5d51d5a357dbd">
<source>Don't show this message again.</source>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
</trans-unit>
@@ -2135,9 +2111,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
</trans-unit>
@@ -2779,12 +2752,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
</trans-unit>
@@ -4058,24 +4025,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="sbb57cd8a3ed12915">
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -6774,9 +6723,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -8426,12 +8372,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -8881,6 +8821,156 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -911,24 +911,8 @@
<source>Not used by any other object.</source>
<target>No lo usa ningún otro objeto.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>objeto se ELIMINARÁ</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>se eliminará la conexión</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>la referencia se restablecerá al valor predeterminado</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>la referencia se establecerá en un valor vacío</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -949,12 +933,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>Eliminado correctamente <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Error al eliminar
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Eliminar
@@ -1339,17 +1317,17 @@
<target>Configurar Vinculaciones</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Política
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Grupo
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Usuario
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2585,18 +2563,6 @@ Si se deja vacío, AuthnContextClassRef se establecerá según los métodos de a
<source>Don't show this message again.</source>
<target>No mostrar este mensaje de nuevo.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Una pista, 'Asistente para nueva aplicación', está oculta actualmente</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Restaurar la Pista del Asistente de la Aplicación</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Crear con asistente</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Proveedor importado correctamente.</target>
@@ -2749,11 +2715,6 @@ Si se deja vacío, AuthnContextClassRef se establecerá según los métodos de a
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Actualizar
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Sincronización iniciada correctamente.</target>
@@ -3585,14 +3546,6 @@ no se aprueba cuando una o ambas de las opciones seleccionadas son iguales o sup
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Crear y vincular Política</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>Vincular existente <x id="0" equiv-text="${this.allowedTypesLabel}"/></target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>El modo de motor de políticas seleccionado actualmente es<x id="0" equiv-text="${policyEngineMode.label}"/>:</target>
@@ -5200,31 +5153,6 @@ El valor de este campo se compara con el atributo de pertenencia del usuario.</t
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Válido durante 360 días, después de lo cual la contraseña cambiará automáticamente. Puede copiar la contraseña de la lista de tokens.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Los siguientes objetos usan
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>se eliminará el objeto de conexión</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>Actualizado correctamente <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Error al actualizar
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8750,9 +8678,6 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10402,12 +10327,6 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10857,6 +10776,156 @@ Las vinculaciones a grupos/usuarios se verifican en función del usuario del eve
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -938,24 +938,8 @@
<source>Not used by any other object.</source>
<target>Ei minkään muun objektin käytössä.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>objekti POISTETAAN</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>yhteys poistetaan</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>referenssi palautetaan oletusarvoon</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>referenssin arvo tyhjennetään</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -976,12 +960,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target> <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/> poistettiin</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Poisto epäonnistui:
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Poista
@@ -1385,17 +1363,17 @@
<target>Määritä liitokset</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Käytäntö
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Ryhmä
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Käyttäjä
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2685,18 +2663,6 @@
<source>Don't show this message again.</source>
<target>Älä näytä tätä viestiä enää.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Yksi vihje, 'Uusi sovellusavustin', on tällä hetkellä piilotettu</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Palauta sovellusavustimen vihje</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Luo avustajalla</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Palveluntarjoajan tuonti onnistui.</target>
@@ -2853,11 +2819,6 @@
<source>Provider not assigned to any application.</source>
<target>Palveluntarjoajaa ei ole liitetty mihinkään sovellukseen.</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Päivitä
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Synkronoinnin käynnistäminen onnistui.</target>
@@ -3714,14 +3675,6 @@ läpäisy estyy kun jompi kumpi tai molemmat vaihtoehdot ylittävät raja-arvon.
<source>Policy actions</source>
<target>Käytännön toiminnot</target>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Luo ja kytke käytäntö</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>Liitä olemassa oleva: <x id="0" equiv-text="${this.allowedTypesLabel}"/></target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>Tällä hetkellä valittu käytäntöjen tila on <x id="0" equiv-text="${policyEngineMode.label}"/>:</target>
@@ -5360,30 +5313,6 @@ läpäisy estyy kun jompi kumpi tai molemmat vaihtoehdot ylittävät raja-arvon.
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Voimassa 360 vuorokautta, jonka jälkeen salasana uusitaan automaattisesti. Voit kopioida salasanan tunnistelistalta.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Seuraavat objektit käyttävät
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>yhdistävä objekti poistetaan</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Päivitys epäonnistui:
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
<target>Esiinnytään käyttäjänä...</target>
@@ -8991,9 +8920,6 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10643,12 +10569,6 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -11098,6 +11018,156 @@ Liitokset käyttäjiin/ryhmiin tarkistetaan tapahtuman käyttäjästä.</target>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -940,24 +940,8 @@
<source>Not used by any other object.</source>
<target>Pas utilisé par un autre objet.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>l'objet sera SUPPRIMÉ</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>la connexion sera supprimée</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>la référence sera réinitialisée à sa valeur par défaut</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>la référence sera réinitialisée à une valeur vide</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -978,12 +962,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>Réussite de la suppression <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Échec de la suppression de
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Supprimer
@@ -1386,17 +1364,17 @@
<target>Configurer les liaisons</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Politique
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Groupe
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Utilisateur
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2676,18 +2654,6 @@
<source>Don't show this message again.</source>
<target>Ne plus montrer ce message.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Un indice, l'assistant nouvelle application est actuellement caché</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Restaurer l'indice de l'assistant de création d'application</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Créer avec l'assistant</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Fournisseur importé avec succès</target>
@@ -2844,11 +2810,6 @@
<source>Provider not assigned to any application.</source>
<target>Le fournisseur n'est assigné à aucune application.</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Mettre à jour
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Synchronisation lancée avec succès.</target>
@@ -3703,14 +3664,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Policy actions</source>
<target>Actions de politique</target>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Créer et lier une Politique</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>Lier un(e) <x id="0" equiv-text="${this.allowedTypesLabel}"/> existant(e)</target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>Le mode du moteur de politique actuellement sélectionné est <x id="0" equiv-text="${policyEngineMode.label}"/> :</target>
@@ -5349,31 +5302,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Valide pendant 360 jours, après quoi le mot de passe sera alterné automatiquement. Vous pouvez copier le mot de passe depuis la liste des jetons.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Les objets suivants utilisent
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>L'objet connecté sera supprimé</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>Mise à jour effectuée avec succès <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Échec de la mise à jour de
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
<target>Usurpation d'identité...</target>
@@ -8980,9 +8908,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10632,12 +10557,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -11087,6 +11006,156 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -902,24 +902,8 @@
<source>Not used by any other object.</source>
<target>Non utilizzato da altri oggetti.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>l'oggetto sarà CANCELLATO</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>la connessione sarà cancellata</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>il riferimento verrà ripristinato al valore predefinito</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>il riferimento verrà impostato su un valore vuoto</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -940,12 +924,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target> <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/> è stato eliminato correttamente</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Impossibile eliminare
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Elimina
@@ -1309,17 +1287,17 @@
<target>Configura associazioni</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Criterio
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Gruppo
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Utente
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2552,18 +2530,6 @@
<source>Don't show this message again.</source>
<target>Non mostrare di nuovo questo messaggio.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Un suggerimento, "New Application Wizard", è attualmente nascosto</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Ripristina il suggerimento per la procedura guidata dell'applicazione</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Crea con la procedura guidata</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Fornitore importato correttamente.</target>
@@ -2716,11 +2682,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Aggiorna
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Sincronizzazione attivata con successo.</target>
@@ -3545,14 +3506,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Crea e associa criterio</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>Associa esistente <x id="0" equiv-text="${this.allowedTypesLabel}"/></target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>La modalità del motore di policy attualmente selezionata è <x id="0" equiv-text="${policyEngineMode.label}"/>:</target>
@@ -5159,31 +5112,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Valido per 360 giorni, dopo di che la password ruoterà automaticamente. È possibile copiare la password dall'elenco dei token.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Il seguente oggetto usa
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>oggetti connessi saranno cancellati</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>Aggiornato con successo <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Impossibile aggiornare
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8699,9 +8627,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10351,12 +10276,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10806,6 +10725,156 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -928,24 +928,8 @@
<source>Not used by any other object.</source>
<target>他のオブジェクトから使用されていません。</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>オブジェクトは削除されます</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>接続は削除されます</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>参照はデフォルト値にリセットされます</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>参照は空の値に設定されます</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target><x id="0" equiv-text="${ub.name}"/><x id="1" equiv-text="${consequence}"/></target>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
@@ -964,10 +948,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/> を削除しました</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target><x id="0" equiv-text="${this.objectLabel}"/> の削除に失敗しました: <x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${this.objectLabel}"/> を削除</target>
@@ -1370,15 +1350,15 @@
<target>バインディングを設定</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>ポリシー <x id="0" equiv-text="${v.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>グループ <x id="0" equiv-text="${v.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>ユーザー <x id="0" equiv-text="${v.userObj?.name}"/></target>
</trans-unit>
<trans-unit id="sc387b20e6d629087">
@@ -2678,18 +2658,6 @@
<source>Don't show this message again.</source>
<target>このメッセージを再度表示しない。</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>1つのヒント「新規アプリウィザード」が現在非表示になっています</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>アプリウィザードのヒントを復元</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>ウィザードで作成</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>プロバイダーをインポートしました。</target>
@@ -2846,10 +2814,6 @@
<source>Provider not assigned to any application.</source>
<target>プロバイダーはどのアプリにも割り当てられていません。</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${item.verboseName}"/>を更新</target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>同期をトリガーしました。</target>
@@ -3705,14 +3669,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Policy actions</source>
<target>ポリシーアクション</target>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>ポリシーを作成してバインド</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>既存の<x id="0" equiv-text="${this.allowedTypesLabel}"/>をバインド</target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>現在選択されているポリシーエンジンモードは<x id="0" equiv-text="${policyEngineMode.label}"/>です:</target>
@@ -5354,28 +5310,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>360日間有効で、その後パスワードが自動的にローテーションされます。トークンリストからパスワードをコピーできます。</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>次のオブジェクトが <x id="0" equiv-text="${objName}"/> を使用しています</target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>接続オブジェクトが削除されます</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target><x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/> を正常に更新しました</target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target><x id="0" equiv-text="${this.objectLabel}"/> の更新に失敗しました: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
<target>ユーザーを偽装しています...</target>
@@ -8975,9 +8909,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10627,12 +10558,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -11082,6 +11007,156 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -882,24 +882,8 @@
<source>Not used by any other object.</source>
<target>다른 오브젝트에서 사용하지 않습니다.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>오브젝트가 삭제됩니다</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>연결이 삭제됩니다</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>참조가 기본값으로 재설정됩니다</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>참조가 빈 값으로 설정됩니다</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
<source>Delete</source>
@@ -917,12 +901,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>성공적으로 <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/>가 제거됨</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>제거 실패
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${this.objectLabel}"/>
@@ -1283,13 +1261,13 @@
<source>Configure Bindings</source>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
</trans-unit>
<trans-unit id="sc387b20e6d629087">
<source>Configure Policy/User/Group Bindings</source>
@@ -2479,16 +2457,6 @@
<source>Don't show this message again.</source>
<target>이 메시지를 다시 표시하지 마세요.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>힌트, '새 애플리케이션 마법사'는 현재, 숨겨져 있습니다.</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>성공적으로 공급자를 불러왔습니다.</target>
@@ -2620,11 +2588,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${item.verboseName}"/>
업데이트</target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>동기화 트리거 선택.</target>
@@ -3413,13 +3376,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>정책 생성 및 바인드</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
</trans-unit>
@@ -4952,27 +4908,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>360일 동안 유효하며, 그 이후에는 비밀번호가 자동으로 회전합니다. 토큰 목록에서 비밀번호를 복사할 수 있습니다.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>다음 오브젝트는 <x id="0" equiv-text="${objName}"/>을(를) 사용합니다.</target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>연결 오브젝트가 삭제됩니다.</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target><x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/> 을(를) 성공적으로 업데이트했습니다</target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8340,9 +8275,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -9992,12 +9924,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10447,6 +10373,156 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -857,24 +857,8 @@
<source>Not used by any other object.</source>
<target>Niet gebruikt door een ander object.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>object zal worden VERWIJDERD</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>verbinding zal worden verwijderd</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>referentie wordt gereset naar standaardwaarde</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>referentie wordt ingesteld naar een lege waarde</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
<source>Delete</source>
@@ -891,9 +875,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/> succesvol verwijderd</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
@@ -1230,13 +1211,13 @@
<source>Configure Bindings</source>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
</trans-unit>
<trans-unit id="sc387b20e6d629087">
<source>Configure Policy/User/Group Bindings</source>
@@ -2373,15 +2354,6 @@
<trans-unit id="s71c5d51d5a357dbd">
<source>Don't show this message again.</source>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Provider succesvol geïmporteerd.</target>
@@ -2507,9 +2479,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
</trans-unit>
@@ -3269,13 +3238,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Beleid aanmaken en koppelen</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
</trans-unit>
@@ -4765,26 +4727,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Geldig voor 360 dagen, waarna het wachtwoord automatisch wordt gewijzigd. Je kunt het wachtwoord kopiëren vanuit de Tokenlijst.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>verbindend object wordt verwijderd</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>Succesvol bijgewerkt <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8017,9 +7959,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -9669,12 +9608,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10124,6 +10057,156 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -895,24 +895,8 @@
<source>Not used by any other object.</source>
<target>Nie używany przez żaden inny obiekt.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>obiekt zostanie USUNIĘTY</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>połączenie zostanie usunięte</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>odniesienie zostanie zresetowane do wartości domyślnej</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>referencja zostanie ustawiona na pustą wartość</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -933,12 +917,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>Pomyślnie usunięto <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Nie udało się usunąć
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Usuń
@@ -1295,17 +1273,17 @@
<source>Configure Bindings</source>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Zasada
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Grupa
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Użytkownik
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2472,16 +2450,6 @@
<source>Don't show this message again.</source>
<target>Nie pokazuj więcej tego komunikatu.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Jedna podpowiedź, „Kreator nowej aplikacji”, jest obecnie ukryty</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Pomyślnie zaimportowano dostawcę.</target>
@@ -2631,11 +2599,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Aktualizacja
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
</trans-unit>
@@ -3430,13 +3393,6 @@ nie przechodzi, gdy jedna lub obie wybrane opcje są równe lub wyższe od progu
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Utwórz i powiąż zasady</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
</trans-unit>
@@ -4969,31 +4925,6 @@ Można tu używać tylko zasad, ponieważ dostęp jest sprawdzany przed uwierzyt
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Ważne przez 360 dni, po czym hasło zostanie automatycznie zmienione. Możesz skopiować hasło z listy tokenów.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Następujące obiekty używają
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>obiekt łączący zostanie usunięty</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>Pomyślnie zaktualizowano <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Nie udało się zaktualizować
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8370,9 +8301,6 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10022,12 +9950,6 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10477,6 +10399,156 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -941,24 +941,8 @@
<source>Not used by any other object.</source>
<target>Não usado por nenhum outro objeto.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>objeto será DELETADO</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>a conexão será apagada</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>a referência será redefinida para o valor padrão</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>a referência será definida como um valor vazio</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</target>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
@@ -977,10 +961,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/> excluído com sucesso</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Falha ao excluir <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Excluir <x id="0" equiv-text="${this.objectLabel}"/></target>
@@ -1382,15 +1362,15 @@
<target>Configurar Vínculos</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Política <x id="0" equiv-text="${v.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Grupo <x id="0" equiv-text="${v.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Usuário <x id="0" equiv-text="${v.userObj?.name}"/></target>
</trans-unit>
<trans-unit id="sc387b20e6d629087">
@@ -2676,18 +2656,6 @@
<source>Don't show this message again.</source>
<target>Não mostrar esta mensagem novamente.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Uma dica, 'Assistente de Nova Aplicação', está atualmente oculta</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Restaurar dica do assistente de aplicativo</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Criar com assistente</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Fornecedor importado com sucesso.</target>
@@ -2845,11 +2813,6 @@
<source>Provider not assigned to any application.</source>
<target>Provedor não atribuído a nenhum aplicativo.</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Atualizar
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Sincronização acionada com sucesso.</target>
@@ -3708,14 +3671,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Policy actions</source>
<target>Ações da política</target>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Criar e vincular Política</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>Vincular existente <x id="0" equiv-text="${this.allowedTypesLabel}"/></target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>O modo de mecanismo de política atualmente selecionado é <x id="0" equiv-text="${policyEngineMode.label}"/>:</target>
@@ -5353,27 +5308,6 @@ Você só pode usar políticas aqui, pois o acesso é verificado antes de o usu
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Válido por 360 dias; após isso, a senha será rotacionada automaticamente. Você pode copiar a senha na Lista de Tokens.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Os seguintes objetos usam <x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>o objeto de conexão será excluído</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Falha ao atualizar <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
<target>Impersonando usuário...</target>
@@ -8967,9 +8901,6 @@ por exemplo: <x id="0" equiv-text="&lt;code&gt;"/>oci://registry.domain.tld/path
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10619,12 +10550,6 @@ por exemplo: <x id="0" equiv-text="&lt;code&gt;"/>oci://registry.domain.tld/path
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -11074,6 +10999,156 @@ por exemplo: <x id="0" equiv-text="&lt;code&gt;"/>oci://registry.domain.tld/path
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -898,24 +898,8 @@
<source>Not used by any other object.</source>
<target>Не используется никаким другим объектом.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>объект будет удален</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>соединение будет удалено</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>ссылка будет сброшена до значения по умолчанию</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>для ссылки будет установлено пустое значение</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
@@ -936,12 +920,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>Успешно удалено <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Не удалось удалить
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Удалить
@@ -1300,17 +1278,17 @@
<source>Configure Bindings</source>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Политика
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Группа
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Пользователь
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2499,18 +2477,6 @@
<source>Don't show this message again.</source>
<target>Больше не показывать это сообщение.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Одна подсказка, "Мастер создания нового приложения", в настоящее время скрыта</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Восстановить подсказку Мастера создания Приложения</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>Создать с помощью мастера</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Провайдер успешно импортирован.</target>
@@ -2660,11 +2626,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Обновить
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Синхронизация успешно запущена.</target>
@@ -3468,13 +3429,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>Создать и привязать политику</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
</trans-unit>
@@ -5019,31 +4973,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Действует в течение 360 дней, после чего пароль автоматически сменяется. Пароль можно скопировать из списка токенов.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Следующие объекты используют
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>подключенный объект будет удалён</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>Успешно обновлено <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>Не удалось обновить
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8458,9 +8387,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10110,12 +10036,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10565,6 +10485,156 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -889,24 +889,8 @@
<source>Not used by any other object.</source>
<target>Başka bir nesne tarafından kullanılmaz.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>nesne SILİNECEK</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>bağlantı silinecek</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>referans varsayılan değere sıfırlanır</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>referans boş bir değere ayarlanacaktır</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</target>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
@@ -925,10 +909,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/> Başarıyla silindi</target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target><x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/> Silinemedi</target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Sil <x id="0" equiv-text="${this.objectLabel}"/></target>
@@ -1285,15 +1265,15 @@
<source>Configure Bindings</source>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>İlke <x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Grup <x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>Kullanıcı <x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
<trans-unit id="sc387b20e6d629087">
@@ -2478,17 +2458,6 @@
<source>Don't show this message again.</source>
<target>Bu mesajı bir daha göstermeyin.</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>Bir ipucu, 'Yeni Uygulama Sihirbazı' şu anda gizli</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>Uygulama Geri Yükleme Sihirbazı İpucu</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Sağlayıcı başarıyla içe aktarıldı.</target>
@@ -2638,10 +2607,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target><x id="0" equiv-text="${item.verboseName}"/> Güncelleştir</target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>Senkronizasyon başarıyla tetiklendi.</target>
@@ -3447,13 +3412,6 @@ Belirlenen seçeneklerden biri veya her ikisi de eşiğe eşit veya eşiğin üz
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>İlke oluşturma ve bağlama</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
</trans-unit>
@@ -5014,28 +4972,6 @@ Belirlenen seçeneklerden biri veya her ikisi de eşiğe eşit veya eşiğin üz
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>360 gün boyunca geçerlidir, bundan sonra parola otomatik olarak dönecektir. Parolayı Token Listesi'nden kopyalayabilirsiniz.</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>Aşağıdaki nesneler <x id="0" equiv-text="${objName}"/> kullanır</target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>bağlantılı nesne silinecek</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target><x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/> Başarıyla güncellendi</target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target><x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/> Güncellemesi başarısız oldu</target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8440,9 +8376,6 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -10092,12 +10025,6 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10547,6 +10474,156 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -940,24 +940,8 @@
<source>Not used by any other object.</source>
<target>不被任何其他对象使用。</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>对象将被删除</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>连接将被删除</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>引用将被重置为默认值</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>引用将被设置为空值</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>
<x id="1" equiv-text="${consequence}"/></target>
@@ -978,12 +962,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>成功删除 <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>删除
<x id="0" equiv-text="${this.objectLabel}"/> 失败:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>删除
@@ -1390,17 +1368,17 @@
<target>配置绑定</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>策略
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>组
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
<target>用户
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
@@ -2688,18 +2666,6 @@
<source>Don't show this message again.</source>
<target>不要再显示此消息。</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>“新应用程序向导”提示目前已隐藏</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
<target>恢复应用程序向导提示</target>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
<target>通过向导创建</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>已成功导入提供程序。</target>
@@ -2856,10 +2822,6 @@
<source>Provider not assigned to any application.</source>
<target>提供程序未分配给任何应用程序。</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>更新 <x id="0" equiv-text="${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
<target>已成功触发同步。</target>
@@ -3715,14 +3677,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Policy actions</source>
<target>策略操作</target>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>创建与绑定策略</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
<target>绑定已存在的 <x id="0" equiv-text="${this.allowedTypesLabel}"/></target>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
<target>当前所选策略引擎模式为 <x id="0" equiv-text="${policyEngineMode.label}"/></target>
@@ -5422,33 +5376,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>有效期为 360 天,之后密码将自动轮换。您可以从令牌列表中复制密码。</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
<target>您确定要删除 <x id="0" equiv-text="${this.objectLabel}${objName}"/> 吗?</target>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>以下对象使用
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>连接对象将被删除</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>成功更新 <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
<target>更新
<x id="0" equiv-text="${this.objectLabel}"/> 失败:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
<target>您确定要更新 <x id="0" equiv-text="${this.objectLabel}${objName}"/> 吗?</target>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
<target>正在模拟身份...</target>
@@ -9068,10 +8995,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
<target>通过 <x id="0" equiv-text="${event.context.device.name}"/></target>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
<target>引用将悬空</target>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
<target>文件拉取失败</target>
@@ -10907,12 +10830,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -11362,6 +11279,156 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -858,24 +858,8 @@
<source>Not used by any other object.</source>
<target>未被其他物件使用。</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>物件將被刪除</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>連線將被刪除</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>引用將被重設為預設值</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>引用將被設為空值</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<source><x id="0" equiv-text="${item.username}"/> (<x id="1" equiv-text="${item.name}"/>)</source>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
<source>Delete</source>
@@ -892,9 +876,6 @@
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
<target>成功刪除 <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
@@ -1245,13 +1226,13 @@
<source>Configure Bindings</source>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${v.policyObj?.name}"/></source>
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${v.groupObj?.name}"/></source>
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${v.userObj?.name}"/></source>
<source>User <x id="0" equiv-text="${item.userObj?.name || item.userObj?.username}"/></source>
</trans-unit>
<trans-unit id="sc387b20e6d629087">
<source>Configure Policy/User/Group Bindings</source>
@@ -2395,16 +2376,6 @@
<source>Don't show this message again.</source>
<target>不要再顯示這個通知。</target>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
<target>提示:「新增應用程式設定精靈」目前處於隱藏中</target>
</trans-unit>
<trans-unit id="sf2da0e95c78f2cb7">
<source>Restore Application Wizard Hint</source>
</trans-unit>
<trans-unit id="s8aac845c63f45ca2">
<source>Create with wizard</source>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>成功匯入供應商。</target>
@@ -2530,9 +2501,6 @@
<trans-unit id="s0fb31bb136cc353a">
<source>Provider not assigned to any application.</source>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="s3b579c4bb6b447ae">
<source>Successfully triggered sync.</source>
</trans-unit>
@@ -3299,13 +3267,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s775f81ca91aa2d0c">
<source>Policy actions</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
<target>建立政策並附加</target>
</trans-unit>
<trans-unit id="s080af72866b69b3d">
<source>Bind existing <x id="0" equiv-text="${this.allowedTypesLabel}"/></source>
</trans-unit>
<trans-unit id="sb7af25ce6e30d61a">
<source>The currently selected policy engine mode is <x id="0" equiv-text="${policyEngineMode.label}"/>:</source>
</trans-unit>
@@ -4800,26 +4761,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>有效期限為360天之後密碼將會自動輪替。您可以在權杖列表中複製密碼。</target>
</trans-unit>
<trans-unit id="s648ba5092c27baa3">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>連線的物件將被刪除</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.getObjectDisplayName()}"/></source>
<target>成功更新 <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></target>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${pluckErrorDetail(parsedError)}"/></source>
</trans-unit>
<trans-unit id="sa8e65d6274f9e2b9">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}${objName}"/>?</source>
</trans-unit>
<trans-unit id="s1fd02f07e4fa3312">
<source>Impersonating user...</source>
</trans-unit>
@@ -8071,9 +8012,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s6cd96061d397f7b5">
<source>Via <x id="0" equiv-text="${event.context.device.name}"/></source>
</trans-unit>
<trans-unit id="sb7ff80582ccd9348">
<source>reference will be left dangling</source>
</trans-unit>
<trans-unit id="s0b7ddc0168e79ea2">
<source>Failed to fetch files</source>
</trans-unit>
@@ -9723,12 +9661,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s56723699a26ba7a9">
<source>Search for a file by name...</source>
</trans-unit>
<trans-unit id="sc1fc93e04011152f">
<source>New Stage</source>
</trans-unit>
<trans-unit id="s0f2367a322aa1549">
<source>Bind Existing Stage</source>
</trans-unit>
<trans-unit id="s8262b0e4fe70ebcc">
<source>Flow Name</source>
</trans-unit>
@@ -10178,6 +10110,156 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s3c12d23036471dfc">
<source>Dialog content</source>
</trans-unit>
<trans-unit id="s83fc3142af4bc45f">
<source>Require Flow token (flow can only be executed from a generated recovery link)</source>
</trans-unit>
<trans-unit id="s5ca66a541124edd6">
<source>Bind New Policy</source>
</trans-unit>
<trans-unit id="sb41bc87dec355a91">
<source>Select the type of policy you want to create.</source>
</trans-unit>
<trans-unit id="sea431948ed259f17">
<source>Bind Existing...</source>
</trans-unit>
<trans-unit id="s6cd8c9a536fe9778">
<source>Select a type to bind an existing object instead of creating a new one.</source>
</trans-unit>
<trans-unit id="s7ca1155850af5440">
<source>Bind a user</source>
</trans-unit>
<trans-unit id="s5d4ac457eb786153">
<source>Statically bind an existing user.</source>
</trans-unit>
<trans-unit id="s55a97843ee3327da">
<source>Bind a group</source>
</trans-unit>
<trans-unit id="s9759d2c08dac5743">
<source>Statically bind an existing group.</source>
</trans-unit>
<trans-unit id="sca7f18bb58977958">
<source>Bind an existing policy</source>
</trans-unit>
<trans-unit id="sad707c5789636382">
<source>Bind an existing policy.</source>
</trans-unit>
<trans-unit id="s2b9ad6a5bc47ea5d">
<source>Create or bind...</source>
</trans-unit>
<trans-unit id="s9ec971c7789af83a">
<source>Bind New Stage</source>
</trans-unit>
<trans-unit id="s0bc6ba00a01970db">
<source>Select the type of stage you want to create.</source>
</trans-unit>
<trans-unit id="s17740986a2eb4322">
<source>Existing Stage</source>
</trans-unit>
<trans-unit id="saf2e473d40ad27c5">
<source>Bind an existing stage to this flow.</source>
</trans-unit>
<trans-unit id="s2483be7a0f8aa9aa">
<source>Deactivating...</source>
</trans-unit>
<trans-unit id="s29c097ef085ee657">
<source>Activating...</source>
</trans-unit>
<trans-unit id="s88e4a2cee2cad378">
<source>Unknown user</source>
</trans-unit>
<trans-unit id="form.headline.deactivation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Deactivation</source>
</trans-unit>
<trans-unit id="form.headline.activation">
<source>Review <x id="0" equiv-text="${this.verboseName}"/> Activation</source>
</trans-unit>
<trans-unit id="usedBy.associated-objects.label">
<source>Objects associated with this user</source>
</trans-unit>
<trans-unit id="sa2ddb53b55f7432b">
<source>Objects</source>
</trans-unit>
<trans-unit id="s35fc18677970b01f">
<source>Related object</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade-many">
<source>Connection will be deleted</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-default">
<source>Reference will be reset to default value</source>
</trans-unit>
<trans-unit id="used-by.consequence.set-null">
<source>Reference will be set to an empty value</source>
</trans-unit>
<trans-unit id="used-by.consequence.left-dangling">
<source><x id="0" equiv-text="${verboseName}"/> will be left dangling (may cause errors)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unknown-default-open-api">
<source><x id="0" equiv-text="${verboseName}"/> has an unknown relationship (check logs)</source>
</trans-unit>
<trans-unit id="used-by.consequence.unrecognized">
<source><x id="0" equiv-text="${verboseName}"/> has an unrecognized relationship (check logs)</source>
</trans-unit>
<trans-unit id="s539942ab7cc7210e">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sc420894701de5ea3">
<source>Modify</source>
</trans-unit>
<trans-unit id="s002c306b920f1e95">
<source>Modifying</source>
</trans-unit>
<trans-unit id="s37293a6cacedffe2">
<source>Unnamed object</source>
</trans-unit>
<trans-unit id="usedBy.description">
<source>List of objects that are associated with this <x id="0" equiv-text="${verboseName}"/>.</source>
</trans-unit>
<trans-unit id="s2f93abbfddb3830d">
<source>Object Name</source>
</trans-unit>
<trans-unit id="scdb4a00d50beb88a">
<source>Consequence</source>
</trans-unit>
<trans-unit id="form-group.default-label">
<source>Details</source>
</trans-unit>
<trans-unit id="used-by.consequence.cascade">
<source><x id="0" equiv-text="${relationName}"/> will be deleted</source>
<note from="lit-localize">Consequence of deletion, when the related object will also be deleted. The name of the related object will be included, in the format 'Related object will be deleted'.</note>
</trans-unit>
<trans-unit id="user.display.unknownUser">
<source>Unknown user</source>
<note from="lit-localize">Placeholder for an unknown user, in the format 'Unknown user'.</note>
</trans-unit>
<trans-unit id="usedBy.count.other">
<source><x id="0" equiv-text="${verboseName}"/> is associated with <x id="1" equiv-text="${usedByList.length}"/> objects.</source>
<note from="lit-localize">Plural: N objects use this entity.</note>
</trans-unit>
<trans-unit id="usedBy.count.one">
<source><x id="0" equiv-text="${verboseName}"/> is associated with one object.</source>
<note from="lit-localize">Singular: exactly one object uses this entity.</note>
</trans-unit>
<trans-unit id="table.empty">
<source>No <x id="0" equiv-text="${verboseNamePlural.toLocaleLowerCase(this.activeLanguageTag)}"/> found.</source>
<note from="lit-localize">The message to show when a table has no content. The placeholder {0} is replaced with the pluralized name of the type of entity being shown in the table.</note>
</trans-unit>
<trans-unit id="user.display.emailInAngleBrackets">
<source>&lt;<x id="0" equiv-text="${email}"/>&gt;</source>
<note from="lit-localize">The user's email in angle brackets, used when the email is different from the username</note>
</trans-unit>
<trans-unit id="user.display.nameInParens">
<source>(<x id="0" equiv-text="${name}"/>)</source>
<note from="lit-localize">The user's name in parentheses, used when the name is different from the username</note>
</trans-unit>
<trans-unit id="used-by-list-item">
<source><x id="0" equiv-text="${formattedName}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<note from="lit-localize">Used in list item, showing the name of the object and the consequence of deletion.</note>
</trans-unit>
<trans-unit id="usedBy.count.zero">
<source><x id="0" equiv-text="${verboseName}"/> is not associated with any objects.</source>
<note from="lit-localize">Zero: no objects use this entity.</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,4 +1,4 @@
FROM --platform=${BUILDPLATFORM} docker.io/library/node:25.9.0-trixie@sha256:b272ff162109860150e3ad7a5aaf5b607f2a929d30ade79c266ef384c1bfec81 AS docs-builder
FROM --platform=${BUILDPLATFORM} docker.io/library/node:25.9.0-trixie@sha256:74ff139f927c4a233bf0757edefe1ee057d185d6548c65d2741bdda68660fb6a AS docs-builder
ENV NODE_ENV=production
@@ -36,7 +36,7 @@ COPY ./SECURITY.md /work/
RUN corepack npm run build
FROM docker.io/library/nginx:1.29-trixie@sha256:3acc8b9cc6421db48299559e937b2ade69ddd609453b4f44c21ccb239d614535
FROM docker.io/library/nginx:1.29-trixie@sha256:6e23479198b998e5e25921dff8455837c7636a67111a04a635cf1bb363d199dc
LABEL org.opencontainers.image.authors="Authentik Security Inc." \
org.opencontainers.image.source="https://github.com/goauthentik/authentik" \
org.opencontainers.image.description="authentik product documentation" \

View File

@@ -2,21 +2,45 @@
title: authentik bindings
---
A binding is, simply put, a connection between two components. The use of a binding adds additional functionality to one the existing components; for example, a policy binding can cause a new stage to be presented within a flow to a specific user or group.
A binding is a connection between two components. In practice, a binding adds behavior to an existing authentik object by telling authentik where to evaluate a policy, user, or group, or where to insert a stage into a flow.
A policy answers a question like "should this pass?" A binding decides where authentik asks that question.
A policy answers the question "should this pass?" A binding decides where authentik asks that question.
:::info
For information about creating and managing bindings, refer to [Work with bindings](./work-with-bindings.md).
:::
Bindings are an important part of authentik; the majority of configuration options are defined in bindings.
Bindings are used throughout authentik. Many access and execution decisions are configured through bindings. The two binding types that you will work with most often are:
It's important to remember that bindings are instantiated objects themselves, and conceptually can be considered as a "connector" between two components. This is why you might read about "binding a binding", because technically, a binding is "spliced" into another binding, in order to intercept and enforce the criteria defined in the second binding. Note that stage-bindings are the only type of binding that you can add (or splice) another binding to.
- **Policy bindings**, which attach a policy, user, or group to an object that supports bindings.
- **Flow-stage bindings**, which attach a stage to a flow in a specific order.
## Relations with bindings
## Types of bindings
This diagram shows the relationships that bindings have between components. The primary components are _policy_, _user_, and _group_; these three objects can be bound to an application, application entitlement, flow, flow-stage binding, source, device, device access group, notification rule, or endpoint.
The two most common types of bindings in authentik are policy bindings and flow-stage bindings. They solve different problems:
- Use a policy binding when you want to control whether a target is allowed, denied, or shown.
- Use a flow-stage binding when you want to place a stage into a flow and decide when it should run.
## Where bindings are used
The policy binding system is shared by several authentik objects. As of the current implementation, you can bind policies, users, and groups to these targets:
- flows
- flow-stage bindings
- applications
- application entitlements
- sources
- devices
- device access groups
- notification rules
- RAC endpoints
Stages themselves are not policy binding targets. A stage is attached to a flow through a flow-stage binding, so when you bind a policy to a stage in a flow, you are binding it to that flow-stage binding.
Because of this, the same stage can be reused in multiple flows, and each flow can apply different policies to that stage.
## Relationships
```mermaid
@@ -73,45 +97,76 @@ flowchart TD
policy_binding --> flow_stage_binding
```
## Types of bindings
## Policy bindings
The two most common types of bindings in authentik are:
A policy binding attaches one of the following to a target:
- policy bindings (which can also bind to users and groups)
- flow-stage bindings
- a policy object
- a user
- a group
### Policy bindings
User and group bindings are simple membership checks. A user binding passes when the current user matches that user. A group binding passes when the current user is a member of that group.
A _policy binding_ connects a specific policy (a policy object) to a flow or stage binding. With the policy binding, the flow (or specifically the stage within the flow) will now have additional content (i.e. the rules of the policy).
This is useful when you want a direct allow or deny rule without creating a separate policy object.
With policy bindings, you can also bind groups and users to another component (an application, a source, a flow, etc.). For example you can bind a specific group to an application, and then only that group (and/or other groups also bound to it, depending on the [policy engine mode](../applications/manage_apps.mdx#use-bindings-to-control-access)), can access the application.
Policy bindings are commonly used with applications, sources, flows, flow-stage bindings, and [application entitlements](../applications/manage_apps.mdx#application-entitlements). For example, you can bind a group directly to an application so that only members of that group can view and launch it.
When you bind a policy to a stage binding, this task is done _per flow_, and does not carry across to other flows that use this same stage. That is, you will need to go to the **Stage Bindings** tab for the specific flow, and add a policy to the stage.
Bindings are evaluated according to the target's **Policy engine mode**:
Bindings are also used for [Application Entitlements](../../add-secure-apps/applications/manage_apps.mdx#application-entitlements), where you can bind specific users or groups to an application as a way to manage who has access to certain areas _within an application_.
- `Any`: the target passes when any binding passes.
- `All`: the target passes only when every binding passes.
:::info
Be aware that any policy binding bound directly to the entire flow (not to a stage within the flow) are evaluated _before_ the flow executes, so if the user has not been identified, the flow will not be accessible. This is due to bindings relying on user information that isn't available yet.
:::
authentik evaluates enabled bindings in ascending order. The order is most noticeable when you are reading logs or combining multiple policies that return messages.
### Flow-stage bindings
Bindings also support these options:
:::info
Be aware that depending on context, user and group policy bindings are not evaluated (i.e. ignored). For example, if you are not authenticated or if authentik has not yet identified the user, a policy binding that depends on knowing who the user is cannot be evaluated.
:::
- **Negate**, which flips the pass or fail result of the binding.
- **Timeout**, which limits how long authentik waits for policy execution.
- **Failure result**, which controls whether a policy error is treated as pass or fail.
Flow-stage bindings (also called stage bindings) are analyzed by authentik's Flow Plan, which starts with the flow, then assesses all of the bound policies, and then runs them in order to build out the plan.
Policy bindings attached directly to a flow are evaluated before the flow starts. In authentication and enrollment flows, that usually means that user- and group-based checks on the flow itself cannot pass until the user has already been identified elsewhere.
A _flow-stage binding_ connects a stage to a flow in a specified order, so that the stage is executed at the desired point within the flow.
If a target has no applicable bindings, authentik treats the result as passing by default.
For example, you can create a binding for a specific group, and then [bind that to a stage binding](../flows-stages/stages/index.md#bind-users-and-groups-to-a-flows-stage-binding), with the result that everyone in that group now will see that stage (and any policies bound to that stage) as part of their flow. Or more specifically, and going one step deeper, you can also _bind a binding to a binding_.
## Flow-stage bindings
Flow-stage bindings can have policy bindings bound to them; this can be used to conditionally run or skip stages within a flow. There are two settings in a flow-stage binding that configure _when_ these policies are executed:
A flow-stage binding attaches a stage to a flow and defines the order in which that stage runs.
- **Evaluate when flow is planned**
Policies are evaluated when authentik creates a flow plan that contains a reference to all of the stages that the user will need to go through to complete the flow. In this case, user-specific attributes are only available if the user is already authenticated before beginning the flow.
Flow-stage bindings are also called stage bindings. authentik uses them while building the flow plan that determines which stages a user will see and in what order.
- **Evaluate when the stage is run**
Policies bound to a flow-stage binding are evaluated before the stage is run (i.e. after the flow has started but before the stage is reached in the flow). Therefore, the context with which policy bindings to the flow-stage binding are evaluated reflects the current state of the flow.
This matters because stages are reusable objects. The same stage can appear in multiple flows, but each flow-stage binding can have its own policies, users, groups, order, and evaluation settings. When you bind a policy to a stage in a specific flow, you are binding it to that flow-stage binding, not to the reusable stage definition itself.
For example, when configuring an authentication flow with an identification stage bound to it, and a user bound to a Captcha flow-stage binding, with this setting (**Evaluate when stage is run**) enabled authentik can check against the user who has identified themselves previously.
### When authentik evaluates stage-binding policies
Flow-stage bindings have two evaluation settings:
- **Evaluate when flow is planned**: authentik evaluates the binding while it is building the flow plan. If the binding does not pass at planning time, the stage is not added to the plan.
- **Evaluate when the stage is run**: authentik adds the stage to the flow plan, then evaluates the binding again immediately before the stage is shown. If the binding no longer passes, authentik removes that stage from the flow plan.
The second option is useful when the decision depends on context that is only available later in the flow. For example, after an identification stage completes, a subsequent stage binding can assess the identified user and then trigger a CAPTCHA or Deny stage as needed.
In other words:
- use **Evaluate when flow is planned** when the decision can already be made before the user reaches the stage
- use **Evaluate when the stage is run** when the decision depends on flow context that is created by an earlier stage
## What to remember
- Stages are attached to flows through flow-stage bindings.
- Policies, users, and groups can all be bound through the same policy binding system.
- The same stage can behave differently in different flows because each flow-stage binding has its own settings and bindings.
- A policy bound directly to a flow is evaluated earlier than a policy bound to a flow-stage binding.
## Common examples
### Restrict an application
By default, applications are accessible to all users. Bind a group or policy to an application when you want to limit access to specific users.
### Run a stage only for some users
Bind a policy, user, or group to the flow-stage binding when a stage should appear only for certain users in that flow. For example, only require an MFA stage for certain users.
### Scope access inside an application
Use [application entitlements](../applications/manage_apps.mdx#application-entitlements) when you need to control access to parts of an application after the user already has access to the application itself. For example, control which users have access to certain administrator functions within an application.

View File

@@ -24,6 +24,62 @@ Keep in mind that when using Code-based devices (TOTP, Static and SMS), values l
### Options
#### Require more than one MFA method
To require users to enroll more than one MFA method and validate with each method on every login, add multiple **Authenticator Validation** stages to the same authentication flow.
Configure each authenticator validation stage with a different set of allowed **Device classes**, and set **Not configured action** to **Configure**.
#### Example: require both TOTP and WebAuthn
To require both TOTP and WebAuthn:
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Create a TOTP setup stage and a WebAuthn setup stage if you do not already have them.
3. Navigate to **Flows and Stages** > **Stages** and create an **Authenticator Validation** stage for TOTP:
- Set **Device classes** to `totp`.
- Set **Not configured action** to **Configure**.
- Set **Configuration stages** to your TOTP setup stage.
4. Create a second **Authenticator Validation** stage for WebAuthn:
- Set **Device classes** to `webauthn`.
- Set **Not configured action** to **Configure**.
- Set **Configuration stages** to your WebAuthn setup stage.
5. Navigate to **Flows and Stages** > **Flows** and open your authentication flow.
6. On the **Stage Bindings** tab, bind both validation stages to the flow in the order that you want users to enroll them.
On first sign-in, users who do not yet have one of the required methods are prompted to configure it before the flow continues. On later sign-ins, each validation stage checks only the device classes configured on that stage.
#### Require at least two enrolled MFA methods of any type
If you want to require users to enroll at least two different MFA methods, regardless of which types they choose, use an [Expression Policy](../../../../customize/policies/types/expression/index.mdx) to count the enrolled device classes for the user.
To enforce this requirement:
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Customization** > **Policies** and create an **Expression Policy**.
3. Add an expression like the following to count the user's confirmed authenticator types:
```python
from authentik.stages.authenticator import devices_for_user
pending_user = request.context.get("pending_user")
if not pending_user or not pending_user.pk:
return False
device_types = {
device.__class__.__name__.lower().replace("device", "")
for device in devices_for_user(pending_user, confirmed=True)
}
return len(device_types) >= 2
```
4. Bind the policy to the flow or stage binding that controls whether the user can continue without enrolling another authenticator.
#### Allow users to choose from multiple enrollment methods
If you select multiple **Configuration stages** on a single validation stage, users can choose which authenticator to enroll for that requirement.
#### Less-frequent validation
You can configure this stage to only ask for MFA validation if the user hasn't authenticated themselves within a defined time period. To configure this, set _Last validation threshold_ to any non-zero value. Any of the user's devices within the selected classes are checked.

View File

@@ -31,29 +31,62 @@ If you create a service account, that account has an automatically generated App
## Passwordless login
There are two different ways to configure passwordless authentication;
There are two different ways to configure passwordless authentication:
- allow users to directly authenticate with their authenticator (only supported for WebAuthn devices), by following [these instructions](../authenticator_validate/index.mdx#passwordless-authentication).
- dynamically skip a Password stage (depending on the user's device), as documented on this page.
If you want users to be able to pick a passkey from the browser's passkey/autofill UI without entering a username first, configure **Passkey autofill (WebAuthn conditional UI)** in the [Identification stage](../identification/index.mdx#passkey-autofill-webauthn-conditional-ui). This is separate from configuring a dedicated passwordless flow, and can be used alongside normal identification flows.
Depending on what kind of device you want to require the user to have:
### Dynamically skip a Password stage
This setup keeps a normal identification flow, but skips the Password stage for users who already have a supported authenticator configured.
To configure this setup:
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Customization** > **Policies** and create an [Expression Policy](../../../../customize/policies/types/expression/index.mdx).
3. Configure the expression so that it returns `True` only when the Password stage should run. Use one of the expressions below, depending on the authenticator type.
4. Navigate to **Flows and Stages** > **Flows** and open your authentication flow.
5. Open the **Stage Bindings** tab, expand the Password stage binding, and bind the Expression Policy there. Do not bind it to the flow itself or directly to the stage object. For more background, see [Bind a policy to a stage binding](../../../../customize/policies/working_with_policies.md#bind-a-policy-to-a-stage-binding).
6. On the Password stage binding, enable **Evaluate when stage is run**. Disable **Evaluate when flow is planned** unless the user is already known before the flow starts.
#### WebAuthn
```python
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
return WebAuthnDevice.objects.filter(user=request.context['pending_user'], confirmed=True).exists()
pending_user = request.context.get("pending_user")
if not pending_user:
return True
return not WebAuthnDevice.objects.filter(user=pending_user, confirmed=True).exists()
```
#### Duo
```python
from authentik.stages.authenticator_duo.models import DuoDevice
return DuoDevice.objects.filter(user=request.context['pending_user'], confirmed=True).exists()
pending_user = request.context.get("pending_user")
if not pending_user:
return True
return not DuoDevice.objects.filter(user=pending_user, confirmed=True).exists()
```
Afterwards, bind the policy you've created to the stage binding of the password stage.
Because the expression already returns whether the Password stage should run, you do not need to enable **Negate result** on the policy binding.
Make sure to uncheck _Evaluate when flow is planned_ and check _Evaluate when stage is run_, otherwise an invalid result will be cached.
If the Password stage binding has more than one policy attached, review its **Policy engine mode** carefully:
- With only this policy attached, either mode works.
- If multiple policies are attached, `all` requires every policy to pass before the Password stage runs.
- If multiple policies are attached, `any` runs the Password stage when any bound policy passes.
#### Default authentication flow
The built-in `default-authentication-flow` already includes a policy binding on its Password stage, `default-authentication-flow-password-stage`, which controls whether the Password stage should appear.
If you add a second policy to that same Password stage binding, set the stage binding's **Policy engine mode** to `all` so both the built-in policy and your Expression Policy must pass before the Password stage runs.
Keep **Evaluate when stage is run** enabled on that binding. In the default blueprint, this is already configured.

View File

@@ -4,44 +4,51 @@ title: Embedded Outpost
authentik includes an embedded outpost to simplify deployments that use the Proxy provider.
The embedded outpost runs in the main `server` container, and is managed by authentik itself. The embedded outpost authenticates itself via the secret key.
The embedded outpost runs as part of the main authentik server deployment and is managed by authentik itself. It authenticates to the authentik API by using the secret key.
You can access the embedded outpost on the same ports as authentik itself, 9000 and 9443.
You can access the embedded outpost on the same ports as authentik itself, `9000` and `9443`.
If the embedded outpost doesn't make sense for your deployment, you can simply ignore it.
## When to use the embedded outpost
### Configuration
Use the embedded outpost when you are using the proxy provider and want the simplest deployment model. It is a good fit when authentik is already behind a reverse proxy and you want proxy provider traffic to be handled by the same authentik deployment, without a separate outpost deployment.
Since authentik doesn't know its own "primary" URL, there might be some configuration required.
Use a [managed outpost](../index.mdx) instead when you want authentik to deploy and update a separate outpost through the [Docker](../integrations/docker.md) or [Kubernetes](../integrations/kubernetes.md) integrations, or when you want the outpost lifecycle to be separate from the core server.
By default, when opening the admin dashboard on a fresh install, authentik will automatically configure the outpost to use the same URL as was used to access authentik.
If the embedded outpost does not fit your deployment, you can ignore it and use a [managed outpost](../index.mdx) instead.
If this isn't correct, or needs to be changed, click the edit button on the right of the outpost, and set the value of `authentik_host` to the URL you want to log in with.
Make sure to set it to a full URL; only configuring a hostname or FQDN will not work.
## Configuration
Additionally, most of the other configuration options can be used as with any other outpost, except for items that are marked as "non-embedded".
Because authentik does not know its own primary URL, you might need to configure the embedded outpost after installation.
By default, when you open the Admin interface on a fresh install, authentik automatically configures the outpost to use the same URL that was used to access authentik.
If this is not correct, navigate to **Applications** > **Outposts**, edit **authentik Embedded Outpost**, and set `authentik_host` to the correct URL.
Make sure that you set a full URL. A hostname or FQDN by itself does not work.
Most other outpost configuration options also apply to the embedded outpost, except for items that are marked as `non-embedded`.
import Configuration from "../_config.md";
<Configuration />
### Routing
## Routing
Routing is handled like this:
Requests are routed as follows:
1. Paths starting with `/static`, `/media` and `/help` return packaged CSS/JS files, and user-uploaded media files.
1. Paths starting with `/static`, `/media`, and `/help` return packaged CSS and JavaScript files, and user-uploaded media files.
2. Paths starting with `/outpost.goauthentik.io` are sent to the embedded outpost.
3. Any hosts configured in the providers assigned to the embedded outpost are sent to the outpost.
4. Everything remaining is sent to the authentik backend server.
### Differences
## How the embedded outpost differs from managed outposts
There are a few more differences between managed outposts and the embedded outpost, mainly due to the fact that authentik can't fully manage the containers.
There are a few differences between managed outposts and the embedded outpost because authentik cannot fully manage the main authentik server deployment in the same way that it manages a separate outpost deployment.
1. (Docker-only) No automatic traefik labels are added to the server container.
1. Docker only: no automatic Traefik labels are added to the server container.
When you deploy a managed outpost on docker, the container has several labels to automatically configure traefik. This is not done for the embedded outpost.
When you deploy a managed outpost on Docker, the container includes labels that can configure Traefik automatically. The embedded outpost does not add those labels to the server container.
2. (Kubernetes-only) An additional service is created.
2. Kubernetes only: an additional Service is created.
Since authentik does not know what the normal authentik Service is called, another one is created with a common set of labels that is always set.
Because authentik does not know the name of the primary authentik Service, it creates another Service with a common set of labels that is always present.

View File

@@ -13,6 +13,8 @@ app.company {
# capitalization of the headers is important, otherwise they will be empty
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
# Add the 'authorization' header to the list if you need proxy providers which
# send a custom HTTP-Basic Authentication header based on values from authentik
# optional, in this config trust all private ranges, should probably be set to the outposts IP
trusted_proxies private_ranges

View File

@@ -20,7 +20,7 @@ spec:
headersToUpstreamOnAllow:
- set-cookie
- x-authentik-*
# Add authorization headers to the allow list if you need proxy providers which
# Add the 'authorization' header to headersToUpstreamOnAllow if you need proxy providers which
# send a custom HTTP-Basic Authentication header based on values from authentik
# - authorization
includeRequestHeadersInCheck:

View File

@@ -41,6 +41,8 @@ metadata:
https://app.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$escaped_request_uri
nginx.ingress.kubernetes.io/auth-response-headers: |-
Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-entitlements,X-authentik-email,X-authentik-name,X-authentik-uid
# Add the 'authorization' header to auth-response-headers if you need proxy providers which
# send a custom HTTP-Basic Authentication header based on values from authentik
nginx.ingress.kubernetes.io/auth-snippet: |
proxy_set_header X-Forwarded-Host $http_host;
```

View File

@@ -33,6 +33,8 @@ services:
traefik.http.middlewares.authentik.forwardauth.address: http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik
traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-entitlements,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version
# Add the 'authorization' header to authResponseHeaders if you need proxy providers which
# send a custom HTTP-Basic Authentication header based on values from authentik
restart: unless-stopped
whoami:

View File

@@ -23,6 +23,9 @@ spec:
- X-authentik-meta-provider
- X-authentik-meta-app
- X-authentik-meta-version
# Add the 'authorization' header to authResponseHeaders if you need proxy providers which
# send a custom HTTP-Basic Authentication header based on values from authentik
# - authorization
```
:::info

View File

@@ -18,6 +18,9 @@ http:
- X-authentik-meta-provider
- X-authentik-meta-app
- X-authentik-meta-version
# Add the 'authorization' header to authResponseHeaders if you need proxy providers which
# send a custom HTTP-Basic Authentication header based on values from authentik
# - authorization
routers:
default-router:
rule: "Host(`app.company`)"

View File

@@ -62,5 +62,3 @@ If you're focusing solely on frontend development, you can create a minimal deve
```
You can now access authentik on http://localhost:9000 (or https://localhost:9443).
You might also want to complete the initial setup under `/if/flow/initial-setup/`.

View File

@@ -174,7 +174,7 @@ make web-watch
After the frontend build completes, set a password for the default admin user (**akadmin**):
1. Navigate to http://localhost:9000/if/flow/initial-setup/ in your browser.
1. Navigate to http://localhost:9000 in your browser.
2. Follow the prompts to set up your admin account.
From now on, you can access authentik at http://localhost:9000 using the credentials you defined in Step 2.

View File

@@ -37,4 +37,4 @@ Follow these instructions to configure the Fleet connector in authentik:
The **Map teams to device access group** setting will not detect changes to a device's groups membership in Fleet. If the device's groups change, you will need to manually configure a [device access group](../../authentik-agent/device-authentication/device-access-groups.mdx).
:::
After creating the connector, it can be used in the [Endpoint Stage](../../../add-secure-apps/flows-stages/stages/endpoint/index.md). Refer to [Device compliance policy](../device-compliance-policy.md) for more information on using device facts from the connector in a flow.
After creating the connector, it can be used in the [Endpoint Stage](../../../add-secure-apps/flows-stages/stages/endpoint/index.md). Refer to [Fleet conditional access](../fleet-conditional-access.md) and [Device compliance policy](../device-compliance-policy.md) for more information on using device facts from the connector in a flow.

View File

@@ -0,0 +1,48 @@
---
title: Fleet conditional access for Apple devices
sidebar_label: Fleet conditional access
tags: [device compliance, compliance, conditional access, fleet, fleetdm]
authentik_version: "2026.5"
---
authentik can be configured to restrict access to specific services so that only Fleet-registered Apple devices are allowed.
authentik automatically retrieves the Conditional Access Root CA certificate from Fleet via the Fleet connector. The Endpoint stage then verifies the devices Fleet-issued certificate against this Root CA. If validation succeeds, the device is bound to the users current authentik session.
## Prerequisites
- You must have [configured compliance](./configuration.md) in authentik
- The [Fleet connector](./connectors/fleetdm.md) must be configured in authentik
- Conditional access Root CA Certificate must be pulled from Fleet via the Fleet connector. This is an automatic process
- A Fleet Enterprise license is required
## Configure Fleet and devices
A Fleet Conditional Access configuration profile must be applied to every device that you wish to apply conditional access to. Please note that that this will only function on iOS and iPadOS devices that are enrolled via Apple Automated Device Enrollment (ADE). The same limitation does not apply to macOS devices.
1. Log in to your Fleet dashboard as an administrator.
2. Navigate to **Settings** > **Integrations** > **Conditional Access**.
3. Next to **Okta**, click **Connect**. Despite being named **Okta**, the same profile is used for all integrations.
4. Click the copy button to the right of **User scope profile**.
5. Save the text as a `.mobileconfig` file. Apply it as a Fleet configuration profile on any Apple device that you wish to apply conditional access to.
Refer to the [Fleet Custom OS settings documentation](https://fleetdm.com/guides/custom-os-settings) for more information on applying configuration profiles.
## Configure authentik
This configuration applies to a specific flow, such as an authentication flow.
### Bind Endpoint stage to flow
The flow must have an [Endpoint stage](../../add-secure-apps/flows-stages/stages/endpoint/index.md) bound to it.
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Flows and Stages > Flows**.
3. Select the flow that you want to modify.
4. Open the **Stage Bindings** tab and click **Create and bind stage**.
5. Select **Endpoint Stage** as the stage type, click **Next**, and configure the following settings:
- **Name**: provide a name for the stage
- **Connector**: select the Fleet connector
- **Mode**: set to `Device required`
6. Click **Next**.
7. Select the order for the stage. Ensure that this places the Endpoint stage in the flow wherever you want device access to be checked.
8. Click **Finish**.

View File

@@ -30,12 +30,12 @@ The stack will output the endpoint of the ALB to which you can point your DNS re
## Access authentik from AWS CloudFormation
To launch authentik, in your browser go to:
To start the initial setup, navigate to `http://<domain_you_configured>`.
`http://<domain_you_configured>/if/flow/initial-setup/`
You are then prompted to set a password for the `akadmin` user (the default user).
:::info Initial setup in browser
You will get a `Not Found` error if initial setup URL doesn't include the trailing forward slash `/`. Also verify that the authentik server, worker, and PostgreSQL database are running and healthy. Review additional tips in our [troubleshooting docs](../../troubleshooting/login.md#cant-access-initial-setup-flow-during-installation-steps).
:::info Issues with initial setup
If you run into issues, refer to our [troubleshooting docs](../../troubleshooting/login.md#cant-access-initial-setup-flow-during-installation-steps).
:::
### Further customization

View File

@@ -116,14 +116,14 @@ The `compose.yml` file statically references the latest version available at the
## Access authentik
To start the initial setup, navigate to `http://<your server's IP or hostname>:9000/if/flow/initial-setup/`.
:::info Initial setup in browser
You will get a `Not Found` error if initial setup URL doesn't include the trailing forward slash `/`. Also verify that the authentik server, worker, and PostgreSQL database are running and healthy. Review additional tips in our [troubleshooting docs](../../troubleshooting/login.md#cant-access-initial-setup-flow-during-installation-steps).
:::
To start the initial setup, navigate to `http://<your server's IP or hostname>:9000`.
You are then prompted to set a password for the `akadmin` user (the default user).
:::info Issues with initial setup
If you run into issues, refer to our [troubleshooting docs](../../troubleshooting/login.md#cant-access-initial-setup-flow-during-installation-steps).
:::
## First steps in authentik
import BlurbFirstSteps from "../first-steps/_blurb_first_steps.mdx";

View File

@@ -109,10 +109,12 @@ During the installation process, the database migrations will be applied automat
## Access authentik
After the installation is complete, access authentik at `https://<authentik-host-name>/if/flow/initial-setup/`. Here, you can set a password for the default `akadmin` user.
To start the initial setup, navigate to `http://<your server's IP or hostname>:9000`.
:::info Initial setup in browser
You will get a `Not Found` error if initial setup URL doesn't include the trailing forward slash `/`. Also verify that the authentik server, worker, and PostgreSQL database are running and healthy. Review additional tips in our [troubleshooting docs](../../troubleshooting/login.md#cant-access-initial-setup-flow-during-installation-steps).
You are then prompted to set a password for the `akadmin` user (the default user).
:::info Issues with initial setup
If you run into issues, refer to our [troubleshooting docs](../../troubleshooting/login.md#cant-access-initial-setup-flow-during-installation-steps).
:::
## First steps in authentik

View File

@@ -876,6 +876,7 @@ const items = [
"endpoint-devices/device-compliance/device-reporting",
"endpoint-devices/device-compliance/device-compliance-policy",
"endpoint-devices/device-compliance/browser-extension",
"endpoint-devices/device-compliance/fleet-conditional-access",
],
},
],

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