Skip to content

Commit

Permalink
Fix: Copilot Chat is logged out (#21360)
Browse files Browse the repository at this point in the history
Closes #21255

Release Notes:

- Fixed Copilot Chat OAuth Token parsing

---------

Co-authored-by: Bennet Bo Fenner <[email protected]>
  • Loading branch information
fred-sch and bennetbo authored Dec 2, 2024
1 parent 89a5696 commit 380679f
Showing 1 changed file with 31 additions and 10 deletions.
41 changes: 31 additions & 10 deletions crates/copilot/src/copilot_chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ pub fn init(fs: Arc<dyn Fs>, client: Arc<dyn HttpClient>, cx: &mut AppContext) {
cx.set_global(GlobalCopilotChat(copilot_chat));
}

fn copilot_chat_config_path() -> &'static PathBuf {
fn copilot_chat_config_dir() -> &'static PathBuf {
static COPILOT_CHAT_CONFIG_DIR: OnceLock<PathBuf> = OnceLock::new();

COPILOT_CHAT_CONFIG_DIR.get_or_init(|| {
Expand All @@ -207,24 +207,39 @@ fn copilot_chat_config_path() -> &'static PathBuf {
home_dir().join(".config")
}
.join("github-copilot")
.join("hosts.json")
})
}

fn copilot_chat_config_paths() -> [PathBuf; 2] {
let base_dir = copilot_chat_config_dir();
[base_dir.join("hosts.json"), base_dir.join("apps.json")]
}

impl CopilotChat {
pub fn global(cx: &AppContext) -> Option<gpui::Model<Self>> {
cx.try_global::<GlobalCopilotChat>()
.map(|model| model.0.clone())
}

pub fn new(fs: Arc<dyn Fs>, client: Arc<dyn HttpClient>, cx: &AppContext) -> Self {
let mut config_file_rx = watch_config_file(
cx.background_executor(),
fs,
copilot_chat_config_path().clone(),
);
let config_paths = copilot_chat_config_paths();

let resolve_config_path = {
let fs = fs.clone();
async move {
for config_path in config_paths.iter() {
if fs.metadata(config_path).await.is_ok_and(|v| v.is_some()) {
return config_path.clone();
}
}
config_paths[0].clone()
}
};

cx.spawn(|cx| async move {
let config_file = resolve_config_path.await;
let mut config_file_rx = watch_config_file(cx.background_executor(), fs, config_file);

while let Some(contents) = config_file_rx.next().await {
let oauth_token = extract_oauth_token(contents);

Expand Down Expand Up @@ -318,9 +333,15 @@ async fn request_api_token(oauth_token: &str, client: Arc<dyn HttpClient>) -> Re
fn extract_oauth_token(contents: String) -> Option<String> {
serde_json::from_str::<serde_json::Value>(&contents)
.map(|v| {
v["github.com"]["oauth_token"]
.as_str()
.map(|v| v.to_string())
v.as_object().and_then(|obj| {
obj.iter().find_map(|(key, value)| {
if key.starts_with("github.com") {
value["oauth_token"].as_str().map(|v| v.to_string())
} else {
None
}
})
})
})
.ok()
.flatten()
Expand Down

0 comments on commit 380679f

Please sign in to comment.