2
0

add cmd refresh

This commit is contained in:
2026-04-01 21:26:02 +09:00
parent f85ee93b34
commit 83e65771b6
4 changed files with 54 additions and 37 deletions

View File

@@ -115,6 +115,21 @@ fn is_token_valid(token: &str) -> bool {
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.
/// If expired, refresh it. If refresh fails, remove the OAuth session file
/// 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 is_token_valid(&oauth_session.access_token) {
let session = if is_bot {
token::load_bot_session().ok()
} else {
token::load_session().ok()
};
return session;
return Some(session_from_oauth(&oauth_session));
}
// Token expired, try refresh
match oauth::refresh_oauth_session(is_bot).await {
Ok((_oauth, session)) => Some(session),
Ok((new_oauth, _session)) => Some(session_from_oauth(&new_oauth)),
Err(_) => {
// Refresh failed — remove broken OAuth session so legacy works
oauth::remove_oauth_session(is_bot);

View File

@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::io::{self, Write};
use super::token::{self, Session, BUNDLE_ID};
use super::token::{Session, BUNDLE_ID};
fn load_site_url() -> Result<String> {
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)
.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 {
did: sub.to_string(),
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()),
};
if is_bot {
token::save_bot_session(&compat)?;
} else {
token::save_session(&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)?;
// 10. Save compatible Session (for existing commands)
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.");
}
// 10. Report success (token.json is NOT overwritten — OAuth uses oauth_session.json only)
println!(
"Logged in as {} ({}) via OAuth",
compat_session.handle, compat_session.did
handle, resolved_did
);
Ok(())

View File

@@ -102,6 +102,28 @@ pub fn show_session(is_bot: bool) -> Result<()> {
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<()> {
let networks = load_networks(networks_path)?;

View File

@@ -369,6 +369,13 @@ enum PdsCommands {
#[arg(long)]
bot: bool,
},
/// Refresh access token
#[command(alias = "r")]
Refresh {
/// Refresh bot token
#[arg(long)]
bot: bool,
},
}
#[tokio::main]
@@ -478,6 +485,9 @@ async fn main() -> Result<()> {
PdsCommands::Session { bot } => {
commands::pds::show_session(bot)?;
}
PdsCommands::Refresh { bot } => {
commands::pds::refresh(bot).await?;
}
}
}
Commands::Oauth { handle, bot } => {