stages: Add ability to set user friendly names for MFA stages (#5005)

* Added ability to name MFA stage

* Schema

* Changed Charfield to Textfield

* Regenerated schema

* Add explicit required

* set null instead of blank so title check works

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

* add help text and adjust wording

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
sdimovv 2023-04-02 15:52:44 +01:00 committed by GitHub
parent fd2677af1f
commit 6192d01b7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 275 additions and 47 deletions

View File

@ -27,6 +27,6 @@ class UserSettingSerializer(PassiveSerializer):
object_uid = CharField()
component = CharField()
title = CharField()
title = CharField(required=True)
configure_url = CharField(required=False)
icon_url = CharField(required=False)

View File

@ -271,6 +271,15 @@ class ConfigurableStage(models.Model):
abstract = True
class FriendlyNamedStage(models.Model):
"""Abstract base class for a Stage that can have a user friendly name configured."""
friendly_name = models.TextField(null=True)
class Meta:
abstract = True
class FlowToken(Token):
"""Subclass of a standard Token, stores the currently active flow plan upon creation.
Can be used to later resume a flow."""

View File

@ -33,6 +33,7 @@ class AuthenticatorDuoStageSerializer(StageSerializer):
model = AuthenticatorDuoStage
fields = StageSerializer.Meta.fields + [
"configure_flow",
"friendly_name",
"client_id",
"client_secret",
"api_hostname",

View File

@ -0,0 +1,20 @@
# Generated by Django 4.1.7 on 2023-04-02 14:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
(
"authentik_stages_authenticator_duo",
"0004_authenticatorduostage_admin_integration_key_and_more",
),
]
operations = [
migrations.AddField(
model_name="authenticatorduostage",
name="friendly_name",
field=models.TextField(null=True),
),
]

View File

@ -12,12 +12,12 @@ from rest_framework.serializers import BaseSerializer, Serializer
from authentik import __version__
from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, Stage
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
from authentik.lib.models import SerializerModel
from authentik.lib.utils.http import authentik_user_agent
class AuthenticatorDuoStage(ConfigurableStage, Stage):
class AuthenticatorDuoStage(ConfigurableStage, FriendlyNamedStage, Stage):
"""Setup Duo authenticator devices"""
api_hostname = models.TextField()
@ -68,7 +68,7 @@ class AuthenticatorDuoStage(ConfigurableStage, Stage):
def ui_user_settings(self) -> Optional[UserSettingSerializer]:
return UserSettingSerializer(
data={
"title": str(self._meta.verbose_name),
"title": self.friendly_name or str(self._meta.verbose_name),
"component": "ak-user-settings-authenticator-duo",
}
)

View File

@ -19,6 +19,7 @@ class AuthenticatorSMSStageSerializer(StageSerializer):
model = AuthenticatorSMSStage
fields = StageSerializer.Meta.fields + [
"configure_flow",
"friendly_name",
"provider",
"from_number",
"account_sid",

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.7 on 2023-04-02 14:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_authenticator_sms", "0005_authenticatorsmsstage_mapping"),
]
operations = [
migrations.AddField(
model_name="authenticatorsmsstage",
name="friendly_name",
field=models.TextField(null=True),
),
]

View File

@ -17,7 +17,7 @@ from twilio.rest import Client
from authentik.core.types import UserSettingSerializer
from authentik.events.models import Event, EventAction, NotificationWebhookMapping
from authentik.events.utils import sanitize_item
from authentik.flows.models import ConfigurableStage, Stage
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
from authentik.lib.models import SerializerModel
from authentik.lib.utils.errors import exception_to_string
from authentik.lib.utils.http import get_http_session
@ -39,7 +39,7 @@ class SMSAuthTypes(models.TextChoices):
BEARER = "bearer"
class AuthenticatorSMSStage(ConfigurableStage, Stage):
class AuthenticatorSMSStage(ConfigurableStage, FriendlyNamedStage, Stage):
"""Use SMS-based TOTP instead of authenticator-based."""
provider = models.TextField(choices=SMSProviders.choices)
@ -168,7 +168,7 @@ class AuthenticatorSMSStage(ConfigurableStage, Stage):
def ui_user_settings(self) -> Optional[UserSettingSerializer]:
return UserSettingSerializer(
data={
"title": str(self._meta.verbose_name),
"title": self.friendly_name or str(self._meta.verbose_name),
"component": "ak-user-settings-authenticator-sms",
}
)

View File

@ -18,7 +18,7 @@ class AuthenticatorStaticStageSerializer(StageSerializer):
class Meta:
model = AuthenticatorStaticStage
fields = StageSerializer.Meta.fields + ["configure_flow", "token_count"]
fields = StageSerializer.Meta.fields + ["configure_flow", "friendly_name", "token_count"]
class AuthenticatorStaticStageViewSet(UsedByMixin, ModelViewSet):

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.7 on 2023-04-02 14:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_authenticator_static", "0005_default_setup_flow"),
]
operations = [
migrations.AddField(
model_name="authenticatorstaticstage",
name="friendly_name",
field=models.TextField(null=True),
),
]

View File

@ -7,10 +7,10 @@ from django.views import View
from rest_framework.serializers import BaseSerializer
from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, Stage
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
class AuthenticatorStaticStage(ConfigurableStage, Stage):
class AuthenticatorStaticStage(ConfigurableStage, FriendlyNamedStage, Stage):
"""Generate static tokens for the user as a backup."""
token_count = models.IntegerField(default=6)
@ -34,7 +34,7 @@ class AuthenticatorStaticStage(ConfigurableStage, Stage):
def ui_user_settings(self) -> Optional[UserSettingSerializer]:
return UserSettingSerializer(
data={
"title": str(self._meta.verbose_name),
"title": self.friendly_name or str(self._meta.verbose_name),
"component": "ak-user-settings-authenticator-static",
}
)

View File

@ -18,7 +18,7 @@ class AuthenticatorTOTPStageSerializer(StageSerializer):
class Meta:
model = AuthenticatorTOTPStage
fields = StageSerializer.Meta.fields + ["configure_flow", "digits"]
fields = StageSerializer.Meta.fields + ["configure_flow", "friendly_name", "digits"]
class AuthenticatorTOTPStageViewSet(UsedByMixin, ModelViewSet):

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.7 on 2023-04-02 14:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_authenticator_totp", "0006_default_setup_flow"),
]
operations = [
migrations.AddField(
model_name="authenticatortotpstage",
name="friendly_name",
field=models.TextField(null=True),
),
]

View File

@ -7,7 +7,7 @@ from django.views import View
from rest_framework.serializers import BaseSerializer
from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, Stage
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
class TOTPDigits(models.IntegerChoices):
@ -17,7 +17,7 @@ class TOTPDigits(models.IntegerChoices):
EIGHT = 8, _("8 digits, not compatible with apps like Google Authenticator")
class AuthenticatorTOTPStage(ConfigurableStage, Stage):
class AuthenticatorTOTPStage(ConfigurableStage, FriendlyNamedStage, Stage):
"""Enroll a user's device into Time-based OTP."""
digits = models.IntegerField(choices=TOTPDigits.choices)
@ -41,7 +41,7 @@ class AuthenticatorTOTPStage(ConfigurableStage, Stage):
def ui_user_settings(self) -> Optional[UserSettingSerializer]:
return UserSettingSerializer(
data={
"title": str(self._meta.verbose_name),
"title": self.friendly_name or str(self._meta.verbose_name),
"component": "ak-user-settings-authenticator-totp",
}
)

View File

@ -19,6 +19,7 @@ class AuthenticateWebAuthnStageSerializer(StageSerializer):
model = AuthenticateWebAuthnStage
fields = StageSerializer.Meta.fields + [
"configure_flow",
"friendly_name",
"user_verification",
"authenticator_attachment",
"resident_key_requirement",

View File

@ -0,0 +1,17 @@
# Generated by Django 4.1.7 on 2023-04-02 14:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_authenticator_webauthn", "0008_alter_webauthndevice_credential_id"),
]
operations = [
migrations.AddField(
model_name="authenticatewebauthnstage",
name="friendly_name",
field=models.TextField(null=True),
),
]

View File

@ -12,7 +12,7 @@ from webauthn.helpers.base64url_to_bytes import base64url_to_bytes
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, Stage
from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
from authentik.lib.models import SerializerModel
@ -66,7 +66,7 @@ class AuthenticatorAttachment(models.TextChoices):
CROSS_PLATFORM = "cross-platform"
class AuthenticateWebAuthnStage(ConfigurableStage, Stage):
class AuthenticateWebAuthnStage(ConfigurableStage, FriendlyNamedStage, Stage):
"""WebAuthn stage"""
user_verification = models.TextField(
@ -100,7 +100,7 @@ class AuthenticateWebAuthnStage(ConfigurableStage, Stage):
def ui_user_settings(self) -> Optional[UserSettingSerializer]:
return UserSettingSerializer(
data={
"title": str(self._meta.verbose_name),
"title": self.friendly_name or str(self._meta.verbose_name),
"component": "ak-user-settings-authenticator-webauthn",
}
)

View File

@ -20345,6 +20345,10 @@ paths:
schema:
type: string
format: uuid
- in: query
name: friendly_name
schema:
type: string
- in: query
name: from_number
schema:
@ -20650,6 +20654,10 @@ paths:
schema:
type: string
format: uuid
- in: query
name: friendly_name
schema:
type: string
- in: query
name: name
schema:
@ -20946,6 +20954,10 @@ paths:
* `6` - 6 digits, widely compatible
* `8` - 8 digits, not compatible with apps like Google Authenticator
- in: query
name: friendly_name
schema:
type: string
- in: query
name: name
schema:
@ -21533,6 +21545,10 @@ paths:
schema:
type: string
format: uuid
- in: query
name: friendly_name
schema:
type: string
- in: query
name: name
schema:
@ -26560,6 +26576,9 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
user_verification:
$ref: '#/components/schemas/UserVerificationEnum'
authenticator_attachment:
@ -26592,6 +26611,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
user_verification:
$ref: '#/components/schemas/UserVerificationEnum'
authenticator_attachment:
@ -26819,6 +26842,9 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
client_id:
type: string
api_hostname:
@ -26875,6 +26901,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
client_id:
type: string
minLength: 1
@ -26973,6 +27003,9 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
provider:
$ref: '#/components/schemas/ProviderEnum'
from_number:
@ -27023,6 +27056,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
provider:
$ref: '#/components/schemas/ProviderEnum'
from_number:
@ -27129,6 +27166,9 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
token_count:
type: integer
maximum: 2147483647
@ -27157,6 +27197,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
token_count:
type: integer
maximum: 2147483647
@ -27240,6 +27284,9 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
digits:
allOf:
- $ref: '#/components/schemas/DigitsEnum'
@ -27270,6 +27317,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
digits:
allOf:
- $ref: '#/components/schemas/DigitsEnum'
@ -35347,6 +35398,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
user_verification:
$ref: '#/components/schemas/UserVerificationEnum'
authenticator_attachment:
@ -35372,6 +35427,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
client_id:
type: string
minLength: 1
@ -35404,6 +35463,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
provider:
$ref: '#/components/schemas/ProviderEnum'
from_number:
@ -35446,6 +35509,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
token_count:
type: integer
maximum: 2147483647
@ -35467,6 +35534,10 @@ components:
nullable: true
description: Flow used by an authenticated user to configure this Stage.
If empty, user will not be able to configure this stage.
friendly_name:
type: string
nullable: true
minLength: 1
digits:
allOf:
- $ref: '#/components/schemas/DigitsEnum'

View File

@ -10,7 +10,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
AuthenticatorDuoStage,
@ -59,11 +58,25 @@ export class AuthenticatorDuoStageForm extends ModelForm<AuthenticatorDuoStage,
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
<input
type="text"
value="${ifDefined(this.instance?.name || "")}"
value="${first(this.instance?.name, "")}"
class="pf-c-form-control"
required
/>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authenticator type name`}
?required=${false}
name="friendlyName"
>
<input
type="text"
value="${first(this.instance?.friendlyName, "")}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${t`Display name of this authenticator, used by users when they enroll an authenticator.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`API Hostname`}
?required=${true}

View File

@ -11,7 +11,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
AuthTypeEnum,
@ -76,7 +75,7 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
>
<input
type="text"
value="${ifDefined(this.instance?.accountSid || "")}"
value="${first(this.instance?.accountSid, "")}"
class="pf-c-form-control"
required
/>
@ -87,7 +86,7 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
<ak-form-element-horizontal label=${t`Twilio Auth Token`} ?required=${true} name="auth">
<input
type="text"
value="${ifDefined(this.instance?.auth || "")}"
value="${first(this.instance?.auth, "")}"
class="pf-c-form-control"
required
/>
@ -131,7 +130,7 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
>
<input
type="text"
value="${ifDefined(this.instance?.accountSid || "")}"
value="${first(this.instance?.accountSid, "")}"
class="pf-c-form-control"
required
/>
@ -142,7 +141,7 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
<ak-form-element-horizontal label=${t`API Auth Username`} ?required=${true} name="auth">
<input
type="text"
value="${ifDefined(this.instance?.auth || "")}"
value="${first(this.instance?.auth, "")}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
@ -156,7 +155,7 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
>
<input
type="text"
value="${ifDefined(this.instance?.authPassword)}"
value="${first(this.instance?.authPassword, "")}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
@ -206,11 +205,25 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
<input
type="text"
value="${ifDefined(this.instance?.name || "")}"
value="${first(this.instance?.name, "")}"
class="pf-c-form-control"
required
/>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authenticator type name`}
?required=${false}
name="friendlyName"
>
<input
type="text"
value="${first(this.instance?.friendlyName, "")}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${t`Display name of this authenticator, used by users when they enroll an authenticator.`}
</p>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form">
@ -247,7 +260,7 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
>
<input
type="text"
value="${ifDefined(this.instance?.fromNumber || "")}"
value="${first(this.instance?.fromNumber, "")}"
class="pf-c-form-control"
required
/>

View File

@ -9,7 +9,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
AuthenticatorStaticStage,
@ -57,11 +56,25 @@ export class AuthenticatorStaticStageForm extends ModelForm<AuthenticatorStaticS
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
<input
type="text"
value="${ifDefined(this.instance?.name || "")}"
value="${first(this.instance?.name, "")}"
class="pf-c-form-control"
required
/>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authenticator type name`}
?required=${false}
name="friendlyName"
>
<input
type="text"
value="${first(this.instance?.friendlyName, "")}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${t`Display name of this authenticator, used by users when they enroll an authenticator.`}
</p>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form">

View File

@ -1,5 +1,6 @@
import { RenderFlowOption } from "@goauthentik/admin/flows/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
@ -9,7 +10,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
AuthenticatorTOTPStage,
@ -58,11 +58,25 @@ export class AuthenticatorTOTPStageForm extends ModelForm<AuthenticatorTOTPStage
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
<input
type="text"
value="${ifDefined(this.instance?.name || "")}"
value="${first(this.instance?.name, "")}"
class="pf-c-form-control"
required
/>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authenticator type name`}
?required=${false}
name="friendlyName"
>
<input
type="text"
value="${first(this.instance?.friendlyName, "")}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${t`Display name of this authenticator, used by users when they enroll an authenticator.`}
</p>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form">

View File

@ -1,5 +1,6 @@
import { RenderFlowOption } from "@goauthentik/admin/flows/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/Radio";
@ -9,7 +10,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
AuthenticateWebAuthnStage,
@ -63,11 +63,25 @@ export class AuthenticateWebAuthnStageForm extends ModelForm<AuthenticateWebAuth
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
<input
type="text"
value="${ifDefined(this.instance?.name || "")}"
value="${first(this.instance?.name, "")}"
class="pf-c-form-control"
required
/>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authenticator type name`}
?required=${false}
name="friendlyName"
>
<input
type="text"
value="${first(this.instance?.friendlyName, "")}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${t`Display name of this authenticator, used by users when they enroll an authenticator.`}
</p>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form">

View File

@ -4,8 +4,7 @@ import "@goauthentik/elements/buttons/ModalButton";
import "@goauthentik/elements/buttons/TokenCopyButton";
import "@goauthentik/elements/forms/DeleteBulkForm";
import "@goauthentik/elements/forms/ModalForm";
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
import "@goauthentik/user/user-settings/mfa/MFADeviceForm";
import { t } from "@lingui/macro";
@ -17,17 +16,8 @@ import { ifDefined } from "lit/directives/if-defined.js";
import { AuthenticatorsApi, Device, UserSetting } from "@goauthentik/api";
export function stageToAuthenticatorName(stage: UserSetting): string {
switch (stage.component) {
case "ak-user-settings-authenticator-duo":
return t`Duo authenticator`;
case "ak-user-settings-authenticator-sms":
return t`SMS authenticator`;
case "ak-user-settings-authenticator-static":
return t`Static authenticator`;
case "ak-user-settings-authenticator-totp":
return t`TOTP authenticator`;
case "ak-user-settings-authenticator-webauthn":
return t`Security key authenticator`;
if (stage.title) {
return stage.title;
}
return `Invalid stage component ${stage.component}`;
}