diff --git a/src/main/kotlin/app/termora/account/LoginServerDialog.kt b/src/main/kotlin/app/termora/account/LoginServerDialog.kt index c11b949..6fb5a81 100644 --- a/src/main/kotlin/app/termora/account/LoginServerDialog.kt +++ b/src/main/kotlin/app/termora/account/LoginServerDialog.kt @@ -37,8 +37,9 @@ class LoginServerDialog(owner: Window) : DialogWrapper(owner) { } private val serverComboBox = OutlineComboBox() - private val usernameTextField = OutlineTextField() + private val usernameTextField = OutlineTextField(128) private val passwordField = OutlinePasswordField() + private val mfaTextField = OutlineTextField(128) private val okAction = OkAction(I18n.getString("termora.settings.account.login")) private val cancelAction = super.createCancelAction() private val cancelButton = super.createJButtonForAction(cancelAction) @@ -70,7 +71,7 @@ class LoginServerDialog(owner: Window) : DialogWrapper(owner) { override fun createCenterPanel(): JComponent { val layout = FormLayout( "left:pref, $FORM_MARGIN, default:grow, $FORM_MARGIN, pref", - "pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN" + "pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref, $FORM_MARGIN" ) var rows = 1 @@ -92,6 +93,8 @@ class LoginServerDialog(owner: Window) : DialogWrapper(owner) { serverComboBox.addItem(Server(server.name, server.server)) } + mfaTextField.placeholderText = I18n.getString("termora.settings.account.mfa") + serverComboBox.renderer = object : DefaultListCellRenderer() { override fun getListCellRendererComponent( list: JList<*>?, @@ -227,6 +230,8 @@ class LoginServerDialog(owner: Window) : DialogWrapper(owner) { .add(registerLink).xy(5, rows).apply { rows += step } .add("${I18n.getString("termora.new-host.general.password")}:").xy(1, rows) .add(passwordField).xy(3, rows).apply { rows += step } + .add("MFA:").xy(1, rows) + .add(mfaTextField).xy(3, rows).apply { rows += step } .build() } @@ -336,6 +341,7 @@ class LoginServerDialog(owner: Window) : DialogWrapper(owner) { okAction.isEnabled = false usernameTextField.isEnabled = false passwordField.isEnabled = false + mfaTextField.isEnabled = false serverComboBox.isEnabled = false cancelButton.isVisible = false onLogin(server) @@ -357,7 +363,10 @@ class LoginServerDialog(owner: Window) : DialogWrapper(owner) { val loginJob = swingCoroutineScope.launch(Dispatchers.IO) { try { - ServerManager.getInstance().login(server, usernameTextField.text, String(passwordField.password)) + ServerManager.getInstance().login( + server, usernameTextField.text, + String(passwordField.password), mfaTextField.text.trim() + ) withContext(Dispatchers.Swing) { super.doOKAction() } @@ -382,6 +391,7 @@ class LoginServerDialog(owner: Window) : DialogWrapper(owner) { passwordField.isEnabled = true serverComboBox.isEnabled = true cancelButton.isVisible = true + mfaTextField.isEnabled = true } isLoggingIn.compareAndSet(true, false) } diff --git a/src/main/kotlin/app/termora/account/ServerManager.kt b/src/main/kotlin/app/termora/account/ServerManager.kt index 01380aa..37b0e24 100644 --- a/src/main/kotlin/app/termora/account/ServerManager.kt +++ b/src/main/kotlin/app/termora/account/ServerManager.kt @@ -28,7 +28,7 @@ class ServerManager private constructor() { /** * 登录,不报错就是登录成功 */ - fun login(server: Server, username: String, password: String) { + fun login(server: Server, username: String, password: String, mfa: String) { if (accountManager.isLocally().not()) { throw IllegalStateException("Already logged in") @@ -39,19 +39,19 @@ class ServerManager private constructor() { } try { - doLogin(server, username, password) + doLogin(server, username, password, mfa) } finally { isLoggingIn.compareAndSet(true, false) } } - private fun doLogin(server: Server, username: String, password: String) { + private fun doLogin(server: Server, username: String, password: String, mfa: String) { // 服务器信息 val serverInfo = getServerInfo(server) // call login - val loginResponse = callLogin(serverInfo, server, username, password) + val loginResponse = callLogin(serverInfo, server, username, password, mfa) // call me val meResponse = callMe(server, loginResponse.accessToken) @@ -106,10 +106,16 @@ class ServerManager private constructor() { return ohMyJson.decodeFromString(AccountHttp.execute(request = request)) } - private fun callLogin(serverInfo: ServerInfo, server: Server, username: String, password: String): LoginResponse { + private fun callLogin( + serverInfo: ServerInfo, + server: Server, + username: String, + password: String, + mfa: String + ): LoginResponse { val passwordHex = DigestUtils.sha256Hex("${serverInfo.salt}:${username}:${password}") - val requestBody = ohMyJson.encodeToString(mapOf("email" to username, "password" to passwordHex)) + val requestBody = ohMyJson.encodeToString(mapOf("email" to username, "password" to passwordHex, "mfa" to mfa)) .toRequestBody("application/json".toMediaType()) val request = Request.Builder() diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index d2ce43b..29c1161 100644 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -100,6 +100,7 @@ termora.settings.account.register=Register termora.settings.account.not-support-register=This server does not support account registration termora.settings.account.login=Log in termora.settings.account.server=Server +termora.settings.account.mfa=MFA is optional termora.settings.account.locally=locally termora.settings.account.lifetime=Lifetime termora.settings.account.upgrade=Upgrade diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties index 3bc06c8..8dce696 100644 --- a/src/main/resources/i18n/messages_zh_CN.properties +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -109,6 +109,7 @@ termora.settings.account.login=登录 termora.settings.account.register=注册 termora.settings.account.not-support-register=该服务器不支持注册账号 termora.settings.account.server=服务器 +termora.settings.account.mfa=多因素验证是可选的 termora.settings.account.locally=本地的 termora.settings.account.lifetime=长期 termora.settings.account.verify=验证 diff --git a/src/main/resources/i18n/messages_zh_TW.properties b/src/main/resources/i18n/messages_zh_TW.properties index dd5d705..d4db0d2 100644 --- a/src/main/resources/i18n/messages_zh_TW.properties +++ b/src/main/resources/i18n/messages_zh_TW.properties @@ -121,6 +121,7 @@ termora.settings.account.login=登入 termora.settings.account.register=註冊 termora.settings.account.not-support-register=此伺服器不支援註冊帳號 termora.settings.account.server=伺服器 +termora.settings.account.mfa=多因素驗證是可選的 termora.settings.account.locally=本地的 termora.settings.account.lifetime=長期 termora.settings.account.verify=驗證