Skip to content

Commit 6c322c8

Browse files
committed
Refactor endpoints, update JSON
1 parent 431a7f5 commit 6c322c8

File tree

9 files changed

+63
-37
lines changed

9 files changed

+63
-37
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Changes to JS assets are not included here, but in [`atomic-data-browser`'s CHAN
66

77
## UNRELEASED
88

9-
- New sign up / register flow. Add `/register` Endpoint #489 #254
9+
- New sign up / register flow. Add `/register`, `/confirm-email`, `/add-public-key` endpoints #489 #254
1010
- Add multi-tenancy support. Users can create their own `Drives` on subdomains. #288
1111
- Refactor URLs. `store.self_url()` returns an `AtomicUrl`, which provides methods to easily add paths, find subdomains and more.
1212
- Add support for subdomains, use a Wildcard TLS certificate #502

lib/defaults/default_base_models.json

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,23 @@
7878
},
7979
{
8080
"@id": "https://atomicdata.dev/classes/Property",
81-
"https://atomicdata.dev/properties/description": "A Resource that should redirect the browser to a new location. It can also set a `redirectAgent`, which is used in Invites to create an Agent Resource on the Server from a Public Key that the user posesses. See the [Invite docs](https://docs.atomicdata.dev/invitations.html).",
81+
"https://atomicdata.dev/properties/description": "A Property is a single field in a Class. It's the thing that a property field in an Atom points to. An example is `birthdate`. An instance of Property requires various Properties, most notably a `datatype` (e.g. `string` or `integer`), a human readable `description` (such as the thing you're reading), and a `shortname`.",
8282
"https://atomicdata.dev/properties/isA": [
8383
"https://atomicdata.dev/classes/Class"
8484
],
85-
"https://atomicdata.dev/properties/requires": [
86-
"https://atomicdata.dev/properties/destination"
87-
],
85+
"https://atomicdata.dev/properties/parent": "https://atomicdata.dev/classes",
8886
"https://atomicdata.dev/properties/recommends": [
89-
"https://atomicdata.dev/properties/invite/redirectAgent"
87+
"https://atomicdata.dev/properties/classtype",
88+
"https://atomicdata.dev/properties/isDynamic",
89+
"https://atomicdata.dev/properties/isLocked",
90+
"https://atomicdata.dev/properties/allowsOnly"
91+
],
92+
"https://atomicdata.dev/properties/requires": [
93+
"https://atomicdata.dev/properties/shortname",
94+
"https://atomicdata.dev/properties/datatype",
95+
"https://atomicdata.dev/properties/description"
9096
],
91-
"https://atomicdata.dev/properties/shortname": "redirect"
97+
"https://atomicdata.dev/properties/shortname": "property"
9298
},
9399
{
94100
"@id": "https://atomicdata.dev/classes/Class",

lib/defaults/default_store.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -749,10 +749,9 @@
749749
"https://atomicdata.dev/properties/isA": [
750750
"https://atomicdata.dev/classes/Property"
751751
],
752-
"https://atomicdata.dev/properties/lastCommit": "https://atomicdata.dev/commits/VB3gtWMkysTX5hKjbYjIM1hfVGPywT3pEPL8c7NwaUAJID6RzptGRPzmix8aKKDeb8Pj1WFv0UPV0YVPxcduBg==",
753752
"https://atomicdata.dev/properties/parent": "https://atomicdata.dev/properties",
754753
"https://atomicdata.dev/properties/shortname": "sub-resources"
755-
},
754+
},´
756755
{
757756
"@id": "https://atomicdata.dev/properties/tags",
758757
"https://atomicdata.dev/properties/classtype": "https://atomicdata.dev/classes/Tag",
@@ -761,10 +760,19 @@
761760
"https://atomicdata.dev/properties/isA": [
762761
"https://atomicdata.dev/classes/Property"
763762
],
764-
"https://atomicdata.dev/properties/lastCommit": "https://atomicdata.dev/commits/fS0krtm1wDk0lodH0psnUKmBHBMKLuxnjkd7E7QbkzDk/irQ43gNW3lWxkwQj58ZNg6rUAUMDGJrLy1X3cHwBQ==",
765763
"https://atomicdata.dev/properties/parent": "https://atomicdata.dev/properties",
766764
"https://atomicdata.dev/properties/shortname": "tags"
767765
},
766+
{
767+
"@id": "https://atomicdata.dev/properties/token",
768+
"https://atomicdata.dev/properties/datatype": "https://atomicdata.dev/datatypes/string",
769+
"https://atomicdata.dev/properties/description": "A server-generated string that should not mean anything to the client. It could be a JWT token, or something else.",
770+
"https://atomicdata.dev/properties/isA": [
771+
"https://atomicdata.dev/classes/Property"
772+
],
773+
"https://atomicdata.dev/properties/parent": "https://atomicdata.dev/properties",
774+
"https://atomicdata.dev/properties/shortname": "token"
775+
},
768776
{
769777
"@id": "https://atomicdata.dev/properties/write",
770778
"https://atomicdata.dev/properties/classtype": "https://atomicdata.dev/classes/Agent",

lib/src/db.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ use crate::{
2424
commit::CommitResponse,
2525
db::{query_index::NO_VALUE, val_prop_sub_index::find_in_val_prop_sub_index},
2626
email::{self, MailMessage},
27-
endpoints::{default_endpoints, Endpoint},
27+
endpoints::Endpoint,
2828
errors::{AtomicError, AtomicResult},
29+
plugins::default_endpoints,
2930
query::QueryResult,
3031
resources::PropVals,
3132
storelike::Storelike,

lib/src/endpoints.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Examples of endpoints are versions for resources, or (pages for) collections.
44
//! See https://docs.atomicdata.dev/endpoints.html or https://atomicdata.dev/classes/Endpoint
55
6-
use crate::{errors::AtomicResult, plugins, urls, Db, Resource, Storelike, Value};
6+
use crate::{errors::AtomicResult, urls, Db, Resource, Storelike, Value};
77

88
/// The function that is called when the request matches the path
99
type HandleFunction =
@@ -54,17 +54,3 @@ impl std::fmt::Debug for Endpoint {
5454
.finish()
5555
}
5656
}
57-
58-
pub fn default_endpoints() -> Vec<Endpoint> {
59-
vec![
60-
plugins::versioning::version_endpoint(),
61-
plugins::versioning::all_versions_endpoint(),
62-
plugins::path::path_endpoint(),
63-
plugins::search::search_endpoint(),
64-
plugins::files::upload_endpoint(),
65-
plugins::register::register_endpoint(),
66-
plugins::register::confirm_email_endpoint(),
67-
#[cfg(feature = "html")]
68-
plugins::bookmark::bookmark_endpoint(),
69-
]
70-
}

lib/src/plugins/reset_pubkey.rs renamed to lib/src/plugins/add_pubkey.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,8 @@ pub fn handle_request_email_pubkey(
4646
) -> AtomicResult<Resource> {
4747
let mut email_option: Option<EmailAddress> = None;
4848
for (k, v) in url.query_pairs() {
49-
match k.as_ref() {
50-
"email" => email_option = Some(EmailAddress::new(v.to_string())?),
51-
_ => {}
49+
if let "email" = k.as_ref() {
50+
email_option = Some(EmailAddress::new(v.to_string())?)
5251
}
5352
}
5453
// by default just return the Endpoint
@@ -57,7 +56,12 @@ pub fn handle_request_email_pubkey(
5756
};
5857

5958
// Find the agent by their email
60-
let agent = Agent::from_email(&email.to_string(), store)?;
59+
let agent = match Agent::from_email(&email.to_string(), store) {
60+
Ok(a) => a,
61+
// If we can't find the agent, we should still return a `success` response,
62+
// in order to prevent users to know that the email exists.
63+
Err(_) => return return_success(),
64+
};
6165

6266
// send the user an e-mail to confirm sign up
6367
let store_clone = store.clone();
@@ -108,12 +112,13 @@ pub fn handle_confirm_add_pubkey(
108112
_ => {}
109113
}
110114
}
111-
let pubkey = pubkey_option.ok_or("No public-key provided")?;
112115

113116
let Some(token) = token_opt else {
114117
return confirm_add_pubkey().to_resource(store);
115118
};
116119

120+
let pubkey = pubkey_option.ok_or("No public-key provided")?;
121+
117122
// Parse and verify the JWT token
118123
let confirmation = crate::token::verify_claim::<AddPubkeyToken>(store, &token)?.custom;
119124

lib/src/plugins/mod.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Plugins can have functions that are called at specific moments by Atomic-Server.
66
77
For example:
88
9-
- Before returning a Resource. These are either Endpoints or Class Extenders.
9+
- Before returning a Resource. These are either [Endpoint]s or Class Extenders.
1010
- Before applying a Commit.
1111
1212
In the long term, these plugins will probably be powered by WASM and can be extended at runtime.
@@ -16,13 +16,13 @@ However, they are designed in such a way that they have a limited scope and a cl
1616
## Extending resources
1717
1818
There are two ways of extending / modifying a Resource.
19-
Endpoints are great for APIs that have a fixed route, and Class Extenders are great for APIs that don't have a fixed route.
19+
[Endpoint]s are great for APIs that have a fixed route, and Class Extenders are great for APIs that don't have a fixed route.
2020
Endpoints are easier to generate from Rust, and will be available the second a server is Running.
2121
22-
### Endpoints
22+
### [Endpoint]s
2323
2424
Resources that typically parse query parameters and return a dynamic resource.
25-
When adding an endpoint, add it to the list of endpoints in [lib/src/endpoints.rs]
25+
When adding an endpoint, add it to the list of [default_endpoints] in this file.
2626
Endpoints are all instances of the [crate] class.
2727
They are presented in the UI as a form.
2828
@@ -31,22 +31,41 @@ They are presented in the UI as a form.
3131
Similar to Endpoints, Class Extenders can modify their contents before creating a response.
3232
Contrary to Endpoints, these can be any type of Class.
3333
They are used for performing custom queries, or calculating dynamic attributes.
34+
Add these by registering the handler at [crate::db::Db::get_resource_extended].
3435
*/
3536

37+
use crate::endpoints::Endpoint;
38+
3639
// Class Extenders
3740
pub mod chatroom;
3841
pub mod importer;
3942
pub mod invite;
4043

4144
// Endpoints
45+
pub mod add_pubkey;
4246
#[cfg(feature = "html")]
4347
pub mod bookmark;
4448
pub mod files;
4549
pub mod path;
4650
pub mod register;
47-
pub mod reset_pubkey;
4851
pub mod search;
4952
pub mod versioning;
5053

5154
// Utilities / helpers
5255
mod utils;
56+
57+
pub fn default_endpoints() -> Vec<Endpoint> {
58+
vec![
59+
versioning::version_endpoint(),
60+
versioning::all_versions_endpoint(),
61+
path::path_endpoint(),
62+
search::search_endpoint(),
63+
files::upload_endpoint(),
64+
register::register_endpoint(),
65+
register::confirm_email_endpoint(),
66+
add_pubkey::request_email_add_pubkey(),
67+
add_pubkey::confirm_add_pubkey(),
68+
#[cfg(feature = "html")]
69+
bookmark::bookmark_endpoint(),
70+
]
71+
}

lib/src/plugins/register.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub fn handle_register_name_and_email(
105105
.get_server_url()
106106
.clone()
107107
.set_path(urls::PATH_CONFIRM_EMAIL)
108+
// .set_subdomain(Some(&name.to_string()))?
108109
.url();
109110
confirm_url.set_query(Some(&format!("token={}", token)));
110111
let message = MailMessage {

lib/src/populate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ pub fn populate_collections(store: &impl Storelike) -> AtomicResult<()> {
247247
pub fn populate_endpoints(store: &crate::Db) -> AtomicResult<()> {
248248
use crate::atomic_url::Routes;
249249

250-
let endpoints = crate::endpoints::default_endpoints();
250+
let endpoints = crate::plugins::default_endpoints();
251251
let endpoints_collection = store.get_server_url().set_route(Routes::Endpoints);
252252
for endpoint in endpoints {
253253
let mut resource = endpoint.to_resource(store)?;

0 commit comments

Comments
 (0)