use axum::{ extract::{Path, Query}, response::{Html, IntoResponse, Redirect}, Extension, }; use axum_extra::extract::CookieJar; use crate::{ assets::initial_context, check_user_blocked_or_private, get_lang, get_user_from_token, routes::pages::{render_error, JournalsAppQuery}, State, }; use tetratto_core::model::{journals::JournalPrivacyPermission, Error}; pub async fn redirect_request() -> impl IntoResponse { Redirect::to("/journals/0/0") } /// `/journals/{journal}/{note}` pub async fn app_request( jar: CookieJar, Extension(data): Extension, Path((selected_journal, selected_note)): Path<(usize, usize)>, Query(props): Query, ) -> impl IntoResponse { let data = data.read().await; let user = match get_user_from_token!(jar, data.0) { Some(ua) => ua, None => { return Err(Html( render_error(Error::NotAllowed, &jar, &data, &None).await, )); } }; let journals = match data.0.get_journals_by_user(user.id).await { Ok(p) => Some(p), Err(e) => { return Err(Html( render_error(e, &jar, &data, &Some(user.to_owned())).await, )); } }; let notes = match data.0.get_notes_by_journal(selected_journal).await { Ok(p) => Some(p), Err(e) => { return Err(Html(render_error(e, &jar, &data, &Some(user)).await)); } }; // get journal and check privacy settings let journal = if selected_journal != 0 { match data.0.get_journal_by_id(selected_journal).await { Ok(p) => Some(p), Err(e) => { return Err(Html(render_error(e, &jar, &data, &Some(user)).await)); } } } else { None }; if let Some(ref j) = journal { // if we're not the owner, we shouldn't be viewing this journal from this endpoint if user.id != j.owner { return Err(Html( render_error(Error::NotAllowed, &jar, &data, &Some(user.to_owned())).await, )); } } // ... let note = if selected_note != 0 { match data.0.get_note_by_id(selected_note).await { Ok(p) => Some(p), Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)), } } else { None }; let lang = get_lang!(jar, data.0); let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await; context.insert("selected_journal", &selected_journal); context.insert("selected_note", &selected_note); context.insert("journal", &journal); context.insert("note", ¬e); context.insert("journals", &journals); context.insert("notes", ¬es); context.insert("view_mode", &props.view); context.insert("is_editor", &true); // return Ok(Html(data.1.render("journals/app.html", &context).unwrap())) } /// `/@{owner}/{journal}/{note}` pub async fn view_request( jar: CookieJar, Extension(data): Extension, Path((owner, selected_journal, mut selected_note)): Path<(String, String, String)>, ) -> impl IntoResponse { let data = data.read().await; let user = match get_user_from_token!(jar, data.0) { Some(ua) => Some(ua), None => None, }; if selected_note == "index" { selected_note = String::new(); } // if we don't have a selected journal, we shouldn't be here probably if selected_journal.is_empty() | (selected_note == "journal.css") { return Err(Html( render_error(Error::NotAllowed, &jar, &data, &user).await, )); } // get owner let owner = match data.0.get_user_by_username(&owner).await { Ok(ua) => ua, Err(e) => { return Err(Html(render_error(e, &jar, &data, &user).await)); } }; check_user_blocked_or_private!(user, owner, data, jar); // get journal and check privacy settings let journal = match data .0 .get_journal_by_owner_title(owner.id, &selected_journal) .await { Ok(p) => p, Err(e) => { return Err(Html(render_error(e, &jar, &data, &user).await)); } }; if journal.privacy == JournalPrivacyPermission::Private { if let Some(ref user) = user { if user.id != journal.owner { return Err(Html( render_error(Error::NotAllowed, &jar, &data, &Some(user.to_owned())).await, )); } } else { return Err(Html( render_error(Error::NotAllowed, &jar, &data, &user).await, )); } } // ... let note = if !selected_note.is_empty() { match data .0 .get_note_by_journal_title(journal.id, &selected_note) .await { Ok(p) => Some(p), Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)), } } else { None }; let lang = get_lang!(jar, data.0); let mut context = initial_context(&data.0.0.0, lang, &user).await; if selected_journal.is_empty() { context.insert("selected_journal", &0); } else { context.insert("selected_journal", &selected_journal); } if selected_note.is_empty() { context.insert("selected_note", &0); } else { context.insert("selected_note", &selected_note); } context.insert("journal", &journal); context.insert("note", ¬e); context.insert("owner", &owner); context.insert::<[i8; 0], &str>("notes", &[]); context.insert("view_mode", &true); context.insert("is_editor", &false); // return Ok(Html(data.1.render("journals/app.html", &context).unwrap())) } /// `/@{owner}/{journal}` pub async fn index_view_request( jar: CookieJar, Extension(data): Extension, Path((owner, selected_journal)): Path<(String, String)>, Query(props): Query, ) -> impl IntoResponse { let data = data.read().await; let user = match get_user_from_token!(jar, data.0) { Some(ua) => Some(ua), None => None, }; // get owner let owner = match data.0.get_user_by_username(&owner).await { Ok(ua) => ua, Err(e) => { return Err(Html(render_error(e, &jar, &data, &user).await)); } }; check_user_blocked_or_private!(user, owner, data, jar); // get journal and check privacy settings let journal = match data .0 .get_journal_by_owner_title(owner.id, &selected_journal) .await { Ok(p) => p, Err(e) => { return Err(Html(render_error(e, &jar, &data, &user).await)); } }; if journal.privacy == JournalPrivacyPermission::Private { if let Some(ref user) = user { if user.id != journal.owner { return Err(Html( render_error(Error::NotAllowed, &jar, &data, &Some(user.to_owned())).await, )); } } else { return Err(Html( render_error(Error::NotAllowed, &jar, &data, &user).await, )); } } // ... let notes = if props.tag.is_empty() { match data.0.get_notes_by_journal(journal.id).await { Ok(p) => Some(p), Err(e) => { return Err(Html(render_error(e, &jar, &data, &user).await)); } } } else { match data .0 .get_notes_by_journal_tag(journal.id, &props.tag) .await { Ok(p) => Some(p), Err(e) => { return Err(Html(render_error(e, &jar, &data, &user).await)); } } }; let lang = get_lang!(jar, data.0); let mut context = initial_context(&data.0.0.0, lang, &user).await; if selected_journal.is_empty() { context.insert("selected_journal", &0); } else { context.insert("selected_journal", &selected_journal); } context.insert("selected_note", &0); context.insert("journal", &journal); context.insert("owner", &owner); context.insert("notes", ¬es); context.insert("view_mode", &true); context.insert("is_editor", &false); context.insert("tag", &props.tag); // return Ok(Html(data.1.render("journals/app.html", &context).unwrap())) }