api: refresh + logout endpoints, update login response
This commit is contained in:
@@ -10,6 +10,7 @@ pub struct LoginRequest {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
||||||
pub struct LoginResponse {
|
pub struct LoginResponse {
|
||||||
pub token: String,
|
pub token: String,
|
||||||
|
pub refresh_token: String,
|
||||||
pub user_id: Uuid,
|
pub user_id: Uuid,
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub expires_at: String,
|
pub expires_at: String,
|
||||||
@@ -22,3 +23,20 @@ pub struct RegisterRequest {
|
|||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
||||||
|
pub struct RefreshRequest {
|
||||||
|
pub refresh_token: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
||||||
|
pub struct RefreshResponse {
|
||||||
|
pub token: String,
|
||||||
|
pub refresh_token: String,
|
||||||
|
pub expires_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
|
||||||
|
pub struct LogoutRequest {
|
||||||
|
pub refresh_token: String,
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use crate::{
|
|||||||
render::render_page,
|
render::render_page,
|
||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
use api_types::{LoginRequest, LoginResponse, RegisterRequest};
|
use api_types::{LoginRequest, LoginResponse, LogoutRequest, RefreshRequest, RefreshResponse, RegisterRequest};
|
||||||
use application::ports::HtmlPageContext;
|
use application::ports::HtmlPageContext;
|
||||||
use template_askama::{LoginTemplate, RegisterTemplate};
|
use template_askama::{LoginTemplate, RegisterTemplate};
|
||||||
|
|
||||||
@@ -68,6 +68,7 @@ pub async fn login(
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(Json(LoginResponse {
|
Ok(Json(LoginResponse {
|
||||||
token: result.token,
|
token: result.token,
|
||||||
|
refresh_token: result.refresh_token,
|
||||||
user_id: result.user_id,
|
user_id: result.user_id,
|
||||||
email: result.email,
|
email: result.email,
|
||||||
expires_at: result.expires_at.to_rfc3339(),
|
expires_at: result.expires_at.to_rfc3339(),
|
||||||
@@ -100,6 +101,41 @@ pub async fn register(
|
|||||||
Ok(StatusCode::CREATED)
|
Ok(StatusCode::CREATED)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[utoipa::path(
|
||||||
|
post, path = "/api/v1/auth/refresh",
|
||||||
|
request_body = RefreshRequest,
|
||||||
|
responses(
|
||||||
|
(status = 200, body = RefreshResponse),
|
||||||
|
(status = 401, description = "Invalid or expired refresh token"),
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub async fn refresh(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Json(req): Json<RefreshRequest>,
|
||||||
|
) -> Result<Json<RefreshResponse>, ApiError> {
|
||||||
|
let result = application::auth::refresh::execute(&state.app_ctx, &req.refresh_token).await?;
|
||||||
|
Ok(Json(RefreshResponse {
|
||||||
|
token: result.token,
|
||||||
|
refresh_token: result.refresh_token,
|
||||||
|
expires_at: result.expires_at.to_rfc3339(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[utoipa::path(
|
||||||
|
post, path = "/api/v1/auth/logout",
|
||||||
|
request_body = LogoutRequest,
|
||||||
|
responses(
|
||||||
|
(status = 204, description = "Logged out"),
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub async fn api_logout(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Json(req): Json<LogoutRequest>,
|
||||||
|
) -> StatusCode {
|
||||||
|
let _ = application::auth::logout::execute(&state.app_ctx, &req.refresh_token).await;
|
||||||
|
StatusCode::NO_CONTENT
|
||||||
|
}
|
||||||
|
|
||||||
// ── HTML ─────────────────────────────────────────────────────────────────────
|
// ── HTML ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
pub async fn get_login_page(
|
pub async fn get_login_page(
|
||||||
|
|||||||
@@ -326,6 +326,8 @@ fn api_routes(rate_limit: u64) -> Router<AppState> {
|
|||||||
)
|
)
|
||||||
.route("/auth/login", routing::post(handlers::auth::login))
|
.route("/auth/login", routing::post(handlers::auth::login))
|
||||||
.route("/auth/register", routing::post(handlers::auth::register))
|
.route("/auth/register", routing::post(handlers::auth::register))
|
||||||
|
.route("/auth/refresh", routing::post(handlers::auth::refresh))
|
||||||
|
.route("/auth/logout", routing::post(handlers::auth::api_logout))
|
||||||
.route("/diary/export", routing::get(handlers::diary::export_diary))
|
.route("/diary/export", routing::get(handlers::diary::export_diary))
|
||||||
.route(
|
.route(
|
||||||
"/activity-feed",
|
"/activity-feed",
|
||||||
|
|||||||
Reference in New Issue
Block a user