forked from coracle/caravel
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 364b8fd26c |
@@ -30,5 +30,6 @@ Members:
|
|||||||
## `async fn sync_relay(&self, relay: &Relay, is_new: bool)`
|
## `async fn sync_relay(&self, relay: &Relay, is_new: bool)`
|
||||||
|
|
||||||
- If `is_new`, sends `POST /relay/:id` to create the relay in zooid.
|
- If `is_new`, sends `POST /relay/:id` to create the relay in zooid.
|
||||||
- Otherwise, sends `PUT /relay/:id` to update it.
|
- Otherwise, sends `PATCH /relay/:id` to update it.
|
||||||
- Passes full relay configuration in the body including host, schema, secret, inactive flag, info, policy, groups, management, blossom, livekit, push, and roles.
|
- Includes `secret` only for relay creation (`POST`) so updates do not rotate relay identity.
|
||||||
|
- Passes relay configuration in the body including host, schema, inactive flag, info, policy, groups, management, blossom, livekit, push, and roles.
|
||||||
|
|||||||
@@ -85,9 +85,8 @@ A relay is a nostr relay owned by a `tenant` and hosted by the attached zooid in
|
|||||||
|
|
||||||
Some attributes persisted to zooid via API have special handling:
|
Some attributes persisted to zooid via API have special handling:
|
||||||
|
|
||||||
- The relay's `secret` is generated once and persisted to the zooid configuration but isn't stored in the database.
|
- The relay's `secret` is generated once on relay creation, persisted to the zooid configuration, and isn't stored in the database. Relay updates do not resend `secret`.
|
||||||
- The relay's `host` is calculated based on `subdomain` + `RELAY_DOMAIN`
|
- The relay's `host` is calculated based on `subdomain` + `RELAY_DOMAIN`
|
||||||
- The value of `inactive` is calculated based on `status`
|
- The value of `inactive` is calculated based on `status`
|
||||||
- The relay's `livekit_*` configuration is inferred based on environment variables and `livekit_enabled`.
|
- The relay's `livekit_*` configuration is inferred based on environment variables and `livekit_enabled`.
|
||||||
- The relay's `roles` are hard-coded for now.
|
- The relay's `roles` are hard-coded for now.
|
||||||
|
|
||||||
|
|||||||
+68
-48
@@ -2,7 +2,7 @@ use anyhow::Result;
|
|||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
|
|
||||||
use crate::command::Command;
|
use crate::command::Command;
|
||||||
use crate::models::{Activity, RELAY_STATUS_DELINQUENT, RELAY_STATUS_INACTIVE};
|
use crate::models::{Activity, Relay, RELAY_STATUS_DELINQUENT, RELAY_STATUS_INACTIVE};
|
||||||
use crate::query::Query;
|
use crate::query::Query;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -70,7 +70,7 @@ impl Infra {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sync_and_report(&self, relay: &crate::models::Relay, is_new: bool) {
|
async fn sync_and_report(&self, relay: &Relay, is_new: bool) {
|
||||||
match self.sync_relay(relay, is_new).await {
|
match self.sync_relay(relay, is_new).await {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
tracing::info!(relay = %relay.id, "relay sync succeeded");
|
tracing::info!(relay = %relay.id, "relay sync succeeded");
|
||||||
@@ -96,7 +96,7 @@ impl Infra {
|
|||||||
Ok(auth)
|
Ok(auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sync_relay(&self, relay: &crate::models::Relay, is_new: bool) -> Result<()> {
|
async fn sync_relay(&self, relay: &Relay, is_new: bool) -> Result<()> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let base = self.api_url.trim_end_matches('/');
|
let base = self.api_url.trim_end_matches('/');
|
||||||
|
|
||||||
@@ -106,8 +106,6 @@ impl Infra {
|
|||||||
format!("{}.{}", relay.subdomain, self.relay_domain)
|
format!("{}.{}", relay.subdomain, self.relay_domain)
|
||||||
};
|
};
|
||||||
|
|
||||||
let secret = Keys::generate().secret_key().to_secret_hex();
|
|
||||||
|
|
||||||
let livekit = if relay.livekit_enabled == 1 {
|
let livekit = if relay.livekit_enabled == 1 {
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
@@ -119,53 +117,28 @@ impl Infra {
|
|||||||
serde_json::json!({ "enabled": false })
|
serde_json::json!({ "enabled": false })
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = serde_json::json!({
|
let body = relay_sync_body(
|
||||||
"host": host,
|
relay,
|
||||||
"schema": relay.schema,
|
host,
|
||||||
"secret": secret,
|
livekit,
|
||||||
"inactive": relay.status == RELAY_STATUS_INACTIVE
|
is_new.then(|| Keys::generate().secret_key().to_secret_hex()),
|
||||||
|| relay.status == RELAY_STATUS_DELINQUENT,
|
);
|
||||||
"info": {
|
|
||||||
"name": relay.info_name,
|
|
||||||
"icon": relay.info_icon,
|
|
||||||
"description": relay.info_description,
|
|
||||||
"pubkey": relay.tenant,
|
|
||||||
},
|
|
||||||
"policy": {
|
|
||||||
"public_join": relay.policy_public_join == 1,
|
|
||||||
"strip_signatures": relay.policy_strip_signatures == 1,
|
|
||||||
},
|
|
||||||
"groups": { "enabled": relay.groups_enabled == 1 },
|
|
||||||
"management": { "enabled": relay.management_enabled == 1 },
|
|
||||||
"blossom": { "enabled": relay.blossom_enabled == 1 },
|
|
||||||
"livekit": livekit,
|
|
||||||
"push": { "enabled": relay.push_enabled == 1 },
|
|
||||||
"roles": {
|
|
||||||
"admin": { "can_manage": true, "can_invite": true },
|
|
||||||
"member": { "can_invite": true },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let response = if is_new {
|
let url = format!("{}/relay/{}", base, relay.id);
|
||||||
let url = format!("{}/relay/{}", base, relay.id);
|
let auth = self.nip98_auth(&url, zooid_sync_http_method(is_new)).await?;
|
||||||
let auth = self.nip98_auth(&url, HttpMethod::POST).await?;
|
|
||||||
client
|
let request = if is_new {
|
||||||
.post(&url)
|
client.post(&url)
|
||||||
.header("Authorization", auth)
|
|
||||||
.json(&body)
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
} else {
|
} else {
|
||||||
let url = format!("{}/relay/{}", base, relay.id);
|
client.patch(&url)
|
||||||
let auth = self.nip98_auth(&url, HttpMethod::PUT).await?;
|
|
||||||
client
|
|
||||||
.put(&url)
|
|
||||||
.header("Authorization", auth)
|
|
||||||
.json(&body)
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let response = request
|
||||||
|
.header("Authorization", auth)
|
||||||
|
.json(&body)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
if !response.status().is_success() {
|
if !response.status().is_success() {
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
let body = response.text().await.unwrap_or_default();
|
let body = response.text().await.unwrap_or_default();
|
||||||
@@ -175,6 +148,53 @@ impl Infra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn zooid_sync_http_method(is_new: bool) -> HttpMethod {
|
||||||
|
if is_new {
|
||||||
|
HttpMethod::POST
|
||||||
|
} else {
|
||||||
|
HttpMethod::PATCH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn relay_sync_body(
|
||||||
|
relay: &Relay,
|
||||||
|
host: String,
|
||||||
|
livekit: serde_json::Value,
|
||||||
|
secret: Option<String>,
|
||||||
|
) -> serde_json::Value {
|
||||||
|
let mut body = serde_json::json!({
|
||||||
|
"host": host,
|
||||||
|
"schema": relay.schema,
|
||||||
|
"inactive": relay.status == RELAY_STATUS_INACTIVE
|
||||||
|
|| relay.status == RELAY_STATUS_DELINQUENT,
|
||||||
|
"info": {
|
||||||
|
"name": relay.info_name,
|
||||||
|
"icon": relay.info_icon,
|
||||||
|
"description": relay.info_description,
|
||||||
|
"pubkey": relay.tenant,
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"public_join": relay.policy_public_join == 1,
|
||||||
|
"strip_signatures": relay.policy_strip_signatures == 1,
|
||||||
|
},
|
||||||
|
"groups": { "enabled": relay.groups_enabled == 1 },
|
||||||
|
"management": { "enabled": relay.management_enabled == 1 },
|
||||||
|
"blossom": { "enabled": relay.blossom_enabled == 1 },
|
||||||
|
"livekit": livekit,
|
||||||
|
"push": { "enabled": relay.push_enabled == 1 },
|
||||||
|
"roles": {
|
||||||
|
"admin": { "can_manage": true, "can_invite": true },
|
||||||
|
"member": { "can_invite": true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if let (Some(secret), Some(body_obj)) = (secret, body.as_object_mut()) {
|
||||||
|
body_obj.insert("secret".to_string(), serde_json::Value::String(secret));
|
||||||
|
}
|
||||||
|
|
||||||
|
body
|
||||||
|
}
|
||||||
|
|
||||||
fn should_sync_relay_activity(activity_type: &str) -> bool {
|
fn should_sync_relay_activity(activity_type: &str) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
activity_type,
|
activity_type,
|
||||||
|
|||||||
Reference in New Issue
Block a user