stages/authenticator_validate: remember (#2828)

* initial

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

* web: cleanup timedelta help

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

* add tooltip

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

* add tests

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

* assert response code in self.assertStageResponse

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

* add more tests, add duo

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

* add docs

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

* fix

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens L 2022-05-10 21:05:22 +02:00 committed by GitHub
parent 4d755dc0f6
commit fd1d38f844
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 2006 additions and 1267 deletions

View File

@ -99,11 +99,18 @@ migrate:
run:
go run -v cmd/server/main.go
web-watch:
cd web && npm run watch
#########################
## Web
#########################
web: web-lint-fix web-lint web-extract
web-install:
cd web && npm ci
web-watch:
cd web && npm run watch
web-lint-fix:
cd web && npm run prettier
@ -114,6 +121,21 @@ web-lint:
web-extract:
cd web && npm run extract
#########################
## Website
#########################
website: website-lint-fix
website-install:
cd website && npm ci
website-lint-fix:
cd website && npm run prettier
website-watch:
cd website && npm run watch
# These targets are use by GitHub actions to allow usage of matrix
# which makes the YAML File a lot smaller
@ -139,10 +161,8 @@ ci-pyright: ci--meta-debug
ci-pending-migrations: ci--meta-debug
./manage.py makemigrations --check
install:
install: web-install website-install
poetry install
cd web && npm ci
cd website && npm ci
a: install
tmux \

View File

@ -12,3 +12,7 @@ class FlowNonApplicableException(SentryIgnoredException):
class EmptyFlowException(SentryIgnoredException):
"""Flow has no stages."""
class FlowSkipStageException(SentryIgnoredException):
"""Exception to skip a stage"""

View File

@ -23,6 +23,7 @@ class FlowTestCase(APITestCase):
**kwargs,
) -> dict[str, Any]:
"""Assert various attributes of a stage response"""
self.assertEqual(response.status_code, 200)
raw_response = loads(response.content.decode())
self.assertIsNotNone(raw_response["component"])
self.assertIsNotNone(raw_response["type"])

View File

@ -87,7 +87,6 @@ class TestFlowExecutor(FlowTestCase):
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
flow=flow,
@ -406,7 +405,6 @@ class TestFlowExecutor(FlowTestCase):
# A get request will evaluate the policies and this will return stage 4
# but it won't save it, hence we can't check the plan
response = self.client.get(exec_url)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(response, flow, component="ak-stage-dummy")
# fourth request, this confirms the last stage (dummy4)
@ -479,7 +477,6 @@ class TestFlowExecutor(FlowTestCase):
exec_url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug})
# First request, run the planner
response = self.client.get(exec_url)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
flow,
@ -491,5 +488,4 @@ class TestFlowExecutor(FlowTestCase):
user_fields=[UserFields.E_MAIL],
)
response = self.client.post(exec_url, {"uid_field": "invalid-string"}, follow=True)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(response, flow, component="ak-stage-access-denied")

View File

@ -50,7 +50,6 @@ class TestPasswordPolicyFlow(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
{"password": "akadmin"},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0.4 on 2022-05-10 17:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_authenticator_duo", "0002_default_setup_flow"),
]
operations = [
migrations.AddField(
model_name="duodevice",
name="last_t",
field=models.DateTimeField(auto_now=True),
),
]

View File

@ -74,6 +74,8 @@ class DuoDevice(Device):
stage = models.ForeignKey(AuthenticatorDuoStage, on_delete=models.CASCADE)
duo_user_id = models.TextField()
last_t = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name or str(self.user)

View File

@ -1,5 +1,6 @@
"""Duo stage"""
from django.http import HttpRequest, HttpResponse
from django.utils.timezone import now
from rest_framework.fields import CharField
from structlog.stdlib import get_logger
@ -85,7 +86,11 @@ class AuthenticatorDuoStageView(ChallengeStageView):
self.request.session.pop(SESSION_KEY_DUO_ACTIVATION_CODE)
if not existing_device:
DuoDevice.objects.create(
name="Duo Device", user=self.get_pending_user(), duo_user_id=user_id, stage=stage
name="Duo Device",
user=self.get_pending_user(),
duo_user_id=user_id,
stage=stage,
last_t=now(),
)
else:
return self.executor.stage_invalid("Device with Credential ID already exists.")

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0.4 on 2022-04-14 20:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_authenticator_sms", "0002_alter_authenticatorsmsstage_from_number"),
]
operations = [
migrations.AddField(
model_name="smsdevice",
name="last_t",
field=models.DateTimeField(auto_now=True),
),
]

View File

@ -168,6 +168,14 @@ class SMSDevice(SideChannelDevice):
phone_number = models.TextField()
last_t = models.DateTimeField(auto_now=True)
def verify_token(self, token):
valid = super().verify_token(token)
if valid:
self.save()
return valid
def __str__(self):
return self.name or str(self.user)

View File

@ -30,6 +30,7 @@ class AuthenticatorValidateStageSerializer(StageSerializer):
"not_configured_action",
"device_classes",
"configuration_stages",
"last_auth_threshold",
]

View File

@ -147,4 +147,5 @@ def validate_challenge_duo(device_pk: int, request: HttpRequest, user: User) ->
# {'result': 'allow', 'status': 'allow', 'status_msg': 'Success. Logging you in...'}
if response["result"] == "deny":
raise ValidationError("Duo denied access")
device.save()
return device_pk

View File

@ -0,0 +1,27 @@
# Generated by Django 4.0.4 on 2022-04-14 20:54
from django.db import migrations, models
import authentik.lib.utils.time
class Migration(migrations.Migration):
dependencies = [
(
"authentik_stages_authenticator_validate",
"0010_remove_authenticatorvalidatestage_configuration_stage_and_more",
),
]
operations = [
migrations.AddField(
model_name="authenticatorvalidatestage",
name="last_auth_threshold",
field=models.TextField(
default="seconds=0",
help_text="If any of the user's device has been used within this threshold, this stage will be skipped",
validators=[authentik.lib.utils.time.timedelta_string_validator],
),
),
]

View File

@ -7,6 +7,7 @@ from django.views import View
from rest_framework.serializers import BaseSerializer
from authentik.flows.models import NotConfiguredAction, Stage
from authentik.lib.utils.time import timedelta_string_validator
class DeviceClasses(models.TextChoices):
@ -57,6 +58,17 @@ class AuthenticatorValidateStage(Stage):
default=default_device_classes,
)
last_auth_threshold = models.TextField(
default="seconds=0",
validators=[timedelta_string_validator],
help_text=_(
(
"If any of the user's device has been used within this threshold, this "
"stage will be skipped"
)
),
)
@property
def serializer(self) -> BaseSerializer:
from authentik.stages.authenticator_validate.api import AuthenticatorValidateStageSerializer

View File

@ -1,6 +1,10 @@
"""Authenticator Validation"""
from datetime import timezone
from django.http import HttpRequest, HttpResponse
from django.utils.timezone import datetime, now
from django_otp import devices_for_user
from django_otp.models import Device
from rest_framework.fields import CharField, IntegerField, JSONField, ListField, UUIDField
from rest_framework.serializers import ValidationError
from structlog.stdlib import get_logger
@ -10,9 +14,11 @@ from authentik.core.models import User
from authentik.events.models import Event, EventAction
from authentik.events.utils import cleanse_dict, sanitize_dict
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
from authentik.flows.exceptions import FlowSkipStageException
from authentik.flows.models import FlowDesignation, NotConfiguredAction, Stage
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import ChallengeStageView
from authentik.lib.utils.time import timedelta_from_string
from authentik.stages.authenticator_sms.models import SMSDevice
from authentik.stages.authenticator_validate.challenge import (
DeviceChallenge,
@ -121,6 +127,15 @@ class AuthenticatorValidationChallengeResponse(ChallengeResponse):
return attrs
def get_device_last_usage(device: Device) -> datetime:
"""Get a datetime object from last_t"""
if not hasattr(device, "last_t"):
return datetime.fromtimestamp(0, tz=timezone.utc)
if isinstance(device.last_t, datetime):
return device.last_t
return datetime.fromtimestamp(device.last_t * device.step, tz=timezone.utc)
class AuthenticatorValidateStageView(ChallengeStageView):
"""Authenticator Validation"""
@ -139,6 +154,9 @@ class AuthenticatorValidateStageView(ChallengeStageView):
stage: AuthenticatorValidateStage = self.executor.current_stage
_now = now()
threshold = timedelta_from_string(stage.last_auth_threshold)
for device in user_devices:
device_class = device.__class__.__name__.lower().replace("device", "")
if device_class not in stage.device_classes:
@ -148,6 +166,16 @@ class AuthenticatorValidateStageView(ChallengeStageView):
# WebAuthn does another device loop to find all webuahtn devices
if device_class in seen_classes:
continue
# check if device has been used within threshold and skip this stage if so
if threshold.total_seconds() > 0:
print("yeet")
print(get_device_last_usage(device))
print(_now - get_device_last_usage(device))
print(threshold)
print(_now - get_device_last_usage(device) <= threshold)
if _now - get_device_last_usage(device) <= threshold:
LOGGER.info("Device has been used within threshold", device=device)
raise FlowSkipStageException()
if device_class not in seen_classes:
seen_classes.append(device_class)
challenge = DeviceChallenge(
@ -181,7 +209,10 @@ class AuthenticatorValidateStageView(ChallengeStageView):
user = self.get_pending_user()
stage: AuthenticatorValidateStage = self.executor.current_stage
if user and not user.is_anonymous:
challenges = self.get_device_challenges()
try:
challenges = self.get_device_challenges()
except FlowSkipStageException:
return self.executor.stage_ok()
else:
if self.executor.flow.designation != FlowDesignation.AUTHENTICATION:
LOGGER.debug("Refusing passwordless flow in non-authentication flow")

View File

@ -0,0 +1,56 @@
"""Test validator stage"""
from unittest.mock import MagicMock, patch
from django.test.client import RequestFactory
from rest_framework.exceptions import ValidationError
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.tests import FlowTestCase
from authentik.lib.generators import generate_id, generate_key
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
from authentik.stages.authenticator_validate.challenge import validate_challenge_duo
class AuthenticatorValidateStageDuoTests(FlowTestCase):
"""Test validator stage"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.request_factory = RequestFactory()
def test_device_challenge_duo(self):
"""Test duo"""
request = self.request_factory.get("/")
stage = AuthenticatorDuoStage.objects.create(
name="test",
client_id=generate_id(),
client_secret=generate_key(),
api_hostname="",
)
duo_device = DuoDevice.objects.create(
user=self.user,
stage=stage,
)
duo_mock = MagicMock(
auth=MagicMock(
return_value={
"result": "allow",
"status": "allow",
"status_msg": "Success. Logging you in...",
}
)
)
failed_duo_mock = MagicMock(auth=MagicMock(return_value={"result": "deny"}))
with patch(
"authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.client",
duo_mock,
):
self.assertEqual(
duo_device.pk, validate_challenge_duo(duo_device.pk, request, self.user)
)
with patch(
"authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.client",
failed_duo_mock,
):
with self.assertRaises(ValidationError):
validate_challenge_duo(duo_device.pk, request, self.user)

View File

@ -0,0 +1,106 @@
"""Test validator stage"""
from time import sleep
from django.test.client import RequestFactory
from django.urls.base import reverse
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.models import Flow, FlowStageBinding, NotConfiguredAction
from authentik.flows.tests import FlowTestCase
from authentik.stages.authenticator_sms.models import AuthenticatorSMSStage, SMSDevice, SMSProviders
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage, DeviceClasses
from authentik.stages.identification.models import IdentificationStage, UserFields
class AuthenticatorValidateStageSMSTests(FlowTestCase):
"""Test validator stage"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.request_factory = RequestFactory()
self.stage = AuthenticatorSMSStage.objects.create(
name="sms",
provider=SMSProviders.GENERIC,
from_number="1234",
)
def test_last_auth_threshold(self):
"""Test last_auth_threshold"""
conf_stage = IdentificationStage.objects.create(
name="conf",
user_fields=[
UserFields.USERNAME,
],
)
device: SMSDevice = SMSDevice.objects.create(
user=self.user,
confirmed=True,
stage=self.stage,
)
# Verify token once here to set last_t etc
token = device.generate_token()
device.verify_token(token)
stage = AuthenticatorValidateStage.objects.create(
name="foo",
last_auth_threshold="milliseconds=0",
not_configured_action=NotConfiguredAction.CONFIGURE,
device_classes=[DeviceClasses.SMS],
)
sleep(1)
stage.configuration_stages.set([conf_stage])
flow = Flow.objects.create(name="test", slug="test", title="test")
FlowStageBinding.objects.create(target=flow, stage=conf_stage, order=0)
FlowStageBinding.objects.create(target=flow, stage=stage, order=1)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
{"uid_field": self.user.username},
)
self.assertEqual(response.status_code, 302)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
follow=True,
)
self.assertStageResponse(
response,
flow,
component="ak-stage-authenticator-validate",
)
def test_last_auth_threshold_valid(self):
"""Test last_auth_threshold"""
conf_stage = IdentificationStage.objects.create(
name="conf",
user_fields=[
UserFields.USERNAME,
],
)
device: SMSDevice = SMSDevice.objects.create(
user=self.user,
confirmed=True,
stage=self.stage,
)
# Verify token once here to set last_t etc
token = device.generate_token()
device.verify_token(token)
stage = AuthenticatorValidateStage.objects.create(
name="foo",
last_auth_threshold="hours=1",
not_configured_action=NotConfiguredAction.CONFIGURE,
device_classes=[DeviceClasses.SMS],
)
stage.configuration_stages.set([conf_stage])
flow = Flow.objects.create(name="test", slug="test", title="test")
FlowStageBinding.objects.create(target=flow, stage=conf_stage, order=0)
FlowStageBinding.objects.create(target=flow, stage=stage, order=1)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
{"uid_field": self.user.username},
)
self.assertEqual(response.status_code, 302)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
follow=True,
)
self.assertStageResponse(response, component="xak-flow-redirect", to="/")

View File

@ -1,34 +1,21 @@
"""Test validator stage"""
from unittest.mock import MagicMock, patch
from django.contrib.sessions.middleware import SessionMiddleware
from django.test.client import RequestFactory
from django.urls.base import reverse
from django_otp.plugins.otp_totp.models import TOTPDevice
from rest_framework.exceptions import ValidationError
from webauthn.helpers import bytes_to_base64url
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.models import Flow, FlowStageBinding, NotConfiguredAction
from authentik.flows.stage import StageView
from authentik.flows.tests import FlowTestCase
from authentik.flows.views.executor import FlowExecutorView
from authentik.lib.generators import generate_id, generate_key
from authentik.lib.tests.utils import dummy_get_response, get_request
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
from authentik.lib.tests.utils import dummy_get_response
from authentik.stages.authenticator_validate.api import AuthenticatorValidateStageSerializer
from authentik.stages.authenticator_validate.challenge import (
get_challenge_for_device,
validate_challenge_code,
validate_challenge_duo,
validate_challenge_webauthn,
)
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage
from authentik.stages.authenticator_validate.stage import (
SESSION_DEVICE_CHALLENGES,
AuthenticatorValidationChallengeResponse,
)
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
from authentik.stages.identification.models import IdentificationStage, UserFields
@ -65,7 +52,6 @@ class AuthenticatorValidateStageTests(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
flow,
@ -90,83 +76,6 @@ class AuthenticatorValidateStageTests(FlowTestCase):
)
self.assertTrue(serializer.is_valid())
def test_device_challenge_totp(self):
"""Test device challenge"""
request = self.request_factory.get("/")
totp_device = TOTPDevice.objects.create(user=self.user, confirmed=True, digits=6)
self.assertEqual(get_challenge_for_device(request, totp_device), {})
with self.assertRaises(ValidationError):
validate_challenge_code("1234", request, self.user)
def test_device_challenge_webauthn(self):
"""Test webauthn"""
request = get_request("/")
request.user = self.user
webauthn_device = WebAuthnDevice.objects.create(
user=self.user,
public_key=bytes_to_base64url(b"qwerqwerqre"),
credential_id=bytes_to_base64url(b"foobarbaz"),
sign_count=0,
rp_id="foo",
)
challenge = get_challenge_for_device(request, webauthn_device)
del challenge["challenge"]
self.assertEqual(
challenge,
{
"allowCredentials": [
{
"id": "Zm9vYmFyYmF6",
"type": "public-key",
}
],
"rpId": "testserver",
"timeout": 60000,
"userVerification": "preferred",
},
)
with self.assertRaises(ValidationError):
validate_challenge_webauthn({}, request, self.user)
def test_device_challenge_duo(self):
"""Test duo"""
request = self.request_factory.get("/")
stage = AuthenticatorDuoStage.objects.create(
name="test",
client_id=generate_id(),
client_secret=generate_key(),
api_hostname="",
)
duo_device = DuoDevice.objects.create(
user=self.user,
stage=stage,
)
duo_mock = MagicMock(
auth=MagicMock(
return_value={
"result": "allow",
"status": "allow",
"status_msg": "Success. Logging you in...",
}
)
)
failed_duo_mock = MagicMock(auth=MagicMock(return_value={"result": "deny"}))
with patch(
"authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.client",
duo_mock,
):
self.assertEqual(
duo_device.pk, validate_challenge_duo(duo_device.pk, request, self.user)
)
with patch(
"authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.client",
failed_duo_mock,
):
with self.assertRaises(ValidationError):
validate_challenge_duo(duo_device.pk, request, self.user)
def test_validate_selected_challenge(self):
"""Test validate_selected_challenge"""
# Prepare request with session

View File

@ -0,0 +1,114 @@
"""Test validator stage"""
from time import sleep
from django.test.client import RequestFactory
from django.urls.base import reverse
from django_otp.oath import TOTP
from django_otp.plugins.otp_totp.models import TOTPDevice
from rest_framework.exceptions import ValidationError
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.models import Flow, FlowStageBinding, NotConfiguredAction
from authentik.flows.tests import FlowTestCase
from authentik.stages.authenticator_validate.challenge import (
get_challenge_for_device,
validate_challenge_code,
)
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage, DeviceClasses
from authentik.stages.identification.models import IdentificationStage, UserFields
class AuthenticatorValidateStageTOTPTests(FlowTestCase):
"""Test validator stage"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.request_factory = RequestFactory()
def test_last_auth_threshold(self):
"""Test last_auth_threshold"""
conf_stage = IdentificationStage.objects.create(
name="conf",
user_fields=[
UserFields.USERNAME,
],
)
device: TOTPDevice = TOTPDevice.objects.create(
user=self.user,
confirmed=True,
)
# Verify token once here to set last_t etc
totp = TOTP(device.bin_key)
sleep(1)
self.assertTrue(device.verify_token(totp.token()))
stage = AuthenticatorValidateStage.objects.create(
name="foo",
last_auth_threshold="milliseconds=0",
not_configured_action=NotConfiguredAction.CONFIGURE,
device_classes=[DeviceClasses.TOTP],
)
stage.configuration_stages.set([conf_stage])
flow = Flow.objects.create(name="test", slug="test", title="test")
FlowStageBinding.objects.create(target=flow, stage=conf_stage, order=0)
FlowStageBinding.objects.create(target=flow, stage=stage, order=1)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
{"uid_field": self.user.username},
)
self.assertEqual(response.status_code, 302)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
follow=True,
)
self.assertStageResponse(
response,
flow,
component="ak-stage-authenticator-validate",
)
def test_last_auth_threshold_valid(self):
"""Test last_auth_threshold"""
conf_stage = IdentificationStage.objects.create(
name="conf",
user_fields=[
UserFields.USERNAME,
],
)
device: TOTPDevice = TOTPDevice.objects.create(
user=self.user,
confirmed=True,
)
# Verify token once here to set last_t etc
totp = TOTP(device.bin_key)
sleep(1)
self.assertTrue(device.verify_token(totp.token()))
stage = AuthenticatorValidateStage.objects.create(
name="foo",
last_auth_threshold="hours=1",
not_configured_action=NotConfiguredAction.CONFIGURE,
device_classes=[DeviceClasses.TOTP],
)
stage.configuration_stages.set([conf_stage])
flow = Flow.objects.create(name="test", slug="test", title="test")
FlowStageBinding.objects.create(target=flow, stage=conf_stage, order=0)
FlowStageBinding.objects.create(target=flow, stage=stage, order=1)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
{"uid_field": self.user.username},
)
self.assertEqual(response.status_code, 302)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
follow=True,
)
self.assertStageResponse(response, component="xak-flow-redirect", to="/")
def test_device_challenge_totp(self):
"""Test device challenge"""
request = self.request_factory.get("/")
totp_device = TOTPDevice.objects.create(user=self.user, confirmed=True, digits=6)
self.assertEqual(get_challenge_for_device(request, totp_device), {})
with self.assertRaises(ValidationError):
validate_challenge_code("1234", request, self.user)

View File

@ -0,0 +1,134 @@
"""Test validator stage"""
from time import sleep
from django.test.client import RequestFactory
from django.urls.base import reverse
from rest_framework.exceptions import ValidationError
from webauthn.helpers import bytes_to_base64url
from authentik.core.tests.utils import create_test_admin_user
from authentik.flows.models import Flow, FlowStageBinding, NotConfiguredAction
from authentik.flows.tests import FlowTestCase
from authentik.lib.tests.utils import get_request
from authentik.stages.authenticator_validate.challenge import (
get_challenge_for_device,
validate_challenge_webauthn,
)
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage, DeviceClasses
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
from authentik.stages.identification.models import IdentificationStage, UserFields
class AuthenticatorValidateStageWebAuthnTests(FlowTestCase):
"""Test validator stage"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.request_factory = RequestFactory()
def test_last_auth_threshold(self):
"""Test last_auth_threshold"""
conf_stage = IdentificationStage.objects.create(
name="conf",
user_fields=[
UserFields.USERNAME,
],
)
device: WebAuthnDevice = WebAuthnDevice.objects.create(
user=self.user,
confirmed=True,
)
device.set_sign_count(device.sign_count + 1)
stage = AuthenticatorValidateStage.objects.create(
name="foo",
last_auth_threshold="milliseconds=0",
not_configured_action=NotConfiguredAction.CONFIGURE,
device_classes=[DeviceClasses.WEBAUTHN],
)
sleep(1)
stage.configuration_stages.set([conf_stage])
flow = Flow.objects.create(name="test", slug="test", title="test")
FlowStageBinding.objects.create(target=flow, stage=conf_stage, order=0)
FlowStageBinding.objects.create(target=flow, stage=stage, order=1)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
{"uid_field": self.user.username},
)
self.assertEqual(response.status_code, 302)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
follow=True,
)
self.assertStageResponse(
response,
flow,
component="ak-stage-authenticator-validate",
)
def test_last_auth_threshold_valid(self):
"""Test last_auth_threshold"""
conf_stage = IdentificationStage.objects.create(
name="conf",
user_fields=[
UserFields.USERNAME,
],
)
device: WebAuthnDevice = WebAuthnDevice.objects.create(
user=self.user,
confirmed=True,
)
device.set_sign_count(device.sign_count + 1)
stage = AuthenticatorValidateStage.objects.create(
name="foo",
last_auth_threshold="hours=1",
not_configured_action=NotConfiguredAction.CONFIGURE,
device_classes=[DeviceClasses.WEBAUTHN],
)
stage.configuration_stages.set([conf_stage])
flow = Flow.objects.create(name="test", slug="test", title="test")
FlowStageBinding.objects.create(target=flow, stage=conf_stage, order=0)
FlowStageBinding.objects.create(target=flow, stage=stage, order=1)
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
{"uid_field": self.user.username},
)
self.assertEqual(response.status_code, 302)
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
follow=True,
)
self.assertStageResponse(response, component="xak-flow-redirect", to="/")
def test_device_challenge_webauthn(self):
"""Test webauthn"""
request = get_request("/")
request.user = self.user
webauthn_device = WebAuthnDevice.objects.create(
user=self.user,
public_key=bytes_to_base64url(b"qwerqwerqre"),
credential_id=bytes_to_base64url(b"foobarbaz"),
sign_count=0,
rp_id="foo",
)
challenge = get_challenge_for_device(request, webauthn_device)
del challenge["challenge"]
self.assertEqual(
challenge,
{
"allowCredentials": [
{
"id": "Zm9vYmFyYmF6",
"type": "public-key",
}
],
"rpId": "testserver",
"timeout": 60000,
"userVerification": "preferred",
},
)
with self.assertRaises(ValidationError):
validate_challenge_webauthn({}, request, self.user)

View File

@ -0,0 +1,21 @@
# Generated by Django 4.0.4 on 2022-04-14 20:58
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
(
"authentik_stages_authenticator_webauthn",
"0006_authenticatewebauthnstage_authenticator_attachment_and_more",
),
]
operations = [
migrations.RenameField(
model_name="webauthndevice",
old_name="last_used_on",
new_name="last_t",
),
]

View File

@ -125,7 +125,7 @@ class WebAuthnDevice(Device):
rp_id = models.CharField(max_length=253)
created_on = models.DateTimeField(auto_now_add=True)
last_used_on = models.DateTimeField(default=now)
last_t = models.DateTimeField(default=now)
@property
def descriptor(self) -> PublicKeyCredentialDescriptor:
@ -133,9 +133,9 @@ class WebAuthnDevice(Device):
return PublicKeyCredentialDescriptor(id=base64url_to_bytes(self.credential_id))
def set_sign_count(self, sign_count: int) -> None:
"""Set the sign_count and update the last_used_on datetime."""
"""Set the sign_count and update the last_t datetime."""
self.sign_count = sign_count
self.last_used_on = now()
self.last_t = now()
self.save()
def __str__(self):

View File

@ -36,7 +36,6 @@ class TestUserDenyStage(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(response, self.flow, component="ak-stage-access-denied")
def test_valid_post(self):
@ -50,5 +49,4 @@ class TestUserDenyStage(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(response, self.flow, component="ak-stage-access-denied")

View File

@ -79,7 +79,6 @@ class TestIdentificationStage(FlowTestCase):
}
url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
response = self.client.post(url, form_data)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,
@ -122,7 +121,6 @@ class TestIdentificationStage(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
form_data,
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,
@ -175,7 +173,6 @@ class TestIdentificationStage(FlowTestCase):
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,
@ -218,7 +215,6 @@ class TestIdentificationStage(FlowTestCase):
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,

View File

@ -55,7 +55,6 @@ class TestUserLoginStage(FlowTestCase):
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
flow=self.flow,

View File

@ -53,7 +53,6 @@ class TestPasswordStage(FlowTestCase):
{"password": self.password},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,
@ -159,7 +158,6 @@ class TestPasswordStage(FlowTestCase):
{"password": self.password + "test"},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,

View File

@ -43,7 +43,6 @@ class TestUserDeleteStage(FlowTestCase):
response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(response, self.flow, component="ak-stage-access-denied")
def test_user_delete_get(self):

View File

@ -94,7 +94,6 @@ class TestUserLoginStage(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,

View File

@ -112,7 +112,6 @@ class TestUserWriteStage(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,
@ -139,7 +138,6 @@ class TestUserWriteStage(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,
@ -167,7 +165,6 @@ class TestUserWriteStage(FlowTestCase):
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,

View File

@ -19894,6 +19894,10 @@ components:
description: Stages used to configure Authenticator when user doesn't have
any compatible devices. After this configuration Stage passes, the user
is not prompted again.
last_auth_threshold:
type: string
description: If any of the user's device has been used within this threshold,
this stage will be skipped
required:
- component
- meta_model_name
@ -19927,6 +19931,11 @@ components:
description: Stages used to configure Authenticator when user doesn't have
any compatible devices. After this configuration Stage passes, the user
is not prompted again.
last_auth_threshold:
type: string
minLength: 1
description: If any of the user's device has been used within this threshold,
this stage will be skipped
required:
- name
AuthenticatorValidationChallenge:
@ -26797,6 +26806,11 @@ components:
description: Stages used to configure Authenticator when user doesn't have
any compatible devices. After this configuration Stage passes, the user
is not prompted again.
last_auth_threshold:
type: string
minLength: 1
description: If any of the user's device has been used within this threshold,
this stage will be skipped
PatchedCaptchaStageRequest:
type: object
description: CaptchaStage Serializer

View File

@ -0,0 +1,54 @@
import { CSSResult, LitElement, TemplateResult, css, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import AKGlobal from "../authentik.css";
import PFTooltip from "@patternfly/patternfly/components/Tooltip/Tooltip.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
@customElement("ak-tooltip")
export class Tooltip extends LitElement {
@state()
open = false;
static get styles(): CSSResult[] {
return [
PFBase,
PFTooltip,
AKGlobal,
css`
.pf-c-tooltip__content {
text-align: inherit;
}
.outer {
position: relative;
}
.pf-c-tooltip {
position: absolute;
}
`,
];
}
render(): TemplateResult {
return html`<slot
@mouseenter=${() => {
this.open = true;
}}
@mouseleave=${() => {
this.open = false;
}}
name="trigger"
></slot>
${this.open
? html`<div class="outer">
<div class="pf-c-tooltip" role="tooltip">
<div class="pf-c-tooltip__arrow"></div>
<div class="pf-c-tooltip__content">
<slot name="tooltip"></slot>
</div>
</div>
</div>`
: html``}`;
}
}

View File

@ -0,0 +1,45 @@
import { t } from "@lingui/macro";
import { CSSResult, LitElement, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import AKGlobal from "../../authentik.css";
import PFForm from "@patternfly/patternfly/components/Form/Form.css";
import PFList from "@patternfly/patternfly/components/List/list.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import "../Tooltip";
@customElement("ak-utils-time-delta-help")
export class TimeDeltaHelp extends LitElement {
@property({ type: Boolean })
negative = false;
static get styles(): CSSResult[] {
return [PFBase, PFForm, PFList, AKGlobal];
}
render(): TemplateResult {
return html` <ak-tooltip>
<p class="pf-c-form__helper-text" slot="trigger">
${this.negative
? t`(Format: hours=-1;minutes=-2;seconds=-3).`
: t`(Format: hours=1;minutes=2;seconds=3).`}
<i class="pf-icon fa fa-question-circle" aria-hidden="true"></i>
</p>
<div slot="tooltip">
${t`The following keywords are supported:`}
<ul class="pf-c-list">
<li><pre>microseconds</pre></li>
<li><pre>milliseconds</pre></li>
<li><pre>seconds</pre></li>
<li><pre>minutes</pre></li>
<li><pre>hours</pre></li>
<li><pre>days</pre></li>
<li><pre>weeks</pre></li>
</ul>
</div>
</ak-tooltip>`;
}
}

View File

@ -33,14 +33,15 @@ msgstr ""
#~ msgid "#/identity/users/{0}"
#~ msgstr "#/Identität/Benutzer/{0}"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(Format: hours=-1;minutes=-2;seconds=-3)."
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr "(Format: hours=-1;minutes=-2;seconds=-3)."
@ -458,8 +459,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "Sind Sie sicher, dass Sie {0} \"{1}\" aktualisieren wollen?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "SAML Assertion nicht gültig am oder nach der aktuellen Uhrzeit + diesem Wert (Format: Stunden=1;Minuten=2;Sekunden=3)."
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "SAML Assertion nicht gültig am oder nach der aktuellen Uhrzeit + diesem Wert (Format: Stunden=1;Minuten=2;Sekunden=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -2496,6 +2501,10 @@ msgstr "Kennung"
#~ msgid "Identity & Cryptography"
#~ msgstr "Identität & Kryptographie"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2769,6 +2778,10 @@ msgstr "Überprüft: {0}"
msgid "Last sync: {0}"
msgstr "Letzte Synchronisierung: {0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -3490,8 +3503,12 @@ msgid "Objects created"
msgstr "Objekte erstellt"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Die Einwilligung erlischt in. (Format: Stunden=1;Minuten=2;Sekunden=3)."
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Die Einwilligung erlischt in. (Format: Stunden=1;Minuten=2;Sekunden=3)."
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -4522,8 +4539,12 @@ msgid "Session duration"
msgstr "Sessionsdauer"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Session am oder nach der aktuellen Uhrzeit + diesem Wert nicht gültig (Format: Stunden=1;Minuten=2;Sekunden=3)."
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Session am oder nach der aktuellen Uhrzeit + diesem Wert nicht gültig (Format: Stunden=1;Minuten=2;Sekunden=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -5331,6 +5352,10 @@ msgstr "Die externe URL, unter der Sie auf die Anwendung zugreifen. Schließen S
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "Die externe URL, bei der Sie sich authentifizieren. Unter dieser URL sollte der Authentik Core Server erreichbar sein."
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "Die folgenden Objekte verwenden {0}:"
@ -5440,8 +5465,12 @@ msgid "Time in minutes the token sent is valid."
msgstr "Zeit in Minuten wie lange der verschickte Token gültig ist"
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Zeitversatz, wann temporäre Benutzer gelöscht werden sollen. Dies gilt nur, wenn Ihr IDP das NameID-Format „transient“ verwendet und der Benutzer sich nicht manuell abmeldet. (Format: Stunden=1;Minuten=2;Sekunden=3)."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Zeitversatz, wann temporäre Benutzer gelöscht werden sollen. Dies gilt nur, wenn Ihr IDP das NameID-Format „transient“ verwendet und der Benutzer sich nicht manuell abmeldet. (Format: Stunden=1;Minuten=2;Sekunden=3)."
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "Zeitbasierte Einmalpasswörter"

View File

@ -13,18 +13,19 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#:
#:
#~ msgid "#/identity/users/{0}"
#~ msgstr "#/identity/users/{0}"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr "(Format: days=-1;minutes=-2;seconds=-3)."
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(Format: hours=-1;minutes=-2;seconds=-3)."
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr "(Format: hours=1;minutes=2;seconds=3)."
@ -144,7 +145,7 @@ msgstr "About applications"
msgid "Access Key"
msgstr "Access Key"
#:
#:
#~ msgid "Access code validity"
#~ msgstr "Access code validity"
@ -448,8 +449,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "Are you sure you want to update {0} \"{1}\"?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr "Assertion not valid on or after current time + this value."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -499,7 +504,7 @@ msgstr "Attributes"
msgid "Audience"
msgstr "Audience"
#:
#:
#~ msgid "Auth Type"
#~ msgstr "Auth Type"
@ -542,7 +547,7 @@ msgstr "Authenticator Attachment"
msgid "Authorization"
msgstr "Authorization"
#:
#:
#~ msgid "Authorization Code"
#~ msgstr "Authorization Code"
@ -702,7 +707,7 @@ msgstr "Browser"
msgid "Build hash:"
msgstr "Build hash:"
#:
#:
#~ msgid "Build hash: {0}"
#~ msgstr "Build hash: {0}"
@ -784,7 +789,7 @@ msgstr "Certificate Subject"
msgid "Certificate used to sign outgoing Responses going to the Service Provider."
msgstr "Certificate used to sign outgoing Responses going to the Service Provider."
#:
#:
#~ msgid "Certificate-Key Pair"
#~ msgstr "Certificate-Key Pair"
@ -877,7 +882,7 @@ msgstr "Check the IP of the Kubernetes service, or"
msgid "Check the logs"
msgstr "Check the logs"
#:
#:
#~ msgid "Check your Emails for a password reset link."
#~ msgstr "Check your Emails for a password reset link."
@ -1026,11 +1031,11 @@ msgstr "Configuration flow"
msgid "Configuration stages"
msgstr "Configuration stages"
#:
#:
#~ msgid "Configure WebAuthn"
#~ msgstr "Configure WebAuthn"
#:
#:
#~ msgid "Configure how long access codes are valid for."
#~ msgstr "Configure how long access codes are valid for."
@ -1066,8 +1071,8 @@ msgstr "Configure how the outpost authenticates requests."
msgid "Configure how the outpost queries the core authentik server's users."
msgstr "Configure how the outpost queries the core authentik server's users."
#:
#:
#:
#:
#~ msgid "Configure settings relevant to your user profile."
#~ msgstr "Configure settings relevant to your user profile."
@ -1189,7 +1194,7 @@ msgstr "Cookie domain"
msgid "Copy"
msgstr "Copy"
#:
#:
#~ msgid "Copy Key"
#~ msgstr "Copy Key"
@ -1391,7 +1396,7 @@ msgstr "Create {0}"
msgid "Created by"
msgstr "Created by"
#:
#:
#~ msgid "Created {0}"
#~ msgstr "Created {0}"
@ -1401,7 +1406,7 @@ msgstr "Created by"
msgid "Creation Date"
msgstr "Creation Date"
#:
#:
#~ msgid "Current plan cntext"
#~ msgstr "Current plan cntext"
@ -1498,24 +1503,24 @@ msgstr "Define how notifications are sent to users, like Email or Webhook."
msgid "Delete"
msgstr "Delete"
#:
#:
#~ msgid "Delete Authorization Code"
#~ msgstr "Delete Authorization Code"
#:
#:
#:
#:
#~ msgid "Delete Binding"
#~ msgstr "Delete Binding"
#:
#:
#~ msgid "Delete Consent"
#~ msgstr "Delete Consent"
#:
#:
#~ msgid "Delete Refresh Code"
#~ msgstr "Delete Refresh Code"
#:
#:
#~ msgid "Delete Session"
#~ msgstr "Delete Session"
@ -1596,7 +1601,7 @@ msgstr "Device classes"
msgid "Device classes which can be used to authenticate."
msgstr "Device classes which can be used to authenticate."
#:
#:
#~ msgid "Device name"
#~ msgstr "Device name"
@ -1629,24 +1634,24 @@ msgstr "Direct querying, always returns the latest data, but slower than cached
msgid "Directory"
msgstr "Directory"
#:
#:
#:
#:
#~ msgid "Disable"
#~ msgstr "Disable"
#:
#:
#~ msgid "Disable Duo authenticator"
#~ msgstr "Disable Duo authenticator"
#:
#:
#~ msgid "Disable SMS authenticator"
#~ msgstr "Disable SMS authenticator"
#:
#:
#~ msgid "Disable Static Tokens"
#~ msgstr "Disable Static Tokens"
#:
#:
#~ msgid "Disable Time-based OTP"
#~ msgstr "Disable Time-based OTP"
@ -1700,7 +1705,7 @@ msgstr "Due to protocol limitations, this certificate is only used when the outp
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
msgstr "Dummy stage used for testing. Shows a simple continue button and always passes."
#:
#:
#~ msgid "Duo"
#~ msgstr "Duo"
@ -1811,16 +1816,16 @@ msgstr "Email: Text field with Email type."
msgid "Embedded outpost is not configured correctly."
msgstr "Embedded outpost is not configured correctly."
#:
#:
#:
#:
#~ msgid "Enable"
#~ msgstr "Enable"
#:
#:
#~ msgid "Enable Duo authenticator"
#~ msgstr "Enable Duo authenticator"
#:
#:
#~ msgid "Enable SMS authenticator"
#~ msgstr "Enable SMS authenticator"
@ -1828,11 +1833,11 @@ msgstr "Embedded outpost is not configured correctly."
msgid "Enable StartTLS"
msgstr "Enable StartTLS"
#:
#:
#~ msgid "Enable Static Tokens"
#~ msgstr "Enable Static Tokens"
#:
#:
#~ msgid "Enable TOTP"
#~ msgstr "Enable TOTP"
@ -1896,7 +1901,7 @@ msgstr "Error when validating assertion on server: {err}"
msgid "Error: unsupported source settings: {0}"
msgstr "Error: unsupported source settings: {0}"
#:
#:
#~ msgid "Error: unsupported stage settings: {0}"
#~ msgstr "Error: unsupported stage settings: {0}"
@ -1951,7 +1956,7 @@ msgstr "Everything is ok."
msgid "Exception"
msgstr "Exception"
#:
#:
#~ msgid "Execute"
#~ msgstr "Execute"
@ -1963,7 +1968,7 @@ msgstr "Exception"
msgid "Execute flow"
msgstr "Execute flow"
#:
#:
#~ msgid "Execute with inspector"
#~ msgstr "Execute with inspector"
@ -2138,7 +2143,7 @@ msgstr "Field of the user object this value is written to."
msgid "Field which contains a unique Identifier."
msgstr "Field which contains a unique Identifier."
#:
#:
#~ msgid "Field which contains members of a group."
#~ msgstr "Field which contains members of a group."
@ -2345,7 +2350,7 @@ msgstr "German"
msgid "Get this value from https://console.twilio.com"
msgstr "Get this value from https://console.twilio.com"
#:
#:
#~ msgid "Go to admin interface"
#~ msgstr "Go to admin interface"
@ -2357,7 +2362,7 @@ msgstr "Go to next page"
msgid "Go to previous page"
msgstr "Go to previous page"
#:
#:
#~ msgid "Go to user interface"
#~ msgstr "Go to user interface"
@ -2538,6 +2543,10 @@ msgstr "Identifier"
#~ msgid "Identity & Cryptography"
#~ msgstr "Identity & Cryptography"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2702,7 +2711,7 @@ msgstr "Invalidation"
msgid "Invalidation flow"
msgstr "Invalidation flow"
#:
#:
#~ msgid "Invitation"
#~ msgstr "Invitation"
@ -2820,6 +2829,10 @@ msgstr "Last seen: {0}"
msgid "Last sync: {0}"
msgstr "Last sync: {0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr "Last validation threshold"
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -2833,7 +2846,7 @@ msgstr "Launch URL"
msgid "Let the user identify themselves with their username or Email address."
msgstr "Let the user identify themselves with their username or Email address."
#:
#:
#~ msgid "Library"
#~ msgstr "Library"
@ -3143,7 +3156,7 @@ msgstr "Model deleted"
msgid "Model updated"
msgstr "Model updated"
#:
#:
#~ msgid "Monitor"
#~ msgstr "Monitor"
@ -3478,7 +3491,7 @@ msgstr "Notification Rules"
msgid "Notification Transports"
msgstr "Notification Transports"
#:
#:
#~ msgid "Notification rule"
#~ msgstr "Notification rule"
@ -3498,7 +3511,7 @@ msgstr "Notification transport(s)"
msgid "Notifications"
msgstr "Notifications"
#:
#:
#~ msgid "Notifications Transport"
#~ msgstr "Notifications Transport"
@ -3548,8 +3561,12 @@ msgid "Objects created"
msgstr "Objects created"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgid "Offset after which consent expires."
msgstr "Offset after which consent expires."
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -3569,7 +3586,7 @@ msgstr "Only send notification once, for example when sending a webhook into a c
msgid "Open API Browser"
msgstr "Open API Browser"
#:
#:
#~ msgid "Open application"
#~ msgstr "Open application"
@ -3651,7 +3668,7 @@ msgstr "Other global settings"
msgid "Outdated outposts"
msgstr "Outdated outposts"
#:
#:
#~ msgid "Outpost"
#~ msgstr "Outpost"
@ -3663,11 +3680,11 @@ msgstr "Outpost Deployment Info"
msgid "Outpost Integrations"
msgstr "Outpost Integrations"
#:
#:
#~ msgid "Outpost Service-connection"
#~ msgstr "Outpost Service-connection"
#:
#:
#~ msgid "Outpost integration"
#~ msgstr "Outpost integration"
@ -3765,7 +3782,7 @@ msgstr "Password set"
msgid "Password stage"
msgstr "Password stage"
#:
#:
#~ msgid "Password, 2FA, etc"
#~ msgstr "Password, 2FA, etc"
@ -3841,7 +3858,7 @@ msgstr "Policy / User / Group"
msgid "Policy Bindings"
msgstr "Policy Bindings"
#:
#:
#~ msgid "Policy binding"
#~ msgstr "Policy binding"
@ -3931,7 +3948,7 @@ msgstr "Private key, acquired from https://www.google.com/recaptcha/intro/v3.htm
msgid "Profile URL"
msgstr "Profile URL"
#:
#:
#~ msgid "Prompt"
#~ msgstr "Prompt"
@ -3948,7 +3965,7 @@ msgstr "Prompt(s)"
msgid "Prompts"
msgstr "Prompts"
#:
#:
#~ msgid "Property Mapping"
#~ msgstr "Property Mapping"
@ -4007,7 +4024,7 @@ msgstr "Provider"
msgid "Provider Type"
msgstr "Provider Type"
#:
#:
#~ msgid "Provider type"
#~ msgstr "Provider type"
@ -4150,7 +4167,7 @@ msgstr "Redirect binding"
msgid "Refresh"
msgstr "Refresh"
#:
#:
#~ msgid "Refresh Code"
#~ msgstr "Refresh Code"
@ -4268,7 +4285,7 @@ msgstr "Result"
msgid "Retry"
msgstr "Retry"
#:
#:
#~ msgid "Retry Task"
#~ msgstr "Retry Task"
@ -4436,7 +4453,7 @@ msgstr "Secret key"
msgid "Secret was rotated"
msgstr "Secret was rotated"
#:
#:
#~ msgid "Secret was rotation"
#~ msgstr "Secret was rotation"
@ -4476,7 +4493,7 @@ msgstr "Select an authentication method."
msgid "Select an enrollment flow"
msgstr "Select an enrollment flow"
#:
#:
#~ msgid "Select an identification method."
#~ msgstr "Select an identification method."
@ -4525,7 +4542,7 @@ msgstr "Select which transports should be used to notify the user. If none are s
msgid "Selected policies are executed when the stage is submitted to validate the data."
msgstr "Selected policies are executed when the stage is submitted to validate the data."
#:
#:
#~ msgid "Selecting a service-connection enables the management of the outpost by authentik."
#~ msgstr "Selecting a service-connection enables the management of the outpost by authentik."
@ -4576,7 +4593,7 @@ msgstr "Server URI"
msgid "Server and client are further than 5 seconds apart."
msgstr "Server and client are further than 5 seconds apart."
#:
#:
#~ msgid "Server name for which this provider's certificate is valid for."
#~ msgstr "Server name for which this provider's certificate is valid for."
@ -4584,7 +4601,7 @@ msgstr "Server and client are further than 5 seconds apart."
msgid "Server validation of credential failed: {err}"
msgstr "Server validation of credential failed: {err}"
#:
#:
#~ msgid "Service Connections"
#~ msgstr "Service Connections"
@ -4592,12 +4609,12 @@ msgstr "Server validation of credential failed: {err}"
msgid "Service Provider Binding"
msgstr "Service Provider Binding"
#:
#:
#:
#:
#~ msgid "Service connection"
#~ msgstr "Service connection"
#:
#:
#~ msgid "Session"
#~ msgstr "Session"
@ -4610,8 +4627,12 @@ msgid "Session duration"
msgstr "Session duration"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr "Session not valid on or after current time + this value."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -4735,7 +4756,7 @@ msgstr "Slug"
msgid "Something went wrong! Please try again later."
msgstr "Something went wrong! Please try again later."
#:
#:
#~ msgid "Source"
#~ msgstr "Source"
@ -4743,7 +4764,7 @@ msgstr "Something went wrong! Please try again later."
msgid "Source linked"
msgstr "Source linked"
#:
#:
#~ msgid "Source name"
#~ msgstr "Source name"
@ -4760,7 +4781,7 @@ msgstr "Source(s)"
msgid "Sources"
msgstr "Sources"
#:
#:
#~ msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
#~ msgstr "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
@ -4789,7 +4810,7 @@ msgstr "Stage Bindings"
msgid "Stage Configuration"
msgstr "Stage Configuration"
#:
#:
#~ msgid "Stage binding"
#~ msgstr "Stage binding"
@ -4910,17 +4931,17 @@ msgstr "Statically deny the flow. To use this stage effectively, disable *Evalua
msgid "Status"
msgstr "Status"
#:
#:
#:
#:
#:
#:
#:
#:
#~ msgid "Status: Disabled"
#~ msgstr "Status: Disabled"
#:
#:
#:
#:
#:
#:
#:
#:
#~ msgid "Status: Enabled"
#~ msgstr "Status: Enabled"
@ -5032,8 +5053,8 @@ msgstr "Successfully created provider."
msgid "Successfully created rule."
msgstr "Successfully created rule."
#:
#:
#:
#:
#~ msgid "Successfully created service-connection."
#~ msgstr "Successfully created service-connection."
@ -5199,8 +5220,8 @@ msgstr "Successfully updated provider."
msgid "Successfully updated rule."
msgstr "Successfully updated rule."
#:
#:
#:
#:
#~ msgid "Successfully updated service-connection."
#~ msgstr "Successfully updated service-connection."
@ -5283,7 +5304,7 @@ msgstr "Suspicious request"
msgid "Symbol charset"
msgstr "Symbol charset"
#:
#:
#~ msgid "Sync"
#~ msgstr "Sync"
@ -5291,7 +5312,7 @@ msgstr "Symbol charset"
msgid "Sync groups"
msgstr "Sync groups"
#:
#:
#~ msgid "Sync parent group"
#~ msgstr "Sync parent group"
@ -5336,7 +5357,7 @@ msgstr "System task execution"
msgid "TLS Authentication Certificate/SSH Keypair"
msgstr "TLS Authentication Certificate/SSH Keypair"
#:
#:
#~ msgid "TLS Server name"
#~ msgstr "TLS Server name"
@ -5445,7 +5466,11 @@ msgstr "The external URL you'll access the application at. Include any non-stand
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
#:
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr "The following keywords are supported:"
#:
#~ msgid "The following objects use {0}:"
#~ msgstr "The following objects use {0}:"
@ -5556,10 +5581,14 @@ msgid "Time in minutes the token sent is valid."
msgstr "Time in minutes the token sent is valid."
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
#:
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#:
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "Time-based One-Time Passwords"
@ -5599,8 +5628,8 @@ msgstr "To let a user directly reset a their password, configure a recovery flow
msgid "To use SSL instead, use 'ldaps://' and disable this option."
msgstr "To use SSL instead, use 'ldaps://' and disable this option."
#:
#:
#:
#:
#~ msgid "Token"
#~ msgstr "Token"
@ -5800,7 +5829,7 @@ msgstr "Unique identifier the token is referenced by."
msgid "Unknown"
msgstr "Unknown"
#:
#:
#~ msgid "Unmanaged"
#~ msgstr "Unmanaged"
@ -6077,8 +6106,8 @@ msgstr "User Property Mappings"
#~ msgid "User Reputation"
#~ msgstr "User Reputation"
#:
#:
#:
#:
#~ msgid "User Settings"
#~ msgstr "User Settings"
@ -6362,7 +6391,7 @@ msgstr "Web Certificate"
msgid "WebAuthn Authenticators"
msgstr "WebAuthn Authenticators"
#:
#:
#~ msgid "WebAuthn Devices"
#~ msgstr "WebAuthn Devices"
@ -6519,11 +6548,11 @@ msgstr "You're currently impersonating {0}. Click to stop."
msgid "app1 running on app1.example.com"
msgstr "app1 running on app1.example.com"
#:
#:
#~ msgid "authentik Builtin Database"
#~ msgstr "authentik Builtin Database"
#:
#:
#~ msgid "authentik LDAP Backend"
#~ msgstr "authentik LDAP Backend"

View File

@ -20,14 +20,15 @@ msgstr ""
#~ msgid "#/identity/users/{0}"
#~ msgstr "#/identidad/usuarios/ {0}"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(Formato: horas = -1; minutos = -2; segundos = -3)."
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr "(Formato: horas = 1; minutos = 2; segundos = 3)."
@ -445,8 +446,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "¿Seguro que quieres actualizar {0} «{1}»?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "La afirmación no es válida en o después de la hora actual + este valor (Formato: horas = 1; minutos = 2; segundos = 3)."
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "La afirmación no es válida en o después de la hora actual + este valor (Formato: horas = 1; minutos = 2; segundos = 3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -2487,6 +2492,10 @@ msgstr "Identificador"
#~ msgid "Identity & Cryptography"
#~ msgstr "Identidad y criptografía"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2762,6 +2771,10 @@ msgstr "Visto por última vez: {0}"
msgid "Last sync: {0}"
msgstr "Última sincronización: {0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -3483,8 +3496,12 @@ msgid "Objects created"
msgstr "Objetos creados"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Compensación después de la cual caduca el consentimiento. (Formato: horas = 1; minutos = 2; segundos = 3)."
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Compensación después de la cual caduca el consentimiento. (Formato: horas = 1; minutos = 2; segundos = 3)."
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -4515,8 +4532,12 @@ msgid "Session duration"
msgstr "Duración de la sesión"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "La sesión no es válida a partir de la hora actual + este valor (Formato: horas=1; minutos=2; segundos=3)."
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "La sesión no es válida a partir de la hora actual + este valor (Formato: horas=1; minutos=2; segundos=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -5325,6 +5346,10 @@ msgstr "La URL externa en la que accederás a la aplicación. Incluya cualquier
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "La URL externa en la que te autenticarás. Se debe poder acceder al servidor principal de authentik en esta URL."
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "Los siguientes objetos usan {0}:"
@ -5434,8 +5459,12 @@ msgid "Time in minutes the token sent is valid."
msgstr "El tiempo en minutos que se envía el token es válido."
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Desplazamiento temporal en el que se deben eliminar los usuarios temporales. Esto solo se aplica si su IDP utiliza el formato NameID «transitorio» y el usuario no cierra sesión manualmente. (Formato: horas = 1; minutos = 2; segundos = 3)."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Desplazamiento temporal en el que se deben eliminar los usuarios temporales. Esto solo se aplica si su IDP utiliza el formato NameID «transitorio» y el usuario no cierra sesión manualmente. (Formato: horas = 1; minutos = 2; segundos = 3)."
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "Contraseñas únicas basadas en tiempo"

View File

@ -19,18 +19,19 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: @lingui/cli\n"
#:
#:
#~ msgid "#/identity/users/{0}"
#~ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(Format : heures=-1;minutes=-2;seconds=-3)"
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr ""
@ -449,8 +450,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "Êtes-vous sûr de vouloir modifier {0} {1} ?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Assertion non valide après écoulement de ce délai (format : hours=1;minutes=2;seconds=3)"
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Assertion non valide après écoulement de ce délai (format : hours=1;minutes=2;seconds=3)"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -500,7 +505,7 @@ msgstr "Attributs"
msgid "Audience"
msgstr "Audience"
#:
#:
#~ msgid "Auth Type"
#~ msgstr ""
@ -873,7 +878,7 @@ msgstr ""
msgid "Check the logs"
msgstr ""
#:
#:
#~ msgid "Check your Emails for a password reset link."
#~ msgstr "Vérifiez vos courriels pour un lien de récupération de mot de passe."
@ -1022,7 +1027,7 @@ msgstr "Flux de configuration"
msgid "Configuration stages"
msgstr ""
#:
#:
#~ msgid "Configure WebAuthn"
#~ msgstr "Configurer WebAuthn"
@ -1182,7 +1187,7 @@ msgstr "Domaine des cookies"
msgid "Copy"
msgstr "Copier"
#:
#:
#~ msgid "Copy Key"
#~ msgstr "Copier la clé"
@ -1384,7 +1389,7 @@ msgstr "Créer {0}"
msgid "Created by"
msgstr "Créé par"
#:
#:
#~ msgid "Created {0}"
#~ msgstr "Créé {0}"
@ -1394,7 +1399,7 @@ msgstr "Créé par"
msgid "Creation Date"
msgstr "Date de création"
#:
#:
#~ msgid "Current plan cntext"
#~ msgstr "Contexte du plan courant"
@ -1581,7 +1586,7 @@ msgstr "Classes d'équipement"
msgid "Device classes which can be used to authenticate."
msgstr "Classe d'équipement qui peut être utilisé pour s'authentifier"
#:
#:
#~ msgid "Device name"
#~ msgstr "Nom de l'équipement"
@ -1617,19 +1622,19 @@ msgstr ""
#~ msgid "Disable"
#~ msgstr "Désactiver"
#:
#:
#~ msgid "Disable Duo authenticator"
#~ msgstr "Désactiver l'authentificateur Duo"
#:
#:
#~ msgid "Disable SMS authenticator"
#~ msgstr ""
#:
#:
#~ msgid "Disable Static Tokens"
#~ msgstr "Désactiver les jetons statiques"
#:
#:
#~ msgid "Disable Time-based OTP"
#~ msgstr "Désactiver les OTP basés sur le temps"
@ -1683,7 +1688,7 @@ msgstr "En raison des limitations de protocole, ce certificat n'est utilisé que
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
msgstr "Étape factice utilisée pour les tests. Montre un simple bouton continuer et réussit toujours."
#:
#:
#~ msgid "Duo"
#~ msgstr "Duo"
@ -1797,11 +1802,11 @@ msgstr "L'avant poste intégré n'est pas configuré correctement"
#~ msgid "Enable"
#~ msgstr "Activer"
#:
#:
#~ msgid "Enable Duo authenticator"
#~ msgstr "Activer l'authentificateur Duo"
#:
#:
#~ msgid "Enable SMS authenticator"
#~ msgstr ""
@ -1809,11 +1814,11 @@ msgstr "L'avant poste intégré n'est pas configuré correctement"
msgid "Enable StartTLS"
msgstr "Activer StartTLS"
#:
#:
#~ msgid "Enable Static Tokens"
#~ msgstr "Activer les jetons statiques"
#:
#:
#~ msgid "Enable TOTP"
#~ msgstr "Activer TOTP"
@ -1877,7 +1882,7 @@ msgstr "Erreur lors de la validation de l'assertion sur le serveur : {err}"
msgid "Error: unsupported source settings: {0}"
msgstr "Erreur : paramètres source non supportés : {0}"
#:
#:
#~ msgid "Error: unsupported stage settings: {0}"
#~ msgstr "Erreur : paramètres d'étape non supporté : {0}"
@ -1932,7 +1937,7 @@ msgstr "Tout va bien."
msgid "Exception"
msgstr "Exception"
#:
#:
#~ msgid "Execute"
#~ msgstr "Exécuter"
@ -1944,7 +1949,7 @@ msgstr "Exception"
msgid "Execute flow"
msgstr "Exécuter le flux"
#:
#:
#~ msgid "Execute with inspector"
#~ msgstr "Exécuter avec inspection"
@ -2516,6 +2521,10 @@ msgstr "Identifiant"
#~ msgid "Identity & Cryptography"
#~ msgstr "Identité et chiffrement"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2793,6 +2802,10 @@ msgstr "Vu le : {0}"
msgid "Last sync: {0}"
msgstr "Dernière synchro : {0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -3517,8 +3530,12 @@ msgid "Objects created"
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Durée d'expiration du consentement (Format : hours=1;minutes=2;seconds=3)."
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Durée d'expiration du consentement (Format : hours=1;minutes=2;seconds=3)."
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -3730,7 +3747,7 @@ msgstr "Mot de passe défini"
msgid "Password stage"
msgstr "Étape de mot de passe"
#:
#:
#~ msgid "Password, 2FA, etc"
#~ msgstr "Mot de passe, 2FA, etc"
@ -4397,7 +4414,7 @@ msgstr "Clé secrète"
msgid "Secret was rotated"
msgstr ""
#:
#:
#~ msgid "Secret was rotation"
#~ msgstr "Rotation du secret effectuée"
@ -4564,8 +4581,12 @@ msgid "Session duration"
msgstr "Durée de la session"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "La session n'est plus valide à partir de l'heure actuelle + cette valeur (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "La session n'est plus valide à partir de l'heure actuelle + cette valeur (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -4696,7 +4717,7 @@ msgstr "Une erreur s'est produite ! Veuillez réessayer plus tard."
msgid "Source linked"
msgstr "Source liée"
#:
#:
#~ msgid "Source name"
#~ msgstr ""
@ -4861,17 +4882,17 @@ msgstr "Refuser statiquement le flux. Pour utiliser cette étape efficacement, d
msgid "Status"
msgstr "Statut"
#:
#:
#:
#:
#:
#:
#:
#:
#~ msgid "Status: Disabled"
#~ msgstr "Statut : Désactivé"
#:
#:
#:
#:
#:
#:
#:
#:
#~ msgid "Status: Enabled"
#~ msgstr "Statut : Activé"
@ -5230,7 +5251,7 @@ msgstr "Requête suspecte"
msgid "Symbol charset"
msgstr "Set de symboles"
#:
#:
#~ msgid "Sync"
#~ msgstr "Synchroniser"
@ -5390,6 +5411,10 @@ msgstr "L'URL externe par laquelle vous accéderez à l'application. Incluez un
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "Les objets suivants utilisent {0} :"
@ -5490,10 +5515,14 @@ msgid "Time in minutes the token sent is valid."
msgstr "Temps en minutes durant lequel le jeton envoyé est valide."
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Délai de suppression des utilisateurs temporaires. Ceci s'applique uniquement si votre fournisseur d'identité utilise le format NameID transitoire ('transient') et que l'utilisateur ne se déconnecte pas manuellement. (Format : heures=1;minutes=2;secondes=3)."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#:
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Délai de suppression des utilisateurs temporaires. Ceci s'applique uniquement si votre fournisseur d'identité utilise le format NameID transitoire ('transient') et que l'utilisateur ne se déconnecte pas manuellement. (Format : heures=1;minutes=2;secondes=3)."
#:
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "Mots de passe unique basés sur le temps"
@ -6291,7 +6320,7 @@ msgstr ""
msgid "WebAuthn Authenticators"
msgstr "Authentificateurs WebAuthn"
#:
#:
#~ msgid "WebAuthn Devices"
#~ msgstr "Équipements WebAuthn"

View File

@ -20,14 +20,15 @@ msgstr ""
#~ msgid "#/identity/users/{0}"
#~ msgstr "#/identity/users/{0}"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(Format: hours=-1;minutes=-2;seconds=-3)."
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr "(Format: hours=1;minutes=2;seconds=3)."
@ -445,8 +446,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "Czy na pewno chcesz zaktualizować {0} \"{1}”?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Asercja nieważna w bieżącym lub późniejszym czasie + ta wartość (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Asercja nieważna w bieżącym lub późniejszym czasie + ta wartość (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -2484,6 +2489,10 @@ msgstr "Identyfikator"
#~ msgid "Identity & Cryptography"
#~ msgstr "Tożsamość i Kryptografia"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2759,6 +2768,10 @@ msgstr "Ostatnio widziany: {0}"
msgid "Last sync: {0}"
msgstr "Ostatnia synchronizacja: {0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -3480,8 +3493,12 @@ msgid "Objects created"
msgstr "Utworzone obiekty"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Przesunięcie, po którym zgoda wygasa. (Format: hours=1;minutes=2;seconds=3)."
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Przesunięcie, po którym zgoda wygasa. (Format: hours=1;minutes=2;seconds=3)."
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -4512,8 +4529,12 @@ msgid "Session duration"
msgstr "Długość sesji"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Sesja nieważna w bieżącym czasie lub później + ta wartość (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Sesja nieważna w bieżącym czasie lub później + ta wartość (Format: hours=1;minutes=2;seconds=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -5322,6 +5343,10 @@ msgstr "Zewnętrzny adres URL, pod którym uzyskasz dostęp do aplikacji. Uwzgl
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "Zewnętrzny adres URL, pod którym będziesz się uwierzytelniać. Jądro serwera authentik powinien być dostępny pod tym adresem URL."
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "Następujące obiekty używają {0}:"
@ -5431,8 +5456,12 @@ msgid "Time in minutes the token sent is valid."
msgstr "Czas w minutach, w którym wysłany token jest ważny."
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Przesunięcie czasowe, kiedy użytkownicy tymczasowi powinni zostać usunięci. Ma to zastosowanie tylko wtedy, gdy IDP używa „przejściowego” formatu NameID, a użytkownik nie wylogowuje się ręcznie. (Format: hours=1;minutes=2;seconds=3)."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Przesunięcie czasowe, kiedy użytkownicy tymczasowi powinni zostać usunięci. Ma to zastosowanie tylko wtedy, gdy IDP używa „przejściowego” formatu NameID, a użytkownik nie wylogowuje się ręcznie. (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "Hasła jednorazowe oparte na czasie"

View File

@ -13,18 +13,19 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#:
#:
#~ msgid "#/identity/users/{0}"
#~ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr ""
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr ""
@ -144,7 +145,7 @@ msgstr ""
msgid "Access Key"
msgstr ""
#:
#:
#~ msgid "Access code validity"
#~ msgstr ""
@ -440,7 +441,11 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
@ -491,7 +496,7 @@ msgstr ""
msgid "Audience"
msgstr ""
#:
#:
#~ msgid "Auth Type"
#~ msgstr ""
@ -534,7 +539,7 @@ msgstr ""
msgid "Authorization"
msgstr ""
#:
#:
#~ msgid "Authorization Code"
#~ msgstr ""
@ -694,7 +699,7 @@ msgstr ""
msgid "Build hash:"
msgstr ""
#:
#:
#~ msgid "Build hash: {0}"
#~ msgstr ""
@ -776,7 +781,7 @@ msgstr ""
msgid "Certificate used to sign outgoing Responses going to the Service Provider."
msgstr ""
#:
#:
#~ msgid "Certificate-Key Pair"
#~ msgstr ""
@ -867,7 +872,7 @@ msgstr ""
msgid "Check the logs"
msgstr ""
#:
#:
#~ msgid "Check your Emails for a password reset link."
#~ msgstr ""
@ -1014,11 +1019,11 @@ msgstr ""
msgid "Configuration stages"
msgstr ""
#:
#:
#~ msgid "Configure WebAuthn"
#~ msgstr ""
#:
#:
#~ msgid "Configure how long access codes are valid for."
#~ msgstr ""
@ -1054,8 +1059,8 @@ msgstr ""
msgid "Configure how the outpost queries the core authentik server's users."
msgstr ""
#:
#:
#:
#:
#~ msgid "Configure settings relevant to your user profile."
#~ msgstr ""
@ -1177,7 +1182,7 @@ msgstr ""
msgid "Copy"
msgstr ""
#:
#:
#~ msgid "Copy Key"
#~ msgstr ""
@ -1379,7 +1384,7 @@ msgstr ""
msgid "Created by"
msgstr ""
#:
#:
#~ msgid "Created {0}"
#~ msgstr ""
@ -1389,7 +1394,7 @@ msgstr ""
msgid "Creation Date"
msgstr ""
#:
#:
#~ msgid "Current plan cntext"
#~ msgstr ""
@ -1486,24 +1491,24 @@ msgstr ""
msgid "Delete"
msgstr ""
#:
#:
#~ msgid "Delete Authorization Code"
#~ msgstr ""
#:
#:
#:
#:
#~ msgid "Delete Binding"
#~ msgstr ""
#:
#:
#~ msgid "Delete Consent"
#~ msgstr ""
#:
#:
#~ msgid "Delete Refresh Code"
#~ msgstr ""
#:
#:
#~ msgid "Delete Session"
#~ msgstr ""
@ -1582,7 +1587,7 @@ msgstr ""
msgid "Device classes which can be used to authenticate."
msgstr ""
#:
#:
#~ msgid "Device name"
#~ msgstr ""
@ -1615,24 +1620,24 @@ msgstr ""
msgid "Directory"
msgstr ""
#:
#:
#:
#:
#~ msgid "Disable"
#~ msgstr ""
#:
#:
#~ msgid "Disable Duo authenticator"
#~ msgstr ""
#:
#:
#~ msgid "Disable SMS authenticator"
#~ msgstr ""
#:
#:
#~ msgid "Disable Static Tokens"
#~ msgstr ""
#:
#:
#~ msgid "Disable Time-based OTP"
#~ msgstr ""
@ -1686,7 +1691,7 @@ msgstr ""
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
msgstr ""
#:
#:
#~ msgid "Duo"
#~ msgstr ""
@ -1797,16 +1802,16 @@ msgstr ""
msgid "Embedded outpost is not configured correctly."
msgstr ""
#:
#:
#:
#:
#~ msgid "Enable"
#~ msgstr ""
#:
#:
#~ msgid "Enable Duo authenticator"
#~ msgstr ""
#:
#:
#~ msgid "Enable SMS authenticator"
#~ msgstr ""
@ -1814,11 +1819,11 @@ msgstr ""
msgid "Enable StartTLS"
msgstr ""
#:
#:
#~ msgid "Enable Static Tokens"
#~ msgstr ""
#:
#:
#~ msgid "Enable TOTP"
#~ msgstr ""
@ -1882,7 +1887,7 @@ msgstr ""
msgid "Error: unsupported source settings: {0}"
msgstr ""
#:
#:
#~ msgid "Error: unsupported stage settings: {0}"
#~ msgstr ""
@ -1937,7 +1942,7 @@ msgstr ""
msgid "Exception"
msgstr ""
#:
#:
#~ msgid "Execute"
#~ msgstr ""
@ -1949,7 +1954,7 @@ msgstr ""
msgid "Execute flow"
msgstr ""
#:
#:
#~ msgid "Execute with inspector"
#~ msgstr ""
@ -2124,7 +2129,7 @@ msgstr ""
msgid "Field which contains a unique Identifier."
msgstr ""
#:
#:
#~ msgid "Field which contains members of a group."
#~ msgstr ""
@ -2331,7 +2336,7 @@ msgstr ""
msgid "Get this value from https://console.twilio.com"
msgstr ""
#:
#:
#~ msgid "Go to admin interface"
#~ msgstr ""
@ -2343,7 +2348,7 @@ msgstr ""
msgid "Go to previous page"
msgstr ""
#:
#:
#~ msgid "Go to user interface"
#~ msgstr ""
@ -2524,6 +2529,10 @@ msgstr ""
#~ msgid "Identity & Cryptography"
#~ msgstr ""
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2684,7 +2693,7 @@ msgstr ""
msgid "Invalidation flow"
msgstr ""
#:
#:
#~ msgid "Invitation"
#~ msgstr ""
@ -2802,6 +2811,10 @@ msgstr ""
msgid "Last sync: {0}"
msgstr ""
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -2815,7 +2828,7 @@ msgstr ""
msgid "Let the user identify themselves with their username or Email address."
msgstr ""
#:
#:
#~ msgid "Library"
#~ msgstr ""
@ -3125,7 +3138,7 @@ msgstr ""
msgid "Model updated"
msgstr ""
#:
#:
#~ msgid "Monitor"
#~ msgstr ""
@ -3460,7 +3473,7 @@ msgstr ""
msgid "Notification Transports"
msgstr ""
#:
#:
#~ msgid "Notification rule"
#~ msgstr ""
@ -3480,7 +3493,7 @@ msgstr ""
msgid "Notifications"
msgstr ""
#:
#:
#~ msgid "Notifications Transport"
#~ msgstr ""
@ -3530,9 +3543,13 @@ msgid "Objects created"
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr ""
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
#: src/pages/events/EventListPage.ts
@ -3551,7 +3568,7 @@ msgstr ""
msgid "Open API Browser"
msgstr ""
#:
#:
#~ msgid "Open application"
#~ msgstr ""
@ -3633,7 +3650,7 @@ msgstr ""
msgid "Outdated outposts"
msgstr ""
#:
#:
#~ msgid "Outpost"
#~ msgstr ""
@ -3645,11 +3662,11 @@ msgstr ""
msgid "Outpost Integrations"
msgstr ""
#:
#:
#~ msgid "Outpost Service-connection"
#~ msgstr ""
#:
#:
#~ msgid "Outpost integration"
#~ msgstr ""
@ -3747,7 +3764,7 @@ msgstr ""
msgid "Password stage"
msgstr ""
#:
#:
#~ msgid "Password, 2FA, etc"
#~ msgstr ""
@ -3823,7 +3840,7 @@ msgstr ""
msgid "Policy Bindings"
msgstr ""
#:
#:
#~ msgid "Policy binding"
#~ msgstr ""
@ -3911,7 +3928,7 @@ msgstr ""
msgid "Profile URL"
msgstr ""
#:
#:
#~ msgid "Prompt"
#~ msgstr ""
@ -3928,7 +3945,7 @@ msgstr ""
msgid "Prompts"
msgstr ""
#:
#:
#~ msgid "Property Mapping"
#~ msgstr ""
@ -3987,7 +4004,7 @@ msgstr ""
msgid "Provider Type"
msgstr ""
#:
#:
#~ msgid "Provider type"
#~ msgstr ""
@ -4130,7 +4147,7 @@ msgstr ""
msgid "Refresh"
msgstr ""
#:
#:
#~ msgid "Refresh Code"
#~ msgstr ""
@ -4248,7 +4265,7 @@ msgstr ""
msgid "Retry"
msgstr ""
#:
#:
#~ msgid "Retry Task"
#~ msgstr ""
@ -4416,7 +4433,7 @@ msgstr ""
msgid "Secret was rotated"
msgstr ""
#:
#:
#~ msgid "Secret was rotation"
#~ msgstr ""
@ -4456,7 +4473,7 @@ msgstr ""
msgid "Select an enrollment flow"
msgstr ""
#:
#:
#~ msgid "Select an identification method."
#~ msgstr ""
@ -4505,7 +4522,7 @@ msgstr ""
msgid "Selected policies are executed when the stage is submitted to validate the data."
msgstr ""
#:
#:
#~ msgid "Selecting a service-connection enables the management of the outpost by authentik."
#~ msgstr ""
@ -4556,7 +4573,7 @@ msgstr ""
msgid "Server and client are further than 5 seconds apart."
msgstr ""
#:
#:
#~ msgid "Server name for which this provider's certificate is valid for."
#~ msgstr ""
@ -4564,7 +4581,7 @@ msgstr ""
msgid "Server validation of credential failed: {err}"
msgstr ""
#:
#:
#~ msgid "Service Connections"
#~ msgstr ""
@ -4572,12 +4589,12 @@ msgstr ""
msgid "Service Provider Binding"
msgstr ""
#:
#:
#:
#:
#~ msgid "Service connection"
#~ msgstr ""
#:
#:
#~ msgid "Session"
#~ msgstr ""
@ -4590,7 +4607,11 @@ msgid "Session duration"
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
@ -4715,7 +4736,7 @@ msgstr ""
msgid "Something went wrong! Please try again later."
msgstr ""
#:
#:
#~ msgid "Source"
#~ msgstr ""
@ -4723,7 +4744,7 @@ msgstr ""
msgid "Source linked"
msgstr ""
#:
#:
#~ msgid "Source name"
#~ msgstr ""
@ -4740,7 +4761,7 @@ msgstr ""
msgid "Sources"
msgstr ""
#:
#:
#~ msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
#~ msgstr ""
@ -4769,7 +4790,7 @@ msgstr ""
msgid "Stage Configuration"
msgstr ""
#:
#:
#~ msgid "Stage binding"
#~ msgstr ""
@ -4890,17 +4911,17 @@ msgstr ""
msgid "Status"
msgstr ""
#:
#:
#:
#:
#:
#:
#:
#:
#~ msgid "Status: Disabled"
#~ msgstr ""
#:
#:
#:
#:
#:
#:
#:
#:
#~ msgid "Status: Enabled"
#~ msgstr ""
@ -5012,8 +5033,8 @@ msgstr ""
msgid "Successfully created rule."
msgstr ""
#:
#:
#:
#:
#~ msgid "Successfully created service-connection."
#~ msgstr ""
@ -5179,8 +5200,8 @@ msgstr ""
msgid "Successfully updated rule."
msgstr ""
#:
#:
#:
#:
#~ msgid "Successfully updated service-connection."
#~ msgstr ""
@ -5263,7 +5284,7 @@ msgstr ""
msgid "Symbol charset"
msgstr ""
#:
#:
#~ msgid "Sync"
#~ msgstr ""
@ -5271,7 +5292,7 @@ msgstr ""
msgid "Sync groups"
msgstr ""
#:
#:
#~ msgid "Sync parent group"
#~ msgstr ""
@ -5316,7 +5337,7 @@ msgstr ""
msgid "TLS Authentication Certificate/SSH Keypair"
msgstr ""
#:
#:
#~ msgid "TLS Server name"
#~ msgstr ""
@ -5425,7 +5446,11 @@ msgstr ""
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr ""
#:
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#:
#~ msgid "The following objects use {0}:"
#~ msgstr ""
@ -5526,10 +5551,14 @@ msgid "Time in minutes the token sent is valid."
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#:
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr ""
#:
#~ msgid "Time-based One-Time Passwords"
#~ msgstr ""
@ -5569,8 +5598,8 @@ msgstr ""
msgid "To use SSL instead, use 'ldaps://' and disable this option."
msgstr ""
#:
#:
#:
#:
#~ msgid "Token"
#~ msgstr ""
@ -5770,7 +5799,7 @@ msgstr ""
msgid "Unknown"
msgstr ""
#:
#:
#~ msgid "Unmanaged"
#~ msgstr ""
@ -6047,8 +6076,8 @@ msgstr ""
#~ msgid "User Reputation"
#~ msgstr ""
#:
#:
#:
#:
#~ msgid "User Settings"
#~ msgstr ""
@ -6332,7 +6361,7 @@ msgstr ""
msgid "WebAuthn Authenticators"
msgstr ""
#:
#:
#~ msgid "WebAuthn Devices"
#~ msgstr ""
@ -6485,11 +6514,11 @@ msgstr ""
msgid "app1 running on app1.example.com"
msgstr ""
#:
#:
#~ msgid "authentik Builtin Database"
#~ msgstr ""
#:
#:
#~ msgid "authentik LDAP Backend"
#~ msgstr ""

View File

@ -20,14 +20,15 @@ msgstr ""
#~ msgid "#/identity/users/{0}"
#~ msgstr "#/kimlik/kullanıcılar/ {0}"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(Biçim: saat=-1; dakika=-2; ikincil=-3)."
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr "(Biçim: saat=1; dakika=2; saniye= 3)."
@ -445,8 +446,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "{0} “{1}” güncellemesini istediğinizden emin misiniz?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Onay işlemi geçerli saat+bu değerden sonra geçerli değil (Biçim: hours=1; Dakika=2; ikinci=3)."
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Onay işlemi geçerli saat+bu değerden sonra geçerli değil (Biçim: hours=1; Dakika=2; ikinci=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -2487,6 +2492,10 @@ msgstr "Tanımlayıcı"
#~ msgid "Identity & Cryptography"
#~ msgstr "Kimlik ve Kriptografi"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2763,6 +2772,10 @@ msgstr "Son görüldü: {0}"
msgid "Last sync: {0}"
msgstr "Son senkronizasyon: {0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -3485,8 +3498,12 @@ msgid "Objects created"
msgstr "Oluşturulan nesneler"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Onay sona erdikten sonra ofset. (Biçim: saat=1; dakika=2; saniye/= 3)."
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Onay sona erdikten sonra ofset. (Biçim: saat=1; dakika=2; saniye/= 3)."
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -4517,8 +4534,12 @@ msgid "Session duration"
msgstr "Oturum süresi"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "Oturum geçerli saat+bu değerden sonra geçerli değil (Biçim: hours=1; Dakika=2; ikinci=3)."
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Oturum geçerli saat+bu değerden sonra geçerli değil (Biçim: hours=1; Dakika=2; ikinci=3)."
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -5327,6 +5348,10 @@ msgstr "Uygulamaya erişeceğiniz harici URL. Standart olmayan herhangi bir bağ
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "Kimlik doğrulayacağınız harici URL. Auentik çekirdek sunucusuna bu URL altında erişilebilir olmalıdır."
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "Aşağıdaki nesneler {0} kullanır:"
@ -5436,8 +5461,12 @@ msgid "Time in minutes the token sent is valid."
msgstr "Gönderilen belirtecin dakika cinsinden geçerlilik süresi."
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Geçici kullanıcıların silinmesi gerektiğinde zaman uzaklığı. Bu yalnızca IDP'niz NameID Biçimi 'geçici' kullanıyorsa ve kullanıcı el ile oturumu kapatmazsa geçerlidir. (Biçim: saat=1; dakika=2; saniye/= 3)."
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "Geçici kullanıcıların silinmesi gerektiğinde zaman uzaklığı. Bu yalnızca IDP'niz NameID Biçimi 'geçici' kullanıyorsa ve kullanıcı el ile oturumu kapatmazsa geçerlidir. (Biçim: saat=1; dakika=2; saniye/= 3)."
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "Zaman Tabanlı Tek seferlik Parolalar"

File diff suppressed because it is too large Load Diff

View File

@ -22,14 +22,15 @@ msgstr ""
#~ msgid "#/identity/users/{0}"
#~ msgstr "#/identity/users/{0}"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(格式: hours=-1;minutes=-2;seconds=-3)."
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr "(格式: hours=1;minutes=2;seconds=3)."
@ -446,8 +447,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "你确定要更新 {0} \"{1}\" 吗?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "断言在当前时间+此值时或之后无效格式hours=1minutes=2seconds=3。"
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "断言在当前时间+此值时或之后无效格式hours=1minutes=2seconds=3。"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -2476,6 +2481,10 @@ msgstr "标识符"
#~ msgid "Identity & Cryptography"
#~ msgstr "身份与加密"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2749,6 +2758,10 @@ msgstr "最后显示:{0}"
msgid "Last sync: {0}"
msgstr "上次同步:{0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -3466,8 +3479,12 @@ msgid "Objects created"
msgstr "已创建对象"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "偏移量在此之后同意过期。格式hours=1;minutes=2;seconds=3。"
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "偏移量在此之后同意过期。格式hours=1;minutes=2;seconds=3。"
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -4485,8 +4502,12 @@ msgid "Session duration"
msgstr "会话持续时间"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "在当前时间+此值时或之后会话无效格式hours=1;minutes=2;seconds=3。"
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "在当前时间+此值时或之后会话无效格式hours=1;minutes=2;seconds=3。"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -5293,6 +5314,10 @@ msgstr "您将通过其访问应用程序的外部 URL。包括任何非标准
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "您将在其中进行身份验证的外部 URL。在此 URL 下应该可以访问身份验证核心服务器。"
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "以下对象使用 {0}"
@ -5402,8 +5427,12 @@ msgid "Time in minutes the token sent is valid."
msgstr "发送的令牌的有效时间(以分钟为单位)。"
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "删除临时用户的时间偏移。这仅适用于您的 IDP 使用 NameID 格式为 “瞬态” 且用户未手动注销的情况。格式hours=1;minutes=2;seconds=3。"
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "删除临时用户的时间偏移。这仅适用于您的 IDP 使用 NameID 格式为 “瞬态” 且用户未手动注销的情况。格式hours=1;minutes=2;seconds=3。"
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "基于时间的一次性密码"

View File

@ -22,14 +22,15 @@ msgstr ""
#~ msgid "#/identity/users/{0}"
#~ msgstr "#/identity/users/{0}"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/saml/SAMLProviderForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
#~ msgid "(Format: days=-1;minutes=-2;seconds=-3)."
#~ msgstr ""
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=-1;minutes=-2;seconds=-3)."
msgstr "(格式: hours=-1;minutes=-2;seconds=-3)."
#: src/pages/stages/user_login/UserLoginStageForm.ts
#: src/elements/utils/TimeDeltaHelp.ts
msgid "(Format: hours=1;minutes=2;seconds=3)."
msgstr "(格式: hours=1;minutes=2;seconds=3)."
@ -446,8 +447,12 @@ msgid "Are you sure you want to update {0} \"{1}\"?"
msgstr "你确定要更新 {0} \"{1}\" 吗?"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "断言在当前时间+此值时或之后无效格式hours=1minutes=2seconds=3。"
#~ msgid "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "断言在当前时间+此值时或之后无效格式hours=1minutes=2seconds=3。"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Assertion valid not before"
@ -2476,6 +2481,10 @@ msgstr "标识符"
#~ msgid "Identity & Cryptography"
#~ msgstr "身份与加密"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "If any of the devices user of the types selected above have been used within this duration, this stage will be skipped."
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
msgid "If enabled, use the local connection. Required Docker socket/Kubernetes Integration."
@ -2749,6 +2758,10 @@ msgstr "最后显示:{0}"
msgid "Last sync: {0}"
msgstr "上次同步:{0}"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Last validation threshold"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/applications/ApplicationViewPage.ts
msgid "Launch"
@ -3466,8 +3479,12 @@ msgid "Objects created"
msgstr "已创建对象"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "偏移量在此之后同意过期。格式hours=1;minutes=2;seconds=3。"
msgid "Offset after which consent expires."
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
#~ msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "偏移量在此之后同意过期。格式hours=1;minutes=2;seconds=3。"
#: src/elements/events/ObjectChangelog.ts
#: src/elements/events/UserEvents.ts
@ -4485,8 +4502,12 @@ msgid "Session duration"
msgstr "会话持续时间"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
msgstr "在当前时间+此值时或之后会话无效格式hours=1;minutes=2;seconds=3。"
#~ msgid "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "在当前时间+此值时或之后会话无效格式hours=1;minutes=2;seconds=3。"
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session not valid on or after current time + this value."
msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts
msgid "Session valid not on or after"
@ -5293,6 +5314,10 @@ msgstr "您将通过其访问应用程序的外部 URL。包括任何非标准
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "您将在其中进行身份验证的外部 URL。在此 URL 下应该可以访问身份验证核心服务器。"
#: src/elements/utils/TimeDeltaHelp.ts
msgid "The following keywords are supported:"
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "以下对象使用 {0}"
@ -5402,8 +5427,12 @@ msgid "Time in minutes the token sent is valid."
msgstr "发送的令牌的有效时间(以分钟为单位)。"
#: src/pages/sources/saml/SAMLSourceForm.ts
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
msgstr "删除临时用户的时间偏移。这仅适用于您的 IDP 使用 NameID 格式为 “瞬态” 且用户未手动注销的情况。格式hours=1;minutes=2;seconds=3。"
msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually."
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
#~ msgid "Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3)."
#~ msgstr "删除临时用户的时间偏移。这仅适用于您的 IDP 使用 NameID 格式为 “瞬态” 且用户未手动注销的情况。格式hours=1;minutes=2;seconds=3。"
#~ msgid "Time-based One-Time Passwords"
#~ msgstr "基于时间的一次性密码"

View File

@ -21,6 +21,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
import "../../../elements/utils/TimeDeltaHelp";
import { first, randomString } from "../../../utils";
@customElement("ak-provider-oauth2-form")
@ -230,9 +231,7 @@ ${this.instance?.redirectUris}</textarea
<p class="pf-c-form__helper-text">
${t`If you are using an Implicit, client-side flow (where the token-endpoint isn't used), you probably want to increase this time.`}
</p>
<p class="pf-c-form__helper-text">
${t`(Format: hours=-1;minutes=-2;seconds=-3).`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Token validity`}
@ -248,9 +247,7 @@ ${this.instance?.redirectUris}</textarea
<p class="pf-c-form__helper-text">
${t`Configure how long refresh tokens and their id_tokens are valid for.`}
</p>
<p class="pf-c-form__helper-text">
${t`(Format: hours=-1;minutes=-2;seconds=-3).`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Scopes`} name="propertyMappings">
<select class="pf-c-form-control" multiple>

View File

@ -25,6 +25,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
import "../../../elements/utils/TimeDeltaHelp";
import { first } from "../../../utils";
@customElement("ak-provider-proxy-form")
@ -329,9 +330,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">${t`Configure how long tokens are valid for.`}</p>
<p class="pf-c-form__helper-text">
${t`(Format: hours=-1;minutes=-2;seconds=-3).`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-group>

View File

@ -21,6 +21,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
import "../../../elements/utils/TimeDeltaHelp";
@customElement("ak-provider-saml-form")
export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
@ -299,9 +300,7 @@ export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
<p class="pf-c-form__helper-text">
${t`Configure the maximum allowed time drift for an assertion.`}
</p>
<p class="pf-c-form__helper-text">
${t`(Format: hours=-1;minutes=-2;seconds=-3).`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Assertion valid not on or after`}
@ -315,8 +314,9 @@ export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
required
/>
<p class="pf-c-form__helper-text">
${t`Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).`}
${t`Assertion not valid on or after current time + this value.`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Session valid not on or after`}
@ -330,8 +330,9 @@ export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
required
/>
<p class="pf-c-form__helper-text">
${t`Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).`}
${t`Session not valid on or after current time + this value.`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-element-horizontal

View File

@ -21,6 +21,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
import "../../../elements/utils/TimeDeltaHelp";
import { first } from "../../../utils";
@customElement("ak-source-saml-form")
@ -243,8 +244,9 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
required
/>
<p class="pf-c-form__helper-text">
${t`Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3).`}
${t`Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually.`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Digest algorithm`}

View File

@ -16,6 +16,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
import "../../../elements/utils/TimeDeltaHelp";
@customElement("ak-stage-authenticator-validate-form")
export class AuthenticatorValidateStageForm extends ModelForm<AuthenticatorValidateStage, string> {
@ -123,6 +124,22 @@ export class AuthenticatorValidateStageForm extends ModelForm<AuthenticatorValid
${t`Hold control/command to select multiple items.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Last validation threshold`}
?required=${true}
name="lastAuthThreshold"
>
<input
type="text"
value="${this.instance?.lastAuthThreshold || "seconds=0"}"
class="pf-c-form-control"
required
/>
<p class="pf-c-form__helper-text">
${t`If any of the devices user of the types selected above have been used within this duration, this stage will be skipped.`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Not configured action`}
?required=${true}

View File

@ -10,6 +10,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
import "../../../elements/utils/TimeDeltaHelp";
@customElement("ak-stage-consent-form")
export class ConsentStageForm extends ModelForm<ConsentStage, string> {
@ -113,8 +114,9 @@ export class ConsentStageForm extends ModelForm<ConsentStage, string> {
required
/>
<p class="pf-c-form__helper-text">
${t`Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3).`}
${t`Offset after which consent expires.`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
</div>
</ak-form-group>

View File

@ -9,6 +9,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
import "../../../elements/utils/TimeDeltaHelp";
import { first } from "../../../utils";
@customElement("ak-stage-user-login-form")
@ -68,9 +69,7 @@ export class UserLoginStageForm extends ModelForm<UserLoginStage, string> {
<p class="pf-c-form__helper-text">
${t`Determines how long a session lasts. Default of 0 seconds means that the sessions lasts until the browser is closed.`}
</p>
<p class="pf-c-form__helper-text">
${t`(Format: hours=1;minutes=2;seconds=3).`}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>
</ak-form-element-horizontal>
</div>
</ak-form-group>

View File

@ -18,6 +18,9 @@ Using the `Not configured action`, you can choose what happens when a user does
- Deny: Access is denied, the flow execution ends
- Configure: This option requires a _Configuration stage_ to be set. The validation stage will be marked as successful, and the configuration stage will be injected into the flow.
By default, authenticator validation is required every time the flow containing this stage is executed. To only change this behavior, set _Last validation threshold_ to a non-zero value. (Requires authentik 2022.5)
Keep in mind that when using Code-based devices (TOTP, Static and SMS), values lower than `seconds=30` cannot be used, as with the way TOTP devices are saved, there is no exact timestamp.
## Passwordless authentication
:::info