#[allow(clippy::wildcard_imports)]
use super::*;
#[derive(Deserialize)]
pub(crate) struct MemberBody {
#[serde(default)]
role: Option<String>,
#[serde(default)]
label: Option<String>,
}
pub(crate) async fn get_account_team(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"GET",
format!("/api/billing/team/{user_id}"),
None,
)
.await?;
finish(status, json)
}
pub(crate) async fn get_account_team_savings(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"GET",
format!("/api/billing/team/{user_id}/savings"),
None,
)
.await?;
finish(status, json)
}
pub(crate) async fn get_account_team_savings_member(
State(state): State<AppState>,
headers: HeaderMap,
axum::extract::Path(signer): axum::extract::Path<String>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
if signer.is_empty()
|| signer.len() > 64
|| !signer
.bytes()
.all(|b| b.is_ascii_alphanumeric() || b == b'_' || b == b'-')
{
return Err((StatusCode::BAD_REQUEST, "invalid signer id".into()));
}
let (status, json) = billing_forward(
&state.cfg,
"GET",
format!("/api/billing/team/{user_id}/savings/member/{signer}"),
None,
)
.await?;
finish(status, json)
}
pub(crate) async fn forward_for_digest(cfg: &Config, path: String) -> Option<(u16, Value)> {
match billing_forward(cfg, "GET", path, None).await {
Ok((status, json)) => Some((status.as_u16(), json)),
Err(_) => None,
}
}
#[derive(Deserialize)]
pub(crate) struct TeamSettingsBody {
#[serde(default, rename = "roiWebhookUrl")]
roi_webhook_url: Option<String>,
}
pub(crate) async fn put_account_team_settings(
State(state): State<AppState>,
headers: HeaderMap,
Json(body): Json<TeamSettingsBody>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"PUT",
format!("/api/billing/team/{user_id}/settings"),
Some(json!({ "roiWebhookUrl": body.roi_webhook_url })),
)
.await?;
finish(status, json)
}
pub(crate) async fn post_account_team_owner_token(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"POST",
format!("/api/billing/team/{user_id}/owner-token"),
Some(json!({})),
)
.await?;
finish(status, json)
}
pub(crate) async fn post_account_team_member(
State(state): State<AppState>,
headers: HeaderMap,
Json(body): Json<MemberBody>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"POST",
format!("/api/billing/team/{user_id}/tokens"),
Some(json!({ "role": body.role, "label": body.label })),
)
.await?;
finish(status, json)
}
#[derive(Deserialize)]
pub(crate) struct InviteBody {
#[serde(default)]
label: Option<String>,
#[serde(default)]
role: Option<String>,
}
pub(crate) async fn post_account_team_invite(
State(state): State<AppState>,
headers: HeaderMap,
Json(body): Json<InviteBody>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"POST",
format!("/api/billing/team/{user_id}/invites"),
Some(json!({ "label": body.label, "role": body.role })),
)
.await?;
finish(status, json)
}
pub(crate) async fn get_account_team_invites(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"GET",
format!("/api/billing/team/{user_id}/invites"),
None,
)
.await?;
finish(status, json)
}
pub(crate) async fn delete_account_team_invite(
State(state): State<AppState>,
headers: HeaderMap,
Path(invite_id): Path<Uuid>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"DELETE",
format!("/api/billing/team/{user_id}/invites/{invite_id}"),
None,
)
.await?;
if status == StatusCode::NO_CONTENT {
return Ok(Json(json!({ "revoked": true })));
}
finish(status, json)
}
pub(crate) async fn forward_invite_redeem(
cfg: &Config,
code: &str,
) -> Result<(StatusCode, Value), (StatusCode, String)> {
billing_forward(
cfg,
"POST",
"/api/billing/invites/redeem".to_string(),
Some(json!({ "code": code })),
)
.await
}
pub(crate) async fn delete_account_team_member(
State(state): State<AppState>,
headers: HeaderMap,
Path(token_id): Path<String>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"DELETE",
format!("/api/billing/team/{user_id}/tokens/{token_id}"),
None,
)
.await?;
if status.is_success() {
return Ok(Json(json!({ "revoked": true })));
}
finish(status, json)
}
pub(crate) async fn post_account_team_seats(
State(state): State<AppState>,
headers: HeaderMap,
Json(body): Json<Value>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"POST",
format!("/api/billing/team/{user_id}/seats"),
Some(body),
)
.await?;
finish(status, json)
}
pub(crate) async fn get_account_team_storage(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"GET",
format!("/api/billing/team/{user_id}/storage"),
None,
)
.await?;
finish(status, json)
}
pub(crate) async fn get_account_team_connectors(
State(state): State<AppState>,
headers: HeaderMap,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"GET",
format!("/api/billing/team/{user_id}/connectors"),
None,
)
.await?;
finish(status, json)
}
pub(crate) async fn post_account_team_connector(
State(state): State<AppState>,
headers: HeaderMap,
Json(body): Json<Value>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"POST",
format!("/api/billing/team/{user_id}/connectors"),
Some(body),
)
.await?;
finish(status, json)
}
pub(crate) async fn patch_account_team_connector(
State(state): State<AppState>,
headers: HeaderMap,
Path(connector_id): Path<String>,
Json(body): Json<Value>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"PATCH",
format!("/api/billing/team/{user_id}/connectors/{connector_id}"),
Some(body),
)
.await?;
if status.is_success() {
return Ok(Json(json!({ "updated": true })));
}
finish(status, json)
}
pub(crate) async fn delete_account_team_connector(
State(state): State<AppState>,
headers: HeaderMap,
Path(connector_id): Path<String>,
) -> Result<Json<Value>, (StatusCode, String)> {
let (user_id, _email) = auth_user(&state, &headers).await?;
let (status, json) = billing_forward(
&state.cfg,
"DELETE",
format!("/api/billing/team/{user_id}/connectors/{connector_id}"),
None,
)
.await?;
if status.is_success() {
return Ok(Json(json!({ "deleted": true })));
}
finish(status, json)
}