diff --git a/authentik/flows/challenge.py b/authentik/flows/challenge.py index a28150f63..15cea8b92 100644 --- a/authentik/flows/challenge.py +++ b/authentik/flows/challenge.py @@ -1,14 +1,14 @@ """Challenge helpers""" from dataclasses import asdict, is_dataclass from enum import Enum +from traceback import format_tb from typing import TYPE_CHECKING, Optional, TypedDict from uuid import UUID from django.core.serializers.json import DjangoJSONEncoder from django.db import models from django.http import JsonResponse -from rest_framework.fields import ChoiceField, DictField -from rest_framework.serializers import CharField +from rest_framework.fields import CharField, ChoiceField, DictField from authentik.core.api.utils import PassiveSerializer @@ -90,6 +90,34 @@ class WithUserInfoChallenge(Challenge): pending_user_avatar = CharField() +class FlowErrorChallenge(WithUserInfoChallenge): + """Challenge class when an unhandled error occurs during a stage. Normal users + are shown an error message, superusers are shown a full stacktrace.""" + + component = CharField(default="xak-flow-error") + + request_id = CharField() + + error = CharField(required=False) + traceback = CharField(required=False) + + def __init__(self, *args, **kwargs): + request = kwargs.pop("request", None) + error = kwargs.pop("error", None) + super().__init__(*args, **kwargs) + if not request or not error: + return + self.request_id = request.request_id + from authentik.core.models import USER_ATTRIBUTE_DEBUG + + if request.user and request.user.is_authenticated: + if request.user.is_superuser or request.user.group_attributes(request).get( + USER_ATTRIBUTE_DEBUG, False + ): + self.error = error + self.traceback = "".join(format_tb(self.error.__traceback__)) + + class AccessDeniedChallenge(WithUserInfoChallenge): """Challenge when a flow's active stage calls `stage_invalid()`.""" diff --git a/authentik/flows/templates/flows/error.html b/authentik/flows/templates/flows/error.html deleted file mode 100644 index 1f729ca30..000000000 --- a/authentik/flows/templates/flows/error.html +++ /dev/null @@ -1,22 +0,0 @@ -{% load i18n %} - - - -
-

- {% trans 'Whoops!' %} -

-
-
-

- {% trans 'Something went wrong! Please try again later.' %} -

- {% if debug %} -
{{ tb }}{{ error }}
- {% endif %} -
diff --git a/authentik/flows/views/executor.py b/authentik/flows/views/executor.py index 908af4491..4392e2f0d 100644 --- a/authentik/flows/views/executor.py +++ b/authentik/flows/views/executor.py @@ -1,7 +1,6 @@ """authentik multi-stage authentication engine""" from copy import deepcopy -from traceback import format_tb -from typing import Any, Optional +from typing import Optional from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin @@ -23,12 +22,12 @@ from sentry_sdk.api import set_tag from sentry_sdk.hub import Hub from structlog.stdlib import BoundLogger, get_logger -from authentik.core.models import USER_ATTRIBUTE_DEBUG from authentik.events.models import Event, EventAction, cleanse_dict from authentik.flows.challenge import ( Challenge, ChallengeResponse, ChallengeTypes, + FlowErrorChallenge, HttpChallengeResponse, RedirectChallenge, ShellChallenge, @@ -253,7 +252,9 @@ class FlowExecutorView(APIView): action=EventAction.SYSTEM_EXCEPTION, message=exception_to_string(exc), ).from_http(self.request) - return to_stage_response(self.request, FlowErrorResponse(self.request, exc)) + return to_stage_response( + self.request, HttpChallengeResponse(FlowErrorChallenge(self.request, exc)) + ) @extend_schema( responses={ @@ -440,30 +441,6 @@ class FlowExecutorView(APIView): del self.request.session[key] -class FlowErrorResponse(TemplateResponse): - """Response class when an unhandled error occurs during a stage. Normal users - are shown an error message, superusers are shown a full stacktrace.""" - - error: Exception - - def __init__(self, request: HttpRequest, error: Exception) -> None: - # For some reason pyright complains about keyword argument usage here - # pyright: reportGeneralTypeIssues=false - super().__init__(request=request, template="flows/error.html") - self.error = error - - def resolve_context(self, context: Optional[dict[str, Any]]) -> Optional[dict[str, Any]]: - if not context: - context = {} - context["error"] = self.error - if self._request.user and self._request.user.is_authenticated: - if self._request.user.is_superuser or self._request.user.group_attributes( - self._request - ).get(USER_ATTRIBUTE_DEBUG, False): - context["tb"] = "".join(format_tb(self.error.__traceback__)) - return context - - class CancelView(View): """View which canels the currently active plan""" diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index b3dc84970..ed50bfdd4 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-27 18:46+0000\n" +"POT-Creation-Date: 2022-09-06 16:46+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -31,19 +31,19 @@ msgstr "" msgid "Validation Error" msgstr "" -#: authentik/blueprints/models.py:29 +#: authentik/blueprints/models.py:42 msgid "Managed by authentik" msgstr "" -#: authentik/blueprints/models.py:98 +#: authentik/blueprints/models.py:156 msgid "Blueprint Instance" msgstr "" -#: authentik/blueprints/models.py:99 +#: authentik/blueprints/models.py:157 msgid "Blueprint Instances" msgstr "" -#: authentik/blueprints/v1/exporter.py:53 +#: authentik/blueprints/v1/exporter.py:62 #, python-format msgid "authentik Export - %(date)s" msgstr "" @@ -184,20 +184,17 @@ msgstr "" msgid "Successfully linked %(source)s!" msgstr "" -#: authentik/core/templates/error/generic.html:27 -msgid "Go to home" -msgstr "" - -#: authentik/core/templates/if/admin.html:24 -#: authentik/core/templates/if/admin.html:30 -#: authentik/core/templates/if/flow.html:38 -#: authentik/core/templates/if/flow.html:44 -#: authentik/core/templates/if/user.html:24 -#: authentik/core/templates/if/user.html:30 +#: authentik/core/templates/if/admin.html:26 +#: authentik/core/templates/if/admin.html:32 +#: authentik/core/templates/if/flow.html:40 +#: authentik/core/templates/if/flow.html:46 +#: authentik/core/templates/if/user.html:26 +#: authentik/core/templates/if/user.html:32 msgid "Loading..." msgstr "" #: authentik/core/templates/if/end_session.html:7 +#: authentik/core/templates/if/error.html:7 msgid "End session" msgstr "" @@ -234,6 +231,10 @@ msgid "" " " msgstr "" +#: authentik/core/templates/if/error.html:18 +msgid "Go home" +msgstr "" + #: authentik/core/templates/login/base_full.html:89 msgid "Powered by authentik" msgstr "" @@ -367,7 +368,7 @@ msgstr "" msgid "Stage (%(type)s)" msgstr "" -#: authentik/flows/api/flows.py:375 +#: authentik/flows/api/flows.py:380 #, python-format msgid "Flow not applicable to current user/request: %(messages)s" msgstr "" @@ -434,14 +435,6 @@ msgstr "" msgid "Flow Tokens" msgstr "" -#: authentik/flows/templates/flows/error.html:12 -msgid "Whoops!" -msgstr "" - -#: authentik/flows/templates/flows/error.html:17 -msgid "Something went wrong! Please try again later." -msgstr "" - #: authentik/lib/utils/time.py:27 #, python-format msgid "%(value)s is not in the correct format of 'hours=3;minutes=1'." diff --git a/schema.yml b/schema.yml index 8158744f6..9b61bac28 100644 --- a/schema.yml +++ b/schema.yml @@ -21253,6 +21253,7 @@ components: - $ref: '#/components/schemas/ConsentChallenge' - $ref: '#/components/schemas/DummyChallenge' - $ref: '#/components/schemas/EmailChallenge' + - $ref: '#/components/schemas/FlowErrorChallenge' - $ref: '#/components/schemas/IdentificationChallenge' - $ref: '#/components/schemas/PasswordChallenge' - $ref: '#/components/schemas/PlexAuthenticationChallenge' @@ -21275,6 +21276,7 @@ components: ak-stage-consent: '#/components/schemas/ConsentChallenge' ak-stage-dummy: '#/components/schemas/DummyChallenge' ak-stage-email: '#/components/schemas/EmailChallenge' + xak-flow-error: '#/components/schemas/FlowErrorChallenge' ak-stage-identification: '#/components/schemas/IdentificationChallenge' ak-stage-password: '#/components/schemas/PasswordChallenge' ak-flow-sources-plex: '#/components/schemas/PlexAuthenticationChallenge' @@ -22506,6 +22508,40 @@ components: readOnly: true required: - diagram + FlowErrorChallenge: + type: object + description: |- + Challenge class when an unhandled error occurs during a stage. Normal users + are shown an error message, superusers are shown a full stacktrace. + properties: + type: + $ref: '#/components/schemas/ChallengeChoices' + flow_info: + $ref: '#/components/schemas/ContextualFlowInfo' + component: + type: string + default: xak-flow-error + response_errors: + type: object + additionalProperties: + type: array + items: + $ref: '#/components/schemas/ErrorDetail' + pending_user: + type: string + pending_user_avatar: + type: string + request_id: + type: string + error: + type: string + traceback: + type: string + required: + - pending_user + - pending_user_avatar + - request_id + - type FlowInspection: type: object description: Serializer for inspect endpoint diff --git a/web/src/flows/stages/FlowErrorStage.ts b/web/src/flows/stages/FlowErrorStage.ts new file mode 100644 index 000000000..1da0b3812 --- /dev/null +++ b/web/src/flows/stages/FlowErrorStage.ts @@ -0,0 +1,64 @@ +import "@goauthentik/web/elements/EmptyState"; +import "@goauthentik/web/flows/FormStatic"; +import { BaseStage } from "@goauthentik/web/flows/stages/base"; + +import { t } from "@lingui/macro"; + +import { CSSResult, TemplateResult, html } from "lit"; +import { customElement } from "lit/decorators.js"; +import { ifDefined } from "lit/directives/if-defined.js"; + +import AKGlobal from "@goauthentik/web/authentik.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 { FlowChallengeResponseRequest, FlowErrorChallenge } from "@goauthentik/api"; + +@customElement("ak-stage-flow-error") +export class FlowErrorStage extends BaseStage { + static get styles(): CSSResult[] { + return [PFBase, PFLogin, PFForm, PFFormControl, PFTitle, AKGlobal]; + } + + render(): TemplateResult { + if (!this.challenge) { + return html` `; + } + return html` + + `; + } +} diff --git a/web/src/locales/de.po b/web/src/locales/de.po index c945f5686..24ded9b78 100644 --- a/web/src/locales/de.po +++ b/web/src/locales/de.po @@ -3062,6 +3062,7 @@ msgstr "Server laden" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3700,6 +3701,7 @@ msgstr "Noch nicht synchronisiert." msgid "Not used by any other object." msgstr "Von keinem anderen Objekt verwendet." +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5069,6 +5071,7 @@ msgid "Slug" msgstr "Slug" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "Etwas ist schiefgelaufen. Bitte probiere es später wieder" diff --git a/web/src/locales/en.po b/web/src/locales/en.po index b7a8cf7a9..de51457a6 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -3114,6 +3114,7 @@ msgstr "Load servers" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3755,6 +3756,7 @@ msgstr "Not synced yet." msgid "Not used by any other object." msgstr "Not used by any other object." +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5158,6 +5160,7 @@ msgid "Slug" msgstr "Slug" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "Something went wrong! Please try again later." diff --git a/web/src/locales/es.po b/web/src/locales/es.po index 6411951b6..5b294a7db 100644 --- a/web/src/locales/es.po +++ b/web/src/locales/es.po @@ -3055,6 +3055,7 @@ msgstr "Servidores de carga" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3693,6 +3694,7 @@ msgstr "Aún no se ha sincronizado." msgid "Not used by any other object." msgstr "No lo usa ningún otro objeto." +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5062,6 +5064,7 @@ msgid "Slug" msgstr "babosa" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "¡Algo salió mal! Inténtelo de nuevo más tarde." diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index dea48ea76..bf5b6edd4 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -3086,6 +3086,7 @@ msgstr "Charger les serveurs" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3726,6 +3727,7 @@ msgstr "Pas encore synchronisé." msgid "Not used by any other object." msgstr "Pas utilisé par un autre objet." +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5112,6 +5114,7 @@ msgid "Slug" msgstr "Slug" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "Une erreur s'est produite ! Veuillez réessayer plus tard." diff --git a/web/src/locales/pl.po b/web/src/locales/pl.po index 26985ff73..87d6f9d56 100644 --- a/web/src/locales/pl.po +++ b/web/src/locales/pl.po @@ -3052,6 +3052,7 @@ msgstr "Załaduj serwery" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3690,6 +3691,7 @@ msgstr "Jeszcze nie zsynchronizowano." msgid "Not used by any other object." msgstr "Nie używany przez żaden inny obiekt." +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5059,6 +5061,7 @@ msgid "Slug" msgstr "Ślimak" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "Coś poszło nie tak! Spróbuj ponownie później." diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 663bc1899..92cb21f24 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -3096,6 +3096,7 @@ msgstr "" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3737,6 +3738,7 @@ msgstr "" msgid "Not used by any other object." msgstr "" +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5138,6 +5140,7 @@ msgid "Slug" msgstr "" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "" diff --git a/web/src/locales/tr.po b/web/src/locales/tr.po index 3a9ba060d..f51a13f3d 100644 --- a/web/src/locales/tr.po +++ b/web/src/locales/tr.po @@ -3056,6 +3056,7 @@ msgstr "Sunucuları yükle" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3694,6 +3695,7 @@ msgstr "Henüz senkronize edilmedi." msgid "Not used by any other object." msgstr "Başka bir nesne tarafından kullanılmaz." +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5064,6 +5066,7 @@ msgid "Slug" msgstr "Kısa İsim" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "Bir şeyler ters gitti! Lütfen daha sonra tekrar deneyin." diff --git a/web/src/locales/zh-Hans.po b/web/src/locales/zh-Hans.po index 32a30ced6..0ab33cdb3 100644 --- a/web/src/locales/zh-Hans.po +++ b/web/src/locales/zh-Hans.po @@ -3039,6 +3039,7 @@ msgstr "加载服务器" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3676,6 +3677,7 @@ msgstr "尚未同步。" msgid "Not used by any other object." msgstr "不被任何其他对象使用。" +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5029,6 +5031,7 @@ msgid "Slug" msgstr "Slug" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "发生了某些错误!请稍后重试。" diff --git a/web/src/locales/zh-Hant.po b/web/src/locales/zh-Hant.po index ce7497b36..5408af91b 100644 --- a/web/src/locales/zh-Hant.po +++ b/web/src/locales/zh-Hant.po @@ -3043,6 +3043,7 @@ msgstr "加载服务器" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3680,6 +3681,7 @@ msgstr "尚未同步。" msgid "Not used by any other object." msgstr "不被任何其他对象使用。" +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5036,6 +5038,7 @@ msgid "Slug" msgstr "Slug" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "发生错误,请稍后重试。" diff --git a/web/src/locales/zh_TW.po b/web/src/locales/zh_TW.po index 8cf4db9d5..811ef94ef 100644 --- a/web/src/locales/zh_TW.po +++ b/web/src/locales/zh_TW.po @@ -3043,6 +3043,7 @@ msgstr "加载服务器" #: src/flows/FlowExecutor.ts #: src/flows/FlowExecutor.ts #: src/flows/FlowInspector.ts +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -3680,6 +3681,7 @@ msgstr "尚未同步。" msgid "Not used by any other object." msgstr "不被任何其他对象使用。" +#: src/flows/stages/FlowErrorStage.ts #: src/flows/stages/access_denied/AccessDeniedStage.ts #: src/flows/stages/authenticator_duo/AuthenticatorDuoStage.ts #: src/flows/stages/authenticator_sms/AuthenticatorSMSStage.ts @@ -5036,6 +5038,7 @@ msgid "Slug" msgstr "Slug" #: src/flows/FlowExecutor.ts +#: src/flows/stages/FlowErrorStage.ts #: src/user/user-settings/details/UserSettingsFlowExecutor.ts msgid "Something went wrong! Please try again later." msgstr "发生错误,请稍后重试。"