mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-26 12:24:26 +03:00
feat: add support for default and git credentials helper as preferred SSH key options in the UI
This commit is contained in:
parent
9b00b5fe7d
commit
4ddc970747
@ -148,7 +148,6 @@ fn main() {
|
|||||||
commands::git_set_global_config,
|
commands::git_set_global_config,
|
||||||
commands::git_get_global_config,
|
commands::git_get_global_config,
|
||||||
commands::project_flush_and_push,
|
commands::project_flush_and_push,
|
||||||
commands::test_git_connection,
|
|
||||||
zip::commands::get_logs_archive_path,
|
zip::commands::get_logs_archive_path,
|
||||||
zip::commands::get_project_archive_path,
|
zip::commands::get_project_archive_path,
|
||||||
zip::commands::get_project_data_archive_path,
|
zip::commands::get_project_data_archive_path,
|
||||||
|
@ -155,59 +155,3 @@ pub async fn project_flush_and_push(handle: tauri::AppHandle, id: &str) -> Resul
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command(async)]
|
|
||||||
#[instrument(skip(handle))]
|
|
||||||
pub async fn test_git_connection(
|
|
||||||
handle: tauri::AppHandle,
|
|
||||||
project_id: &str,
|
|
||||||
) -> Result<serde_json::Value, Error> {
|
|
||||||
let project_id = project_id.parse().map_err(|_| Error::UserError {
|
|
||||||
code: Code::Validation,
|
|
||||||
message: "Malformed project id".into(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let users = handle.state::<users::Controller>().inner().clone();
|
|
||||||
let projects = handle.state::<projects::Controller>().inner().clone();
|
|
||||||
let local_data_dir = DataDir::try_from(&handle)?;
|
|
||||||
|
|
||||||
let project = projects.get(&project_id).context("failed to get project")?;
|
|
||||||
let user = users.get_user()?;
|
|
||||||
let project_repository = project_repository::Repository::open(&project)?;
|
|
||||||
let gb_repo =
|
|
||||||
gb_repository::Repository::open(&local_data_dir, &project_repository, user.as_ref())
|
|
||||||
.context("failed to open repository")?;
|
|
||||||
|
|
||||||
let default_target = gb_repo
|
|
||||||
.default_target()
|
|
||||||
.context("failed to get default target")?
|
|
||||||
.ok_or_else(|| Error::UserError {
|
|
||||||
code: Code::Branches,
|
|
||||||
message: "No default target set".into(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let remote_name = default_target.branch.remote();
|
|
||||||
|
|
||||||
let helper = git::credentials::Helper::from(&handle);
|
|
||||||
|
|
||||||
let mut results = HashMap::new();
|
|
||||||
let refspec = &format!("+refs/heads/*:refs/remotes/{}/*", remote_name);
|
|
||||||
for (mut remote, credentials) in helper.enumerate(&project_repository, remote_name)? {
|
|
||||||
let remote_url = remote.url().context("failed to get remote url")?.unwrap();
|
|
||||||
let results = results
|
|
||||||
.entry(remote_url.to_string())
|
|
||||||
.or_insert_with(Vec::new);
|
|
||||||
for callback in credentials {
|
|
||||||
let mut fetch_opts = git2::FetchOptions::new();
|
|
||||||
fetch_opts.remote_callbacks(callback.clone().into());
|
|
||||||
fetch_opts.prune(git2::FetchPrune::On);
|
|
||||||
|
|
||||||
results.push(serde_json::json!({
|
|
||||||
"callback": format!("{:?}", callback),
|
|
||||||
"error": remote.fetch(&[refspec], Some(&mut fetch_opts)).err().map(|e| e.to_string()),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(serde_json::json!(results))
|
|
||||||
}
|
|
||||||
|
@ -15,7 +15,6 @@ pub enum SshCredential {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum HttpsCredential {
|
pub enum HttpsCredential {
|
||||||
UsernamePassword { username: String, password: String },
|
|
||||||
CredentialHelper { username: String, password: String },
|
CredentialHelper { username: String, password: String },
|
||||||
GitHubToken(String),
|
GitHubToken(String),
|
||||||
}
|
}
|
||||||
@ -53,12 +52,6 @@ impl From<Credential> for git2::RemoteCallbacks<'_> {
|
|||||||
git2::Cred::ssh_key_from_memory("git", None, &key.to_string(), None)
|
git2::Cred::ssh_key_from_memory("git", None, &key.to_string(), None)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Credential::Https(HttpsCredential::UsernamePassword { username, password }) => {
|
|
||||||
remote_callbacks.credentials(move |url, _username_from_url, _allowed_types| {
|
|
||||||
tracing::info!("authenticating with {url} as '{username}' with password");
|
|
||||||
git2::Cred::userpass_plaintext(&username, &password)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Credential::Https(HttpsCredential::CredentialHelper { username, password }) => {
|
Credential::Https(HttpsCredential::CredentialHelper { username, password }) => {
|
||||||
remote_callbacks.credentials(move |url, _username_from_url, _allowed_types| {
|
remote_callbacks.credentials(move |url, _username_from_url, _allowed_types| {
|
||||||
tracing::info!("authenticating with {url} as '{username}' with password using credential helper");
|
tracing::info!("authenticating with {url} as '{username}' with password using credential helper");
|
||||||
@ -147,87 +140,6 @@ impl Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns all possible credentials for a remote, without trying to be smart.
|
|
||||||
pub fn enumerate<'a>(
|
|
||||||
&'a self,
|
|
||||||
project_repository: &'a project_repository::Repository,
|
|
||||||
remote: &str,
|
|
||||||
) -> Result<Vec<(super::Remote, Vec<Credential>)>, HelpError> {
|
|
||||||
let remote = project_repository.git_repository.find_remote(remote)?;
|
|
||||||
let remote_url = remote.url()?.ok_or(HelpError::NoUrlSet)?;
|
|
||||||
|
|
||||||
let mut flow = vec![];
|
|
||||||
|
|
||||||
if let projects::AuthKey::Local {
|
|
||||||
private_key_path,
|
|
||||||
passphrase,
|
|
||||||
} = &project_repository.project().preferred_key
|
|
||||||
{
|
|
||||||
let ssh_remote = if remote_url.scheme == super::Scheme::Ssh {
|
|
||||||
project_repository
|
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&remote_url)
|
|
||||||
} else {
|
|
||||||
let ssh_url = remote_url.as_ssh()?;
|
|
||||||
project_repository.git_repository.remote_anonymous(&ssh_url)
|
|
||||||
}?;
|
|
||||||
flow.push((
|
|
||||||
ssh_remote,
|
|
||||||
vec![Credential::Ssh(SshCredential::Keyfile {
|
|
||||||
key_path: private_key_path.clone(),
|
|
||||||
passphrase: passphrase.clone(),
|
|
||||||
})],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// is github is authenticated, only try github.
|
|
||||||
if remote_url.is_github() {
|
|
||||||
if let Some(github_access_token) = self
|
|
||||||
.users
|
|
||||||
.get_user()?
|
|
||||||
.and_then(|user| user.github_access_token)
|
|
||||||
{
|
|
||||||
let https_remote = if remote_url.scheme == super::Scheme::Https {
|
|
||||||
project_repository
|
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&remote_url)
|
|
||||||
} else {
|
|
||||||
let ssh_url = remote_url.as_ssh()?;
|
|
||||||
project_repository.git_repository.remote_anonymous(&ssh_url)
|
|
||||||
}?;
|
|
||||||
flow.push((
|
|
||||||
https_remote,
|
|
||||||
vec![Credential::Https(HttpsCredential::GitHubToken(
|
|
||||||
github_access_token,
|
|
||||||
))],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(https_url) = remote_url.as_https() {
|
|
||||||
flow.push((
|
|
||||||
project_repository
|
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&https_url)?,
|
|
||||||
Self::https_flow(project_repository, &https_url)?
|
|
||||||
.into_iter()
|
|
||||||
.map(Credential::Https)
|
|
||||||
.collect(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(ssh_url) = remote_url.as_ssh() {
|
|
||||||
flow.push((
|
|
||||||
project_repository
|
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&ssh_url)?,
|
|
||||||
self.ssh_flow()?.into_iter().map(Credential::Ssh).collect(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(flow)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn help<'a>(
|
pub fn help<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
project_repository: &'a project_repository::Repository,
|
project_repository: &'a project_repository::Repository,
|
||||||
@ -241,146 +153,174 @@ impl Helper {
|
|||||||
return Ok(vec![(remote, vec![Credential::Noop])]);
|
return Ok(vec![(remote, vec![Credential::Noop])]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if prefernce set, only try that.
|
match &project_repository.project().preferred_key {
|
||||||
if let projects::AuthKey::Local {
|
projects::AuthKey::Local {
|
||||||
private_key_path,
|
private_key_path,
|
||||||
passphrase,
|
passphrase,
|
||||||
} = &project_repository.project().preferred_key
|
} => {
|
||||||
{
|
let ssh_remote = if remote_url.scheme == super::Scheme::Ssh {
|
||||||
let ssh_remote = if remote_url.scheme == super::Scheme::Ssh {
|
Ok(remote)
|
||||||
Ok(remote)
|
} else {
|
||||||
} else {
|
let ssh_url = remote_url.as_ssh()?;
|
||||||
let ssh_url = remote_url.as_ssh()?;
|
project_repository.git_repository.remote_anonymous(&ssh_url)
|
||||||
project_repository.git_repository.remote_anonymous(&ssh_url)
|
}?;
|
||||||
}?;
|
|
||||||
|
|
||||||
return Ok(vec![(
|
Ok(vec![(
|
||||||
ssh_remote,
|
ssh_remote,
|
||||||
vec![Credential::Ssh(SshCredential::Keyfile {
|
vec![Credential::Ssh(SshCredential::Keyfile {
|
||||||
key_path: private_key_path.clone(),
|
key_path: private_key_path.clone(),
|
||||||
passphrase: passphrase.clone(),
|
passphrase: passphrase.clone(),
|
||||||
})],
|
})],
|
||||||
)]);
|
)])
|
||||||
}
|
}
|
||||||
|
projects::AuthKey::Generated => {
|
||||||
|
let ssh_remote = if remote_url.scheme == super::Scheme::Ssh {
|
||||||
|
Ok(remote)
|
||||||
|
} else {
|
||||||
|
let ssh_url = remote_url.as_ssh()?;
|
||||||
|
project_repository.git_repository.remote_anonymous(&ssh_url)
|
||||||
|
}?;
|
||||||
|
|
||||||
// is github is authenticated, only try github.
|
let key = self.keys.get_or_create()?;
|
||||||
if remote_url.is_github() {
|
Ok(vec![(
|
||||||
if let Some(github_access_token) = self
|
ssh_remote,
|
||||||
.users
|
vec![Credential::Ssh(SshCredential::GitButlerKey(Box::new(key)))],
|
||||||
.get_user()?
|
)])
|
||||||
.and_then(|user| user.github_access_token)
|
}
|
||||||
{
|
projects::AuthKey::GitCredentialsHelper => {
|
||||||
let https_remote = if remote_url.scheme == super::Scheme::Https {
|
let https_remote = if remote_url.scheme == super::Scheme::Https {
|
||||||
Ok(remote)
|
Ok(remote)
|
||||||
} else {
|
} else {
|
||||||
let url = remote_url.as_https()?;
|
let url = remote_url.as_https()?;
|
||||||
project_repository.git_repository.remote_anonymous(&url)
|
project_repository.git_repository.remote_anonymous(&url)
|
||||||
}?;
|
}?;
|
||||||
return Ok(vec![(
|
let flow = Self::https_flow(project_repository, &remote_url)?
|
||||||
https_remote,
|
|
||||||
vec![Credential::Https(HttpsCredential::GitHubToken(
|
|
||||||
github_access_token,
|
|
||||||
))],
|
|
||||||
)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match remote_url.scheme {
|
|
||||||
super::Scheme::Https => {
|
|
||||||
let mut flow = vec![];
|
|
||||||
|
|
||||||
let https_flow = Self::https_flow(project_repository, &remote_url)?
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Credential::Https)
|
.map(Credential::Https)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
Ok(vec![(https_remote, flow)])
|
||||||
if !https_flow.is_empty() {
|
|
||||||
flow.push((remote, https_flow));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(ssh_url) = remote_url.as_ssh() {
|
|
||||||
let ssh_flow = self
|
|
||||||
.ssh_flow()?
|
|
||||||
.into_iter()
|
|
||||||
.map(Credential::Ssh)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
if !ssh_flow.is_empty() {
|
|
||||||
flow.push((
|
|
||||||
project_repository
|
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&ssh_url)?,
|
|
||||||
ssh_flow,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(flow)
|
|
||||||
}
|
}
|
||||||
super::Scheme::Ssh => {
|
projects::AuthKey::Default => {
|
||||||
let mut flow = vec![];
|
// is github is authenticated, only try github.
|
||||||
|
if remote_url.is_github() {
|
||||||
let ssh_flow = self
|
if let Some(github_access_token) = self
|
||||||
.ssh_flow()?
|
.users
|
||||||
.into_iter()
|
.get_user()?
|
||||||
.map(Credential::Ssh)
|
.and_then(|user| user.github_access_token)
|
||||||
.collect::<Vec<_>>();
|
{
|
||||||
if !ssh_flow.is_empty() {
|
let https_remote = if remote_url.scheme == super::Scheme::Https {
|
||||||
flow.push((remote, ssh_flow));
|
Ok(remote)
|
||||||
}
|
} else {
|
||||||
|
let url = remote_url.as_https()?;
|
||||||
if let Ok(https_url) = remote_url.as_https() {
|
project_repository.git_repository.remote_anonymous(&url)
|
||||||
let https_flow = Self::https_flow(project_repository, &https_url)?
|
}?;
|
||||||
.into_iter()
|
return Ok(vec![(
|
||||||
.map(Credential::Https)
|
https_remote,
|
||||||
.collect::<Vec<_>>();
|
vec![Credential::Https(HttpsCredential::GitHubToken(
|
||||||
if !https_flow.is_empty() {
|
github_access_token,
|
||||||
flow.push((
|
))],
|
||||||
project_repository
|
)]);
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&https_url)?,
|
|
||||||
https_flow,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(flow)
|
match remote_url.scheme {
|
||||||
}
|
super::Scheme::Https => {
|
||||||
_ => {
|
let mut flow = vec![];
|
||||||
let mut flow = vec![];
|
|
||||||
|
|
||||||
if let Ok(https_url) = remote_url.as_https() {
|
let https_flow = Self::https_flow(project_repository, &remote_url)?
|
||||||
let https_flow = Self::https_flow(project_repository, &https_url)?
|
.into_iter()
|
||||||
.into_iter()
|
.map(Credential::Https)
|
||||||
.map(Credential::Https)
|
.collect::<Vec<_>>();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
if !https_flow.is_empty() {
|
if !https_flow.is_empty() {
|
||||||
flow.push((
|
flow.push((remote, https_flow));
|
||||||
project_repository
|
}
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&https_url)?,
|
if let Ok(ssh_url) = remote_url.as_ssh() {
|
||||||
https_flow,
|
let ssh_flow = self
|
||||||
));
|
.ssh_flow()?
|
||||||
|
.into_iter()
|
||||||
|
.map(Credential::Ssh)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if !ssh_flow.is_empty() {
|
||||||
|
flow.push((
|
||||||
|
project_repository
|
||||||
|
.git_repository
|
||||||
|
.remote_anonymous(&ssh_url)?,
|
||||||
|
ssh_flow,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(flow)
|
||||||
|
}
|
||||||
|
super::Scheme::Ssh => {
|
||||||
|
let mut flow = vec![];
|
||||||
|
|
||||||
|
let ssh_flow = self
|
||||||
|
.ssh_flow()?
|
||||||
|
.into_iter()
|
||||||
|
.map(Credential::Ssh)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if !ssh_flow.is_empty() {
|
||||||
|
flow.push((remote, ssh_flow));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(https_url) = remote_url.as_https() {
|
||||||
|
let https_flow = Self::https_flow(project_repository, &https_url)?
|
||||||
|
.into_iter()
|
||||||
|
.map(Credential::Https)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if !https_flow.is_empty() {
|
||||||
|
flow.push((
|
||||||
|
project_repository
|
||||||
|
.git_repository
|
||||||
|
.remote_anonymous(&https_url)?,
|
||||||
|
https_flow,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(flow)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let mut flow = vec![];
|
||||||
|
|
||||||
|
if let Ok(https_url) = remote_url.as_https() {
|
||||||
|
let https_flow = Self::https_flow(project_repository, &https_url)?
|
||||||
|
.into_iter()
|
||||||
|
.map(Credential::Https)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !https_flow.is_empty() {
|
||||||
|
flow.push((
|
||||||
|
project_repository
|
||||||
|
.git_repository
|
||||||
|
.remote_anonymous(&https_url)?,
|
||||||
|
https_flow,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(ssh_url) = remote_url.as_ssh() {
|
||||||
|
let ssh_flow = self
|
||||||
|
.ssh_flow()?
|
||||||
|
.into_iter()
|
||||||
|
.map(Credential::Ssh)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if !ssh_flow.is_empty() {
|
||||||
|
flow.push((
|
||||||
|
project_repository
|
||||||
|
.git_repository
|
||||||
|
.remote_anonymous(&ssh_url)?,
|
||||||
|
ssh_flow,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(flow)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(ssh_url) = remote_url.as_ssh() {
|
|
||||||
let ssh_flow = self
|
|
||||||
.ssh_flow()?
|
|
||||||
.into_iter()
|
|
||||||
.map(Credential::Ssh)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
if !ssh_flow.is_empty() {
|
|
||||||
flow.push((
|
|
||||||
project_repository
|
|
||||||
.git_repository
|
|
||||||
.remote_anonymous(&ssh_url)?,
|
|
||||||
ssh_flow,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(flow)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,9 @@ use crate::{git, id::Id, types::default_true::DefaultTrue};
|
|||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum AuthKey {
|
pub enum AuthKey {
|
||||||
#[default]
|
#[default]
|
||||||
|
Default,
|
||||||
Generated,
|
Generated,
|
||||||
|
GitCredentialsHelper,
|
||||||
Local {
|
Local {
|
||||||
private_key_path: path::PathBuf,
|
private_key_path: path::PathBuf,
|
||||||
passphrase: Option<String>,
|
passphrase: Option<String>,
|
||||||
|
@ -12,7 +12,9 @@ import {
|
|||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
export type Key =
|
export type Key =
|
||||||
|
| 'default'
|
||||||
| 'generated'
|
| 'generated'
|
||||||
|
| 'gitCredentialsHelper'
|
||||||
| {
|
| {
|
||||||
local: { private_key_path: string; passphrase?: string };
|
local: { private_key_path: string; passphrase?: string };
|
||||||
};
|
};
|
||||||
|
@ -24,12 +24,28 @@
|
|||||||
sshKey = key;
|
sshKey = key;
|
||||||
});
|
});
|
||||||
|
|
||||||
let selectedOption = project.preferred_key === 'generated' ? 'generated' : 'local';
|
let selectedOption =
|
||||||
|
project.preferred_key === 'generated'
|
||||||
|
? 'generated'
|
||||||
|
: project.preferred_key === 'default'
|
||||||
|
? 'default'
|
||||||
|
: project.preferred_key === 'gitCredentialsHelper'
|
||||||
|
? 'gitCredentialsHelper'
|
||||||
|
: 'local';
|
||||||
|
|
||||||
let privateKeyPath =
|
let privateKeyPath =
|
||||||
project.preferred_key === 'generated' ? '' : project.preferred_key.local.private_key_path;
|
project.preferred_key === 'generated' ||
|
||||||
|
project.preferred_key === 'default' ||
|
||||||
|
project.preferred_key === 'gitCredentialsHelper'
|
||||||
|
? ''
|
||||||
|
: project.preferred_key.local.private_key_path;
|
||||||
let privateKeyPassphrase =
|
let privateKeyPassphrase =
|
||||||
project.preferred_key === 'generated' ? '' : project.preferred_key.local.passphrase;
|
project.preferred_key === 'generated' ||
|
||||||
|
project.preferred_key === 'default' ||
|
||||||
|
project.preferred_key === 'gitCredentialsHelper'
|
||||||
|
? ''
|
||||||
|
: project.preferred_key.local.passphrase;
|
||||||
|
|
||||||
function setLocalKey() {
|
function setLocalKey() {
|
||||||
dispatch('updated', {
|
dispatch('updated', {
|
||||||
preferred_key: {
|
preferred_key: {
|
||||||
@ -44,6 +60,18 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setGitCredentialsHelperKey() {
|
||||||
|
dispatch('updated', {
|
||||||
|
preferred_key: 'gitCredentialsHelper'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDefaultKey() {
|
||||||
|
dispatch('updated', {
|
||||||
|
preferred_key: 'default'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function setGeneratedKey() {
|
function setGeneratedKey() {
|
||||||
dispatch('updated', {
|
dispatch('updated', {
|
||||||
preferred_key: 'generated'
|
preferred_key: 'generated'
|
||||||
@ -52,7 +80,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<p>Preferred SSH Key</p>
|
<p>Git Authentication</p>
|
||||||
<div class="pr-8 text-sm text-light-700 dark:text-dark-200">
|
<div class="pr-8 text-sm text-light-700 dark:text-dark-200">
|
||||||
<div>
|
<div>
|
||||||
Select the SSH key that GitButler will use to authenticate with your Git provider. These keys
|
Select the SSH key that GitButler will use to authenticate with your Git provider. These keys
|
||||||
@ -61,8 +89,44 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-2" style="grid-template-columns: max-content 1fr;">
|
<div class="grid grid-cols-2 gap-2" style="grid-template-columns: max-content 1fr;">
|
||||||
<input type="radio" bind:group={selectedOption} value="generated" on:input={setGeneratedKey} />
|
<input type="radio" bind:group={selectedOption} value="default" on:input={setDefaultKey} />
|
||||||
|
<div class="flex flex-col space-y-2">
|
||||||
|
<div>Default</div>
|
||||||
|
|
||||||
|
{#if selectedOption === 'default'}
|
||||||
|
<div class="pr-8">
|
||||||
|
<div>
|
||||||
|
We will try all of: your local SHH keys, git credentials helper and local GitButler key.
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
It is recommended to select a specific authenticatation flow for a better expirience.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
bind:group={selectedOption}
|
||||||
|
value="gitCredentialsHelper"
|
||||||
|
on:input={setGitCredentialsHelperKey}
|
||||||
|
/>
|
||||||
|
<div class="flex flex-col space-y-2">
|
||||||
|
<div class="pr-8">
|
||||||
|
<div>
|
||||||
|
Use <a href="https://git-scm.com/doc/credential-helpers">git credentials helper</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#if selectedOption === 'gitCredentialsHelper'}
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
We will use the system git credentials helper to authenticate with your Git provider.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="radio" bind:group={selectedOption} value="generated" on:input={setGeneratedKey} />
|
||||||
<div class="flex flex-col space-y-2">
|
<div class="flex flex-col space-y-2">
|
||||||
<div class="pr-8">
|
<div class="pr-8">
|
||||||
<div>Use locally generated SSH key</div>
|
<div>Use locally generated SSH key</div>
|
||||||
@ -103,7 +167,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="radio" bind:group={selectedOption} value="local" on:input={() => setLocalKey} />
|
<input type="radio" bind:group={selectedOption} value="local" on:input={setLocalKey} />
|
||||||
<div class="flex flex-col space-y-2">
|
<div class="flex flex-col space-y-2">
|
||||||
<div>Use existing SSH key</div>
|
<div>Use existing SSH key</div>
|
||||||
|
|
||||||
@ -121,7 +185,7 @@
|
|||||||
<label for="path">Path to private key</label>
|
<label for="path">Path to private key</label>
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
placeholder="/absolute/path/id_rsa"
|
placeholder="~/.ssh/id_rsa"
|
||||||
bind:value={privateKeyPath}
|
bind:value={privateKeyPath}
|
||||||
on:change={setLocalKey}
|
on:change={setLocalKey}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user