diff --git a/lib/src/db.rs b/lib/src/db.rs index 0c4e1692a..d78c88e8f 100644 --- a/lib/src/db.rs +++ b/lib/src/db.rs @@ -20,18 +20,20 @@ use tracing::{info, instrument}; use crate::{ agents::ForAgent, - atomic_url::AtomicUrl, + atomic_url::{AtomicUrl, Routes}, atoms::IndexAtom, commit::CommitResponse, db::{query_index::requires_query_index, val_prop_sub_index::find_in_val_prop_sub_index}, email::{self, MailMessage}, - endpoints::{default_endpoints, Endpoint, HandleGetContext}, + endpoints::{build_default_endpoints, Endpoint, HandleGetContext}, errors::{AtomicError, AtomicResult}, + plugins, query::QueryResult, resources::PropVals, storelike::Storelike, + urls, values::SortableValue, - Atom, Query, Resource, + Atom, Query, Resource, Value, }; use self::{ @@ -112,7 +114,7 @@ impl Db { prop_val_sub_index, server_url: AtomicUrl::try_from(server_url)?, watched_queries, - endpoints: default_endpoints(), + endpoints: Vec::new(), handle_commit: None, smtp_client: None, }; @@ -220,6 +222,28 @@ impl Db { Some(Resource::from_propvals(propvals, subject)) } + pub fn register_default_endpoints(&mut self) -> AtomicResult<()> { + // First we delete all existing endpoint resources, as they might not be there in this new run + let found_endpoints = self.query(&Query::new_class(urls::ENDPOINT))?.resources; + + for mut found in found_endpoints { + found.destroy(self)?; + } + + let mut endpoints = build_default_endpoints(); + + if self.smtp_client.is_some() { + endpoints.push(plugins::register::register_endpoint()); + endpoints.push(plugins::register::confirm_email_endpoint()); + } + + for endpoint in endpoints { + self.register_endpoint(endpoint)?; + } + + Ok(()) + } + fn build_index_for_atom( &self, atom: &IndexAtom, @@ -321,8 +345,17 @@ impl Db { } /// Adds an [Endpoint] to the store. This means adding a route with custom behavior. - pub fn register_endpoint(&mut self, endpoint: Endpoint) { + pub fn register_endpoint(&mut self, endpoint: Endpoint) -> AtomicResult<()> { + let mut resource = endpoint.to_resource(self)?; + let endpoints_collection = self.get_server_url().set_route(Routes::Endpoints); + resource.set_propval( + urls::PARENT.into(), + Value::AtomicUrl(endpoints_collection.to_string()), + self, + )?; + resource.save_locally(self)?; self.endpoints.push(endpoint); + Ok(()) } /// Registers an SMTP client to the store, allowing the store to send emails. diff --git a/lib/src/endpoints.rs b/lib/src/endpoints.rs index 29d8940c2..fc4e4d3b8 100644 --- a/lib/src/endpoints.rs +++ b/lib/src/endpoints.rs @@ -87,15 +87,13 @@ impl std::fmt::Debug for Endpoint { } } -pub fn default_endpoints() -> Vec { +pub fn build_default_endpoints() -> Vec { vec![ plugins::versioning::version_endpoint(), plugins::versioning::all_versions_endpoint(), plugins::path::path_endpoint(), plugins::search::search_endpoint(), plugins::files::upload_endpoint(), - plugins::register::register_endpoint(), - plugins::register::confirm_email_endpoint(), #[cfg(feature = "html")] plugins::bookmark::bookmark_endpoint(), plugins::importer::import_endpoint(), diff --git a/lib/src/plugins/mod.rs b/lib/src/plugins/mod.rs index 87c0f6ecd..d240f5907 100644 --- a/lib/src/plugins/mod.rs +++ b/lib/src/plugins/mod.rs @@ -34,8 +34,6 @@ They are used for performing custom queries, or calculating dynamic attributes. Add these by registering the handler at [crate::db::Db::get_resource_extended]. */ -use crate::endpoints::Endpoint; - // Class Extenders pub mod chatroom; pub mod importer; @@ -55,19 +53,3 @@ pub mod versioning; // Utilities / helpers mod utils; - -pub fn default_endpoints() -> Vec { - vec![ - versioning::version_endpoint(), - versioning::all_versions_endpoint(), - path::path_endpoint(), - search::search_endpoint(), - files::upload_endpoint(), - register::register_endpoint(), - register::confirm_email_endpoint(), - add_pubkey::request_email_add_pubkey(), - add_pubkey::confirm_add_pubkey(), - #[cfg(feature = "html")] - bookmark::bookmark_endpoint(), - ] -} diff --git a/lib/src/populate.rs b/lib/src/populate.rs index f0f43c4e2..94db99aad 100644 --- a/lib/src/populate.rs +++ b/lib/src/populate.rs @@ -383,7 +383,6 @@ pub fn populate_all(store: &crate::Db) -> AtomicResult<()> { .map_err(|e| format!("Failed to create default ontology. {}", e))?; set_drive_rights(store, true)?; populate_collections(store).map_err(|e| format!("Failed to populate collections. {}", e))?; - populate_endpoints(store).map_err(|e| format!("Failed to populate endpoints. {}", e))?; populate_sidebar_items(store) .map_err(|e| format!("Failed to populate sidebar items. {}", e))?; Ok(()) diff --git a/server/src/appstate.rs b/server/src/appstate.rs index 57bec6646..9818d4c48 100644 --- a/server/src/appstate.rs +++ b/server/src/appstate.rs @@ -29,10 +29,12 @@ pub struct AppState { /// Initializes the Store and sets the default agent. pub fn init_store(config: &Config) -> AtomicServerResult { - let store = atomic_lib::Db::init(&config.store_path, &config.server_url)?; + let mut store = atomic_lib::Db::init(&config.store_path, &config.server_url)?; tracing::info!("Setting default agent"); set_default_agent(config, &store)?; + store.register_default_endpoints()?; + Ok(store) }