mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-22 15:40:07 -04:00
Remove keyring crate
We found a different solution, as the keyring crate isn't supported on Android
This commit is contained in:
BIN
Cargo.lock
generated
BIN
Cargo.lock
generated
Binary file not shown.
@@ -30,9 +30,7 @@ import SuperTokens from 'supertokens-web-js';
|
||||
import EmailPassword from 'supertokens-web-js/recipe/emailpassword';
|
||||
import Session from 'supertokens-web-js/recipe/session';
|
||||
import ThirdParty from 'supertokens-web-js/recipe/thirdparty';
|
||||
import getCookieHandler, {
|
||||
setAppReady
|
||||
} from '@sd/interface/app/$libraryId/settings/client/account/handlers/cookieHandler';
|
||||
import getCookieHandler from '@sd/interface/app/$libraryId/settings/client/account/handlers/cookieHandler';
|
||||
import getWindowHandler from '@sd/interface/app/$libraryId/settings/client/account/handlers/windowHandler';
|
||||
import { useLocale } from '@sd/interface/hooks';
|
||||
|
||||
@@ -62,9 +60,7 @@ const startupError = (window as any).__SD_ERROR__ as string | undefined;
|
||||
export default function App() {
|
||||
useEffect(() => {
|
||||
// This tells Tauri to show the current window because it's finished loading
|
||||
commands.appReady().then(() => {
|
||||
setAppReady();
|
||||
});
|
||||
commands.appReady();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -133,8 +133,6 @@ sysinfo = "0.29.11" # Update blocked due to API breaking changes
|
||||
tar = "0.4.41"
|
||||
tower-service = "0.3.2"
|
||||
tracing-appender = "0.2.3"
|
||||
keyring = { version = "3.0.4", features = ["apple-native", "windows-native", "sync-secret-service"] }
|
||||
whoami = "1.5.1"
|
||||
|
||||
# Override features of transitive dependencies
|
||||
[dependencies.openssl]
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// TODO: Ensure this file has normalised caching setup before reenabling
|
||||
|
||||
use keyring::Entry;
|
||||
use rspc::alpha::AlphaRouter;
|
||||
// use keyring::Entry;
|
||||
// use rspc::alpha::AlphaRouter;
|
||||
|
||||
use serde_json::Value;
|
||||
use tracing::{debug, error};
|
||||
// use serde_json::Value;
|
||||
// use tracing::{debug, error};
|
||||
// use sd_crypto::keys::keymanager::{StoredKey, StoredKeyType};
|
||||
// use sd_crypto::primitives::SECRET_KEY_IDENTIFIER;
|
||||
// use sd_crypto::types::{Algorithm, HashingAlgorithm, OnboardingConfig, SecretKeyString};
|
||||
@@ -20,7 +20,7 @@ use tracing::{debug, error};
|
||||
// use crate::{invalidate_query, prisma::key};
|
||||
|
||||
// use super::utils::library;
|
||||
use super::{Ctx, R};
|
||||
// use super::{Ctx, R};
|
||||
|
||||
// #[derive(Type, Deserialize)]
|
||||
// pub struct KeyAddArgs {
|
||||
@@ -57,73 +57,73 @@ use super::{Ctx, R};
|
||||
// status: bool,
|
||||
// }
|
||||
|
||||
pub(crate) fn mount() -> AlphaRouter<Ctx> {
|
||||
R.router()
|
||||
.procedure("set", {
|
||||
R.mutation(|_, key: String| async move {
|
||||
let username = whoami::username();
|
||||
let entry = match Entry::new("spacedrive-auth-service", username.as_str()) {
|
||||
Ok(entry) => entry,
|
||||
Err(e) => {
|
||||
error!("Error creating entry: {}", e);
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error creating entry".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
// pub(crate) fn mount() -> AlphaRouter<Ctx> {
|
||||
// R.router()
|
||||
// .procedure("set", {
|
||||
// R.mutation(|_, key: String| async move {
|
||||
// let username = whoami::username();
|
||||
// let entry = match Entry::new("spacedrive-auth-service", username.as_str()) {
|
||||
// Ok(entry) => entry,
|
||||
// Err(e) => {
|
||||
// error!("Error creating entry: {}", e);
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error creating entry".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
match entry.set_password(key.as_str()) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("Error setting key: {}", e);
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error setting key".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
// match entry.set_password(key.as_str()) {
|
||||
// Ok(_) => (),
|
||||
// Err(e) => {
|
||||
// error!("Error setting key: {}", e);
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error setting key".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
|
||||
debug!(
|
||||
"Key set successfully: key={key}, service={service}",
|
||||
key = key,
|
||||
service = "spacedrive-auth-service",
|
||||
);
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
.procedure("get", {
|
||||
R.query(|_, _: ()| async move {
|
||||
let username = whoami::username();
|
||||
let entry = match Entry::new("spacedrive-auth-service", username.as_str()) {
|
||||
Ok(entry) => entry,
|
||||
Err(e) => {
|
||||
error!("Error creating entry: {}", e);
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error creating entry".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
// debug!(
|
||||
// "Key set successfully: key={key}, service={service}",
|
||||
// key = key,
|
||||
// service = "spacedrive-auth-service",
|
||||
// );
|
||||
// Ok(())
|
||||
// })
|
||||
// })
|
||||
// .procedure("get", {
|
||||
// R.query(|_, _: ()| async move {
|
||||
// let username = whoami::username();
|
||||
// let entry = match Entry::new("spacedrive-auth-service", username.as_str()) {
|
||||
// Ok(entry) => entry,
|
||||
// Err(e) => {
|
||||
// error!("Error creating entry: {}", e);
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error creating entry".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
let data = match entry.get_password() {
|
||||
Ok(key) => key,
|
||||
Err(e) => {
|
||||
error!("Error retrieving key: {}. Does the key exist yet?", e);
|
||||
return Ok("".to_string());
|
||||
}
|
||||
};
|
||||
// let data = match entry.get_password() {
|
||||
// Ok(key) => key,
|
||||
// Err(e) => {
|
||||
// error!("Error retrieving key: {}. Does the key exist yet?", e);
|
||||
// return Ok("".to_string());
|
||||
// }
|
||||
// };
|
||||
|
||||
debug!(
|
||||
"Key retrieved successfully: service={service}, data={_data}",
|
||||
_data = data,
|
||||
service = "spacedrive-auth-service",
|
||||
);
|
||||
// debug!(
|
||||
// "Key retrieved successfully: service={service}, data={_data}",
|
||||
// _data = data,
|
||||
// service = "spacedrive-auth-service",
|
||||
// );
|
||||
|
||||
Ok(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
// Ok(data)
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
//NOTE(@Rocky43007): OLD PROCEDURES -> MAY BE USEFUL FOR REFERENCE AND COULD BE USED IN THE FUTURE
|
||||
// .procedure("list", {
|
||||
|
||||
@@ -28,7 +28,8 @@ mod cloud;
|
||||
mod ephemeral_files;
|
||||
mod files;
|
||||
mod jobs;
|
||||
mod keys;
|
||||
// #[cfg(not(any(target_os = "ios", target_os = "android")))]
|
||||
// mod keys;
|
||||
mod labels;
|
||||
mod libraries;
|
||||
pub mod locations;
|
||||
@@ -201,7 +202,6 @@ pub(crate) fn mount() -> Arc<Router> {
|
||||
.merge("tags.", tags::mount())
|
||||
.merge("labels.", labels::mount())
|
||||
// .merge("categories.", categories::mount())
|
||||
.merge("keys.", keys::mount())
|
||||
.merge("locations.", locations::mount())
|
||||
.merge("ephemeralFiles.", ephemeral_files::mount())
|
||||
.merge("files.", files::mount())
|
||||
@@ -225,6 +225,9 @@ pub(crate) fn mount() -> Arc<Router> {
|
||||
);
|
||||
});
|
||||
|
||||
// #[cfg(not(any(target_os = "ios", target_os = "android")))]
|
||||
// let r = r.merge("keys.", keys::mount());
|
||||
|
||||
let r = r
|
||||
.build(
|
||||
#[allow(clippy::let_and_return)]
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::path::Path;
|
||||
|
||||
use keyring::Entry;
|
||||
// #[cfg(not(any(target_os = "ios", target_os = "android")))]
|
||||
// use keyring::Entry;
|
||||
|
||||
use regex::Regex;
|
||||
use tokio::{fs, io};
|
||||
use tracing::{debug, error};
|
||||
@@ -39,63 +41,71 @@ pub async fn get_size(path: impl AsRef<Path>) -> Result<u64, io::Error> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_access_token() -> Result<String, rspc::Error> {
|
||||
let username = whoami::username();
|
||||
let entry = match Entry::new("spacedrive-auth-service", username.as_str()) {
|
||||
Ok(entry) => entry,
|
||||
Err(e) => {
|
||||
error!("Error creating entry: {}", e);
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error creating entry".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
// pub fn get_access_token() -> Result<String, rspc::Error> {
|
||||
// // If target is ios or android, return an error as this function is not supported on those platforms
|
||||
// if cfg!(any(target_os = "ios", target_os = "android")) {
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Function not supported on this platform".to_string(),
|
||||
// ));
|
||||
// } else {
|
||||
// let username = whoami::username();
|
||||
// let entry = match Entry::new("spacedrive-auth-service", username.as_str()) {
|
||||
// Ok(entry) => entry,
|
||||
// Err(e) => {
|
||||
// error!("Error creating entry: {}", e);
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error creating entry".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
let data = match entry.get_password() {
|
||||
Ok(key) => key,
|
||||
Err(e) => {
|
||||
error!("Error retrieving key: {}. Does the key exist yet?", e);
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error retrieving key".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
// let data = match entry.get_password() {
|
||||
// Ok(key) => key,
|
||||
// Err(e) => {
|
||||
// error!("Error retrieving key: {}. Does the key exist yet?", e);
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error retrieving key".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
let re = match Regex::new(r#"st-access-token=([^;]+)"#) {
|
||||
Ok(re) => re,
|
||||
Err(e) => {
|
||||
error!("Error creating regex: {}", e);
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error creating regex".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
// let re = match Regex::new(r#"st-access-token=([^;]+)"#) {
|
||||
// Ok(re) => re,
|
||||
// Err(e) => {
|
||||
// error!("Error creating regex: {}", e);
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error creating regex".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
let token = match re.captures(&data) {
|
||||
Some(captures) => match captures.get(1) {
|
||||
Some(token) => token.as_str(),
|
||||
None => {
|
||||
error!("Error parsing Cookie String value: {}", "No token found");
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error parsing Cookie String value".to_string(),
|
||||
));
|
||||
}
|
||||
},
|
||||
None => {
|
||||
error!(
|
||||
"Error parsing Cookie String value: {}",
|
||||
"No token cookie string found"
|
||||
);
|
||||
return Err(rspc::Error::new(
|
||||
rspc::ErrorCode::InternalServerError,
|
||||
"Error parsing Cookie String value".to_string(),
|
||||
));
|
||||
}
|
||||
};
|
||||
// let token = match re.captures(&data) {
|
||||
// Some(captures) => match captures.get(1) {
|
||||
// Some(token) => token.as_str(),
|
||||
// None => {
|
||||
// error!("Error parsing Cookie String value: {}", "No token found");
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error parsing Cookie String value".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// },
|
||||
// None => {
|
||||
// error!(
|
||||
// "Error parsing Cookie String value: {}",
|
||||
// "No token cookie string found"
|
||||
// );
|
||||
// return Err(rspc::Error::new(
|
||||
// rspc::ErrorCode::InternalServerError,
|
||||
// "Error parsing Cookie String value".to_string(),
|
||||
// ));
|
||||
// }
|
||||
// };
|
||||
|
||||
Ok(token.to_string())
|
||||
}
|
||||
// Ok(token.to_string())
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import { CookieHandlerInterface } from "supertokens-website/utils/cookieHandler/types";
|
||||
import { nonLibraryClient } from '@sd/client'
|
||||
|
||||
let APP_READY = false;
|
||||
const frontendCookiesKey = "frontendCookies";
|
||||
|
||||
async function getCookiesFromStorage(): Promise<string> {
|
||||
if (!APP_READY) {
|
||||
return "";
|
||||
}
|
||||
const cookiesFromStorage = await nonLibraryClient.query(['keys.get'])
|
||||
/**
|
||||
* Tauri handles cookies differently than in browser environments. The SuperTokens
|
||||
* SDK uses frontend cookies, to make sure everything work correctly we add custom
|
||||
* cookie handling and store cookies in local storage instead (This is not a problem
|
||||
* since these are frontend cookies and not server side cookies)
|
||||
*/
|
||||
function getCookiesFromStorage(): string {
|
||||
const cookiesFromStorage = window.localStorage.getItem(frontendCookiesKey);
|
||||
|
||||
if (cookiesFromStorage.length === 0) {
|
||||
if (cookiesFromStorage === null) {
|
||||
window.localStorage.setItem(frontendCookiesKey, "[]");
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -22,54 +25,47 @@ async function getCookiesFromStorage(): Promise<string> {
|
||||
|
||||
for (let cookieIndex = 0; cookieIndex < cookieArrayInStorage.length; cookieIndex++) {
|
||||
const currentCookieString = cookieArrayInStorage[cookieIndex];
|
||||
const parts = currentCookieString?.split(";") ?? [];
|
||||
const parts = currentCookieString?.split(";");
|
||||
let expirationString: string = "";
|
||||
|
||||
for (let partIndex = 0; partIndex < parts.length; partIndex++) {
|
||||
const currentPart = parts[partIndex];
|
||||
for (let partIndex = 0; partIndex < parts!.length; partIndex++) {
|
||||
const currentPart = parts![partIndex];
|
||||
|
||||
if (currentPart?.toLocaleLowerCase().includes("expires=")) {
|
||||
expirationString = currentPart;
|
||||
if (currentPart!.toLocaleLowerCase().includes("expires=")) {
|
||||
expirationString = currentPart!;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (expirationString !== "") {
|
||||
const expirationValueString = expirationString.split("=")[1];
|
||||
const expirationDate = expirationValueString ? new Date(expirationValueString) : null;
|
||||
const expirationDate = new Date(expirationValueString!);
|
||||
const currentTimeInMillis = Date.now();
|
||||
|
||||
// if the cookie has expired, we skip it
|
||||
if (expirationDate && expirationDate.getTime() < currentTimeInMillis) {
|
||||
if (expirationDate.getTime() < currentTimeInMillis) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentCookieString !== undefined) {
|
||||
cookieArrayToReturn.push(currentCookieString);
|
||||
}
|
||||
cookieArrayToReturn.push(currentCookieString!);
|
||||
}
|
||||
|
||||
/**
|
||||
* After processing and removing expired cookies we need to update the cookies
|
||||
* in storage so we dont have to process the expired ones again
|
||||
*/
|
||||
await nonLibraryClient.mutation(['keys.set', JSON.stringify(cookieArrayToReturn)])
|
||||
window.localStorage.setItem(frontendCookiesKey, JSON.stringify(cookieArrayToReturn));
|
||||
|
||||
return cookieArrayToReturn.join("; ");
|
||||
}
|
||||
|
||||
async function setCookieToStorage(cookieString: string): Promise<void> {
|
||||
if (!APP_READY) {
|
||||
return;
|
||||
}
|
||||
const cookieName = cookieString.split(";")[0]?.split("=")[0];
|
||||
|
||||
const cookiesFromStorage = await nonLibraryClient.query(['keys.get'])
|
||||
|
||||
function setCookieToStorage(cookieString: string) {
|
||||
const cookieName = cookieString.split(";")[0]!.split("=")[0];
|
||||
const cookiesFromStorage = window.localStorage.getItem(frontendCookiesKey);
|
||||
let cookiesArray: string[] = [];
|
||||
|
||||
if (cookiesFromStorage.length !== 0) {
|
||||
if (cookiesFromStorage !== null) {
|
||||
const cookiesArrayFromStorage: string[] = JSON.parse(cookiesFromStorage);
|
||||
cookiesArray = cookiesArrayFromStorage;
|
||||
}
|
||||
@@ -79,7 +75,7 @@ async function setCookieToStorage(cookieString: string): Promise<void> {
|
||||
for (let i = 0; i < cookiesArray.length; i++) {
|
||||
const currentCookie = cookiesArray[i];
|
||||
|
||||
if (currentCookie?.indexOf(`${cookieName}=`) !== -1) {
|
||||
if (currentCookie!.indexOf(`${cookieName}=`) !== -1) {
|
||||
cookieIndex = i;
|
||||
break;
|
||||
}
|
||||
@@ -97,21 +93,18 @@ async function setCookieToStorage(cookieString: string): Promise<void> {
|
||||
cookiesArray.push(cookieString);
|
||||
}
|
||||
|
||||
await nonLibraryClient.mutation(['keys.set', JSON.stringify(cookiesArray)])
|
||||
window.localStorage.setItem(frontendCookiesKey, JSON.stringify(cookiesArray));
|
||||
}
|
||||
|
||||
export default function getCookieHandler(original: CookieHandlerInterface): CookieHandlerInterface {
|
||||
return {
|
||||
...original,
|
||||
getCookie: async function () {
|
||||
return getCookiesFromStorage();
|
||||
const cookies = getCookiesFromStorage();
|
||||
return cookies;
|
||||
},
|
||||
setCookie: async function (cookieString: string) {
|
||||
return setCookieToStorage(cookieString);
|
||||
setCookieToStorage(cookieString);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function setAppReady() {
|
||||
APP_READY = true;
|
||||
}
|
||||
|
||||
2
packages/client/src/core.ts
generated
2
packages/client/src/core.ts
generated
@@ -23,7 +23,6 @@ export type Procedures = {
|
||||
{ key: "invalidation.test-invalidate", input: never, result: number } |
|
||||
{ key: "jobs.isActive", input: LibraryArgs<null>, result: boolean } |
|
||||
{ key: "jobs.reports", input: LibraryArgs<null>, result: JobGroup[] } |
|
||||
{ key: "keys.get", input: never, result: string } |
|
||||
{ key: "labels.count", input: LibraryArgs<null>, result: number } |
|
||||
{ key: "labels.get", input: LibraryArgs<number>, result: Label | null } |
|
||||
{ key: "labels.getForObject", input: LibraryArgs<number>, result: Label[] } |
|
||||
@@ -111,7 +110,6 @@ export type Procedures = {
|
||||
{ key: "jobs.objectValidator", input: LibraryArgs<ObjectValidatorArgs>, result: null } |
|
||||
{ key: "jobs.pause", input: LibraryArgs<string>, result: null } |
|
||||
{ key: "jobs.resume", input: LibraryArgs<string>, result: null } |
|
||||
{ key: "keys.set", input: string, result: null } |
|
||||
{ key: "labels.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "library.create", input: CreateLibraryArgs, result: LibraryConfigWrapped } |
|
||||
{ key: "library.delete", input: string, result: null } |
|
||||
|
||||
Reference in New Issue
Block a user