mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-02-23 19:15:00 +01:00
Compare commits
4 Commits
v2025.4.0-
...
v2025.4.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1b18105b5 | ||
|
|
eb5ef7d7d5 | ||
|
|
6eb16afd96 | ||
|
|
9e68e276a1 |
@@ -24,7 +24,7 @@ export async function getAccessToken(
|
||||
params: HttpUrlParameter[];
|
||||
},
|
||||
): Promise<AccessTokenRawResponse> {
|
||||
console.log('Getting access token', accessTokenUrl);
|
||||
console.log('[oauth2] Getting access token', accessTokenUrl);
|
||||
const httpRequest: Partial<HttpRequest> = {
|
||||
method: 'POST',
|
||||
url: accessTokenUrl,
|
||||
|
||||
@@ -68,7 +68,7 @@ export async function getOrRefreshAccessToken(ctx: Context, contextId: string, {
|
||||
if (resp.status === 401) {
|
||||
// Bad refresh token, so we'll force it to fetch a fresh access token by deleting
|
||||
// and returning null;
|
||||
console.log('Unauthorized refresh_token request');
|
||||
console.log('[oauth2] Unauthorized refresh_token request');
|
||||
await deleteToken(ctx, contextId);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ export async function getAuthorizationCode(
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const authorizationUrlStr = authorizationUrl.toString();
|
||||
console.log('Authorizing', authorizationUrlStr);
|
||||
const logsEnabled = (await ctx.store.get('enable_logs')) ?? false;
|
||||
console.log('[oauth2] Authorizing', authorizationUrlStr);
|
||||
|
||||
let foundCode = false;
|
||||
|
||||
@@ -85,11 +86,15 @@ export async function getAuthorizationCode(
|
||||
},
|
||||
async onNavigate({ url: urlStr }) {
|
||||
const url = new URL(urlStr);
|
||||
if (logsEnabled) console.log('[oauth2] Navigated to', urlStr);
|
||||
|
||||
if (url.searchParams.has('error')) {
|
||||
return reject(new Error(`Failed to authorize: ${url.searchParams.get('error')}`));
|
||||
}
|
||||
|
||||
const code = url.searchParams.get('code');
|
||||
if (!code) {
|
||||
console.log('[oauth2] Code not found');
|
||||
return; // Could be one of many redirects in a chain, so skip it
|
||||
}
|
||||
|
||||
@@ -97,6 +102,7 @@ export async function getAuthorizationCode(
|
||||
foundCode = true;
|
||||
close();
|
||||
|
||||
console.log('[oauth2] Code found');
|
||||
const response = await getAccessToken(ctx, {
|
||||
grantType: 'authorization_code',
|
||||
accessTokenUrl,
|
||||
|
||||
@@ -53,6 +53,7 @@ const authorizationUrls = [
|
||||
'https://www.dropbox.com/oauth2/authorize',
|
||||
'https://www.linkedin.com/oauth/v2/authorization',
|
||||
'https://MY_SHOP.myshopify.com/admin/oauth/access_token',
|
||||
'https://appcenter.intuit.com/app/connect/oauth2/authorize',
|
||||
];
|
||||
|
||||
const accessTokenUrls = [
|
||||
@@ -69,6 +70,7 @@ const accessTokenUrls = [
|
||||
'https://www.googleapis.com/oauth2/v4/token',
|
||||
'https://www.linkedin.com/oauth/v2/accessToken',
|
||||
'https://MY_SHOP.myshopify.com/admin/oauth/authorize',
|
||||
'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer',
|
||||
];
|
||||
|
||||
export const plugin: PluginDefinition = {
|
||||
@@ -109,6 +111,17 @@ export const plugin: PluginDefinition = {
|
||||
await resetDataDirKey(ctx, contextId);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Toggle Debug Logs',
|
||||
async onSelect(ctx) {
|
||||
const enableLogs = !(await ctx.store.get('enable_logs'));
|
||||
await ctx.store.set('enable_logs', enableLogs);
|
||||
await ctx.toast.show({
|
||||
message: `Debug logs ${enableLogs ? 'enabled' : 'disabled'}`,
|
||||
color: 'info',
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
args: [
|
||||
{
|
||||
@@ -290,6 +303,7 @@ export const plugin: PluginDefinition = {
|
||||
const headerPrefix = stringArg(values, 'headerPrefix');
|
||||
const grantType = stringArg(values, 'grantType') as GrantType;
|
||||
const credentialsInBody = values.credentials === 'body';
|
||||
const tokenName = values.tokenName === 'id_token' ? 'id_token' : 'access_token';
|
||||
|
||||
let token: AccessToken;
|
||||
if (grantType === 'authorization_code') {
|
||||
@@ -315,7 +329,7 @@ export const plugin: PluginDefinition = {
|
||||
codeVerifier: stringArgOrNull(values, 'pkceCodeVerifier'),
|
||||
}
|
||||
: null,
|
||||
tokenName: values.tokenName === 'id_token' ? 'id_token' : 'access_token',
|
||||
tokenName: tokenName,
|
||||
});
|
||||
} else if (grantType === 'implicit') {
|
||||
const authorizationUrl = stringArg(values, 'authorizationUrl');
|
||||
@@ -329,7 +343,7 @@ export const plugin: PluginDefinition = {
|
||||
scope: stringArgOrNull(values, 'scope'),
|
||||
audience: stringArgOrNull(values, 'audience'),
|
||||
state: stringArgOrNull(values, 'state'),
|
||||
tokenName: values.tokenName === 'id_token' ? 'id_token' : 'access_token',
|
||||
tokenName: tokenName,
|
||||
});
|
||||
} else if (grantType === 'client_credentials') {
|
||||
const accessTokenUrl = stringArg(values, 'accessTokenUrl');
|
||||
@@ -361,7 +375,7 @@ export const plugin: PluginDefinition = {
|
||||
throw new Error('Invalid grant type ' + grantType);
|
||||
}
|
||||
|
||||
const headerValue = `${headerPrefix} ${token.response.access_token}`.trim();
|
||||
const headerValue = `${headerPrefix} ${token.response[tokenName]}`.trim();
|
||||
return {
|
||||
setHeaders: [
|
||||
{
|
||||
|
||||
@@ -37,12 +37,12 @@ export async function getDataDirKey(ctx: Context, contextId: string) {
|
||||
return `${contextId}::${key}`;
|
||||
}
|
||||
|
||||
function tokenStoreKey(context_id: string) {
|
||||
return ['token', context_id].join('::');
|
||||
function tokenStoreKey(contextId: string) {
|
||||
return ['token', contextId].join('::');
|
||||
}
|
||||
|
||||
function dataDirStoreKey(context_id: string) {
|
||||
return ['data_dir', context_id].join('::');
|
||||
function dataDirStoreKey(contextId: string) {
|
||||
return ['data_dir', contextId].join('::');
|
||||
}
|
||||
|
||||
export interface AccessToken {
|
||||
|
||||
@@ -1388,7 +1388,7 @@ pub fn run() {
|
||||
if let Err(e) = app_handle.save_window_state(StateFlags::all()) {
|
||||
warn!("Failed to save window state {e:?}");
|
||||
} else {
|
||||
debug!("Saved window state");
|
||||
info!("Saved window state");
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::window_menu::app_menu;
|
||||
use log::{info, warn};
|
||||
use rand::random;
|
||||
use std::process::exit;
|
||||
use tauri::{
|
||||
AppHandle, Emitter, LogicalSize, Manager, Runtime, WebviewUrl, WebviewWindow, WindowEvent,
|
||||
};
|
||||
@@ -119,7 +118,7 @@ pub(crate) fn create_window<R: Runtime>(
|
||||
win.on_window_event(move |event| match event {
|
||||
WindowEvent::CloseRequested { .. } => {
|
||||
let tx = tx.clone();
|
||||
tauri::async_runtime::block_on(async move {
|
||||
tauri::async_runtime::spawn(async move {
|
||||
tx.send(()).await.unwrap();
|
||||
});
|
||||
}
|
||||
@@ -135,7 +134,14 @@ pub(crate) fn create_window<R: Runtime>(
|
||||
|
||||
let event_id = event.id().0.as_str();
|
||||
match event_id {
|
||||
"quit" => exit(0),
|
||||
"hacked_quit" => {
|
||||
// Cmd+Q on macOS doesn't trigger `CloseRequested` so we use a custom Quit menu
|
||||
// and trigger close() for each window.
|
||||
w.webview_windows().iter().for_each(|(_, w)| {
|
||||
info!("Closing window {}", w.label());
|
||||
let _ = w.close();
|
||||
});
|
||||
}
|
||||
"close" => w.close().unwrap(),
|
||||
"zoom_reset" => w.emit("zoom_reset", true).unwrap(),
|
||||
"zoom_in" => w.emit("zoom_in", true).unwrap(),
|
||||
@@ -199,7 +205,13 @@ pub(crate) fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow
|
||||
create_window(handle, config)
|
||||
}
|
||||
|
||||
pub(crate) fn create_child_window(parent_window: &WebviewWindow, url: &str, label: &str, title: &str, inner_size: (f64, f64)) -> WebviewWindow {
|
||||
pub(crate) fn create_child_window(
|
||||
parent_window: &WebviewWindow,
|
||||
url: &str,
|
||||
label: &str,
|
||||
title: &str,
|
||||
inner_size: (f64, f64),
|
||||
) -> WebviewWindow {
|
||||
let app_handle = parent_window.app_handle();
|
||||
let label = format!("{OTHER_WINDOW_PREFIX}_{label}");
|
||||
let scale_factor = parent_window.scale_factor().unwrap();
|
||||
@@ -247,7 +259,7 @@ pub(crate) fn create_child_window(parent_window: &WebviewWindow, url: &str, labe
|
||||
let child_window = child_window.clone();
|
||||
parent_window.clone().on_window_event(move |e| match e {
|
||||
// When the parent window is closed, close the child
|
||||
WindowEvent::CloseRequested { .. } => child_window.destroy().unwrap(),
|
||||
WindowEvent::CloseRequested { .. } => child_window.close().unwrap(),
|
||||
// When the parent window is focused, bring the child above
|
||||
WindowEvent::Focused(focus) => {
|
||||
if *focus {
|
||||
@@ -259,6 +271,6 @@ pub(crate) fn create_child_window(parent_window: &WebviewWindow, url: &str, labe
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
child_window
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use tauri::menu::{
|
||||
AboutMetadata, Menu, MenuItemBuilder, PredefinedMenuItem, Submenu, HELP_SUBMENU_ID,
|
||||
WINDOW_SUBMENU_ID,
|
||||
};
|
||||
pub use tauri::AppHandle;
|
||||
use tauri::Runtime;
|
||||
use tauri::menu::{
|
||||
AboutMetadata, HELP_SUBMENU_ID, Menu, MenuItemBuilder, PredefinedMenuItem, Submenu,
|
||||
WINDOW_SUBMENU_ID,
|
||||
};
|
||||
|
||||
pub fn app_menu<R: Runtime>(app_handle: &AppHandle<R>) -> tauri::Result<Menu<R>> {
|
||||
let pkg_info = app_handle.package_info();
|
||||
@@ -64,7 +64,16 @@ pub fn app_menu<R: Runtime>(app_handle: &AppHandle<R>) -> tauri::Result<Menu<R>>
|
||||
&PredefinedMenuItem::hide(app_handle, None)?,
|
||||
&PredefinedMenuItem::hide_others(app_handle, None)?,
|
||||
&PredefinedMenuItem::separator(app_handle)?,
|
||||
&PredefinedMenuItem::quit(app_handle, None)?,
|
||||
// NOTE: Replace the predefined quit item with a custom one because, for some
|
||||
// reason, ExitRequested events are not fired on cmd+Q. Perhaps this will be
|
||||
// fixed in the future?
|
||||
// https://github.com/tauri-apps/tauri/issues/9198
|
||||
&MenuItemBuilder::with_id(
|
||||
"hacked_quit".to_string(),
|
||||
format!("Quit {}", app_handle.package_info().name),
|
||||
)
|
||||
.accelerator("CmdOrCtrl+q")
|
||||
.build(app_handle)?,
|
||||
],
|
||||
)?,
|
||||
#[cfg(not(any(
|
||||
|
||||
Reference in New Issue
Block a user