Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions src/api/auth.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use crate::api::client::{ApiClient, Endpoint};
use crate::{
Result,
api::client::{ApiClient, Endpoint},
error::AuthError,
};
use keyring::KeyringEntry;
use serde_json::Value;

Expand All @@ -7,22 +11,20 @@ pub struct Auth {
}

impl Auth {
pub fn new() -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
pub fn new() -> Result<Self> {
let crate_id = "vimstoat";
let token_entry = KeyringEntry::try_new(crate_id)?;
Ok(Self { token_entry })
}

pub async fn store_token(&self, token: &str) -> Result<(), String> {
self.token_entry.set_secret(token).await.map_err(|e| {
format!(
"{}\n\nUnderlying Details:\n{:?}\n\n💡 Hint: If you are on a minimal Linux install, you likely need to install a Secret Service provider (e.g., `sudo pacman -S gnome-keyring`).",
e, e
)
})
pub async fn store_token(&self, token: &str) -> Result<()> {
self.token_entry
.set_secret(token)
.await
.map_err(|e| e.into())
}

pub async fn validate_token(&self, token: &str) -> Result<ApiClient, String> {
pub async fn validate_token(&self, token: &str) -> Result<ApiClient> {
let client = ApiClient::new(token.to_string());

client
Expand All @@ -32,12 +34,14 @@ impl Auth {
.map_err(|e| {
let err_msg = e.to_string();
if err_msg.contains("401") {
"Invalid token. Please check your session token and try again.".to_string()
AuthError::InvalidToken(
"Please check your session token and try again.".to_string(),
)
.into()
} else if err_msg.contains("API GET request") {
err_msg
AuthError::RequestError(err_msg).into()
} else {
"Could not connect to the server. Please check your internet connection."
.to_string()
AuthError::ServerConnectionError.into()
}
})
}
Expand Down
1 change: 1 addition & 0 deletions src/api/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::de::DeserializeOwned;
const BASE_URL: &str = "https://api.stoat.chat";

#[derive(Debug)]
#[allow(unused)]
pub enum Endpoint {
Config,
CurrentUser,
Expand Down
2 changes: 1 addition & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub enum AppState {
InputToken,
ValidatingToken,
LoggedIn,
Error(String),
Error(anyhow::Error),
}

pub struct App {
Expand Down
21 changes: 21 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,24 @@ impl From<pickledb::error::Error> for CacheError {
CacheError::DbError(value)
}
}

#[derive(Error, Debug)]
pub enum AuthError {
#[error("Keyring Error: {0:?}")]
KeyringError(keyring::Error),

#[error("Invalid Token: {0}")]
InvalidToken(String),

#[error("Could not connect to the server. Please check your internet connection.")]
ServerConnectionError,

#[error("Request Error: {0}")]
RequestError(String),
}

impl From<keyring::Error> for AuthError {
fn from(value: keyring::Error) -> Self {
AuthError::KeyringError(value)
}
}
2 changes: 1 addition & 1 deletion src/ui/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ pub fn render(f: &mut Frame, app: &App) {
AppState::InputToken => input_token::render(f, app),
AppState::ValidatingToken => validating_token::render(f),
AppState::LoggedIn => server_list::render(f, app),
AppState::Error(message) => error::render(f, message),
AppState::Error(message) => error::render(f, &message.to_string()),
}
}