mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-02 13:03:08 +00:00
Closes #10828 # Which Problems Are Solved The IDP callback flow was calling retrieveIDPIntent() twice, causing single-use token failures with error: "Intent Token is invalid". This occurred due to Next.js 15's dynamicIO feature triggering double renders # How the Problems Are Solved Completely refactored the IDP callback architecture to ensure single-use tokens are consumed exactly once: - Centralized Business Logic: Moved all IDP callback logic into a single server action (processIDPCallback) that: - Consumes the token once - Handles all 6 business scenarios (login, linking, auto-linking, auto-creation, manual registration, account not found) - Integrates session creation in the same action - Returns `{ redirect?: string; error?: string }` for client-side navigation - Client Component Invocation: Created `IdpProcessHandler` client component that: - Calls the server action from browser context (enables cookie modification) - Prevents double execution with useRef - Handles loading states and error display - Clean Architecture: - Removed 403-line success page with complex logic - Removed component files from `/components/idps/pages/` folder - Moved all UI directly into server pages - Created dedicated result pages with minimal params # Additional Changes - Added translations to all 8 supported languages --------- Co-authored-by: Ramon <mail@conblem.me>
441 lines
24 KiB
JSON
441 lines
24 KiB
JSON
{
|
||
"common": {
|
||
"back": "Назад",
|
||
"title": "Войти с Zitadel"
|
||
},
|
||
"accounts": {
|
||
"title": "Аккаунты",
|
||
"description": "Выберите аккаунт, который хотите использовать.",
|
||
"addAnother": "Добавить другой аккаунт",
|
||
"noResults": "Аккаунты не найдены",
|
||
"verified": "проверенный",
|
||
"expired": "истёк"
|
||
},
|
||
"logout": {
|
||
"title": "Выход",
|
||
"description": "Выберите аккаунт, который хотите удалить",
|
||
"noResults": "Аккаунты не найдены",
|
||
"clear": "Удалить сессию",
|
||
"verifiedAt": "Последняя активность: {time}",
|
||
"success": {
|
||
"title": "Выход выполнен успешно",
|
||
"description": "Вы успешно вышли из системы."
|
||
}
|
||
},
|
||
"loginname": {
|
||
"title": "С возвращением!",
|
||
"description": "Введите свои данные для входа.",
|
||
"register": "Зарегистрировать нового пользователя",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"loginname": "Логин",
|
||
"username": "Имя пользователя",
|
||
"usernameOrPhoneNumber": "Имя пользователя или номер телефона",
|
||
"usernameOrEmail": "Имя пользователя или электронная почта"
|
||
},
|
||
"required": {
|
||
"loginName": "Это поле обязательно для заполнения"
|
||
},
|
||
"errors": {
|
||
"internalError": "Произошла внутренняя ошибка",
|
||
"couldNotGetLoginSettings": "Не удалось получить настройки входа",
|
||
"couldNotSearchUsers": "Не удалось выполнить поиск пользователей",
|
||
"couldNotGetDomain": "Не удалось получить домен",
|
||
"couldNotGetHost": "Не удалось получить хост",
|
||
"couldNotStartIDPFlow": "Не удалось запустить поток IDP",
|
||
"moreThanOneUserFound": "Найдено более одного пользователя. Укажите уникальный идентификатор.",
|
||
"userNotFound": "Пользователь не найден в системе",
|
||
"couldNotCreateSession": "Не удалось создать сессию для пользователя",
|
||
"initialUserNotSupported": "Начальный пользователь не поддерживается",
|
||
"usernamePasswordNotAllowed": "Использование имени пользователя и пароля не разрешено! Обратитесь к администратору за дополнительной информацией.",
|
||
"passkeysNotAllowed": "Ключи доступа не разрешены! Обратитесь к администратору за дополнительной информацией.",
|
||
"couldNotFindIdentityProvider": "Не удалось найти поставщика удостоверений.",
|
||
"userNotActive": "Пользователь неактивен. Обратитесь к администратору за дополнительной информацией."
|
||
}
|
||
},
|
||
"zitadel": {
|
||
"errors": {
|
||
"errorOccured": "Произошла ошибка",
|
||
"multipleUsersFound": "Найдено несколько пользователей",
|
||
"userNotFound": "Пользователь не найден в системе"
|
||
}
|
||
},
|
||
"password": {
|
||
"verify": {
|
||
"title": "Пароль",
|
||
"description": "Введите ваш пароль.",
|
||
"resetPassword": "Сбросить пароль",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"password": "Пароль"
|
||
},
|
||
"required": {
|
||
"password": "Это поле обязательно для заполнения"
|
||
},
|
||
"errors": {
|
||
"couldNotVerifyPassword": "Не удалось проверить пароль",
|
||
"couldNotResetPassword": "Не удалось сбросить пароль"
|
||
},
|
||
"info": {
|
||
"passwordResetSent": "Пароль был сброшен. Пожалуйста, проверьте свою электронную почту"
|
||
}
|
||
},
|
||
"set": {
|
||
"title": "Установить пароль",
|
||
"description": "Установите пароль для вашего аккаунта",
|
||
"codeSent": "Код отправлен на ваш адрес электронной почты.",
|
||
"noCodeReceived": "Не получили код?",
|
||
"resend": "Отправить код повторно",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"code": "Код",
|
||
"newPassword": "Новый пароль",
|
||
"confirmPassword": "Подтвердите пароль"
|
||
},
|
||
"required": {
|
||
"code": "Это поле обязательно для заполнения",
|
||
"newPassword": "Вы должны указать пароль!",
|
||
"confirmPassword": "Это поле обязательно для заполнения"
|
||
},
|
||
"errors": {
|
||
"couldNotSetPassword": "Не удалось установить пароль",
|
||
"couldNotResetPassword": "Не удалось сбросить пароль",
|
||
"couldNotVerifyPassword": "Не удалось проверить пароль"
|
||
}
|
||
},
|
||
"change": {
|
||
"title": "Изменить пароль",
|
||
"description": "Установите пароль для вашего аккаунта",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"newPassword": "Новый пароль",
|
||
"confirmPassword": "Подтвердите пароль"
|
||
},
|
||
"required": {
|
||
"newPassword": "Вы должны указать новый пароль!",
|
||
"confirmPassword": "Это поле обязательно для заполнения"
|
||
},
|
||
"errors": {
|
||
"couldNotChangePassword": "Не удалось изменить пароль",
|
||
"couldNotVerifyPassword": "Не удалось проверить пароль",
|
||
"unknownError": "Неизвестная ошибка"
|
||
}
|
||
},
|
||
"complexity": {
|
||
"length": "Минимум {minLength} символов.",
|
||
"hasSymbol": "Должен содержать специальный символ.",
|
||
"hasNumber": "Должен содержать цифру.",
|
||
"hasUppercase": "Должен содержать заглавную букву.",
|
||
"hasLowercase": "Должен содержать строчную букву.",
|
||
"equals": "Пароли должны совпадать.",
|
||
"matches": "Совпадает",
|
||
"doesNotMatch": "Не совпадает"
|
||
},
|
||
"errors": {
|
||
"noHostFound": "Хост не найден",
|
||
"couldNotSendResetLink": "Не удалось отправить ссылку для сброса пароля",
|
||
"couldNotCreateSessionForUser": "Не удалось создать сессию для пользователя",
|
||
"couldNotVerifyPassword": "Не удалось проверить пароль",
|
||
"failedToAuthenticate": "Не удалось пройти аутентификацию. У вас было {failedAttempts} из {maxPasswordAttempts} попыток ввода пароля.{lockoutMessage}",
|
||
"failedToAuthenticateNoLimit": "Не удалось пройти аутентификацию.",
|
||
"accountLockedContactAdmin": " Свяжитесь с администратором, чтобы разблокировать вашу учетную запись",
|
||
"userNotFound": "Пользователь не найден в системе",
|
||
"initialUserNotSupported": "Первичный пользователь не поддерживается",
|
||
"userInitialStateNotSupported": "Начальное состояние пользователя не поддерживается",
|
||
"codeOrVerificationRequired": "Вы должны предоставить код или иметь действительную проверку пользователя",
|
||
"verificationRequired": "Необходимо выполнить проверку пользователя",
|
||
"couldNotLoadSession": "Не удалось загрузить сессию",
|
||
"couldNotLoadAuthMethods": "Не удалось загрузить методы аутентификации",
|
||
"failedPrecondition": "Нарушено предварительное условие",
|
||
"sessionNotValid": "Сессия недействительна"
|
||
}
|
||
},
|
||
"idp": {
|
||
"title": "Войти через SSO",
|
||
"description": "Выберите одного из провайдеров для входа",
|
||
"orSignInWith": "или войти через",
|
||
"signInWithApple": "Войти через Apple",
|
||
"signInWithGoogle": "Войти через Google",
|
||
"signInWithAzureAD": "Войти через AzureAD",
|
||
"signInWithGithub": "Войти через GitHub",
|
||
"signInWithGitlab": "Войти через GitLab",
|
||
"loginError": {
|
||
"title": "Ошибка входа",
|
||
"description": "Произошла ошибка при попытке входа."
|
||
},
|
||
"linkingError": {
|
||
"title": "Ошибка привязки аккаунта",
|
||
"description": "Произошла ошибка при попытке привязать аккаунт."
|
||
},
|
||
"completeRegister": {
|
||
"title": "Завершите регистрацию",
|
||
"description": "Завершите регистрацию вашего аккаунта."
|
||
},
|
||
"accountNotFound": {
|
||
"title": "Аккаунт не найден",
|
||
"description": "Мы не смогли найти аккаунт, связанный с учетными данными вашего провайдера идентификации.",
|
||
"info": "Существующий аккаунт не найден. Пожалуйста, войдите с существующим аккаунтом или обратитесь к администратору за помощью.",
|
||
"backToLogin": "Вернуться к входу"
|
||
},
|
||
"registrationFailed": {
|
||
"title": "Регистрация недоступна",
|
||
"description": "Мы не смогли завершить процесс регистрации.",
|
||
"info": "Не удалось определить организацию для регистрации. Пожалуйста, обратитесь к администратору за помощью.",
|
||
"backToLogin": "Вернуться к входу"
|
||
},
|
||
"processing": {
|
||
"message": "Обработка аутентификации...",
|
||
"noRedirect": "Не получено перенаправления или ошибки от сервера",
|
||
"unexpectedError": "Произошла неожиданная ошибка"
|
||
},
|
||
"errors": {
|
||
"missingParameters": "Отсутствуют обязательные параметры",
|
||
"missingIdpInfo": "Отсутствует информация IDP",
|
||
"idpNotFound": "Провайдер идентификации не найден",
|
||
"linkingNotAllowed": "Связывание не разрешено для этого провайдера идентификации",
|
||
"linkingFailed": "Не удалось связать провайдера идентификации с учетной записью",
|
||
"autoLinkingFailed": "Не удалось автоматически связать учетную запись",
|
||
"userCreationFailed": "Не удалось создать учетную запись пользователя",
|
||
"orgResolutionFailed": "Не удалось определить организацию для регистрации",
|
||
"sessionCreationFailed": "Не удалось создать сеанс или определить перенаправление",
|
||
"unknownError": "Произошла неизвестная ошибка"
|
||
}
|
||
},
|
||
"ldap": {
|
||
"title": "Войти через LDAP",
|
||
"description": "Введите ваши учетные данные LDAP.",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"username": "Имя пользователя",
|
||
"password": "Пароль"
|
||
},
|
||
"required": {
|
||
"username": "Это поле обязательно для заполнения",
|
||
"password": "Это поле обязательно для заполнения"
|
||
}
|
||
},
|
||
"mfa": {
|
||
"verify": {
|
||
"title": "Подтвердите вашу личность",
|
||
"description": "Выберите один из следующих факторов.",
|
||
"noResults": "Нет доступных методов двухфакторной аутентификации"
|
||
},
|
||
"set": {
|
||
"title": "Настройка двухфакторной аутентификации",
|
||
"description": "Выберите один из следующих методов.",
|
||
"skip": "Пропустить"
|
||
}
|
||
},
|
||
"otp": {
|
||
"verify": {
|
||
"title": "Подтверждение 2FA",
|
||
"totpDescription": "Введите код из приложения-аутентификатора.",
|
||
"smsDescription": "Введите код, полученный по SMS.",
|
||
"emailDescription": "Введите код, полученный по email.",
|
||
"noCodeReceived": "Не получили код?",
|
||
"resendCode": "Отправить код повторно",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"code": "Код"
|
||
},
|
||
"required": {
|
||
"code": "Это поле обязательно для заполнения"
|
||
}
|
||
},
|
||
"set": {
|
||
"title": "Настройка двухфакторной аутентификации",
|
||
"totpDescription": "Отсканируйте QR-код в приложении-аутентификаторе.",
|
||
"smsDescription": "Введите номер телефона для получения кода по SMS.",
|
||
"emailDescription": "Введите email для получения кода.",
|
||
"totpRegisterDescription": "Отсканируйте QR-код или перейдите по ссылке вручную.",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"code": "Код"
|
||
},
|
||
"required": {
|
||
"code": "Это поле обязательно для заполнения"
|
||
}
|
||
}
|
||
},
|
||
"passkey": {
|
||
"verify": {
|
||
"title": "Аутентификация с помощью пасскей",
|
||
"description": "Устройство запросит отпечаток пальца, лицо или экранный замок",
|
||
"usePassword": "Использовать пароль",
|
||
"submit": "Продолжить"
|
||
},
|
||
"set": {
|
||
"title": "Настройка пасскей",
|
||
"description": "Устройство запросит отпечаток пальца, лицо или экранный замок",
|
||
"info": {
|
||
"description": "Пасскей — метод аутентификации через устройство (отпечаток пальца, Apple FaceID и аналоги).",
|
||
"link": "Аутентификация без пароля"
|
||
},
|
||
"skip": "Пропустить",
|
||
"submit": "Продолжить"
|
||
}
|
||
},
|
||
"u2f": {
|
||
"verify": {
|
||
"title": "Подтверждение 2FA",
|
||
"description": "Подтвердите аккаунт с помощью устройства."
|
||
},
|
||
"set": {
|
||
"title": "Настройка двухфакторной аутентификации",
|
||
"description": "Настройте устройство как второй фактор.",
|
||
"submit": "Продолжить"
|
||
}
|
||
},
|
||
"register": {
|
||
"methods": {
|
||
"passkey": "Пасскей",
|
||
"password": "Пароль"
|
||
},
|
||
"disabled": {
|
||
"title": "Регистрация отключена",
|
||
"description": "Регистрация недоступна. Обратитесь к администратору."
|
||
},
|
||
"missingdata": {
|
||
"title": "Недостаточно данных",
|
||
"description": "Укажите email, имя и фамилию для регистрации."
|
||
},
|
||
"title": "Регистрация",
|
||
"description": "Создайте свой аккаунт ZITADEL.",
|
||
"noMethodAvailableWarning": "Нет доступных методов аутентификации. Обратитесь к администратору.",
|
||
"selectMethod": "Выберите метод аутентификации",
|
||
"agreeTo": "Для регистрации необходимо принять условия:",
|
||
"termsOfService": "Условия использования",
|
||
"privacyPolicy": "Политика конфиденциальности",
|
||
"submit": "Продолжить",
|
||
"password": {
|
||
"title": "Установить пароль",
|
||
"description": "Установите пароль для вашего аккаунта",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"password": "Пароль",
|
||
"confirmPassword": "Подтвердите пароль"
|
||
},
|
||
"required": {
|
||
"password": "Вы должны указать пароль!",
|
||
"confirmPassword": "Это поле обязательно для заполнения"
|
||
}
|
||
},
|
||
"labels": {
|
||
"firstname": "Имя",
|
||
"lastname": "Фамилия",
|
||
"email": "Электронная почта"
|
||
},
|
||
"required": {
|
||
"firstname": "Это поле обязательно для заполнения",
|
||
"lastname": "Это поле обязательно для заполнения",
|
||
"email": "Это поле обязательно для заполнения"
|
||
},
|
||
"errors": {
|
||
"couldNotCreateUser": "Не удалось создать пользователя",
|
||
"couldNotCreateSession": "Не удалось создать сессию",
|
||
"userNotFound": "Пользователь не найден в системе",
|
||
"couldNotLinkIDP": "Не удалось привязать IDP к пользователю",
|
||
"couldNotRegisterUser": "Не удалось зарегистрировать пользователя"
|
||
}
|
||
},
|
||
"invite": {
|
||
"title": "Пригласить пользователя",
|
||
"description": "Укажите email и имя пользователя для приглашения.",
|
||
"info": "Пользователь получит email с инструкциями.",
|
||
"notAllowed": "Ваши настройки не позволяют приглашать пользователей.",
|
||
"submit": "Продолжить",
|
||
"success": {
|
||
"title": "Пользователь приглашён",
|
||
"description": "Письмо успешно отправлено.",
|
||
"verified": "Пользователь приглашён и уже подтвердил email.",
|
||
"notVerifiedYet": "Пользователь приглашён. Он получит email с инструкциями.",
|
||
"submit": "Пригласить другого пользователя"
|
||
}
|
||
},
|
||
"signedin": {
|
||
"title": "Добро пожаловать, {user}!",
|
||
"description": "Вы вошли в систему.",
|
||
"continue": "Продолжить",
|
||
"error": {
|
||
"title": "Ошибка",
|
||
"description": "Не удалось войти в систему. Проверьте свои данные и попробуйте снова."
|
||
}
|
||
},
|
||
"verify": {
|
||
"userIdMissing": "Не указан userId!",
|
||
"successTitle": "Пользователь подтверждён",
|
||
"successDescription": "Пользователь успешно подтверждён.",
|
||
"setupAuthenticator": "Настроить аутентификатор",
|
||
"verify": {
|
||
"title": "Подтверждение пользователя",
|
||
"description": "Введите код из письма подтверждения.",
|
||
"noCodeReceived": "Не получили код?",
|
||
"resendCode": "Отправить код повторно",
|
||
"codeSent": "Код отправлен на ваш email.",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"code": "Код"
|
||
},
|
||
"required": {
|
||
"code": "Это поле обязательно для заполнения"
|
||
}
|
||
},
|
||
"errors": {
|
||
"couldNotResendEmail": "Не удалось повторно отправить электронное письмо",
|
||
"couldNotVerifyUser": "Не удалось подтвердить пользователя",
|
||
"couldNotVerifyInvite": "Не удалось подтвердить приглашение",
|
||
"couldNotVerifyEmail": "Не удалось подтвердить электронную почту",
|
||
"couldNotVerify": "Не удалось подтвердить",
|
||
"couldNotLoadUser": "Не удалось загрузить пользователя",
|
||
"couldNotLoadAuthenticators": "Не удалось загрузить доступные средства аутентификации",
|
||
"couldNotCreateSession": "Не удалось создать сеанс",
|
||
"noHostFound": "Хост не найден",
|
||
"userAlreadyVerified": "Пользователь уже подтверждён!",
|
||
"couldNotResendInvite": "Не удалось повторно отправить приглашение",
|
||
"inviteSendFailed": "Не удалось отправить письмо с приглашением",
|
||
"emailSendFailed": "Не удалось отправить письмо с подтверждением"
|
||
}
|
||
},
|
||
"authenticator": {
|
||
"title": "Выбор метода аутентификации",
|
||
"description": "Выберите предпочитаемый метод аутентификации",
|
||
"noMethodsAvailable": "Нет доступных методов аутентификации",
|
||
"allSetup": "Аутентификатор уже настроен!",
|
||
"linkWithIDP": "или привязать через Identity Provider"
|
||
},
|
||
"device": {
|
||
"usercode": {
|
||
"title": "Код устройства",
|
||
"description": "Введите код.",
|
||
"submit": "Продолжить",
|
||
"labels": {
|
||
"code": "Код"
|
||
},
|
||
"required": {
|
||
"code": "Это поле обязательно для заполнения"
|
||
}
|
||
},
|
||
"request": {
|
||
"title": "{appName} хочет подключиться:",
|
||
"description": "{appName} получит доступ к:",
|
||
"disclaimer": "Нажимая «Разрешить», вы разрешаете этому приложению и Zitadel использовать вашу информацию в соответствии с их условиями использования и политиками конфиденциальности. Вы можете отозвать этот доступ в любое время.",
|
||
"submit": "Разрешить",
|
||
"deny": "Запретить"
|
||
},
|
||
"scope": {
|
||
"openid": "Проверка вашей личности.",
|
||
"email": "Доступ к вашему адресу электронной почты.",
|
||
"profile": "Доступ к полной информации вашего профиля.",
|
||
"offline_access": "Разрешить офлайн-доступ к вашему аккаунту."
|
||
}
|
||
},
|
||
"error": {
|
||
"noUserCode": "Не указан код пользователя!",
|
||
"noDeviceRequest": "Не найдена ни одна заявка на устройство.",
|
||
"unknownContext": "Не удалось получить контекст пользователя. Укажите имя пользователя или loginName в параметрах поиска.",
|
||
"sessionExpired": "Ваша сессия истекла. Войдите снова.",
|
||
"failedLoading": "Ошибка загрузки данных. Попробуйте ещё раз.",
|
||
"tryagain": "Попробовать снова"
|
||
}
|
||
}
|