mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 12:45:56 +08:00
Connect login: updating also user script when refreshed access token arives, this should fix passing old token on page reload
This commit is contained in:
parent
f9164da380
commit
3d130ceb76
@ -332,6 +332,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
Utils/Http.hpp
|
||||
Utils/FixModelByWin10.cpp
|
||||
Utils/FixModelByWin10.hpp
|
||||
Utils/Jwt.cpp
|
||||
Utils/Jwt.hpp
|
||||
Utils/Moonraker.cpp
|
||||
Utils/Moonraker.hpp
|
||||
Utils/OctoPrint.cpp
|
||||
|
@ -475,8 +475,7 @@ void UserAccountCommunication::enqueue_refresh()
|
||||
BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in.";
|
||||
return;
|
||||
}
|
||||
if (m_session->is_enqueued(UserAccountActionID::USER_ACCOUNT_ACTION_REFRESH_TOKEN))
|
||||
{
|
||||
if (m_session->is_enqueued(UserAccountActionID::USER_ACCOUNT_ACTION_REFRESH_TOKEN)) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "User Account: Token refresh already enqueued, skipping...";
|
||||
return;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "GUI_App.hpp"
|
||||
#include "format.hpp"
|
||||
#include "../Utils/Http.hpp"
|
||||
#include "../Utils/Jwt.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
@ -53,8 +54,17 @@ void UserActionGetWithEvent::perform(wxEvtHandler* evt_handler, const std::strin
|
||||
{
|
||||
std::string url = m_url + input;
|
||||
auto http = Http::get(std::move(url));
|
||||
if (!access_token.empty())
|
||||
if (!access_token.empty()) {
|
||||
http.header("Authorization", "Bearer " + access_token);
|
||||
#ifndef _NDEBUG
|
||||
// In debug mode, also verify the token expiration
|
||||
// This is here to help with "dev" accounts with shorten (sort of faked) expiration time
|
||||
// The /api/v1/me will accept these tokens even if these are fake-marked as expired
|
||||
if (!Utils::verify_exp(access_token)) {
|
||||
fail_callback("Token Expired");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
http.on_error([evt_handler, fail_callback, action_name = &m_action_name, fail_evt_type = m_fail_evt_type](std::string body, std::string error, unsigned status) {
|
||||
if (fail_callback)
|
||||
fail_callback(body);
|
||||
|
@ -540,7 +540,7 @@ void ConnectRequestHandler::handle_message(const std::string& message)
|
||||
|
||||
void ConnectRequestHandler::on_connect_action_error(const std::string &message_data)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "WebKit runtime error: " << message_data;
|
||||
BOOST_LOG_TRIVIAL(error) << "WebView runtime error: " << message_data;
|
||||
}
|
||||
|
||||
void ConnectRequestHandler::resend_config()
|
||||
@ -550,7 +550,7 @@ void ConnectRequestHandler::resend_config()
|
||||
|
||||
void ConnectRequestHandler::on_connect_action_log(const std::string& message_data)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "WebKit log: " << message_data;
|
||||
BOOST_LOG_TRIVIAL(info) << "WebView log: " << message_data;
|
||||
}
|
||||
|
||||
void ConnectRequestHandler::on_connect_action_request_config(const std::string& message_data)
|
||||
@ -647,8 +647,9 @@ wxString ConnectWebViewPanel::get_login_script(bool refresh)
|
||||
R"(
|
||||
if (window._prusaSlicer_initLogin !== undefined) {
|
||||
console.log('Refreshing login');
|
||||
_prusaSlicer.postMessage({action: 'LOG', message: 'Refreshing login'});
|
||||
_prusaSlicer_initLogin('%s');
|
||||
if (window._prusaSlicer !== undefined)
|
||||
_prusaSlicer.postMessage({action: 'LOG', message: 'Refreshing login'});
|
||||
_prusaSlicer_initLogin('%s', 'refresh');
|
||||
} else {
|
||||
console.log('Refreshing login skipped as no _prusaSlicer_initLogin defined (yet?)');
|
||||
if (window._prusaSlicer === undefined) {
|
||||
@ -660,7 +661,11 @@ wxString ConnectWebViewPanel::get_login_script(bool refresh)
|
||||
)"
|
||||
:
|
||||
R"(
|
||||
function _prusaSlicer_log(msg) { console.log(msg); _prusaSlicer.postMessage({action: 'LOG', message: msg}); }
|
||||
function _prusaSlicer_log(msg) {
|
||||
console.log(msg);
|
||||
if (window._prusaSlicer !== undefined)
|
||||
_prusaSlicer.postMessage({action: 'LOG', message: msg});
|
||||
}
|
||||
function _prusaSlicer_errorHandler(err) {
|
||||
const msg = {
|
||||
action: 'ERROR',
|
||||
@ -677,7 +682,7 @@ wxString ConnectWebViewPanel::get_login_script(bool refresh)
|
||||
});
|
||||
}
|
||||
|
||||
async function _prusaSlicer_initLogin(token) {
|
||||
async function _prusaSlicer_initLogin(token, reason) {
|
||||
const parts = token.split('.');
|
||||
const claims = JSON.parse(atob(parts[1]));
|
||||
const now = new Date().getTime() / 1000;
|
||||
@ -694,10 +699,10 @@ wxString ConnectWebViewPanel::get_login_script(bool refresh)
|
||||
let error = false;
|
||||
|
||||
try {
|
||||
_prusaSlicer_log('Slicer Login request');
|
||||
_prusaSlicer_log('Slicer Login request (' + reason + ') ' + token.substring(token.length - 8));
|
||||
let resp = await fetch('/slicer/login', {method: 'POST', headers: {Authorization: 'Bearer ' + token}});
|
||||
let body = await resp.text();
|
||||
_prusaSlicer_log('Slicer Login resp ' + resp.status + ' body: ' + body);
|
||||
_prusaSlicer_log('Slicer Login resp ' + resp.status + ' (' +reason + ' ' + token.substring(token.length - 8) + ') body: ' + body);
|
||||
if (resp.status >= 500 || resp.status == 408) {
|
||||
retry = true;
|
||||
} else {
|
||||
@ -721,7 +726,7 @@ wxString ConnectWebViewPanel::get_login_script(bool refresh)
|
||||
}
|
||||
if (window._prusaSlicer_initialLoad === undefined) {
|
||||
console.log('Initial login');
|
||||
_prusaSlicer_initLogin('%s');
|
||||
_prusaSlicer_initLogin('%s', 'init-load');
|
||||
window._prusaSlicer_initialLoad = true;
|
||||
}
|
||||
)",
|
||||
@ -743,7 +748,12 @@ void ConnectWebViewPanel::on_user_token(UserAccountSuccessEvent& e)
|
||||
e.Skip();
|
||||
auto access_token = wxGetApp().plater()->get_user_account()->get_access_token();
|
||||
assert(!access_token.empty());
|
||||
wxString javascript = get_login_script(true);
|
||||
wxString javascript = get_login_script(false);
|
||||
|
||||
m_browser->RemoveAllUserScripts();
|
||||
m_browser->AddUserScript(javascript);
|
||||
|
||||
javascript = get_login_script(true);
|
||||
//m_browser->AddUserScript(javascript, wxWEBVIEW_INJECT_AT_DOCUMENT_END);
|
||||
BOOST_LOG_TRIVIAL(debug) << "RunScript " << javascript << "\n";
|
||||
m_browser->RunScriptAsync(javascript);
|
||||
|
58
src/slic3r/Utils/Jwt.cpp
Normal file
58
src/slic3r/Utils/Jwt.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "Jwt.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/beast/core/detail/base64.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
namespace Slic3r::Utils {
|
||||
|
||||
bool verify_exp(const std::string& token)
|
||||
{
|
||||
size_t payload_start = token.find('.');
|
||||
if (payload_start == std::string::npos)
|
||||
return false;
|
||||
payload_start += 1; // payload starts after dot
|
||||
|
||||
const size_t payload_end = token.find('.', payload_start);
|
||||
if (payload_end == std::string::npos)
|
||||
return false;
|
||||
|
||||
size_t encoded_length = payload_end - payload_start;
|
||||
size_t decoded_length = boost::beast::detail::base64::decoded_size(encoded_length);
|
||||
|
||||
auto json_b64 = token.substr(payload_start, encoded_length);
|
||||
std::replace(json_b64.begin(), json_b64.end(), '-', '+');
|
||||
std::replace(json_b64.begin(), json_b64.end(), '_', '/');
|
||||
|
||||
size_t padding = encoded_length % 4;
|
||||
encoded_length += padding;
|
||||
while (padding--) json_b64 += '=';
|
||||
|
||||
|
||||
std::string json;
|
||||
json.resize(decoded_length + 2);
|
||||
size_t read_bytes, written_bytes;
|
||||
std::tie(written_bytes, read_bytes) = boost::beast::detail::base64::decode(json.data(), json_b64.data(), json_b64.length());
|
||||
json.resize(written_bytes);
|
||||
if (written_bytes == 0)
|
||||
return false;
|
||||
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
pt::ptree payload;
|
||||
std::istringstream iss(json);
|
||||
pt::json_parser::read_json(iss, payload);
|
||||
|
||||
auto exp_opt = payload.get_optional<double>("exp");
|
||||
if (!exp_opt)
|
||||
return false;
|
||||
|
||||
auto now = time(nullptr);
|
||||
return exp_opt.get() > now;
|
||||
}
|
||||
|
||||
}
|
10
src/slic3r/Utils/Jwt.hpp
Normal file
10
src/slic3r/Utils/Jwt.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r::Utils {
|
||||
|
||||
bool verify_exp(const std::string& token);
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user