Skip to content

Commit d9f8bcc

Browse files
committed
WIP
1 parent 5f410c8 commit d9f8bcc

File tree

10 files changed

+208
-103
lines changed

10 files changed

+208
-103
lines changed

lib/src/atomic_url.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl AtomicUrl {
112112
}
113113

114114
/// Removes existing path, sets the new one. Escapes special characters
115-
pub fn set_path(&mut self, path: &str) -> &Self {
115+
pub fn set_path(mut self, path: &str) -> Self {
116116
self.url.set_path(path);
117117
self
118118
}

lib/src/plugins/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ pub mod bookmark;
4444
pub mod files;
4545
pub mod path;
4646
pub mod register;
47+
pub mod reset_pubkey;
4748
pub mod search;
4849
pub mod versioning;

lib/src/plugins/register.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414

1515
pub fn register_endpoint() -> Endpoint {
1616
Endpoint {
17-
path: "/register".to_string(),
17+
path: urls::PATH_REGISTER.to_string(),
1818
params: [
1919
urls::NAME.to_string(),
2020
urls::EMAIL.to_string(),
@@ -27,7 +27,7 @@ pub fn register_endpoint() -> Endpoint {
2727

2828
pub fn confirm_email_endpoint() -> Endpoint {
2929
Endpoint {
30-
path: "/confirmEmail".to_string(),
30+
path: urls::PATH_CONFIRM_EMAIL.to_string(),
3131
params: [urls::TOKEN.to_string(), urls::INVITE_PUBKEY.to_string()].into(),
3232
description: "Confirm email address and set a key for your Agent.".to_string(),
3333
shortname: "confirm-email".to_string(),
@@ -113,6 +113,7 @@ pub fn construct_confirm_email_redirect(
113113
let mut token_opt: Option<String> = None;
114114
let mut pubkey_option = None;
115115

116+
println!("url: {:?}", url);
116117
for (k, v) in url.query_pairs() {
117118
match k.as_ref() {
118119
"token" | urls::TOKEN => token_opt = Some(v.to_string()),
@@ -134,11 +135,15 @@ pub fn construct_confirm_email_redirect(
134135
// Note: this happens before the drive is saved, which checks if the name is available.
135136
// We get new agents that just do nothing, but perhaps that's not a problem.
136137
let drive_creator_agent: String = {
137-
let mut new = Agent::new_from_public_key(store, &pubkey)?;
138-
new.name = Some(confirmation.name.clone());
139-
let net_agent_subject = new.subject.to_string();
140-
new.to_resource()?.save(store)?;
141-
net_agent_subject
138+
let mut new_agent = Agent::new_from_public_key(store, &pubkey)?;
139+
new_agent.name = Some(confirmation.name.clone());
140+
let net_agent_subject = store
141+
.get_server_url()
142+
.clone()
143+
.set_path(&format!("agents/{}", confirmation.name));
144+
new_agent.subject = net_agent_subject.to_string();
145+
new_agent.to_resource()?.save(store)?;
146+
net_agent_subject.to_string()
142147
};
143148

144149
// Create the new Drive

lib/src/plugins/reset_pubkey.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*!
2+
Reset email
3+
*/
4+
5+
use crate::{endpoints::Endpoint, errors::AtomicResult, urls, Db, Resource};
6+
7+
pub fn request_email_pubkey_reset() -> Endpoint {
8+
Endpoint {
9+
path: urls::PATH_RESET_PUBKEY.to_string(),
10+
params: [urls::TOKEN.to_string(), urls::INVITE_PUBKEY.to_string()].into(),
11+
description: "Requests an email to set a new PublicKey to an Agent.".to_string(),
12+
shortname: "request-pubkey-reset".to_string(),
13+
handle: Some(construct_reset_pubkey),
14+
}
15+
}
16+
17+
pub fn confirm_pubkey_reset() -> Endpoint {
18+
Endpoint {
19+
path: urls::PATH_CONFIRM_RESET.to_string(),
20+
params: [urls::TOKEN.to_string(), urls::INVITE_PUBKEY.to_string()].into(),
21+
description: "Requests an email to set a new PublicKey to an Agent.".to_string(),
22+
shortname: "request-pubkey-reset".to_string(),
23+
handle: Some(construct_confirm_reset_pubkey),
24+
}
25+
}
26+
27+
#[tracing::instrument(skip(store))]
28+
pub fn construct_confirm_reset_pubkey(
29+
url: url::Url,
30+
store: &Db,
31+
for_agent: Option<&str>,
32+
) -> AtomicResult<Resource> {
33+
let mut token_opt: Option<String> = None;
34+
let mut pubkey_option = None;
35+
36+
println!("url: {:?}", url);
37+
for (k, v) in url.query_pairs() {
38+
match k.as_ref() {
39+
"token" | urls::TOKEN => token_opt = Some(v.to_string()),
40+
"public-key" | urls::INVITE_PUBKEY => pubkey_option = Some(v.to_string()),
41+
_ => {}
42+
}
43+
}
44+
let Some(token) = token_opt else {
45+
return confirm_pubkey_reset().to_resource(store);
46+
};
47+
let pubkey = pubkey_option.ok_or("No public-key provided")?;
48+
49+
// Parse and verify the JWT token
50+
let confirmation = crate::token::verify_claim::<MailConfirmation>(store, &token)?.custom;
51+
52+
// Add the drive to the Agent's list of drives
53+
let mut agent = store.get_resource(&drive_creator_agent)?;
54+
agent.push_propval(
55+
urls::USED_PUBKEYS.into(),
56+
SubResource::Subject(drive.get_subject().into()),
57+
true,
58+
)?;
59+
agent.save_locally(store)?;
60+
61+
// Construct the Redirect Resource, which might provide the Client with a Subject for his Agent.
62+
let mut redirect = Resource::new_instance(urls::REDIRECT, store)?;
63+
redirect.set_propval_string(urls::DESTINATION.into(), drive.get_subject(), store)?;
64+
redirect.set_propval(
65+
urls::REDIRECT_AGENT.into(),
66+
crate::Value::AtomicUrl(drive_creator_agent),
67+
store,
68+
)?;
69+
Ok(redirect)
70+
}

lib/src/storelike.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ pub trait Storelike: Sized {
235235
if subject.starts_with(self_url.as_str()) {
236236
return Ok(false);
237237
} else {
238+
// Is it a subdomain of the self_url?
238239
let subject_url = url::Url::parse(subject)?;
239240
let subject_host = subject_url.host().ok_or_else(|| {
240241
AtomicError::not_found(format!("Subject URL has no host: {}", subject))
@@ -243,8 +244,20 @@ pub trait Storelike: Sized {
243244
let self_host = self_url.host().ok_or_else(|| {
244245
AtomicError::not_found(format!("Self URL has no host: {}", self_url))
245246
})?;
246-
info!("Comparing hosts: {} and {}", subject_host, self_host);
247-
if subject_host == self_host {
247+
// remove the subdomain from subject, if any.
248+
// The server can have multiple subdomains
249+
let subject_host_string = subject_host.to_string();
250+
let subject_host_parts = subject_host_string.split('.').collect::<Vec<&str>>();
251+
252+
// Check if the last part of the host is equal
253+
let Some(subject_host_stripped) = subject_host_parts.last() else {
254+
return Ok(false)
255+
};
256+
info!(
257+
"Comparing hosts: {} and {}",
258+
subject_host_stripped, self_host
259+
);
260+
if subject_host_stripped == &self_host.to_string() {
248261
return Ok(false);
249262
}
250263
}

lib/src/urls.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,7 @@ pub const PATH_TPF: &str = "/tpf";
142142
pub const PATH_PATH: &str = "/path";
143143
pub const PATH_COMMITS: &str = "/commits";
144144
pub const PATH_ENDPOINTS: &str = "/endpoints";
145+
pub const PATH_REGISTER: &str = "/register";
146+
pub const PATH_CONFIRM_EMAIL: &str = "/confirm-email";
147+
pub const PATH_RESET_PUBKEY: &str = "/reset-public-key";
148+
pub const PATH_CONFIRM_RESET: &str = "/confirm-reset-public-key";

server/app_assets/dist/index.js

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

server/app_assets/dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/e2e_tests/e2e-generated.spec.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,11 @@ test.describe('data-browser', async () => {
107107
await editProfileAndCommit(page);
108108
});
109109

110-
test('search', async ({ page }) => {
111-
await page.fill(addressBar, 'setup');
112-
await page.click('text=setup');
113-
await expect(page.locator('text=Use this Invite')).toBeVisible();
110+
test('text search', async ({ page }) => {
111+
await page.fill(addressBar, 'welcome');
112+
await expect(page.locator('text=Welcome to your')).toBeVisible();
113+
await page.keyboard.press('Enter');
114+
await expect(page.locator('text=resources:')).toBeVisible();
114115
});
115116

116117
test('scoped search', async ({ page }) => {

server/src/handlers/commit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub async fn post_commit(
1313
let mut builder = HttpResponse::Ok();
1414
let incoming_commit_resource = parse_json_ad_commit_resource(&body, store)?;
1515
let incoming_commit = Commit::from_resource(incoming_commit_resource)?;
16-
if store.is_external_subject(&incoming_commit.subject)? {
16+
if store.is_external_subject(&incoming_commit.subject)? {
1717
return Err("Subject of commit is external, and should be sent to its origin domain. This store can not own this resource. See https://github.com/atomicdata-dev/atomic-data-rust/issues/509".into());
1818
}
1919
let opts = CommitOpts {

0 commit comments

Comments
 (0)