Remove U2F support (#20141)

- Completely remove U2F support from 1.18.0, 1.17.0 will be the last
release that U2F is somewhat supported. Users who used U2F would already
be warned about using U2F for a while now and should hopefully already
be migrated. But starting 1.18 definitely remove it.
This commit is contained in:
Gusted 2022-06-27 04:20:58 +02:00 committed by GitHub
parent 5d3f99c7c6
commit 0048595811
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 4 additions and 61 deletions

View File

@ -475,20 +475,6 @@ ENABLE = true
;; Maximum length of oauth2 token/cookie stored on server ;; Maximum length of oauth2 token/cookie stored on server
;MAX_TOKEN_LENGTH = 32767 ;MAX_TOKEN_LENGTH = 32767
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[U2F]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; NOTE: THE DEFAULT VALUES HERE WILL NEED TO BE CHANGED
;; Two Factor authentication with security keys
;; https://developers.yubico.com/U2F/App_ID.html
;;
;; DEPRECATED - this only applies to previously registered security keys using the U2F standard
APP_ID = ; e.g. http://localhost:3000/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[log] [log]

View File

@ -1003,9 +1003,6 @@ Default templates for project boards:
List of locales shown in language selector. The first locale will be used as the default if user browser's language doesn't match any locale in the list. List of locales shown in language selector. The first locale will be used as the default if user browser's language doesn't match any locale in the list.
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Türkçe,Čeština,Српски,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia,മലയാളം**: Visible names corresponding to the locales - `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Türkçe,Čeština,Српски,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia,മലയാളം**: Visible names corresponding to the locales
## U2F (`U2F`) **DEPRECATED**
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application which is used for authentication of previously registered U2F keys. Requires HTTPS.
## Markup (`markup`) ## Markup (`markup`)
- `MERMAID_MAX_SOURCE_CHARACTERS`: **5000**: Set the maximum size of a Mermaid source. (Set to -1 to disable) - `MERMAID_MAX_SOURCE_CHARACTERS`: **5000**: Set the maximum size of a Mermaid source. (Set to -1 to disable)

View File

@ -50,7 +50,7 @@ menu:
| 有寫入權限的儲存庫 Token | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ | | 有寫入權限的儲存庫 Token | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
| 內建 Container Registry | [](https://github.com/go-gitea/gitea/issues/2316) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | 內建 Container Registry | [](https://github.com/go-gitea/gitea/issues/2316) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| 對外部 Git 鏡像 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | 對外部 Git 鏡像 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
| FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | | FIDO (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
| 內建 CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | 內建 CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
| 子群組: 群組中的群組 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ | | 子群組: 群組中的群組 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ |

View File

@ -402,11 +402,6 @@ var (
MaxTokenLength: math.MaxInt16, MaxTokenLength: math.MaxInt16,
} }
// FIXME: DEPRECATED to be removed in v1.18.0
U2F = struct {
AppID string
}{}
// Metrics settings // Metrics settings
Metrics = struct { Metrics = struct {
Enabled bool Enabled bool
@ -1103,16 +1098,6 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
for _, emoji := range UI.CustomEmojis { for _, emoji := range UI.CustomEmojis {
UI.CustomEmojisMap[emoji] = ":" + emoji + ":" UI.CustomEmojisMap[emoji] = ":" + emoji + ":"
} }
// FIXME: DEPRECATED to be removed in v1.18.0
U2F.AppID = strings.TrimSuffix(AppURL, "/")
if Cfg.Section("U2F").HasKey("APP_ID") {
log.Error("Deprecated setting `[U2F]` `APP_ID` present. This fallback will be removed in v1.18.0")
U2F.AppID = Cfg.Section("U2F").Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/"))
} else if Cfg.Section("u2f").HasKey("APP_ID") {
log.Error("Deprecated setting `[u2]` `APP_ID` present. This fallback will be removed in v1.18.0")
U2F.AppID = Cfg.Section("u2f").Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/"))
}
} }
func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) { func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) {

View File

@ -46,7 +46,6 @@ webauthn_error_unable_to_process=Server nemohl zpracovat váš požadavek.
webauthn_error_duplicated=Zabezpečovací klíč není pro tento požadavek povolen. Prosím ujistěte se, zda klíč není již registrován. webauthn_error_duplicated=Zabezpečovací klíč není pro tento požadavek povolen. Prosím ujistěte se, zda klíč není již registrován.
webauthn_error_empty=Musíte nastavit název tohoto klíče. webauthn_error_empty=Musíte nastavit název tohoto klíče.
webauthn_error_timeout=Požadavek vypršel dříve, než se podařilo přečíst váš klíč. Znovu načtěte tuto stránku a akci opakujte. webauthn_error_timeout=Požadavek vypršel dříve, než se podařilo přečíst váš klíč. Znovu načtěte tuto stránku a akci opakujte.
webauthn_u2f_deprecated=Klíč: „%s“ autentifikuje pomocí zastaralého procesu U2F. Měli byste znovu zaregistrovat tento klíč a zrušit starou registraci.
webauthn_reload=Znovu načíst webauthn_reload=Znovu načíst
repository=Repozitář repository=Repozitář

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=Der Server konnte deine Anfrage nicht bearbeite
webauthn_error_duplicated=Für diese Anfrage ist der Sicherheitsschlüssel nicht erlaubt. Bitte stell sicher, dass er nicht bereits registriert ist. webauthn_error_duplicated=Für diese Anfrage ist der Sicherheitsschlüssel nicht erlaubt. Bitte stell sicher, dass er nicht bereits registriert ist.
webauthn_error_empty=Du musst einen Namen für diesen Schlüssel festlegen. webauthn_error_empty=Du musst einen Namen für diesen Schlüssel festlegen.
webauthn_error_timeout=Das Zeitlimit wurde erreicht, bevor dein Schlüssel gelesen werden konnte. Bitte lade die Seite erneut. webauthn_error_timeout=Das Zeitlimit wurde erreicht, bevor dein Schlüssel gelesen werden konnte. Bitte lade die Seite erneut.
webauthn_u2f_deprecated=Der Schlüssel: '%s' authentifiziert sich über den veralteten U2F-Prozess. Bitte registriere den Schlüssel neu und lösche die alte Registrierung.
webauthn_reload=Neu laden webauthn_reload=Neu laden
repository=Repository repository=Repository

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=Ο διακομιστής δεν μπόρεσε
webauthn_error_duplicated=Το κλειδί ασφαλείας δεν επιτρέπεται για αυτό το αίτημα. Βεβαιωθείτε ότι το κλειδί δεν έχει ήδη καταχωρηθεί. webauthn_error_duplicated=Το κλειδί ασφαλείας δεν επιτρέπεται για αυτό το αίτημα. Βεβαιωθείτε ότι το κλειδί δεν έχει ήδη καταχωρηθεί.
webauthn_error_empty=Πρέπει να ορίσετε ένα όνομα για αυτό το κλειδί. webauthn_error_empty=Πρέπει να ορίσετε ένα όνομα για αυτό το κλειδί.
webauthn_error_timeout=Το χρονικό όριο έφτασε πριν το κλειδί να διαβαστεί. Παρακαλώ ανανεώστε τη σελίδα και προσπαθήστε ξανά. webauthn_error_timeout=Το χρονικό όριο έφτασε πριν το κλειδί να διαβαστεί. Παρακαλώ ανανεώστε τη σελίδα και προσπαθήστε ξανά.
webauthn_u2f_deprecated=Το κλειδί: '%s' πιστοποιεί χρησιμοποιώντας το παρωχημένο πρωτόκολλο U2F. Θα πρέπει να καταχωρήσετε ξανά αυτό το κλειδί και να καταργήσετε την παλιά εγγραφή.
webauthn_reload=Ανανέωση webauthn_reload=Ανανέωση
repository=Αποθετήριο repository=Αποθετήριο

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process = The server could not process your request.
webauthn_error_duplicated = The security key is not permitted for this request. Please make sure that the key is not already registered. webauthn_error_duplicated = The security key is not permitted for this request. Please make sure that the key is not already registered.
webauthn_error_empty = You must set a name for this key. webauthn_error_empty = You must set a name for this key.
webauthn_error_timeout = Timeout reached before your key could be read. Please reload this page and retry. webauthn_error_timeout = Timeout reached before your key could be read. Please reload this page and retry.
webauthn_u2f_deprecated = The key: '%s' authenticates using the deprecated U2F process. You should re-register this key and remove the old registration.
webauthn_reload = Reload webauthn_reload = Reload
repository = Repository repository = Repository

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=El servidor no pudo procesar su solicitud.
webauthn_error_duplicated=La clave de seguridad no está permitida para esta solicitud. Por favor, asegúrese de que la clave no está ya registrada. webauthn_error_duplicated=La clave de seguridad no está permitida para esta solicitud. Por favor, asegúrese de que la clave no está ya registrada.
webauthn_error_empty=Debe establecer un nombre para esta clave. webauthn_error_empty=Debe establecer un nombre para esta clave.
webauthn_error_timeout=Tiempo de espera máximo alcanzado antes de que su clave pudiese ser leída. Por favor, cargue la página y vuelva a intentarlo. webauthn_error_timeout=Tiempo de espera máximo alcanzado antes de que su clave pudiese ser leída. Por favor, cargue la página y vuelva a intentarlo.
webauthn_u2f_deprecated=La clave: '%s' se autentifica usando el proceso U2F obsoleto. Debe volver a registrar esta clave y eliminar el registro antiguo.
webauthn_reload=Recargar webauthn_reload=Recargar
repository=Repositorio repository=Repositorio

View File

@ -46,7 +46,6 @@ webauthn_error_unable_to_process=Netþjónninn gat ekki ráðið við beiðni þ
webauthn_error_duplicated=Öryggislykillinn er ekki leyfður fyrir þessa beiðni. Gakktu úr skugga um að lykillinn sé ekki þegar skráður. webauthn_error_duplicated=Öryggislykillinn er ekki leyfður fyrir þessa beiðni. Gakktu úr skugga um að lykillinn sé ekki þegar skráður.
webauthn_error_empty=Þú verður að setja nafn fyrir þennan lykil. webauthn_error_empty=Þú verður að setja nafn fyrir þennan lykil.
webauthn_error_timeout=Tímamörk náð áður en hægt var að lesa lykilinn þinn. Vinsamlegast endurhlaðið þessa síðu og reyndu aftur. webauthn_error_timeout=Tímamörk náð áður en hægt var að lesa lykilinn þinn. Vinsamlegast endurhlaðið þessa síðu og reyndu aftur.
webauthn_u2f_deprecated=Lykillinn: „%s“ auðkennir með því að nota úrelta U2F aðferð. Þú ættir að endurskrá þennan lykil og fjarlægja gömlu skráninguna.
webauthn_reload=Endurhlaða webauthn_reload=Endurhlaða
repository=Hugbúnaðarsafn repository=Hugbúnaðarsafn

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=サーバーがリクエストを処理でき
webauthn_error_duplicated=このリクエストに対しては、許可されていないセキュリティキーです。 キーが未登録であることを確認してください。 webauthn_error_duplicated=このリクエストに対しては、許可されていないセキュリティキーです。 キーが未登録であることを確認してください。
webauthn_error_empty=このキーに名前を設定する必要があります。 webauthn_error_empty=このキーに名前を設定する必要があります。
webauthn_error_timeout=キーを読み取る前にタイムアウトになりました。 このページをリロードしてもう一度やり直してください。 webauthn_error_timeout=キーを読み取る前にタイムアウトになりました。 このページをリロードしてもう一度やり直してください。
webauthn_u2f_deprecated=キー: '%s' は非推奨のU2Fプロセスを使用して認証しています。このキーを再登録して古い登録を削除したほうが良いでしょう。
webauthn_reload=リロード webauthn_reload=リロード
repository=リポジトリ repository=リポジトリ

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=Serveris nevar apstrādāt Jūsu pieprasījumu.
webauthn_error_duplicated=Drošības atslēga nav atļauta šim pieprasījumam. Pārliecinieties, ka šī atslēga jau nav reģistrēta. webauthn_error_duplicated=Drošības atslēga nav atļauta šim pieprasījumam. Pārliecinieties, ka šī atslēga jau nav reģistrēta.
webauthn_error_empty=Norādiet atslēgas nosaukumu. webauthn_error_empty=Norādiet atslēgas nosaukumu.
webauthn_error_timeout=Iestājusies noildze, mēģinot, nolasīt atslēgu. Pārlādējiet lapu un mēģiniet vēlreiz. webauthn_error_timeout=Iestājusies noildze, mēģinot, nolasīt atslēgu. Pārlādējiet lapu un mēģiniet vēlreiz.
webauthn_u2f_deprecated=Atslēga '%s' izmanto novecojušu U2F procesu. Noņemiet iepriekšējo reģistrāciju un veiciet reģistrācijas procesu no jauna.
webauthn_reload=Pārlādēt webauthn_reload=Pārlādēt
repository=Repozitorijs repository=Repozitorijs

View File

@ -46,7 +46,6 @@ webauthn_error_unable_to_process=Serwer nie mógł obsłużyć Twojego żądania
webauthn_error_duplicated=Klucz bezpieczeństwa nie jest dozwolony dla tego żądania. Upewnij się, że klucz nie jest już zarejestrowany. webauthn_error_duplicated=Klucz bezpieczeństwa nie jest dozwolony dla tego żądania. Upewnij się, że klucz nie jest już zarejestrowany.
webauthn_error_empty=Musisz ustawić nazwę dla tego klucza. webauthn_error_empty=Musisz ustawić nazwę dla tego klucza.
webauthn_error_timeout=Osiągnięto limit czasu zanim Twój klucz może zostać odczytany. Odśwież stronę i spróbuj ponownie. webauthn_error_timeout=Osiągnięto limit czasu zanim Twój klucz może zostać odczytany. Odśwież stronę i spróbuj ponownie.
webauthn_u2f_deprecated=Klucz '%s' uwierzytelnia przy użyciu przestarzałego procesu U2F. Powinieneś ponownie zarejestrować ten klucz i usunąć starą rejestrację.
webauthn_reload=Odśwież webauthn_reload=Odśwież
repository=Repozytorium repository=Repozytorium

View File

@ -46,7 +46,6 @@ webauthn_error_unable_to_process=O servidor não pôde processar sua solicitaç
webauthn_error_duplicated=A chave de segurança não é permitida para esta solicitação. Por favor, certifique-se que a chave já não está registrada. webauthn_error_duplicated=A chave de segurança não é permitida para esta solicitação. Por favor, certifique-se que a chave já não está registrada.
webauthn_error_empty=Você deve definir um nome para esta chave. webauthn_error_empty=Você deve definir um nome para esta chave.
webauthn_error_timeout=Tempo limite atingido antes de sua chave poder ser lida. Por favor, recarregue esta página e tente novamente. webauthn_error_timeout=Tempo limite atingido antes de sua chave poder ser lida. Por favor, recarregue esta página e tente novamente.
webauthn_u2f_deprecated=A chave: '%s' autentica utilizando o processo U2F descontinuado. Você deve registrar novamente esta chave e remover o registro antigo.
webauthn_reload=Recarregar webauthn_reload=Recarregar
repository=Repositório repository=Repositório

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=O servidor não conseguiu processar o seu pedid
webauthn_error_duplicated=A chave de segurança não é permitida neste pedido. Certifique-se de que a chave não está já registada. webauthn_error_duplicated=A chave de segurança não é permitida neste pedido. Certifique-se de que a chave não está já registada.
webauthn_error_empty=Você tem que definir um nome para esta chave. webauthn_error_empty=Você tem que definir um nome para esta chave.
webauthn_error_timeout=O tempo limite foi atingido antes que a sua chave pudesse ser lida. Recarregue esta página e tente novamente. webauthn_error_timeout=O tempo limite foi atingido antes que a sua chave pudesse ser lida. Recarregue esta página e tente novamente.
webauthn_u2f_deprecated=A chave: '%s' autentica usando o processo U2F, mas este foi descontinuado. Você deveria registar novamente esta chave e remover o registo antigo.
webauthn_reload=Recarregar webauthn_reload=Recarregar
repository=Repositório repository=Repositório

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=服务器无法处理您的请求。
webauthn_error_duplicated=此安全密钥未被许可用于这个请求。请确保该密钥尚未注册。 webauthn_error_duplicated=此安全密钥未被许可用于这个请求。请确保该密钥尚未注册。
webauthn_error_empty=您必须为此密钥设置一个名称。 webauthn_error_empty=您必须为此密钥设置一个名称。
webauthn_error_timeout=未能在允许的时限内读取密钥。请重新加载此页面并重试。 webauthn_error_timeout=未能在允许的时限内读取密钥。请重新加载此页面并重试。
webauthn_u2f_deprecated=密钥 '%s' 使用的是已经废弃的 U2F 进行身份验证。您应该重新注册此密钥并删除旧的注册。
webauthn_reload=重新加载 webauthn_reload=重新加载
repository=仓库 repository=仓库

View File

@ -47,7 +47,6 @@ webauthn_error_unable_to_process=伺服器無法執行您的請求。
webauthn_error_duplicated=此請求不允許使用這個安全金鑰。請確保該金鑰尚未註冊。 webauthn_error_duplicated=此請求不允許使用這個安全金鑰。請確保該金鑰尚未註冊。
webauthn_error_empty=您必須命名此金鑰。 webauthn_error_empty=您必須命名此金鑰。
webauthn_error_timeout=在成功讀取金鑰之前已逾時,請重新載入此頁面並重試。 webauthn_error_timeout=在成功讀取金鑰之前已逾時,請重新載入此頁面並重試。
webauthn_u2f_deprecated=「%s」金鑰使用已廢棄的 U2F 流程進行驗證。您應該重新註冊此金鑰並將先前註冊的移除。
webauthn_reload=重新載入 webauthn_reload=重新載入
repository=儲存庫 repository=儲存庫

View File

@ -266,7 +266,7 @@ func SignInPost(ctx *context.Context) {
} }
if hasTOTPtwofa { if hasTOTPtwofa {
// User will need to use U2F, save data // User will need to use WebAuthn, save data
if err := ctx.Session.Set("totpEnrolled", u.ID); err != nil { if err := ctx.Session.Set("totpEnrolled", u.ID); err != nil {
ctx.ServerError("UserSignIn: Unable to set WebAuthn Enrolled in session", err) ctx.ServerError("UserSignIn: Unable to set WebAuthn Enrolled in session", err)
return return
@ -278,7 +278,7 @@ func SignInPost(ctx *context.Context) {
return return
} }
// If we have U2F redirect there first // If we have WebAuthn redirect there first
if hasWebAuthnTwofa { if hasWebAuthnTwofa {
ctx.Redirect(setting.AppSubURL + "/user/webauthn") ctx.Redirect(setting.AppSubURL + "/user/webauthn")
return return
@ -317,7 +317,6 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe
_ = ctx.Session.Delete("openid_determined_username") _ = ctx.Session.Delete("openid_determined_username")
_ = ctx.Session.Delete("twofaUid") _ = ctx.Session.Delete("twofaUid")
_ = ctx.Session.Delete("twofaRemember") _ = ctx.Session.Delete("twofaRemember")
_ = ctx.Session.Delete("u2fChallenge")
_ = ctx.Session.Delete("linkAccount") _ = ctx.Session.Delete("linkAccount")
if err := ctx.Session.Set("uid", u.ID); err != nil { if err := ctx.Session.Set("uid", u.ID); err != nil {
log.Error("Error setting uid %d in session: %v", u.ID, err) log.Error("Error setting uid %d in session: %v", u.ID, err)

View File

@ -67,10 +67,7 @@ func WebAuthnLoginAssertion(ctx *context.Context) {
return return
} }
// FIXME: DEPRECATED appid is deprecated and is planned to be removed in v1.18.0 assertion, sessionData, err := wa.WebAuthn.BeginLogin((*wa.User)(user))
assertion, sessionData, err := wa.WebAuthn.BeginLogin((*wa.User)(user), webauthn.WithAssertionExtensions(protocol.AuthenticationExtensions{
"appid": setting.U2F.AppID,
}))
if err != nil { if err != nil {
ctx.ServerError("webauthn.BeginLogin", err) ctx.ServerError("webauthn.BeginLogin", err)
return return
@ -159,12 +156,5 @@ func WebAuthnLoginAssertionPost(ctx *context.Context) {
} }
_ = ctx.Session.Delete("twofaUid") _ = ctx.Session.Delete("twofaUid")
// Finally check if the appid extension was used:
if value, ok := parsedResponse.ClientExtensionResults["appid"]; ok {
if appid, ok := value.(bool); ok && appid {
ctx.Flash.Error(ctx.Tr("webauthn_u2f_deprecated", dbCred.Name))
}
}
ctx.JSON(http.StatusOK, map[string]string{"redirect": redirect}) ctx.JSON(http.StatusOK, map[string]string{"redirect": redirect})
} }

View File

@ -26,7 +26,6 @@ const (
func Security(ctx *context.Context) { func Security(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsSettingsSecurity"] = true ctx.Data["PageIsSettingsSecurity"] = true
ctx.Data["RequireU2F"] = true
if ctx.FormString("openid.return_to") != "" { if ctx.FormString("openid.return_to") != "" {
settingsOpenIDVerify(ctx) settingsOpenIDVerify(ctx)