Skip to content

Commit 05e3735

Browse files
committed
refactor api-nango
Signed-off-by: Yujong Lee <yujonglee.dev@gmail.com>
1 parent e9a8c1a commit 05e3735

8 files changed

Lines changed: 504 additions & 162 deletions

File tree

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/api-nango/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,10 @@ tracing = { workspace = true }
2323
serde = { workspace = true, features = ["derive"] }
2424
serde_json = { workspace = true }
2525
thiserror = { workspace = true }
26+
27+
[dev-dependencies]
28+
hex = "0.4"
29+
hmac = { workspace = true }
30+
sha2 = { workspace = true }
31+
tokio = { workspace = true }
32+
wiremock = { workspace = true }

crates/api-nango/src/config.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ impl NangoConfig {
2222
supabase_service_role_key,
2323
}
2424
}
25+
26+
#[cfg(test)]
27+
pub(crate) fn for_test(nango_base: &str, supabase_base: &str) -> Self {
28+
Self {
29+
nango: NangoEnv {
30+
nango_api_base: Some(nango_base.to_string()),
31+
nango_secret_key: "test-secret".to_string(),
32+
},
33+
supabase_url: supabase_base.to_string(),
34+
supabase_anon_key: "test-anon-key".to_string(),
35+
supabase_service_role_key: Some("test-service-role-key".to_string()),
36+
}
37+
}
2538
}
2639

2740
pub(crate) fn build_nango_client(config: &NangoConfig) -> Result<NangoClient, hypr_nango::Error> {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use hypr_nango::OwnedNangoProxy;
2+
3+
#[derive(serde::Deserialize)]
4+
struct GoogleUserInfo {
5+
email: Option<String>,
6+
name: Option<String>,
7+
}
8+
9+
#[derive(serde::Deserialize)]
10+
struct OutlookMe {
11+
mail: Option<String>,
12+
#[serde(rename = "userPrincipalName")]
13+
user_principal_name: Option<String>,
14+
#[serde(rename = "displayName")]
15+
display_name: Option<String>,
16+
}
17+
18+
pub(crate) async fn fetch_identity(
19+
nango: &hypr_nango::NangoClient,
20+
integration_id: &str,
21+
connection_id: &str,
22+
) -> std::result::Result<(Option<String>, Option<String>), String> {
23+
let proxy = OwnedNangoProxy::new(nango, integration_id.to_string(), connection_id.to_string());
24+
25+
match integration_id {
26+
// https://docs.cloud.google.com/identity-platform/docs/reference/rest/v1/UserInfo
27+
"google-calendar" | "google-drive" => {
28+
let resp = proxy
29+
.get("/oauth2/v1/userinfo?alt=json")
30+
.map_err(|e| e.to_string())?
31+
.send()
32+
.await
33+
.map_err(|e| e.to_string())?
34+
.error_for_status()
35+
.map_err(|e| e.to_string())?;
36+
37+
let me: GoogleUserInfo = resp.json().await.map_err(|e| e.to_string())?;
38+
Ok((me.email, me.name))
39+
}
40+
41+
// https://learn.microsoft.com/en-us/graph/api/user-get
42+
"outlook" => {
43+
let resp = proxy
44+
.get("/v1.0/me?$select=mail,userPrincipalName,displayName")
45+
.map_err(|e| e.to_string())?
46+
.send()
47+
.await
48+
.map_err(|e| e.to_string())?
49+
.error_for_status()
50+
.map_err(|e| e.to_string())?;
51+
52+
let me: OutlookMe = resp.json().await.map_err(|e| e.to_string())?;
53+
Ok((me.mail.or(me.user_principal_name), me.display_name))
54+
}
55+
56+
other => Err(format!("unsupported integration: {other}")),
57+
}
58+
}

crates/api-nango/src/routes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub(crate) mod connect;
22
pub(crate) mod disconnect;
3+
pub(crate) mod identity;
34
pub(crate) mod status;
45
pub(crate) mod webhook;
56
pub(crate) mod whoami;

0 commit comments

Comments
 (0)