fix(tree-wide): re-apply yuzu specific changes

This commit is contained in:
liushuyu 2021-10-14 21:13:31 -06:00
parent a816cbe767
commit dde96db57c
No known key found for this signature in database
GPG Key ID: 23D1CE4534419437
16 changed files with 133 additions and 127 deletions

View File

@ -2,7 +2,6 @@
//!
//! Provides mechanisms to authenticate users using JWT.
use std::collections::HashMap;
use std::sync::Arc;
use futures::{Future, Stream};
@ -13,16 +12,14 @@ use jwt::{decode, Algorithm, Validation};
use reqwest::header::USER_AGENT;
use url::form_urlencoded;
use crate::frontend::rest::services::Future as InternalFuture;
use crate::frontend::rest::services::{default_future, Request, Response, WebService};
use frontend::rest::services::Future as InternalFuture;
use frontend::rest::services::{default_future, Request, Response, WebService};
use crate::http::{build_async_client, build_client};
use http::{build_async_client, build_client};
use crate::config::JWTValidation;
use config::JWTValidation;
use logging::LoggingErrors;
use crate::logging::LoggingErrors;
#[derive(Debug, Serialize, Deserialize)]
struct Auth {
@ -48,6 +45,12 @@ pub struct JWTClaims {
pub is_subscribed: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
struct AuthRequest {
username: String,
token: String
}
/// Calls the given server to obtain a JWT token and returns a Future<String> with the response
pub fn authenticate_async(
url: String,
@ -163,6 +166,7 @@ pub fn validate_token(
}
pub fn handle(service: &WebService, _req: Request) -> InternalFuture {
info!("Handling authentication");
let framework = service
.framework
.read()
@ -185,14 +189,12 @@ pub fn handle(service: &WebService, _req: Request) -> InternalFuture {
_req.body()
.concat2()
.map(move |body| {
let req = form_urlencoded::parse(body.as_ref())
.into_owned()
.collect::<HashMap<String, String>>();
let req: AuthRequest = serde_json::from_slice(&body).log_expect("Malformed request");
// Determine which credentials we should use
let (username, token) = {
let req_username = req.get("username").log_expect("No username in request");
let req_token = req.get("token").log_expect("No token in request");
let req_username = req.username;
let req_token = req.token;
// if the user didn't provide credentials, and theres nothing stored in the
// database, return an early error

View File

@ -2,20 +2,21 @@
//!
//! Launches the user's web browser on request from the frontend.
use frontend::rest::services::Future as InternalFuture;
use frontend::rest::services::{Request, Response, WebService};
use crate::frontend::rest::services::Future as InternalFuture;
use crate::frontend::rest::services::{Request, Response, WebService};
use crate::logging::LoggingErrors;
use futures::{Future, Stream};
use hyper::header::ContentType;
use logging::LoggingErrors;
use std::collections::HashMap;
use url::form_urlencoded;
#[derive(Debug, Serialize, Deserialize, Clone)]
struct OpenRequest {
url: String,
}
pub fn handle(_service: &WebService, req: Request) -> InternalFuture {
Box::new(req.body().concat2().map(move |body| {
let req = form_urlencoded::parse(body.as_ref())
.into_owned()
.collect::<HashMap<String, String>>();
if webbrowser::open(req.get("url").log_expect("No URL to launch")).is_ok() {
let req: OpenRequest = serde_json::from_slice(&body).log_expect("Malformed request");
if webbrowser::open(&req.url).is_ok() {
Response::new()
.with_status(hyper::Ok)
.with_header(ContentType::json())

View File

@ -39,6 +39,7 @@ pub fn handle(service: &WebService, req: Request) -> Future {
} else if key == "installDesktopShortcut" {
info!("Found installDesktopShortcut {:?}", value);
install_desktop_shortcut = value == "true";
continue;
}
if key == "mode" && value == "force" {

View File

@ -17,7 +17,7 @@ enum CallbackType {
/// Starts the main web UI. Will return when UI is closed.
pub fn start_ui(app_name: &str, http_address: &str, is_launcher: bool) {
let size = if is_launcher { (600, 300) } else { (1024, 500) };
let size = if is_launcher { (600, 300) } else { (1024, 600) };
info!("Spawning web view instance");

View File

@ -333,7 +333,7 @@ mod natives {
};
path.push(format!("{}.desktop", slugify(name))); // file name
let desktop_file = format!(
"[Desktop Entry]\nName={}\nExec=\"{}\" {}\nComment={}\nPath={}\n",
"[Desktop Entry]\nName={}\nExec=\"{}\" {}\nComment={}\nType=Application\nPath={}\n",
name, target, args, description, working_dir
);
let desktop_f = File::create(path);

View File

@ -2,10 +2,10 @@
//!
//! Contains the yuzu-emu core API implementation of a release source.
use http::build_client;
use crate::http::build_client;
use crate::sources::types::*;
use reqwest::header::USER_AGENT;
use reqwest::StatusCode;
use sources::types::*;
pub struct PatreonReleases {}

View File

@ -1,13 +1,13 @@
//! Validates that users have correct authorization to download packages.
use frontend::rest::services::authentication;
use crate::frontend::rest::services::authentication;
use installer::InstallerFramework;
use crate::installer::InstallerFramework;
use logging::LoggingErrors;
use crate::logging::LoggingErrors;
use tasks::resolver::ResolvePackageTask;
use tasks::{Task, TaskDependency, TaskMessage, TaskOrdering, TaskParamType};
use crate::tasks::resolver::ResolvePackageTask;
use crate::tasks::{Task, TaskDependency, TaskMessage, TaskOrdering, TaskParamType};
pub struct CheckAuthorizationTask {
pub name: String,

View File

@ -9,8 +9,6 @@ use crate::tasks::TaskMessage;
use crate::tasks::TaskOrdering;
use crate::tasks::TaskParamType;
use crate::tasks::resolver::ResolvePackageTask;
use crate::http::stream_file;
use number_prefix::NumberPrefix::{self, Prefixed, Standalone};

View File

@ -1,17 +1,17 @@
//! Generates shortcuts for a specified file.
use installer::InstallerFramework;
use crate::installer::InstallerFramework;
use tasks::Task;
use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType;
use crate::tasks::Task;
use crate::tasks::TaskDependency;
use crate::tasks::TaskMessage;
use crate::tasks::TaskParamType;
use config::PackageDescription;
use crate::config::PackageDescription;
use logging::LoggingErrors;
use crate::logging::LoggingErrors;
use native::create_desktop_shortcut;
use crate::native::create_shortcut;
pub struct InstallDesktopShortcutTask {
pub name: String,
@ -81,7 +81,7 @@ impl Task for InstallDesktopShortcutTask {
.to_str()
.log_expect("Unable to build shortcut metadata (exe)");
installed_files.push(create_desktop_shortcut(
installed_files.push(create_shortcut(
&shortcut.name,
&shortcut.description,
tool_path,

View File

@ -22,9 +22,9 @@ use crate::logging::LoggingErrors;
use crate::archives;
use crate::tasks::install_desktop_shortcut::InstallDesktopShortcutTask;
use std::fs::OpenOptions;
use std::path::Path;
use tasks::install_desktop_shortcut::InstallDesktopShortcutTask;
pub struct InstallPackageTask {
pub name: String,
@ -70,13 +70,18 @@ impl Task for InstallPackageTask {
// Ignore input from the uninstaller - no useful information passed
// If a previous task Breaks, then just early exit
match input.pop().log_expect("Install Package Task should have guaranteed output!") {
match input
.pop()
.log_expect("Install Package Task should have guaranteed output!")
{
TaskParamType::Break => return Ok(TaskParamType::None),
_ => (),
};
// Grab data from the resolver
let data = input.pop().log_expect("Install Package Task should have input from resolver!");
let data = input
.pop()
.log_expect("Install Package Task should have input from resolver!");
let (version, file, data) = match data {
TaskParamType::FileContents(version, file, data) => (version, file, data),
_ => return Err("Unexpected file contents param type to install package".to_string()),
@ -201,7 +206,7 @@ impl Task for InstallPackageTask {
TaskOrdering::Post,
Box::new(InstallDesktopShortcutTask {
name: self.name.clone(),
should_run: self.create_desktop_shortcuts
should_run: self.create_desktop_shortcuts,
}),
),
TaskDependency::build(TaskOrdering::Post, Box::new(SaveDatabaseTask {})),

View File

@ -2,16 +2,16 @@
//! If theres multiple launchable packages, then choose the first listed in config
//! If there are multiple shortcuts for the first package, then launch the first.
use installer::InstallerFramework;
use crate::installer::InstallerFramework;
use tasks::Task;
use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType;
use crate::tasks::Task;
use crate::tasks::TaskDependency;
use crate::tasks::TaskMessage;
use crate::tasks::TaskParamType;
use config::PackageDescription;
use crate::config::PackageDescription;
use logging::LoggingErrors;
use crate::logging::LoggingErrors;
pub struct LaunchOnExitTask {}

View File

@ -100,7 +100,8 @@ app.get('/api/config', (req, res) => {
})
app.post('/api/start-install', (req, res) => {
console.log(`-- Install: ${req}`)
console.log('-- Install:')
console.log(req.body)
progressSimulation(res)
})

View File

@ -152,10 +152,13 @@ const app = new Vue({
const that = this
const app = this.$root
app.ajax('/api/check-auth', function (auth) {
app.$data.username = auth.username
app.$data.token = auth.token
that.jwt_token = auth.jwt_token
axios.post('/api/check-auth', {
username: app.$data.username,
token: app.$data.token
}).then(function (resp) {
app.$data.username = resp.data.username
app.$data.token = resp.data.token
that.jwt_token = resp.data.jwt_token
that.is_authenticated = Object.keys(that.jwt_token).length !== 0 && that.jwt_token.constructor === Object
if (that.is_authenticated) {
// Give all permissions to vip roles
@ -166,13 +169,10 @@ const app = new Vue({
if (success) {
success()
}
}, function (e) {
}).catch(function () {
if (error) {
error()
}
}, {
username: app.$data.username,
token: app.$data.token
})
},
stream_ajax: streamAjax

View File

@ -75,56 +75,55 @@
<script>
export default {
name: 'AuthenticationView',
created: function() {
created: function () {
// If they are already authenticated when this page is loaded,
// then we can asssume they are "clicking here for more details" and should show the appropriate error message
if (this.$root.is_authenticated) {
this.verification_opened = true;
this.verification_opened = true
}
},
data: function() {
data: function () {
return {
browser_opened: false,
verification_opened: false,
invalid_token: false,
invalid_token: false
}
},
computed: {
show_header: function() {
return !this.browser_opened && !this.verification_opened && !this.invalid_token;
show_header: function () {
return !this.browser_opened && !this.verification_opened && !this.invalid_token
},
invalid_login: function() {
return this.verification_opened && !this.$root.is_authenticated;
invalid_login: function () {
return this.verification_opened && !this.$root.is_authenticated
},
unlinked_patreon: function() {
return this.verification_opened && this.$root.is_authenticated && !this.$root.is_linked;
unlinked_patreon: function () {
return this.verification_opened && this.$root.is_authenticated && !this.$root.is_linked
},
no_subscription: function() {
return this.verification_opened && this.$root.is_linked && !this.$root.is_subscribed;
no_subscription: function () {
return this.verification_opened && this.$root.is_linked && !this.$root.is_subscribed
},
tier_not_selected: function() {
return this.verification_opened && this.$root.is_linked && this.$root.is_subscribed && !this.$root.has_reward_tier;
tier_not_selected: function () {
return this.verification_opened && this.$root.is_linked && this.$root.is_subscribed && !this.$root.has_reward_tier
},
combined_token: {
// getter
get: function () {
if (this.$root.$data.username && this.$root.$data.token) {
return btoa(this.$root.$data.username + ":" + this.$root.$data.token)
return btoa(this.$root.$data.username + ':' + this.$root.$data.token)
}
return "";
return ''
},
// setter
set: function (newValue) {
try {
var split = atob(newValue).split(':')
this.$root.$data.username = split[0];
this.$root.$data.token = split[1];
this.invalid_token = false;
const split = atob(newValue).split(':')
this.$root.$data.username = split[0]
this.$root.$data.token = split[1]
this.invalid_token = false
} catch (e) {
this.invalid_token = true;
this.invalid_token = true
}
}
}
@ -134,37 +133,35 @@ export default {
this.$router.go(-1)
},
paste: function () {
document.getElementById("token").focus();
document.execCommand("paste");
document.getElementById('token').focus()
document.execCommand('paste')
},
launch_browser: function(url) {
const that = this;
let app = this.$root;
app.ajax('/api/open-browser', function (e) {
launch_browser: function (url) {
const that = this
this.$http.post('/api/open-browser', {
url: url
}).then(function () {
// only open the browser opened message if there isn't an error message currently
if (!that.verification_opened) {
that.browser_opened = true;
that.browser_opened = true
}
}, function (e) {}, {
"url": url,
});
}).catch(function () {})
},
verify_token: function() {
this.browser_opened = false;
this.$root.check_authentication(this.success, this.error);
verify_token: function () {
this.browser_opened = false
this.$root.check_authentication(this.success, this.error)
},
success: function() {
success: function () {
// if they are eligible, go back to the select package page
if (this.$root.has_reward_tier) {
this.$router.go(-1);
return;
this.$router.go(-1)
return
}
// They aren't currently eligible for the release, so display the error message
this.verification_opened = true;
this.verification_opened = true
},
error: function() {
this.verification_opened = true;
error: function () {
this.verification_opened = true
}
}
}

View File

@ -26,20 +26,20 @@
</template>
<script>
export default {
name: "ReAuthenticationView",
methods: {
go_authenticate: function() {
this.$router.replace('/authentication')
},
launch_old_version: function () {
this.$root.exit()
},
go_packages: function () {
this.$router.push('/packages')
}
export default {
name: 'ReAuthenticationView',
methods: {
go_authenticate: function () {
this.$router.replace('/authentication')
},
launch_old_version: function () {
this.$root.exit()
},
go_packages: function () {
this.$router.push('/packages')
}
}
}
</script>
<style scoped>

View File

@ -26,14 +26,14 @@
</div>
</div>
</div>
<div class="tile is-child is-6 box clickable-box" v-if="!$root.$data.metadata.preexisting_install" v-on:click.capture.stop="installDesktopShortcut = !installDesktopShortcut">
<h4>Install Options</h4>
<b-checkbox v-model="installDesktopShortcut">
Create Desktop Shortcut
</b-checkbox>
</div>
</div>
</div>
<div class="tile is-child is-6 box clickable-box" v-if="!$root.$data.metadata.preexisting_install" v-on:click.capture.stop="installDesktopShortcut = !installDesktopShortcut">
<h4>Install Options</h4>
<b-checkbox v-model="installDesktopShortcut">
Create Desktop Shortcut
</b-checkbox>
</div>
<div class="subtitle is-6" v-if="!$root.$data.metadata.preexisting_install && advanced">{{ $t('select_packages.location') }}</div>
<div class="field has-addons" v-if="!$root.$data.metadata.preexisting_install && advanced">
@ -79,6 +79,7 @@ export default {
name: 'SelectPackages',
data: function () {
return {
publicPath: process.env.BASE_URL,
advanced: false,
repair: false,
installDesktopShortcut: true
@ -131,22 +132,22 @@ export default {
}
// maintenance + repair
if (this.repair) {
this.$router.push('/install/repair')
this.$router.push('/install/repair/' + this.installDesktopShortcut.toString())
return
}
// maintenance + modify
if (this.$root.$data.metadata.preexisting_install) {
this.$router.push('/install/regular')
this.$router.push('/install/regular/' + this.installDesktopShortcut.toString())
return
}
const my = this
this.$http.post('/api/verify-path', `path=${this.$root.$data.install_location}`).then(function (resp) {
const data = resp.data || {}
if (!data.exists) {
my.$router.push('/install/regular')
my.$router.push('/install/regular/' + my.installDesktopShortcut.toString())
} else {
my.show_overwrite_dialog(function () {
my.$router.push('/install/repair')
my.$router.push('/install/repair/' + my.installDesktopShortcut.toString())
})
}
})