diff --git a/authentik/stages/authenticator_static/migrations/0012_alter_authenticatorstaticstage_token_length_and_more.py b/authentik/stages/authenticator_static/migrations/0012_alter_authenticatorstaticstage_token_length_and_more.py new file mode 100644 index 000000000000..8a3a4208f8e1 --- /dev/null +++ b/authentik/stages/authenticator_static/migrations/0012_alter_authenticatorstaticstage_token_length_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 5.2.9 on 2026-01-06 23:52 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ( + "authentik_stages_authenticator_static", + "0011_alter_authenticatorstaticstage_friendly_name", + ), + ] + + operations = [ + migrations.AlterField( + model_name="authenticatorstaticstage", + name="token_length", + field=models.PositiveIntegerField( + default=12, validators=[django.core.validators.MaxValueValidator(100)] + ), + ), + migrations.AlterField( + model_name="statictoken", + name="token", + field=models.CharField(db_index=True, max_length=100), + ), + ] diff --git a/authentik/stages/authenticator_static/models.py b/authentik/stages/authenticator_static/models.py index f9ac8012bfa4..72776db689f9 100644 --- a/authentik/stages/authenticator_static/models.py +++ b/authentik/stages/authenticator_static/models.py @@ -4,6 +4,7 @@ from os import urandom from django.conf import settings +from django.core.validators import MaxValueValidator from django.db import models from django.utils.translation import gettext_lazy as _ from django.views import View @@ -19,7 +20,7 @@ class AuthenticatorStaticStage(ConfigurableStage, FriendlyNamedStage, Stage): """Setup static token based authentication for the user.""" token_count = models.PositiveIntegerField(default=6) - token_length = models.PositiveIntegerField(default=12) + token_length = models.PositiveIntegerField(default=12, validators=[MaxValueValidator(100)]) @property def serializer(self) -> type[BaseSerializer]: @@ -109,11 +110,11 @@ class StaticToken(models.Model): .. attribute:: token - *CharField*: A random string up to 16 characters. + *CharField*: A random string up to 100 characters. """ device = models.ForeignKey(StaticDevice, related_name="token_set", on_delete=models.CASCADE) - token = models.CharField(max_length=16, db_index=True) + token = models.CharField(max_length=100, db_index=True) class Meta: verbose_name = _("Static Token") diff --git a/blueprints/schema.json b/blueprints/schema.json index 033329a7f60b..bd6ab2bccb00 100644 --- a/blueprints/schema.json +++ b/blueprints/schema.json @@ -13712,7 +13712,7 @@ "token_length": { "type": "integer", "minimum": 0, - "maximum": 2147483647, + "maximum": 100, "title": "Token length" } }, diff --git a/schema.yml b/schema.yml index 549f71e0319b..3485793db036 100644 --- a/schema.yml +++ b/schema.yml @@ -34095,7 +34095,7 @@ components: minimum: 0 token_length: type: integer - maximum: 2147483647 + maximum: 100 minimum: 0 required: - component @@ -34126,7 +34126,7 @@ components: minimum: 0 token_length: type: integer - maximum: 2147483647 + maximum: 100 minimum: 0 required: - name @@ -45848,7 +45848,7 @@ components: minimum: 0 token_length: type: integer - maximum: 2147483647 + maximum: 100 minimum: 0 PatchedAuthenticatorTOTPStageRequest: type: object @@ -53840,7 +53840,7 @@ components: properties: token: type: string - maxLength: 16 + maxLength: 100 required: - token SubModeEnum: diff --git a/web/src/admin/stages/authenticator_static/AuthenticatorStaticStageForm.ts b/web/src/admin/stages/authenticator_static/AuthenticatorStaticStageForm.ts index e8af6f3b93ba..7880872687d5 100644 --- a/web/src/admin/stages/authenticator_static/AuthenticatorStaticStageForm.ts +++ b/web/src/admin/stages/authenticator_static/AuthenticatorStaticStageForm.ts @@ -94,14 +94,16 @@ export class AuthenticatorStaticStageForm extends BaseStageForm

${msg( - "The length of the individual generated tokens. Can be increased to improve security.", + "The length of the individual generated tokens. Can be set to a maximum of 100 characters.", )}

diff --git a/web/src/flow/stages/authenticator_static/AuthenticatorStaticStage.ts b/web/src/flow/stages/authenticator_static/AuthenticatorStaticStage.ts index 7e0218a34b78..58c2121421cc 100644 --- a/web/src/flow/stages/authenticator_static/AuthenticatorStaticStage.ts +++ b/web/src/flow/stages/authenticator_static/AuthenticatorStaticStage.ts @@ -36,17 +36,16 @@ export class AuthenticatorStaticStage extends BaseStage< PFButton, css` /* Static OTP Tokens */ - ul { - list-style: circle; - columns: 2; - -webkit-columns: 2; - -moz-columns: 2; - column-width: 1em; - margin-left: var(--pf-global--spacer--xs); + .token-list { + list-style: disc; + padding-left: var(--pf-global--spacer--lg); + margin: var(--pf-global--spacer--sm) 0; } - ul li { - font-size: var(--pf-global--FontSize--2xl); - margin: 0 2rem; + .token-list li { + font-family: var(--pf-global--FontFamily--monospace); + font-size: var(--pf-global--FontSize--md); + margin-bottom: var(--pf-global--spacer--xs); + word-break: break-all; } `, ]; @@ -65,13 +64,11 @@ export class AuthenticatorStaticStage extends BaseStage< > -
- -
+

${msg("Make sure to keep these tokens in a safe place.")}