stages/authenticator_sms: Add SMS Authenticator Stage (#1577)

* stages/authenticator_sms: initial implementation

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

* web/admin: add initial stage UI

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

* web/elements: clear invalid state when old input was invalid but new input is correct

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

* stages/authenticator_sms: add more logic

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

* web/user: add basic SMS settings

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

* stages/authenticator_sms: initial working version

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

* stages/authenticator_sms: add tests

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

* web/flows: optimise totp password manager entry on authenticator_validation stage

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

* web/elements: add grouping support for table

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

* web/admin: allow sms class in authenticator stage

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

* web/admin: add grouping to more pages

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

* stages/authenticator_validate: add SMS support

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

* api: add throttling for flow executor based on session key and pending user

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

* web: fix style issues

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

* ci: add workflow to compile backend translations

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens L
2021-10-11 17:51:49 +02:00
committed by GitHub
parent 7bf587af24
commit aef9d27706
48 changed files with 2425 additions and 93 deletions

View File

@ -219,6 +219,9 @@ export class Form<T> extends LitElement {
element.errorMessage =
errorMessage[camelToSnake(elementName)].join(", ");
element.invalid = true;
} else {
element.errorMessage = "";
element.invalid = false;
}
});
if ("non_field_errors" in errorMessage) {

View File

@ -15,6 +15,7 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { AKResponse } from "../../api/Client";
import { EVENT_REFRESH } from "../../constants";
import { groupBy } from "../../utils";
import "../EmptyState";
import "../chips/Chip";
import "../chips/ChipGroup";
@ -154,6 +155,12 @@ export abstract class Table<T> extends LitElement {
});
}
public groupBy(items: T[]): [string, T[]][] {
return groupBy(items, () => {
return "";
});
}
public fetch(): void {
if (this.isLoading) {
return;
@ -213,7 +220,22 @@ export abstract class Table<T> extends LitElement {
if (this.data.pagination.count === 0) {
return [this.renderEmpty()];
}
return this.data.results.map((item: T) => {
const groupedResults = this.groupBy(this.data.results);
if (groupedResults.length === 1) {
return this.renderRowGroup(groupedResults[0][1]);
}
return groupedResults.map(([group, items]) => {
return html`<thead>
<tr role="row">
<th role="columnheader" scope="row" colspan="200">${group}</th>
</tr>
</thead>
${this.renderRowGroup(items)}`;
});
}
private renderRowGroup(items: T[]): TemplateResult[] {
return items.map((item) => {
return html`<tbody
role="rowgroup"
class="${this.expandedElements.indexOf(item) > -1 ? "pf-m-expanded" : ""}"

View File

@ -36,6 +36,7 @@ import "./access_denied/FlowAccessDenied";
import "./sources/plex/PlexLoginInit";
import "./stages/RedirectStage";
import "./stages/authenticator_duo/AuthenticatorDuoStage";
import "./stages/authenticator_sms/AuthenticatorSMSStage";
import "./stages/authenticator_static/AuthenticatorStaticStage";
import "./stages/authenticator_totp/AuthenticatorTOTPStage";
import "./stages/authenticator_validate/AuthenticatorValidateStage";
@ -311,6 +312,11 @@ export class FlowExecutor extends LitElement implements StageHost {
.host=${this as StageHost}
.challenge=${this.challenge}
></ak-stage-authenticator-validate>`;
case "ak-stage-authenticator-sms":
return html`<ak-stage-authenticator-sms
.host=${this as StageHost}
.challenge=${this.challenge}
></ak-stage-authenticator-sms>`;
case "ak-flow-sources-plex":
return html`<ak-flow-sources-plex
.host=${this as StageHost}

View File

@ -0,0 +1,158 @@
import { t } from "@lingui/macro";
import { CSSResult, html, TemplateResult } from "lit";
import { customElement } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import AKGlobal from "../../../authentik.css";
import PFAlert from "@patternfly/patternfly/components/Alert/alert.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import {
AuthenticatorSMSChallenge,
AuthenticatorSMSChallengeResponseRequest,
} from "@goauthentik/api";
import "../../../elements/EmptyState";
import "../../../elements/forms/FormElement";
import "../../FormStatic";
import { BaseStage } from "../base";
@customElement("ak-stage-authenticator-sms")
export class AuthenticatorSMSStage extends BaseStage<
AuthenticatorSMSChallenge,
AuthenticatorSMSChallengeResponseRequest
> {
static get styles(): CSSResult[] {
return [PFBase, PFAlert, PFLogin, PFForm, PFFormControl, PFTitle, PFButton, AKGlobal];
}
renderPhoneNumber(): TemplateResult {
return html`<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
</header>
<div class="pf-c-login__main-body">
<form
class="pf-c-form"
@submit=${(e: Event) => {
this.submitForm(e);
}}
>
<ak-form-static
class="pf-c-form__group"
userAvatar="${this.challenge.pendingUserAvatar}"
user=${this.challenge.pendingUser}
>
<div slot="link">
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
>${t`Not you?`}</a
>
</div>
</ak-form-static>
<ak-form-element
label="${t`Phone number`}"
?required="${true}"
class="pf-c-form__group"
.errors=${(this.challenge?.responseErrors || {})["phone_number"]}
>
<!-- @ts-ignore -->
<input
type="tel"
name="phoneNumber"
placeholder="${t`Please enter your Phone number.`}"
autofocus=""
autocomplete="tel"
class="pf-c-form-control"
required
/>
</ak-form-element>
${"non_field_errors" in (this.challenge?.responseErrors || {})
? this.renderNonFieldErrors(
this.challenge?.responseErrors?.non_field_errors || [],
)
: html``}
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${t`Continue`}
</button>
</div>
</form>
</div>
<footer class="pf-c-login__main-footer">
<ul class="pf-c-login__main-footer-links"></ul>
</footer>`;
}
renderCode(): TemplateResult {
return html`<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
</header>
<div class="pf-c-login__main-body">
<form
class="pf-c-form"
@submit=${(e: Event) => {
this.submitForm(e);
}}
>
<ak-form-static
class="pf-c-form__group"
userAvatar="${this.challenge.pendingUserAvatar}"
user=${this.challenge.pendingUser}
>
<div slot="link">
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
>${t`Not you?`}</a
>
</div>
</ak-form-static>
<ak-form-element
label="${t`Code`}"
?required="${true}"
class="pf-c-form__group"
.errors=${(this.challenge?.responseErrors || {})["code"]}
>
<!-- @ts-ignore -->
<input
type="text"
name="code"
inputmode="numeric"
pattern="[0-9]*"
placeholder="${t`Please enter your TOTP Code`}"
autofocus=""
autocomplete="one-time-code"
class="pf-c-form-control"
required
/>
</ak-form-element>
${"non_field_errors" in (this.challenge?.responseErrors || {})
? this.renderNonFieldErrors(
this.challenge?.responseErrors?.non_field_errors || [],
)
: html``}
<div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${t`Continue`}
</button>
</div>
</form>
</div>
<footer class="pf-c-login__main-footer">
<ul class="pf-c-login__main-footer-links"></ul>
</footer>`;
}
render(): TemplateResult {
if (!this.challenge) {
return html`<ak-empty-state ?loading="${true}" header=${t`Loading`}> </ak-empty-state>`;
}
if (this.challenge.phoneNumberRequired) {
return this.renderPhoneNumber();
}
return this.renderCode();
}
}

View File

@ -15,21 +15,17 @@ import {
AuthenticatorValidationChallenge,
AuthenticatorValidationChallengeResponseRequest,
DeviceChallenge,
DeviceClassesEnum,
FlowsApi,
} from "@goauthentik/api";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { BaseStage, StageHost } from "../base";
import { PasswordManagerPrefill } from "../identification/IdentificationStage";
import "./AuthenticatorValidateStageCode";
import "./AuthenticatorValidateStageDuo";
import "./AuthenticatorValidateStageWebAuthn";
export enum DeviceClasses {
STATIC = "static",
TOTP = "totp",
WEBAUTHN = "webauthn",
DUO = "duo",
}
@customElement("ak-stage-authenticator-validate")
export class AuthenticatorValidateStage
extends BaseStage<
@ -38,8 +34,29 @@ export class AuthenticatorValidateStage
>
implements StageHost
{
flowSlug = "";
_selectedDeviceChallenge?: DeviceChallenge;
@property({ attribute: false })
selectedDeviceChallenge?: DeviceChallenge;
set selectedDeviceChallenge(value: DeviceChallenge | undefined) {
this._selectedDeviceChallenge = value;
// We don't use this.submit here, as we don't want to advance the flow.
// We just want to notify the backend which challenge has been selected.
new FlowsApi(DEFAULT_CONFIG).flowsExecutorSolve({
flowSlug: this.host.flowSlug,
query: window.location.search.substring(1),
flowChallengeResponseRequest: {
// @ts-ignore
component: this.challenge.component || "",
selectedChallenge: value,
},
});
}
get selectedDeviceChallenge(): DeviceChallenge | undefined {
return this._selectedDeviceChallenge;
}
submit(payload: AuthenticatorValidationChallengeResponseRequest): Promise<void> {
return this.host?.submit(payload) || Promise.resolve();
@ -74,7 +91,7 @@ export class AuthenticatorValidateStage
renderDevicePickerSingle(deviceChallenge: DeviceChallenge): TemplateResult {
switch (deviceChallenge.deviceClass) {
case DeviceClasses.DUO:
case DeviceClassesEnum.Duo:
return html`<i class="fas fa-mobile-alt"></i>
<div class="right">
<p>${t`Duo push-notifications`}</p>
@ -82,37 +99,30 @@ export class AuthenticatorValidateStage
>${t`Receive a push notification on your phone to prove your identity.`}</small
>
</div>`;
case DeviceClasses.WEBAUTHN:
case DeviceClassesEnum.Webauthn:
return html`<i class="fas fa-mobile-alt"></i>
<div class="right">
<p>${t`Authenticator`}</p>
<small>${t`Use a security key to prove your identity.`}</small>
</div>`;
case DeviceClasses.TOTP:
// TOTP is a bit special, assuming that TOTP is allowed from the backend,
// and we have a pre-filled value from the password manager,
// directly set the the TOTP device Challenge as active.
if (PasswordManagerPrefill.totp) {
console.debug(
"authentik/stages/authenticator_validate: found prefill totp code, selecting totp challenge",
);
this.selectedDeviceChallenge = deviceChallenge;
// Delay the update as a re-render isn't triggered from here
setTimeout(() => {
this.requestUpdate();
}, 100);
}
case DeviceClassesEnum.Totp:
return html`<i class="fas fa-clock"></i>
<div class="right">
<p>${t`Traditional authenticator`}</p>
<small>${t`Use a code-based authenticator.`}</small>
</div>`;
case DeviceClasses.STATIC:
case DeviceClassesEnum.Static:
return html`<i class="fas fa-key"></i>
<div class="right">
<p>${t`Recovery keys`}</p>
<small>${t`In case you can't access any other method.`}</small>
</div>`;
case DeviceClassesEnum.Sms:
return html`<i class="fas fa-mobile"></i>
<div class="right">
<p>${t`SMS`}</p>
<small>${t`Tokens sent via SMS.`}</small>
</div>`;
default:
break;
}
@ -142,8 +152,9 @@ export class AuthenticatorValidateStage
return html``;
}
switch (this.selectedDeviceChallenge?.deviceClass) {
case DeviceClasses.STATIC:
case DeviceClasses.TOTP:
case DeviceClassesEnum.Static:
case DeviceClassesEnum.Totp:
case DeviceClassesEnum.Sms:
return html`<ak-stage-authenticator-validate-code
.host=${this}
.challenge=${this.challenge}
@ -151,7 +162,7 @@ export class AuthenticatorValidateStage
.showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1}
>
</ak-stage-authenticator-validate-code>`;
case DeviceClasses.WEBAUTHN:
case DeviceClassesEnum.Webauthn:
return html`<ak-stage-authenticator-validate-webauthn
.host=${this}
.challenge=${this.challenge}
@ -159,7 +170,7 @@ export class AuthenticatorValidateStage
.showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1}
>
</ak-stage-authenticator-validate-webauthn>`;
case DeviceClasses.DUO:
case DeviceClassesEnum.Duo:
return html`<ak-stage-authenticator-validate-duo
.host=${this}
.challenge=${this.challenge}
@ -179,6 +190,18 @@ export class AuthenticatorValidateStage
if (this.challenge?.deviceChallenges.length === 1) {
this.selectedDeviceChallenge = this.challenge.deviceChallenges[0];
}
// TOTP is a bit special, assuming that TOTP is allowed from the backend,
// and we have a pre-filled value from the password manager,
// directly set the the TOTP device Challenge as active.
const totpChallenge = this.challenge.deviceChallenges.find(
(challenge) => challenge.deviceClass === DeviceClassesEnum.Totp,
);
if (PasswordManagerPrefill.totp && totpChallenge) {
console.debug(
"authentik/stages/authenticator_validate: found prefill totp code, selecting totp challenge",
);
this.selectedDeviceChallenge = totpChallenge;
}
return html`<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
${this.selectedDeviceChallenge

View File

@ -16,6 +16,7 @@ import {
AuthenticatorValidationChallenge,
AuthenticatorValidationChallengeResponseRequest,
DeviceChallenge,
DeviceClassesEnum,
} from "@goauthentik/api";
import "../../../elements/EmptyState";
@ -62,6 +63,9 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
>
</div>
</ak-form-static>
${this.deviceChallenge?.deviceClass == DeviceClassesEnum.Sms
? html`<p>${t`A code has been sent to you via SMS.`}</p>`
: html``}
<ak-form-element
label="${t`Code`}"
?required="${true}"
@ -74,7 +78,7 @@ export class AuthenticatorValidateStageWebCode extends BaseStage<
name="code"
inputmode="numeric"
pattern="[0-9]*"
placeholder="${t`Please enter your TOTP Code`}"
placeholder="${t`Please enter your Code`}"
autofocus=""
autocomplete="one-time-code"
class="pf-c-form-control"

View File

@ -5,6 +5,7 @@ import { ErrorDetail } from "@goauthentik/api";
export interface StageHost {
challenge?: unknown;
flowSlug: string;
submit(payload: unknown): Promise<void>;
}

View File

@ -56,6 +56,10 @@ msgstr "6 digits, widely compatible"
msgid "8 digits, not compatible with apps like Google Authenticator"
msgstr "8 digits, not compatible with apps like Google Authenticator"
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "A code has been sent to you via SMS."
msgstr "A code has been sent to you via SMS."
#: src/interfaces/AdminInterface.ts
msgid "A newer version of the frontend is available."
msgstr "A newer version of the frontend is available."
@ -415,7 +419,7 @@ msgstr "Audience"
msgid "Authenticating with Plex..."
msgstr "Authenticating with Plex..."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Authentication"
msgstr "Authentication"
@ -431,7 +435,7 @@ msgstr "Authentication flow"
msgid "Authenticator"
msgstr "Authenticator"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Authorization"
msgstr "Authorization"
@ -805,6 +809,7 @@ msgstr "Client type"
msgid "Close"
msgstr "Close"
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
@ -835,6 +840,7 @@ msgid "Configuration error"
msgstr "Configuration error"
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/password/PasswordStageForm.ts
@ -960,6 +966,8 @@ msgstr "Consumer secret"
msgid "Context"
msgstr "Context"
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
@ -1333,7 +1341,6 @@ msgid "Designates whether this user should be treated as active. Unselect this i
msgstr "Designates whether this user should be treated as active. Unselect this instead of deleting accounts."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/FlowListPage.ts
msgid "Designation"
msgstr "Designation"
@ -1383,6 +1390,10 @@ msgstr "Digits"
msgid "Disable Duo authenticator"
msgstr "Disable Duo authenticator"
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "Disable SMS authenticator"
msgstr "Disable SMS authenticator"
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
msgid "Disable Static Tokens"
msgstr "Disable Static Tokens"
@ -1540,6 +1551,10 @@ msgstr "Embedded outpost is not configured correctly."
msgid "Enable Duo authenticator"
msgstr "Enable Duo authenticator"
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "Enable SMS authenticator"
msgstr "Enable SMS authenticator"
#: src/pages/sources/ldap/LDAPSourceForm.ts
msgid "Enable StartTLS"
msgstr "Enable StartTLS"
@ -1569,7 +1584,7 @@ msgstr "Enabled"
msgid "Enabling this toggle will create a group named after the user, with the user as member."
msgstr "Enabling this toggle will create a group named after the user, with the user as member."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Enrollment"
msgstr "Enrollment"
@ -1870,6 +1885,7 @@ msgid "Flow used by an authenticated user to configure their password. If empty,
msgstr "Flow used by an authenticated user to configure their password. If empty, user will not be able to configure change their password."
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
msgid "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
@ -1954,6 +1970,10 @@ msgstr "From"
msgid "From address"
msgstr "From address"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "From number"
msgstr "From number"
#: src/pages/providers/ldap/LDAPProviderForm.ts
msgid "GID start number"
msgstr "GID start number"
@ -1975,6 +1995,11 @@ msgstr "Generate"
msgid "Generate Certificate-Key Pair"
msgstr "Generate Certificate-Key Pair"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
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"
@ -2260,7 +2285,7 @@ msgstr "Internal host SSL Validation"
msgid "Invalid response action"
msgstr "Invalid response action"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Invalidation"
msgstr "Invalidation"
@ -2415,6 +2440,7 @@ msgstr "Load servers"
#: src/flows/FlowInspector.ts
#: src/flows/access_denied/FlowAccessDenied.ts
#: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
@ -2484,6 +2510,7 @@ msgstr "Loading"
#: src/pages/sources/saml/SAMLSourceForm.ts
#: src/pages/sources/saml/SAMLSourceForm.ts
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -2721,6 +2748,7 @@ msgstr "My applications"
#: src/pages/sources/saml/SAMLSourceViewPage.ts
#: src/pages/stages/StageListPage.ts
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -2883,6 +2911,8 @@ msgid "Not used by any other object."
msgstr "Not used by any other object."
#: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
@ -2931,6 +2961,10 @@ msgstr "Notifications"
msgid "Number"
msgstr "Number"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Number the SMS will be sent from."
msgstr "Number the SMS will be sent from."
#: src/pages/users/UserViewPage.ts
msgid "OAuth Authorization Codes"
msgstr "OAuth Authorization Codes"
@ -3147,6 +3181,10 @@ msgstr "Password: Masked input, password is validated against sources. Policies
msgid "Persistent"
msgstr "Persistent"
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
msgid "Phone number"
msgstr "Phone number"
#: src/pages/stages/prompt/PromptForm.ts
msgid "Placeholder"
msgstr "Placeholder"
@ -3155,8 +3193,16 @@ msgstr "Placeholder"
msgid "Plan history"
msgstr "Plan history"
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr "Please enter your Code"
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
msgid "Please enter your Phone number."
msgstr "Please enter your Phone number."
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
msgid "Please enter your TOTP Code"
msgstr "Please enter your TOTP Code"
@ -3339,6 +3385,7 @@ msgstr "Provide support for protocols like SAML and OAuth to assigned applicatio
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Provider"
msgstr "Provider"
@ -3434,7 +3481,7 @@ msgstr "Re-evaluate policies"
msgid "Receive a push notification on your phone to prove your identity."
msgstr "Receive a push notification on your phone to prove your identity."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/users/UserListPage.ts
msgid "Recovery"
@ -3622,6 +3669,15 @@ msgstr "SHA512"
msgid "SLO URL"
msgstr "SLO URL"
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "SMS"
msgstr "SMS"
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "SMS-based Authenticators"
msgstr "SMS-based Authenticators"
#: src/pages/stages/email/EmailStageForm.ts
msgid "SMTP Host"
msgstr "SMTP Host"
@ -3978,7 +4034,7 @@ msgstr "Stage"
msgid "Stage Bindings"
msgstr "Stage Bindings"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Stage Configuration"
msgstr "Stage Configuration"
@ -4026,6 +4082,10 @@ msgstr "Stage used to configure a duo-based authenticator. This stage should be
msgid "Stage used to configure a static authenticator (i.e. static tokens). This stage should be used for configuration flows."
msgstr "Stage used to configure a static authenticator (i.e. static tokens). This stage should be used for configuration flows."
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Stage used to configure an SMS-based TOTP authenticator."
msgstr "Stage used to configure an SMS-based TOTP authenticator."
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Stage used to validate any authenticator. This stage should be used during authentication or authorization flows."
msgstr "Stage used to validate any authenticator. This stage should be used during authentication or authorization flows."
@ -4035,6 +4095,7 @@ msgid "Stage(s)"
msgstr "Stage(s)"
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4086,12 +4147,14 @@ msgid "Status"
msgstr "Status"
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
msgid "Status: Disabled"
msgstr "Status: Disabled"
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
msgid "Status: Enabled"
@ -4218,6 +4281,7 @@ msgid "Successfully created source."
msgstr "Successfully created source."
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4375,6 +4439,7 @@ msgid "Successfully updated source."
msgstr "Successfully updated source."
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4731,6 +4796,10 @@ msgstr "Tokens and App passwords"
msgid "Tokens are used throughout authentik for Email validation stages, Recovery keys and API access."
msgstr "Tokens are used throughout authentik for Email validation stages, Recovery keys and API access."
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
msgid "Tokens sent via SMS."
msgstr "Tokens sent via SMS."
#: src/pages/admin-overview/charts/FlowStatusChart.ts
msgid "Total flows"
msgstr "Total flows"
@ -4759,6 +4828,18 @@ msgstr "Transient"
msgid "Transports"
msgstr "Transports"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio"
msgstr "Twilio"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio Account SID"
msgstr "Twilio Account SID"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio Auth Token"
msgstr "Twilio Auth Token"
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/ServiceConnectionListPage.ts
@ -4816,7 +4897,7 @@ msgstr "URL used to request the initial token. This URL is only required for OAu
msgid "Unbound policies"
msgstr "Unbound policies"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Unenrollment"
msgstr "Unenrollment"

View File

@ -62,6 +62,10 @@ msgstr "6 chiffres, compatibilité large"
msgid "8 digits, not compatible with apps like Google Authenticator"
msgstr "8 chiffres, incompatible avec certaines applications telles que Google Authenticator"
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "A code has been sent to you via SMS."
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "A newer version of the frontend is available."
msgstr "Une nouvelle version de l'interface est disponible."
@ -419,7 +423,7 @@ msgstr "Audience"
msgid "Authenticating with Plex..."
msgstr "Authentification avec Plex..."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Authentication"
msgstr "Authentification"
@ -435,7 +439,7 @@ msgstr "Flux d'authentification"
msgid "Authenticator"
msgstr "Authentificateur"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Authorization"
msgstr "Authorisation"
@ -806,6 +810,7 @@ msgstr "Type du client"
msgid "Close"
msgstr "Fermer"
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
@ -836,6 +841,7 @@ msgid "Configuration error"
msgstr "Erreur de configuration"
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/password/PasswordStageForm.ts
@ -958,6 +964,8 @@ msgstr "Secret consumer"
msgid "Context"
msgstr "Contexte"
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
@ -1323,7 +1331,6 @@ msgid "Designates whether this user should be treated as active. Unselect this i
msgstr "Indique si cet utilisateur doit être traité comme actif. Désélectionnez cette option au lieu de supprimer les comptes."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/FlowListPage.ts
msgid "Designation"
msgstr "Désignation"
@ -1371,6 +1378,10 @@ msgstr "Chiffres"
msgid "Disable Duo authenticator"
msgstr "Désactiver l'authentificateur Duo"
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "Disable SMS authenticator"
msgstr ""
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
msgid "Disable Static Tokens"
msgstr "Désactiver les jetons statiques"
@ -1526,6 +1537,10 @@ msgstr "L'avant poste intégré n'est pas configuré correctement"
msgid "Enable Duo authenticator"
msgstr "Activer l'authentificateur Duo"
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "Enable SMS authenticator"
msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts
msgid "Enable StartTLS"
msgstr "Activer StartTLS"
@ -1555,7 +1570,7 @@ msgstr "Activé"
msgid "Enabling this toggle will create a group named after the user, with the user as member."
msgstr "Activer cette option va créer un groupe du même nom que l'utilisateur dont il sera membre."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Enrollment"
msgstr "Inscription"
@ -1855,6 +1870,7 @@ msgid "Flow used by an authenticated user to configure their password. If empty,
msgstr "Flux utilisé par un utilisateur authentifié pour configurer son mot de passe. S'il est vide, l'utilisateur ne sera pas en mesure de changer son mot de passe."
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
msgid "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
@ -1939,6 +1955,10 @@ msgstr "De"
msgid "From address"
msgstr "Adresse d'origine"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "From number"
msgstr ""
#: src/pages/providers/ldap/LDAPProviderForm.ts
msgid "GID start number"
msgstr "Numéro de départ du GID"
@ -1960,6 +1980,11 @@ msgstr "Générer"
msgid "Generate Certificate-Key Pair"
msgstr "Générer une paire clé/certificat"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Get this value from https://console.twilio.com"
msgstr ""
#~ msgid "Go to admin interface"
#~ msgstr "Aller à l'interface d'administration"
@ -2243,7 +2268,7 @@ msgstr "Validation SSL de l'hôte interne"
msgid "Invalid response action"
msgstr "Action de réponse invalide"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Invalidation"
msgstr "Invalidation"
@ -2396,6 +2421,7 @@ msgstr "Charger les serveurs"
#: src/flows/FlowInspector.ts
#: src/flows/access_denied/FlowAccessDenied.ts
#: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
@ -2465,6 +2491,7 @@ msgstr "Chargement en cours"
#: src/pages/sources/saml/SAMLSourceForm.ts
#: src/pages/sources/saml/SAMLSourceForm.ts
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -2701,6 +2728,7 @@ msgstr "Mes applications"
#: src/pages/sources/saml/SAMLSourceViewPage.ts
#: src/pages/stages/StageListPage.ts
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -2863,6 +2891,8 @@ msgid "Not used by any other object."
msgstr "Pas utilisé par un autre objet."
#: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
@ -2909,6 +2939,10 @@ msgstr "Notifications"
msgid "Number"
msgstr "Nombre"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Number the SMS will be sent from."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "OAuth Authorization Codes"
msgstr "Code d'autorisation OAuth"
@ -3121,6 +3155,10 @@ msgstr "Mot de passe : Entrée masquée, le mot de passe est vérifié par les s
msgid "Persistent"
msgstr "Persistant"
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
msgid "Phone number"
msgstr ""
#: src/pages/stages/prompt/PromptForm.ts
msgid "Placeholder"
msgstr "Par défaut"
@ -3129,8 +3167,16 @@ msgstr "Par défaut"
msgid "Plan history"
msgstr "Historique du plan"
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr ""
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
msgid "Please enter your Phone number."
msgstr ""
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
msgid "Please enter your TOTP Code"
msgstr "Veuillez saisirvotre code TOTP"
@ -3310,6 +3356,7 @@ msgstr "Assure la prise en charge de protocoles tels que SAML et OAuth aux appli
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Provider"
msgstr "Fournisseur"
@ -3404,7 +3451,7 @@ msgstr "Ré-évaluer les politiques"
msgid "Receive a push notification on your phone to prove your identity."
msgstr "Recevez une notification push sur votre téléphone pour prouver votre identité."
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/users/UserListPage.ts
msgid "Recovery"
@ -3590,6 +3637,15 @@ msgstr "SHA512"
msgid "SLO URL"
msgstr "URL SLO"
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "SMS"
msgstr ""
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "SMS-based Authenticators"
msgstr ""
#: src/pages/stages/email/EmailStageForm.ts
msgid "SMTP Host"
msgstr "Hôte SMTP"
@ -3937,7 +3993,7 @@ msgstr "Étape"
msgid "Stage Bindings"
msgstr "Liaisons de l'étape"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Stage Configuration"
msgstr "Configuration de l'étape"
@ -3984,6 +4040,10 @@ msgstr "Étape de configuration d'un authentificateur Duo. Cette étape devrait
msgid "Stage used to configure a static authenticator (i.e. static tokens). This stage should be used for configuration flows."
msgstr "Étape de configuration d'un authentificateur statique (jetons statiques). Cette étape devrait être utilisée en flux de configuration."
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Stage used to configure an SMS-based TOTP authenticator."
msgstr ""
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Stage used to validate any authenticator. This stage should be used during authentication or authorization flows."
msgstr "Étape utilisée pour valider tout type d'authentificateur. Cette étape devrait être utilisée en flux d'authentification ou d'autorisation."
@ -3993,6 +4053,7 @@ msgid "Stage(s)"
msgstr "Étape(s)"
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4044,12 +4105,14 @@ msgid "Status"
msgstr "Statut"
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
msgid "Status: Disabled"
msgstr "Statut : Désactivé"
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
msgid "Status: Enabled"
@ -4174,6 +4237,7 @@ msgid "Successfully created source."
msgstr "Source créée avec succès"
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4329,6 +4393,7 @@ msgid "Successfully updated source."
msgstr "Source mise à jour avec succès"
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4673,6 +4738,10 @@ msgstr "Jetons et mots de passe d'application"
msgid "Tokens are used throughout authentik for Email validation stages, Recovery keys and API access."
msgstr "Les jetons sont utilisés dans authentik pour les étapes de validation des courriels, les clés de récupération et l'accès aux API."
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
msgid "Tokens sent via SMS."
msgstr ""
#: src/pages/admin-overview/charts/FlowStatusChart.ts
msgid "Total flows"
msgstr "Flux totaux"
@ -4701,6 +4770,18 @@ msgstr "Transitoire"
msgid "Transports"
msgstr "Transports"
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio Account SID"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio Auth Token"
msgstr ""
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/ServiceConnectionListPage.ts
@ -4758,7 +4839,7 @@ msgstr "URL utilisée pour demander le jeton initial. Cette URL est uniquement r
msgid "Unbound policies"
msgstr "Politiques non liées"
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Unenrollment"
msgstr "Désinscription"

View File

@ -56,6 +56,10 @@ msgstr ""
msgid "8 digits, not compatible with apps like Google Authenticator"
msgstr ""
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "A code has been sent to you via SMS."
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "A newer version of the frontend is available."
msgstr ""
@ -411,7 +415,7 @@ msgstr ""
msgid "Authenticating with Plex..."
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Authentication"
msgstr ""
@ -427,7 +431,7 @@ msgstr ""
msgid "Authenticator"
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Authorization"
msgstr ""
@ -799,6 +803,7 @@ msgstr ""
msgid "Close"
msgstr ""
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Code"
@ -829,6 +834,7 @@ msgid "Configuration error"
msgstr ""
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/password/PasswordStageForm.ts
@ -954,6 +960,8 @@ msgstr ""
msgid "Context"
msgstr ""
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
@ -1325,7 +1333,6 @@ msgid "Designates whether this user should be treated as active. Unselect this i
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/FlowListPage.ts
msgid "Designation"
msgstr ""
@ -1375,6 +1382,10 @@ msgstr ""
msgid "Disable Duo authenticator"
msgstr ""
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "Disable SMS authenticator"
msgstr ""
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
msgid "Disable Static Tokens"
msgstr ""
@ -1532,6 +1543,10 @@ msgstr ""
msgid "Enable Duo authenticator"
msgstr ""
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "Enable SMS authenticator"
msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts
msgid "Enable StartTLS"
msgstr ""
@ -1561,7 +1576,7 @@ msgstr ""
msgid "Enabling this toggle will create a group named after the user, with the user as member."
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Enrollment"
msgstr ""
@ -1862,6 +1877,7 @@ msgid "Flow used by an authenticated user to configure their password. If empty,
msgstr ""
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
msgid "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
@ -1946,6 +1962,10 @@ msgstr ""
msgid "From address"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "From number"
msgstr ""
#: src/pages/providers/ldap/LDAPProviderForm.ts
msgid "GID start number"
msgstr ""
@ -1967,6 +1987,11 @@ msgstr ""
msgid "Generate Certificate-Key Pair"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Get this value from https://console.twilio.com"
msgstr ""
#:
#~ msgid "Go to admin interface"
#~ msgstr ""
@ -2252,7 +2277,7 @@ msgstr ""
msgid "Invalid response action"
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Invalidation"
msgstr ""
@ -2407,6 +2432,7 @@ msgstr ""
#: src/flows/FlowInspector.ts
#: src/flows/access_denied/FlowAccessDenied.ts
#: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
@ -2476,6 +2502,7 @@ msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts
#: src/pages/sources/saml/SAMLSourceForm.ts
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -2713,6 +2740,7 @@ msgstr ""
#: src/pages/sources/saml/SAMLSourceViewPage.ts
#: src/pages/stages/StageListPage.ts
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -2875,6 +2903,8 @@ msgid "Not used by any other object."
msgstr ""
#: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
@ -2923,6 +2953,10 @@ msgstr ""
msgid "Number"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Number the SMS will be sent from."
msgstr ""
#: src/pages/users/UserViewPage.ts
msgid "OAuth Authorization Codes"
msgstr ""
@ -3139,6 +3173,10 @@ msgstr ""
msgid "Persistent"
msgstr ""
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
msgid "Phone number"
msgstr ""
#: src/pages/stages/prompt/PromptForm.ts
msgid "Placeholder"
msgstr ""
@ -3147,8 +3185,16 @@ msgstr ""
msgid "Plan history"
msgstr ""
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStageCode.ts
msgid "Please enter your Code"
msgstr ""
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
msgid "Please enter your Phone number."
msgstr ""
#: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts
msgid "Please enter your TOTP Code"
msgstr ""
@ -3331,6 +3377,7 @@ msgstr ""
#: src/pages/applications/ApplicationForm.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/applications/ApplicationViewPage.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Provider"
msgstr ""
@ -3426,7 +3473,7 @@ msgstr ""
msgid "Receive a push notification on your phone to prove your identity."
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/users/UserListPage.ts
msgid "Recovery"
@ -3614,6 +3661,15 @@ msgstr ""
msgid "SLO URL"
msgstr ""
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
msgid "SMS"
msgstr ""
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "SMS-based Authenticators"
msgstr ""
#: src/pages/stages/email/EmailStageForm.ts
msgid "SMTP Host"
msgstr ""
@ -3970,7 +4026,7 @@ msgstr ""
msgid "Stage Bindings"
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Stage Configuration"
msgstr ""
@ -4018,6 +4074,10 @@ msgstr ""
msgid "Stage used to configure a static authenticator (i.e. static tokens). This stage should be used for configuration flows."
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Stage used to configure an SMS-based TOTP authenticator."
msgstr ""
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
msgid "Stage used to validate any authenticator. This stage should be used during authentication or authorization flows."
msgstr ""
@ -4027,6 +4087,7 @@ msgid "Stage(s)"
msgstr ""
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4078,12 +4139,14 @@ msgid "Status"
msgstr ""
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
msgid "Status: Disabled"
msgstr ""
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorSMS.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
msgid "Status: Enabled"
@ -4210,6 +4273,7 @@ msgid "Successfully created source."
msgstr ""
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4367,6 +4431,7 @@ msgid "Successfully updated source."
msgstr ""
#: src/pages/stages/authenticator_duo/AuthenticatorDuoStageForm.ts
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
@ -4716,6 +4781,10 @@ msgstr ""
msgid "Tokens are used throughout authentik for Email validation stages, Recovery keys and API access."
msgstr ""
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
msgid "Tokens sent via SMS."
msgstr ""
#: src/pages/admin-overview/charts/FlowStatusChart.ts
msgid "Total flows"
msgstr ""
@ -4744,6 +4813,18 @@ msgstr ""
msgid "Transports"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio Account SID"
msgstr ""
#: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts
msgid "Twilio Auth Token"
msgstr ""
#: src/pages/flows/BoundStagesList.ts
#: src/pages/outposts/OutpostForm.ts
#: src/pages/outposts/ServiceConnectionListPage.ts
@ -4801,7 +4882,7 @@ msgstr ""
msgid "Unbound policies"
msgstr ""
#: src/pages/flows/FlowForm.ts
#: src/pages/flows/utils.ts
msgid "Unenrollment"
msgstr ""

View File

@ -17,6 +17,7 @@ import { config, DEFAULT_CONFIG } from "../../api/Config";
import "../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../elements/forms/ModelForm";
import { first } from "../../utils";
import { DesignationToLabel } from "./utils";
@customElement("ak-flow-form")
export class FlowForm extends ModelForm<Flow, string> {
@ -80,43 +81,43 @@ export class FlowForm extends ModelForm<Flow, string> {
value=${FlowDesignationEnum.Authentication}
?selected=${this.instance?.designation === FlowDesignationEnum.Authentication}
>
${t`Authentication`}
${DesignationToLabel(FlowDesignationEnum.Authentication)}
</option>
<option
value=${FlowDesignationEnum.Authorization}
?selected=${this.instance?.designation === FlowDesignationEnum.Authorization}
>
${t`Authorization`}
${DesignationToLabel(FlowDesignationEnum.Authorization)}
</option>
<option
value=${FlowDesignationEnum.Enrollment}
?selected=${this.instance?.designation === FlowDesignationEnum.Enrollment}
>
${t`Enrollment`}
${DesignationToLabel(FlowDesignationEnum.Enrollment)}
</option>
<option
value=${FlowDesignationEnum.Invalidation}
?selected=${this.instance?.designation === FlowDesignationEnum.Invalidation}
>
${t`Invalidation`}
${DesignationToLabel(FlowDesignationEnum.Invalidation)}
</option>
<option
value=${FlowDesignationEnum.Recovery}
?selected=${this.instance?.designation === FlowDesignationEnum.Recovery}
>
${t`Recovery`}
${DesignationToLabel(FlowDesignationEnum.Recovery)}
</option>
<option
value=${FlowDesignationEnum.StageConfiguration}
?selected=${this.instance?.designation === FlowDesignationEnum.StageConfiguration}
>
${t`Stage Configuration`}
${DesignationToLabel(FlowDesignationEnum.StageConfiguration)}
</option>
<option
value=${FlowDesignationEnum.Unenrollment}
?selected=${this.instance?.designation === FlowDesignationEnum.Unenrollment}
>
${t`Unenrollment`}
${DesignationToLabel(FlowDesignationEnum.Unenrollment)}
</option>
`;
}

View File

@ -14,8 +14,10 @@ import "../../elements/forms/DeleteBulkForm";
import "../../elements/forms/ModalForm";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import { groupBy } from "../../utils";
import "./FlowForm";
import "./FlowImportForm";
import { DesignationToLabel } from "./utils";
@customElement("ak-flow-list")
export class FlowListPage extends TablePage<Flow> {
@ -46,11 +48,19 @@ export class FlowListPage extends TablePage<Flow> {
});
}
groupBy(items: Flow[]): [string, Flow[]][] {
return groupBy(items, (flow) => {
if (!flow.designation) {
return "";
}
return DesignationToLabel(flow.designation);
});
}
columns(): TableColumn[] {
return [
new TableColumn(t`Identifier`, "slug"),
new TableColumn(t`Name`, "name"),
new TableColumn(t`Designation`, "designation"),
new TableColumn(t`Stages`),
new TableColumn(t`Policies`),
new TableColumn(t`Actions`),
@ -85,7 +95,6 @@ export class FlowListPage extends TablePage<Flow> {
<code>${item.slug}</code>
</a>`,
html`${item.name}`,
html`${item.designation}`,
html`${Array.from(item.stages || []).length}`,
html`${Array.from(item.policies || []).length}`,
html` <ak-forms-modal>

View File

@ -0,0 +1,22 @@
import { t } from "@lingui/macro";
import { FlowDesignationEnum } from "@goauthentik/api";
export function DesignationToLabel(designation: FlowDesignationEnum): string {
switch (designation) {
case FlowDesignationEnum.Authentication:
return t`Authentication`;
case FlowDesignationEnum.Authorization:
return t`Authorization`;
case FlowDesignationEnum.Enrollment:
return t`Enrollment`;
case FlowDesignationEnum.Invalidation:
return t`Invalidation`;
case FlowDesignationEnum.Recovery:
return t`Recovery`;
case FlowDesignationEnum.StageConfiguration:
return t`Stage Configuration`;
case FlowDesignationEnum.Unenrollment:
return t`Unenrollment`;
}
}

View File

@ -18,6 +18,7 @@ import "../../elements/forms/ModalForm";
import "../../elements/forms/ProxyForm";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import { groupBy } from "../../utils";
import "./PolicyTestForm";
import "./dummy/DummyPolicyForm";
import "./event_matcher/EventMatcherPolicyForm";
@ -64,6 +65,10 @@ export class PolicyListPage extends TablePage<Policy> {
];
}
groupBy(items: Policy[]): [string, Policy[]][] {
return groupBy(items, (policy) => policy.verboseNamePlural);
}
row(item: Policy): TemplateResult[] {
return [
html`<div>

View File

@ -17,6 +17,7 @@ import "../../elements/forms/ModalForm";
import "../../elements/forms/ProxyForm";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import { groupBy } from "../../utils";
import "./PropertyMappingLDAPForm";
import "./PropertyMappingNotification";
import "./PropertyMappingSAMLForm";
@ -56,6 +57,10 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
});
}
groupBy(items: PropertyMapping[]): [string, PropertyMapping[]][] {
return groupBy(items, (mapping) => mapping.verboseNamePlural);
}
columns(): TableColumn[] {
return [
new TableColumn(t`Name`, "name"),

View File

@ -17,7 +17,9 @@ import "../../elements/forms/ModalForm";
import "../../elements/forms/ProxyForm";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import { groupBy } from "../../utils";
import "./authenticator_duo/AuthenticatorDuoStageForm.ts";
import "./authenticator_sms/AuthenticatorSMSStageForm.ts";
import "./authenticator_static/AuthenticatorStaticStageForm.ts";
import "./authenticator_totp/AuthenticatorTOTPStageForm.ts";
import "./authenticator_validate/AuthenticatorValidateStageForm.ts";
@ -65,6 +67,10 @@ export class StageListPage extends TablePage<Stage> {
});
}
groupBy(items: Stage[]): [string, Stage[]][] {
return groupBy(items, (stage) => stage.verboseNamePlural);
}
columns(): TableColumn[] {
return [
new TableColumn(t`Name`, "name"),

View File

@ -0,0 +1,169 @@
import { t } from "@lingui/macro";
import { html, TemplateResult } from "lit";
import { customElement } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { until } from "lit/directives/until";
import {
FlowsApi,
StagesApi,
FlowsInstancesListDesignationEnum,
AuthenticatorSMSStage,
ProviderEnum,
} from "@goauthentik/api";
import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-authenticator-sms-form")
export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage, string> {
loadInstance(pk: string): Promise<AuthenticatorSMSStage> {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorSmsRetrieve({
stageUuid: pk,
});
}
getSuccessMessage(): string {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
}
}
send = (data: AuthenticatorSMSStage): Promise<AuthenticatorSMSStage> => {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorSmsUpdate({
stageUuid: this.instance.pk || "",
authenticatorSMSStageRequest: data,
});
} else {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorSmsCreate({
authenticatorSMSStageRequest: data,
});
}
};
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<div class="form-help-text">
${t`Stage used to configure an SMS-based TOTP authenticator.`}
</div>
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
<input
type="text"
value="${ifDefined(this.instance?.name || "")}"
class="pf-c-form-control"
required
/>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal
label=${t`Provider`}
?required=${true}
name="provider"
>
<select name="users" class="pf-c-form-control">
<option
value="${ProviderEnum.Twilio}"
?selected=${this.instance?.provider === ProviderEnum.Twilio}
>
${t`Twilio`}
</option>
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`From number`}
?required=${true}
name="fromNumber"
>
<input
type="text"
value="${ifDefined(this.instance?.fromNumber || "")}"
class="pf-c-form-control"
required
/>
<p class="pf-c-form__helper-text">
${t`Number the SMS will be sent from.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Twilio Account SID`}
?required=${true}
name="twilioAccountSid"
>
<input
type="text"
value="${ifDefined(this.instance?.twilioAccountSid || "")}"
class="pf-c-form-control"
required
/>
<p class="pf-c-form__helper-text">
${t`Get this value from https://console.twilio.com`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Twilio Auth Token`}
?required=${true}
name="twilioAuth"
>
<input
type="text"
value="${ifDefined(this.instance?.twilioAuth || "")}"
class="pf-c-form-control"
required
/>
<p class="pf-c-form__helper-text">
${t`Get this value from https://console.twilio.com`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Configuration flow`} name="configureFlow">
<select class="pf-c-form-control">
<option
value=""
?selected=${this.instance?.configureFlow === undefined}
>
---------
</option>
${until(
new FlowsApi(DEFAULT_CONFIG)
.flowsInstancesList({
ordering: "pk",
designation:
FlowsInstancesListDesignationEnum.StageConfiguration,
})
.then((flows) => {
return flows.results.map((flow) => {
let selected = this.instance?.configureFlow === flow.pk;
if (
!this.instance?.pk &&
!this.instance?.configureFlow &&
flow.slug === "default-otp-time-configure"
) {
selected = true;
}
return html`<option
value=${ifDefined(flow.pk)}
?selected=${selected}
>
${flow.name} (${flow.slug})
</option>`;
});
}),
html`<option>${t`Loading...`}</option>`,
)}
</select>
<p class="pf-c-form__helper-text">
${t`Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage.`}
</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
</form>`;
}
}

View File

@ -10,6 +10,7 @@ import {
AuthenticatorTOTPStage,
StagesApi,
FlowsInstancesListDesignationEnum,
DigitsEnum,
} from "@goauthentik/api";
import { DEFAULT_CONFIG } from "../../../api/Config";
@ -64,10 +65,16 @@ export class AuthenticatorTOTPStageForm extends ModelForm<AuthenticatorTOTPStage
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal label=${t`Digits`} ?required=${true} name="digits">
<select name="users" class="pf-c-form-control">
<option value="6" ?selected=${this.instance?.digits === 6}>
<option
value="${DigitsEnum.NUMBER_6}"
?selected=${this.instance?.digits === DigitsEnum.NUMBER_6}
>
${t`6 digits, widely compatible`}
</option>
<option value="8" ?selected=${this.instance?.digits === 8}>
<option
value="${DigitsEnum.NUMBER_8}"
?selected=${this.instance?.digits === DigitsEnum.NUMBER_8}
>
${t`8 digits, not compatible with apps like Google Authenticator`}
</option>
</select>

View File

@ -109,6 +109,12 @@ export class AuthenticatorValidateStageForm extends ModelForm<AuthenticatorValid
>
${t`Duo Authenticators`}
</option>
<option
value=${DeviceClassesEnum.Sms}
?selected=${this.isDeviceClassSelected(DeviceClassesEnum.Sms)}
>
${t`SMS-based Authenticators`}
</option>
</select>
<p class="pf-c-form__helper-text">
${t`Device classes which can be used to authenticate.`}

View File

@ -12,6 +12,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
import { EVENT_REFRESH } from "../../../constants";
import "../../../elements/EmptyState";
import "./UserSettingsAuthenticatorDuo";
import "./UserSettingsAuthenticatorSMS";
import "./UserSettingsAuthenticatorStatic";
import "./UserSettingsAuthenticatorTOTP";
import "./UserSettingsAuthenticatorWebAuthn";
@ -69,6 +70,12 @@ export class UserStageSettingsPage extends LitElement {
.configureUrl=${stage.configureUrl}
>
</ak-user-settings-authenticator-duo>`;
case "ak-user-settings-authenticator-sms":
return html`<ak-user-settings-authenticator-sms
objectId=${stage.objectUid}
.configureUrl=${stage.configureUrl}
>
</ak-user-settings-authenticator-sms>`;
default:
return html`<p>${t`Error: unsupported stage settings: ${stage.component}`}</p>`;
}

View File

@ -0,0 +1,83 @@
import { t } from "@lingui/macro";
import { html, TemplateResult } from "lit";
import { customElement } from "lit/decorators";
import { until } from "lit/directives/until";
import { AuthenticatorsApi } from "@goauthentik/api";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { EVENT_REFRESH } from "../../../constants";
import { BaseUserSettings } from "../BaseUserSettings";
@customElement("ak-user-settings-authenticator-sms")
export class UserSettingsAuthenticatorSMS extends BaseUserSettings {
renderEnabled(): TemplateResult {
return html`<div class="pf-c-card__body">
<p>
${t`Status: Enabled`}
<i class="pf-icon pf-icon-ok"></i>
</p>
</div>
<div class="pf-c-card__footer">
<button
class="pf-c-button pf-m-danger"
@click=${() => {
return new AuthenticatorsApi(DEFAULT_CONFIG)
.authenticatorsSmsList({})
.then((devices) => {
if (devices.results.length < 1) {
return;
}
// TODO: Handle multiple devices, currently we assume only one TOTP Device
return new AuthenticatorsApi(DEFAULT_CONFIG)
.authenticatorsSmsDestroy({
id: devices.results[0].pk || 0,
})
.then(() => {
this.dispatchEvent(
new CustomEvent(EVENT_REFRESH, {
bubbles: true,
composed: true,
}),
);
});
});
}}
>
${t`Disable SMS authenticator`}
</button>
</div>`;
}
renderDisabled(): TemplateResult {
return html` <div class="pf-c-card__body">
<p>
${t`Status: Disabled`}
<i class="pf-icon pf-icon-error-circle-o"></i>
</p>
</div>
<div class="pf-c-card__footer">
${this.configureUrl
? html`<a
href="${this.configureUrl}?next=/${encodeURIComponent("#/settings")}"
class="pf-c-button pf-m-primary"
>${t`Enable SMS authenticator`}
</a>`
: html``}
</div>`;
}
render(): TemplateResult {
return html`<div class="pf-c-card">
<div class="pf-c-card__title">${t`SMS`}</div>
${until(
new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsSmsList({}).then((devices) => {
return devices.results.length > 0
? this.renderEnabled()
: this.renderDisabled();
}),
)}
</div>`;
}
}