diff options
Diffstat (limited to 'src/frontend/mod.rs')
-rw-r--r-- | src/frontend/mod.rs | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index ad50161..49faf59 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -126,10 +126,17 @@ struct OnboardingFeed { struct OnboardingData { user: serde_json::Value, first_post: serde_json::Value, + #[serde(default = "OnboardingData::default_blog_name")] blog_name: String, feeds: Vec<OnboardingFeed>, } +impl OnboardingData { + fn default_blog_name() -> String { + "Kitty Box!".to_owned() + } +} + /*pub async fn onboarding_receiver<S: Storage>(mut req: Request<ApplicationState<S>>) -> Result { use serde_json::json; @@ -268,23 +275,79 @@ pub fn homepage<D: Storage>(db: D, endpoints: IndiewebEndpoints) -> impl Filter< let feeds = db.get_channels(&owner).await.unwrap_or_default(); match content { (Some(card), Some(feed), StatusCode::OK) => { - warp::reply::html(Template { + Box::new(warp::reply::html(Template { title: &blog_name, blog_name: &blog_name, endpoints, feeds, user: None, // TODO content: MainPage { feed: &feed, card: &card }.to_string() - }.to_string()) + }.to_string())) as Box<dyn warp::Reply> }, - _ => { + (None, None, StatusCode::NOT_FOUND) => { // TODO Onboarding - todo!("Onboarding flow") + Box::new(warp::redirect::found( + hyper::Uri::from_static("/onboarding") + )) as Box<dyn warp::Reply> + } + _ => { + todo!("Handle cases where either main h-card or main h-feed are deleted") } } }) } +pub fn onboarding<D: Storage, T: hyper::client::connect::Connect + Clone + Send + Sync + 'static>( + db: D, endpoints: IndiewebEndpoints, http: hyper::Client<T, hyper::Body> +) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone { + let inject_db = move || db.clone(); + warp::get() + .map(move || warp::reply::html(Template { + title: "Kittybox - Onboarding", + blog_name: "Kittybox", + endpoints: endpoints.clone(), + feeds: vec![], + user: None, + content: OnboardingPage {}.to_string() + }.to_string())) + .or(warp::post() + .and(crate::util::require_host()) + .and(warp::any().map(inject_db)) + .and(warp::body::json::<OnboardingData>()) + .and(warp::any().map(move || http.clone())) + .and_then(|host: warp::host::Authority, db: D, body: OnboardingData, http: _| async move { + let user_uid = format!("https://{}/", host.as_str()); + if db.post_exists(&user_uid).await.map_err(FrontendError::from)? { + + return Ok(warp::redirect(hyper::Uri::from_static("/"))); + } + let user = crate::indieauth::User::new(&user_uid, "https://kittybox.fireburn.ru/", "create"); + if body.user["type"][0] != "h-card" || body.first_post["type"][0] != "h-entry" { + return Err(FrontendError::with_code(StatusCode::BAD_REQUEST, "user and first_post should be an h-card and an h-entry").into()); + } + db.set_setting("site_name", user.me.as_str(), &body.blog_name) + .await + .map_err(FrontendError::from)?; + + let (_, hcard) = { + let mut hcard = body.user; + hcard["properties"]["uid"] = serde_json::json!([&user_uid]); + crate::micropub::normalize_mf2(hcard, &user) + }; + db.put_post(&hcard, &user_uid).await.map_err(FrontendError::from)?; + let (uid, post) = crate::micropub::normalize_mf2(body.first_post, &user); + crate::micropub::_post(user, uid, post, db, http).await.map_err(|e| { + FrontendError { + msg: "Error while posting the first post".to_string(), + source: Some(Box::new(e)), + code: StatusCode::INTERNAL_SERVER_ERROR + } + })?; + Ok::<_, warp::Rejection>(warp::redirect(hyper::Uri::from_static("/"))) + })) + +} + #[forbid(clippy::unwrap_used)] pub fn catchall<D: Storage>(db: D, endpoints: IndiewebEndpoints) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone { let inject_db = move || db.clone(); |