proper layout
This commit is contained in:
@@ -63,7 +63,14 @@
|
||||
<a href="/" class="btn btn-ghost btn-sm">Home</a>
|
||||
<a href="/about" class="btn btn-ghost btn-sm">About</a>
|
||||
<a href="/blog" class="btn btn-ghost btn-sm">Blog</a>
|
||||
{% if logged_in_admin %}
|
||||
<a href="/admin/dashboard" class="btn btn-ghost btn-sm">Dashboard</a>
|
||||
<form method="post" action="/admin/logout">
|
||||
<button type="submit" class="btn btn-ghost btn-sm">Logout</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<a href="/admin/login" class="btn btn-ghost btn-sm">Admin</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="dropdown dropdown-end md:hidden">
|
||||
@@ -78,7 +85,14 @@
|
||||
<a href="/" class="btn btn-ghost btn-sm justify-start">Home</a>
|
||||
<a href="/about" class="btn btn-ghost btn-sm justify-start">About</a>
|
||||
<a href="/blog" class="btn btn-ghost btn-sm justify-start">Blog</a>
|
||||
{% if logged_in_admin %}
|
||||
<a href="/admin/dashboard" class="btn btn-ghost btn-sm justify-start">Dashboard</a>
|
||||
<form method="post" action="/admin/logout">
|
||||
<button type="submit" class="btn btn-ghost btn-sm w-full justify-start">Logout</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<a href="/admin/login" class="btn btn-ghost btn-sm justify-start">Admin</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown dropdown-end">
|
||||
|
||||
@@ -14,7 +14,7 @@ use std::sync::OnceLock;
|
||||
use time::Duration as TimeDuration;
|
||||
|
||||
pub static EMAIL_DOMAIN_RE: OnceLock<Regex> = OnceLock::new();
|
||||
const AUTH_COOKIE: &str = "auth_token";
|
||||
pub(crate) const AUTH_COOKIE: &str = "auth_token";
|
||||
|
||||
fn get_allow_email_domain_re() -> &'static Regex {
|
||||
EMAIL_DOMAIN_RE.get_or_init(|| {
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::{
|
||||
users::{self, LoginParams},
|
||||
},
|
||||
};
|
||||
use axum_extra::extract::cookie::CookieJar;
|
||||
use chrono::Utc;
|
||||
use loco_rs::prelude::*;
|
||||
use sea_orm::{
|
||||
@@ -87,8 +88,27 @@ async fn article_by_id(ctx: &AppContext, id: Uuid) -> Result<blog_articles::Mode
|
||||
.ok_or_else(|| Error::NotFound)
|
||||
}
|
||||
|
||||
async fn logged_in_admin(ctx: &AppContext, jar: &CookieJar) -> bool {
|
||||
let Some(cookie) = jar.get(auth_controller::AUTH_COOKIE) else {
|
||||
return false;
|
||||
};
|
||||
let Ok(jwt_config) = ctx.config.get_jwt_config() else {
|
||||
return false;
|
||||
};
|
||||
let Ok(claims) = loco_rs::auth::jwt::JWT::new(&jwt_config.secret).validate(cookie.value())
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
let Ok(user) = users::Model::find_by_pid(&ctx.db, &claims.claims.pid).await else {
|
||||
return false;
|
||||
};
|
||||
|
||||
admin::is_admin(ctx, &user)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn home(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
@@ -99,19 +119,32 @@ async fn home(
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
|
||||
format::view(&v, "home/index.html", json!({ "articles": articles }))
|
||||
format::view(
|
||||
&v,
|
||||
"home/index.html",
|
||||
json!({ "articles": articles, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn about(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
format::view(&v, "pages/about.html", json!({ "page": about_page(&ctx).await? }))
|
||||
format::view(
|
||||
&v,
|
||||
"pages/about.html",
|
||||
json!({
|
||||
"page": about_page(&ctx).await?,
|
||||
"logged_in_admin": logged_in_admin(&ctx, &jar).await,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn blog_index(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
@@ -121,11 +154,16 @@ async fn blog_index(
|
||||
.all(&ctx.db)
|
||||
.await?;
|
||||
|
||||
format::view(&v, "blog/index.html", json!({ "articles": articles }))
|
||||
format::view(
|
||||
&v,
|
||||
"blog/index.html",
|
||||
json!({ "articles": articles, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn blog_show(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
Path(slug): Path<String>,
|
||||
State(ctx): State<AppContext>,
|
||||
@@ -142,12 +180,28 @@ async fn blog_show(
|
||||
active.view_count = Set(next_count);
|
||||
let article = active.update(&ctx.db).await?;
|
||||
|
||||
format::view(&v, "blog/show.html", json!({ "article": article }))
|
||||
format::view(
|
||||
&v,
|
||||
"blog/show.html",
|
||||
json!({ "article": article, "logged_in_admin": logged_in_admin(&ctx, &jar).await }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn admin_login_page(ViewEngine(v): ViewEngine<TeraView>) -> Result<Response> {
|
||||
format::view(&v, "admin/login.html", json!({ "error": null }))
|
||||
async fn admin_login_page(
|
||||
jar: CookieJar,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
) -> Result<Response> {
|
||||
if logged_in_admin(&ctx, &jar).await {
|
||||
return format::redirect("/admin/dashboard");
|
||||
}
|
||||
|
||||
format::view(
|
||||
&v,
|
||||
"admin/login.html",
|
||||
json!({ "error": null, "logged_in_admin": false }),
|
||||
)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
@@ -157,11 +211,19 @@ async fn admin_login(
|
||||
Form(params): Form<LoginParams>,
|
||||
) -> Result<Response> {
|
||||
let Ok(user) = users::Model::find_by_email(&ctx.db, ¶ms.email).await else {
|
||||
return format::view(&v, "admin/login.html", json!({ "error": "Invalid credentials" }));
|
||||
return format::view(
|
||||
&v,
|
||||
"admin/login.html",
|
||||
json!({ "error": "Invalid credentials", "logged_in_admin": false }),
|
||||
);
|
||||
};
|
||||
|
||||
if !user.verify_password(¶ms.password) || !admin::is_admin(&ctx, &user) {
|
||||
return format::view(&v, "admin/login.html", json!({ "error": "Invalid credentials" }));
|
||||
return format::view(
|
||||
&v,
|
||||
"admin/login.html",
|
||||
json!({ "error": "Invalid credentials", "logged_in_admin": false }),
|
||||
);
|
||||
}
|
||||
|
||||
let jwt_secret = ctx.config.get_jwt_config()?;
|
||||
|
||||
Reference in New Issue
Block a user