mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-03 16:41:27 +01:00
Terminal-themed markdown diary
Single-user diary served as one Rust binary with the Svelte frontend embedded. - axum 0.8 + SQLite (sqlx), migrations run at startup - stateless HMAC session cookie; credentials from .env, compared in constant time - FTS5 full-text search, user input rewritten into quoted prefix terms - media uploads linked to entries by scanning bodies for /api/media/<id>, which scopes share-token media access and entry deletion - unguessable share links (192-bit token) serving a public read-only page - vim keybindings via CodeMirror plus a modal browse layer and : command line; disabled on touch devices
This commit is contained in:
commit
4002a35305
41 files changed
+6195
No files matched your search
@@ -0,0 +1,50 @@
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::{header, StatusCode},
|
||||
response::IntoResponse,
|
||||
Json,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
auth::{self, Session},
|
||||
error::{AppError, AppResult},
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct LoginRequest {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
pub async fn login(
|
||||
State(state): State<AppState>,
|
||||
Json(body): Json<LoginRequest>,
|
||||
) -> AppResult<impl IntoResponse> {
|
||||
if !auth::credentials_match(&state.config, &body.username, &body.password) {
|
||||
return Err(AppError::BadRequest("invalid credentials".into()));
|
||||
}
|
||||
let token = auth::issue_token(&state.config);
|
||||
Ok((
|
||||
StatusCode::OK,
|
||||
[(
|
||||
header::SET_COOKIE,
|
||||
auth::session_cookie(&state.config, &token),
|
||||
)],
|
||||
Json(json!({ "user": state.config.username })),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn logout(State(state): State<AppState>) -> impl IntoResponse {
|
||||
(
|
||||
StatusCode::OK,
|
||||
[(header::SET_COOKIE, auth::clear_cookie(&state.config))],
|
||||
Json(json!({ "ok": true })),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn me(_: Session, State(state): State<AppState>) -> impl IntoResponse {
|
||||
Json(json!({ "user": state.config.username }))
|
||||
}
|
||||
Reference in new issue
Block a user