add cmd refresh
This commit is contained in:
@@ -115,6 +115,21 @@ fn is_token_valid(token: &str) -> bool {
|
|||||||
exp > now + 60 // valid if expires more than 60s from now
|
exp > now + 60 // valid if expires more than 60s from now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build a Session from an OAuthSession (without touching token.json)
|
||||||
|
fn session_from_oauth(oauth: &oauth::OAuthSession) -> Session {
|
||||||
|
let pds_host = oauth.pds
|
||||||
|
.strip_prefix("https://")
|
||||||
|
.unwrap_or(&oauth.pds)
|
||||||
|
.trim_end_matches('/');
|
||||||
|
Session {
|
||||||
|
did: oauth.did.clone(),
|
||||||
|
handle: oauth.handle.clone(),
|
||||||
|
access_jwt: oauth.access_token.clone(),
|
||||||
|
refresh_jwt: String::new(), // not used for OAuth
|
||||||
|
pds: Some(pds_host.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get OAuth session and return it if access_token is still valid.
|
/// Get OAuth session and return it if access_token is still valid.
|
||||||
/// If expired, refresh it. If refresh fails, remove the OAuth session file
|
/// If expired, refresh it. If refresh fails, remove the OAuth session file
|
||||||
/// so we cleanly fall back to legacy on next call.
|
/// so we cleanly fall back to legacy on next call.
|
||||||
@@ -128,16 +143,11 @@ async fn try_oauth_session(is_bot: bool) -> Option<Session> {
|
|||||||
};
|
};
|
||||||
// If token is still valid, use it without refreshing
|
// If token is still valid, use it without refreshing
|
||||||
if is_token_valid(&oauth_session.access_token) {
|
if is_token_valid(&oauth_session.access_token) {
|
||||||
let session = if is_bot {
|
return Some(session_from_oauth(&oauth_session));
|
||||||
token::load_bot_session().ok()
|
|
||||||
} else {
|
|
||||||
token::load_session().ok()
|
|
||||||
};
|
|
||||||
return session;
|
|
||||||
}
|
}
|
||||||
// Token expired, try refresh
|
// Token expired, try refresh
|
||||||
match oauth::refresh_oauth_session(is_bot).await {
|
match oauth::refresh_oauth_session(is_bot).await {
|
||||||
Ok((_oauth, session)) => Some(session),
|
Ok((new_oauth, _session)) => Some(session_from_oauth(&new_oauth)),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// Refresh failed — remove broken OAuth session so legacy works
|
// Refresh failed — remove broken OAuth session so legacy works
|
||||||
oauth::remove_oauth_session(is_bot);
|
oauth::remove_oauth_session(is_bot);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use super::token::{self, Session, BUNDLE_ID};
|
use super::token::{Session, BUNDLE_ID};
|
||||||
|
|
||||||
fn load_site_url() -> Result<String> {
|
fn load_site_url() -> Result<String> {
|
||||||
let config = super::token::load_config()?;
|
let config = super::token::load_config()?;
|
||||||
@@ -537,6 +537,8 @@ pub async fn refresh_oauth_session(is_bot: bool) -> Result<(OAuthSession, Sessio
|
|||||||
.unwrap_or(&oauth.pds)
|
.unwrap_or(&oauth.pds)
|
||||||
.trim_end_matches('/');
|
.trim_end_matches('/');
|
||||||
|
|
||||||
|
// Build compat session (for callers that need Session struct)
|
||||||
|
// Do NOT overwrite token.json — it holds legacy refresh_jwt
|
||||||
let compat = Session {
|
let compat = Session {
|
||||||
did: sub.to_string(),
|
did: sub.to_string(),
|
||||||
handle: oauth.handle.clone(),
|
handle: oauth.handle.clone(),
|
||||||
@@ -545,12 +547,6 @@ pub async fn refresh_oauth_session(is_bot: bool) -> Result<(OAuthSession, Sessio
|
|||||||
pds: Some(pds_host.to_string()),
|
pds: Some(pds_host.to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_bot {
|
|
||||||
token::save_bot_session(&compat)?;
|
|
||||||
} else {
|
|
||||||
token::save_session(&compat)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok((new_oauth, compat));
|
return Ok((new_oauth, compat));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,31 +778,10 @@ pub async fn oauth_login(handle: &str, is_bot: bool) -> Result<()> {
|
|||||||
};
|
};
|
||||||
save_oauth_session(&oauth_session, is_bot)?;
|
save_oauth_session(&oauth_session, is_bot)?;
|
||||||
|
|
||||||
// 10. Save compatible Session (for existing commands)
|
// 10. Report success (token.json is NOT overwritten — OAuth uses oauth_session.json only)
|
||||||
let pds_host = pds_url
|
|
||||||
.strip_prefix("https://")
|
|
||||||
.unwrap_or(&pds_url)
|
|
||||||
.trim_end_matches('/');
|
|
||||||
|
|
||||||
let compat_session = Session {
|
|
||||||
did: resolved_did.to_string(),
|
|
||||||
handle: handle.to_string(),
|
|
||||||
access_jwt: token_res.access_token,
|
|
||||||
refresh_jwt: token_res.refresh_token.unwrap_or_default(),
|
|
||||||
pds: Some(pds_host.to_string()),
|
|
||||||
};
|
|
||||||
|
|
||||||
if is_bot {
|
|
||||||
token::save_bot_session(&compat_session)?;
|
|
||||||
println!("Bot session saved.");
|
|
||||||
} else {
|
|
||||||
token::save_session(&compat_session)?;
|
|
||||||
println!("Session saved.");
|
|
||||||
}
|
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Logged in as {} ({}) via OAuth",
|
"Logged in as {} ({}) via OAuth",
|
||||||
compat_session.handle, compat_session.did
|
handle, resolved_did
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -102,6 +102,28 @@ pub fn show_session(is_bot: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Refresh access token
|
||||||
|
pub async fn refresh(is_bot: bool) -> Result<()> {
|
||||||
|
use super::auth;
|
||||||
|
|
||||||
|
let session = if is_bot {
|
||||||
|
auth::refresh_bot_session().await?
|
||||||
|
} else {
|
||||||
|
auth::refresh_session().await?
|
||||||
|
};
|
||||||
|
|
||||||
|
let has_oauth = super::oauth::has_oauth_session(is_bot);
|
||||||
|
let info = serde_json::json!({
|
||||||
|
"did": session.did,
|
||||||
|
"handle": session.handle,
|
||||||
|
"pds": session.pds.as_deref().unwrap_or("bsky.social"),
|
||||||
|
"auth": if has_oauth { "oauth" } else { "legacy" },
|
||||||
|
"refreshed": true,
|
||||||
|
});
|
||||||
|
println!("{}", serde_json::to_string_pretty(&info)?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn check_versions(networks_path: &str) -> Result<()> {
|
pub async fn check_versions(networks_path: &str) -> Result<()> {
|
||||||
let networks = load_networks(networks_path)?;
|
let networks = load_networks(networks_path)?;
|
||||||
|
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -369,6 +369,13 @@ enum PdsCommands {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
bot: bool,
|
bot: bool,
|
||||||
},
|
},
|
||||||
|
/// Refresh access token
|
||||||
|
#[command(alias = "r")]
|
||||||
|
Refresh {
|
||||||
|
/// Refresh bot token
|
||||||
|
#[arg(long)]
|
||||||
|
bot: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@@ -478,6 +485,9 @@ async fn main() -> Result<()> {
|
|||||||
PdsCommands::Session { bot } => {
|
PdsCommands::Session { bot } => {
|
||||||
commands::pds::show_session(bot)?;
|
commands::pds::show_session(bot)?;
|
||||||
}
|
}
|
||||||
|
PdsCommands::Refresh { bot } => {
|
||||||
|
commands::pds::refresh(bot).await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Commands::Oauth { handle, bot } => {
|
Commands::Oauth { handle, bot } => {
|
||||||
|
|||||||
Reference in New Issue
Block a user