diff --git a/src/confighttp.cpp b/src/confighttp.cpp index 92f50a16..b7fd1552 100644 --- a/src/confighttp.cpp +++ b/src/confighttp.cpp @@ -766,8 +766,8 @@ namespace confighttp { } outputTree.put("otp", nvhttp::request_otp(it->second)); - outputTree.put("statue", true); - outputTree.put("message", "OTP created, effective within 1 minute."); + outputTree.put("status", true); + outputTree.put("message", "OTP created, effective within 3 minutes."); } catch (std::exception &e) { BOOST_LOG(warning) << "OTP creation failed: "sv << e.what(); diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index 74f2fcca..9971f05d 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -619,10 +619,10 @@ namespace nvhttp { tree.put("root..status_code", 503); tree.put("root..status_message", "OTP auth not available."); } else { - auto hash = util::hex(crypto::hash(one_time_pin + ptr->second.async_insert_pin.salt + otp_passphrase)); + auto hash = util::hex(crypto::hash(one_time_pin + ptr->second.async_insert_pin.salt + otp_passphrase), true); if (hash.to_string_view() == it->second) { - getservercert(ptr->second, tree, one_time_pin); + pin(one_time_pin, deviceName); one_time_pin.clear(); otp_passphrase.clear(); return; diff --git a/src/nvhttp.h b/src/nvhttp.h index 7bd70d32..ada9b197 100644 --- a/src/nvhttp.h +++ b/src/nvhttp.h @@ -44,7 +44,7 @@ namespace nvhttp { */ constexpr auto PORT_HTTPS = -5; - constexpr auto OTP_EXPIRE_DURATION = 60s; + constexpr auto OTP_EXPIRE_DURATION = 180s; /** * @brief Start the nvhttp server. diff --git a/src_assets/common/assets/web/pin.html b/src_assets/common/assets/web/pin.html index 2b09a188..5174c8cc 100644 --- a/src_assets/common/assets/web/pin.html +++ b/src_assets/common/assets/web/pin.html @@ -3,23 +3,49 @@ <%- header %> + + -
-

{{ $t('pin.pin_pairing') }}

-
+
+ + +
+

{{ otp && otp || '????' }}

+ + +
+
{{ otpMessage }}
+
{{ $t('pin.otp_msg') }}
+ +
-
- {{ $t('_common.warning') }} {{ $t('pin.warning_msg') }} -
+
+ {{ $t('_common.warning') }} {{ $t('pin.warning_msg') }} +
@@ -28,11 +54,22 @@ import { initApp } from './init' import Navbar from './Navbar.vue' + let resetOTPTimeout = null; + let app = createApp({ components: { Navbar }, inject: ['i18n'], + data() { + return { + currentTab: 'OTP', + otp: '', + passphrase: '', + otpMessage: '', + otpStatus: 'warning' + } + }, methods: { registerDevice(e) { let pin = document.querySelector("#pin-input").value; @@ -54,6 +91,29 @@ ).innerHTML = ``; } }); + }, + requestOTP() { + fetch(`/api/otp?passphrase=${this.passphrase}`) + .then(resp => resp.json()) + .then(resp => { + if (resp.status !== 'true') { + this.otpMessage = resp.message + this.otpStatus = 'danger' + return + } + + this.otp = resp.otp + this.otpStatus = 'success' + this.otpMessage = this.i18n.t('pin.otp_success') + + if (resetOTPTimeout !== null) clearTimeout(resetOTPTimeout) + resetOTPTimeout = setTimeout(() => { + this.otp = this.i18n.t('pin.otp_expired') + this.otpMessage = this.i18n.t('pin.otp_expired_msg') + this.otpStatus = 'warning' + resetOTPTimeout = null + }, 3 * 60 * 1000) + }) } } }); diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json index 1350f266..716332fd 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -373,7 +373,14 @@ "pair_success": "Success! Please check Moonlight to continue", "pin_pairing": "PIN Pairing", "send": "Send", - "warning_msg": "Make sure you have access to the client you are pairing with. This software can give total control to your computer, so be careful!" + "warning_msg": "Make sure you have access to the client you are pairing with. This software can give total control to your computer, so be careful!", + "otp_pairing": "OTP Pairing", + "generate_pin": "Generate PIN", + "otp_passphrase": "One Time Passphrase", + "otp_expired": "EXPIRED", + "otp_expired_msg": "OTP expired. Please request a new one.", + "otp_success": "PIN request success, the PIN is available within 3 minutes.", + "otp_msg": "OTP pairing is only available for Artemis clients. Please use legacy pairing method for other clients." }, "resource_card": { "github_discussions": "GitHub Discussions", diff --git a/src_assets/common/assets/web/public/assets/locale/zh.json b/src_assets/common/assets/web/public/assets/locale/zh.json index 4b84a1e1..74bf4084 100644 --- a/src_assets/common/assets/web/public/assets/locale/zh.json +++ b/src_assets/common/assets/web/public/assets/locale/zh.json @@ -374,7 +374,14 @@ "pair_success": "成功!请检查 Moonlight 以继续", "pin_pairing": "PIN 码配对", "send": "发送", - "warning_msg": "请确保您可以掌控您正在配对的客户端。该软件可以完全控制您的计算机,请务必小心!" + "warning_msg": "请确保您可以掌控您正在配对的客户端。该软件可以完全控制您的计算机,请务必小心!", + "otp_pairing": "OTP 配对", + "generate_pin": "生成 PIN", + "otp_passphrase": "一次性口令", + "otp_expired": "已过期", + "otp_expired_msg": "口令已过期,请重新请求。", + "otp_success": "一次性 PIN 请求成功,3分钟内有效。", + "otp_msg": "一次性口令目前仅支持 Artemis 客户端使用。其他客户端请使用传统配对方式。" }, "resource_card": { "github_discussions": "Github 讨论区",