Compare commits
No commits in common. "8014e202f84ca8ffe4f5d16b3e6a900e8dff8bbe" and "a070e3f8fc553fdba20bbc10f0e6f2f39abee24f" have entirely different histories.
8014e202f8
...
a070e3f8fc
@ -7,13 +7,12 @@ on:
|
|||||||
branches: [main, master]
|
branches: [main, master]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_NET_OFFLINE: false
|
RUSTUP_UPDATE_ROOT: https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup
|
||||||
|
RUSTUP_DIST_SERVER: https://mirrors.tuna.tsinghua.edu.cn/rustup
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/library/rust:bookworm
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
run: |
|
run: |
|
||||||
@ -25,7 +24,7 @@ jobs:
|
|||||||
- name: Configure Cargo mirror
|
- name: Configure Cargo mirror
|
||||||
run: |
|
run: |
|
||||||
mkdir -p "$HOME/.cargo"
|
mkdir -p "$HOME/.cargo"
|
||||||
cat > "$HOME/.cargo/config.toml" <<EOF
|
cat > "$HOME/.cargo/config.toml" <>EOF
|
||||||
[source.crates-io]
|
[source.crates-io]
|
||||||
replace-with = 'ustc'
|
replace-with = 'ustc'
|
||||||
|
|
||||||
@ -33,6 +32,11 @@ jobs:
|
|||||||
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"
|
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
run: |
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
|
||||||
|
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
@ -61,11 +65,10 @@ jobs:
|
|||||||
|
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/library/rust:bookworm
|
|
||||||
needs: check
|
needs: check
|
||||||
env:
|
env:
|
||||||
CARGO_NET_OFFLINE: false
|
RUSTUP_UPDATE_ROOT: https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup
|
||||||
|
RUSTUP_DIST_SERVER: https://mirrors.tuna.tsinghua.edu.cn/rustup
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
run: |
|
run: |
|
||||||
@ -77,7 +80,7 @@ jobs:
|
|||||||
- name: Configure Cargo mirror
|
- name: Configure Cargo mirror
|
||||||
run: |
|
run: |
|
||||||
mkdir -p "$HOME/.cargo"
|
mkdir -p "$HOME/.cargo"
|
||||||
cat > "$HOME/.cargo/config.toml" <<EOF
|
cat > "$HOME/.cargo/config.toml" <>EOF
|
||||||
[source.crates-io]
|
[source.crates-io]
|
||||||
replace-with = 'ustc'
|
replace-with = 'ustc'
|
||||||
|
|
||||||
@ -85,6 +88,11 @@ jobs:
|
|||||||
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"
|
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
run: |
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
|
||||||
|
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
|
|||||||
@ -229,7 +229,10 @@ pub async fn login(username: String, password: String) -> Result<AuthResponse, S
|
|||||||
.await
|
.await
|
||||||
.map_err(AppError::query)?;
|
.map_err(AppError::query)?;
|
||||||
|
|
||||||
let cookie = session::session_cookie(&token, 30 * 24 * 60 * 60, session::cookie_secure());
|
let cookie = format!(
|
||||||
|
"session={token}; HttpOnly; Path=/; Max-Age={}; SameSite=Lax",
|
||||||
|
30 * 24 * 60 * 60
|
||||||
|
);
|
||||||
if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
||||||
if let Ok(value) = HeaderValue::try_from(cookie.as_str()) {
|
if let Ok(value) = HeaderValue::try_from(cookie.as_str()) {
|
||||||
ctx.add_response_header(SET_COOKIE, value);
|
ctx.add_response_header(SET_COOKIE, value);
|
||||||
@ -249,11 +252,11 @@ pub async fn logout() -> Result<AuthResponse, ServerFnError> {
|
|||||||
|
|
||||||
let client = get_conn().await.map_err(AppError::db_conn)?;
|
let client = get_conn().await.map_err(AppError::db_conn)?;
|
||||||
|
|
||||||
let cookie = session::session_cookie("", 0, session::cookie_secure());
|
|
||||||
if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
if let Some(ctx) = dioxus::fullstack::FullstackContext::current() {
|
||||||
if let Ok(value) = HeaderValue::try_from(cookie.as_str()) {
|
ctx.add_response_header(
|
||||||
ctx.add_response_header(SET_COOKIE, value);
|
SET_COOKIE,
|
||||||
}
|
HeaderValue::from_static("session=; HttpOnly; Path=/; Max-Age=0; SameSite=Lax"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(t) = token {
|
if let Some(t) = token {
|
||||||
|
|||||||
@ -19,22 +19,6 @@ pub fn default_expiry() -> DateTime<Utc> {
|
|||||||
Utc::now() + Duration::days(30)
|
Utc::now() + Duration::days(30)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
pub fn cookie_secure() -> bool {
|
|
||||||
std::env::var("COOKIE_SECURE")
|
|
||||||
.ok()
|
|
||||||
.map(|v| matches!(v.as_str(), "1" | "true" | "yes"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
pub fn session_cookie(token: &str, max_age_seconds: i32, secure: bool) -> String {
|
|
||||||
let secure_flag = if secure { "; Secure" } else { "" };
|
|
||||||
format!(
|
|
||||||
"session={token}; HttpOnly; Path=/; Max-Age={max_age_seconds}; SameSite=Lax{secure_flag}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
pub fn parse_session_token(cookie_header: &str) -> Option<&str> {
|
pub fn parse_session_token(cookie_header: &str) -> Option<&str> {
|
||||||
cookie_header.split(';').map(|s| s.trim()).find_map(|pair| {
|
cookie_header.split(';').map(|s| s.trim()).find_map(|pair| {
|
||||||
@ -148,25 +132,4 @@ mod tests {
|
|||||||
let expected = sha2::Sha256::digest(b"hello");
|
let expected = sha2::Sha256::digest(b"hello");
|
||||||
assert_eq!(hash, hex::encode(expected));
|
assert_eq!(hash, hex::encode(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn session_cookie_without_secure() {
|
|
||||||
let cookie = session_cookie("abc", 3600, false);
|
|
||||||
assert!(cookie.contains("session=abc"));
|
|
||||||
assert!(cookie.contains("HttpOnly"));
|
|
||||||
assert!(cookie.contains("SameSite=Lax"));
|
|
||||||
assert!(!cookie.contains("Secure"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn session_cookie_with_secure() {
|
|
||||||
let cookie = session_cookie("abc", 3600, true);
|
|
||||||
assert!(cookie.contains("Secure"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn session_cookie_logout_has_zero_max_age() {
|
|
||||||
let cookie = session_cookie("", 0, false);
|
|
||||||
assert!(cookie.contains("Max-Age=0"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user