refactor: make logout works on safari (#442)

This commit is contained in:
sigoden 2024-08-27 16:07:17 +08:00 committed by GitHub
parent 964bf61c37
commit 5b338c40da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 44 additions and 19 deletions

View file

@ -91,6 +91,10 @@ let $emptyFolder;
* @type Element * @type Element
*/ */
let $editor; let $editor;
/**
* @type Element
*/
let $loginBtn;
/** /**
* @type Element * @type Element
*/ */
@ -121,6 +125,7 @@ async function ready() {
$uploadersTable = document.querySelector(".uploaders-table"); $uploadersTable = document.querySelector(".uploaders-table");
$emptyFolder = document.querySelector(".empty-folder"); $emptyFolder = document.querySelector(".empty-folder");
$editor = document.querySelector(".editor"); $editor = document.querySelector(".editor");
$loginBtn = document.querySelector(".login-btn");
$logoutBtn = document.querySelector(".logout-btn"); $logoutBtn = document.querySelector(".logout-btn");
$userName = document.querySelector(".user-name"); $userName = document.querySelector(".user-name");
@ -517,13 +522,12 @@ async function setupAuth() {
$logoutBtn.addEventListener("click", logout); $logoutBtn.addEventListener("click", logout);
$userName.textContent = DATA.user; $userName.textContent = DATA.user;
} else { } else {
const $loginBtn = document.querySelector(".login-btn");
$loginBtn.classList.remove("hidden"); $loginBtn.classList.remove("hidden");
$loginBtn.addEventListener("click", async () => { $loginBtn.addEventListener("click", async () => {
try { try {
await checkAuth(); await checkAuth();
location.reload();
} catch {} } catch {}
location.reload();
}); });
} }
} }
@ -745,19 +749,19 @@ async function saveChange() {
async function checkAuth() { async function checkAuth() {
if (!DATA.auth) return; if (!DATA.auth) return;
const res = await fetch(baseUrl(), { const res = await fetch(baseUrl(), {
method: "AUTH", method: "CHECKAUTH",
}); });
await assertResOK(res); await assertResOK(res);
document.querySelector(".login-btn").classList.add("hidden"); $loginBtn.classList.add("hidden");
$logoutBtn.classList.remove("hidden"); $logoutBtn.classList.remove("hidden");
$userName.textContent = ""; $userName.textContent = await res.text();
} }
function logout() { function logout() {
if (!DATA.auth) return; if (!DATA.auth) return;
const url = baseUrl(); const url = baseUrl();
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open("AUTH", url, true, ":"); xhr.open("LOGOUT", url, true, DATA.user);
xhr.onload = () => { xhr.onload = () => {
location.href = url; location.href = url;
} }

View file

@ -429,7 +429,8 @@ fn is_readonly_method(method: &Method) -> bool {
|| method == Method::OPTIONS || method == Method::OPTIONS
|| method == Method::HEAD || method == Method::HEAD
|| method.as_str() == "PROPFIND" || method.as_str() == "PROPFIND"
|| method.as_str() == "AUTH" || method.as_str() == "CHECKAUTH"
|| method.as_str() == "LOGOUT"
} }
fn strip_prefix<'a>(search: &'a [u8], prefix: &[u8]) -> Option<&'a [u8]> { fn strip_prefix<'a>(search: &'a [u8], prefix: &[u8]) -> Option<&'a [u8]> {

View file

@ -200,11 +200,17 @@ impl Server {
.map(|(k, v)| (k.to_string(), v.to_string())) .map(|(k, v)| (k.to_string(), v.to_string()))
.collect(); .collect();
if method.as_str() == "AUTH" { if method.as_str() == "CHECKAUTH" {
if user.is_none() { match user.clone() {
self.auth_reject(&mut res)?; Some(user) => {
*res.body_mut() = body_full(user);
}
None => self.auth_reject(&mut res)?,
} }
return Ok(res); return Ok(res);
} else if method.as_str() == "LOGOUT" {
self.auth_reject(&mut res)?;
return Ok(res);
} }
let head_only = method == Method::HEAD; let head_only = method == Method::HEAD;
@ -1722,7 +1728,9 @@ fn is_hidden(hidden: &[String], file_name: &str, is_dir_type: bool) -> bool {
fn set_webdav_headers(res: &mut Response) { fn set_webdav_headers(res: &mut Response) {
res.headers_mut().insert( res.headers_mut().insert(
"Allow", "Allow",
HeaderValue::from_static("GET,HEAD,PUT,OPTIONS,DELETE,PATCH,PROPFIND,COPY,MOVE"), HeaderValue::from_static(
"GET,HEAD,PUT,OPTIONS,DELETE,PATCH,PROPFIND,COPY,MOVE,CHECKAUTH,LOGOUT",
),
); );
res.headers_mut() res.headers_mut()
.insert("DAV", HeaderValue::from_static("1, 2, 3")); .insert("DAV", HeaderValue::from_static("1, 2, 3"));

View file

@ -119,29 +119,41 @@ fn auth_check(
#[with(&["--auth", "user:pass@/:rw", "--auth", "user2:pass2@/", "-A"])] server: TestServer, #[with(&["--auth", "user:pass@/:rw", "--auth", "user2:pass2@/", "-A"])] server: TestServer,
) -> Result<(), Error> { ) -> Result<(), Error> {
let url = format!("{}index.html", server.url()); let url = format!("{}index.html", server.url());
let resp = fetch!(b"AUTH", &url).send()?; let resp = fetch!(b"CHECKAUTH", &url).send()?;
assert_eq!(resp.status(), 401); assert_eq!(resp.status(), 401);
let resp = send_with_digest_auth(fetch!(b"AUTH", &url), "user", "pass")?; let resp = send_with_digest_auth(fetch!(b"CHECKAUTH", &url), "user", "pass")?;
assert_eq!(resp.status(), 200); assert_eq!(resp.status(), 200);
let resp = send_with_digest_auth(fetch!(b"AUTH", &url), "user2", "pass2")?; let resp = send_with_digest_auth(fetch!(b"CHECKAUTH", &url), "user2", "pass2")?;
assert_eq!(resp.status(), 200); assert_eq!(resp.status(), 200);
Ok(()) Ok(())
} }
#[rstest] #[rstest]
fn auth_compact_rules( fn auth_check2(
#[with(&["--auth", "user:pass@/:rw|user2:pass2@/", "-A"])] server: TestServer, #[with(&["--auth", "user:pass@/:rw|user2:pass2@/", "-A"])] server: TestServer,
) -> Result<(), Error> { ) -> Result<(), Error> {
let url = format!("{}index.html", server.url()); let url = format!("{}index.html", server.url());
let resp = fetch!(b"AUTH", &url).send()?; let resp = fetch!(b"CHECKAUTH", &url).send()?;
assert_eq!(resp.status(), 401); assert_eq!(resp.status(), 401);
let resp = send_with_digest_auth(fetch!(b"AUTH", &url), "user", "pass")?; let resp = send_with_digest_auth(fetch!(b"CHECKAUTH", &url), "user", "pass")?;
assert_eq!(resp.status(), 200); assert_eq!(resp.status(), 200);
let resp = send_with_digest_auth(fetch!(b"AUTH", &url), "user2", "pass2")?; let resp = send_with_digest_auth(fetch!(b"CHECKAUTH", &url), "user2", "pass2")?;
assert_eq!(resp.status(), 200); assert_eq!(resp.status(), 200);
Ok(()) Ok(())
} }
#[rstest]
fn auth_logout(
#[with(&["--auth", "user:pass@/:rw", "-A"])] server: TestServer,
) -> Result<(), Error> {
let url = format!("{}index.html", server.url());
let resp = fetch!(b"LOGOUT", &url).send()?;
assert_eq!(resp.status(), 401);
let resp = send_with_digest_auth(fetch!(b"LOGOUT", &url), "user", "pass")?;
assert_eq!(resp.status(), 401);
Ok(())
}
#[rstest] #[rstest]
fn auth_readonly( fn auth_readonly(
#[with(&["--auth", "user:pass@/:rw", "--auth", "user2:pass2@/", "-A"])] server: TestServer, #[with(&["--auth", "user:pass@/:rw", "--auth", "user2:pass2@/", "-A"])] server: TestServer,

View file

@ -265,7 +265,7 @@ fn options_dir(server: TestServer) -> Result<(), Error> {
assert_eq!(resp.status(), 200); assert_eq!(resp.status(), 200);
assert_eq!( assert_eq!(
resp.headers().get("allow").unwrap(), resp.headers().get("allow").unwrap(),
"GET,HEAD,PUT,OPTIONS,DELETE,PATCH,PROPFIND,COPY,MOVE" "GET,HEAD,PUT,OPTIONS,DELETE,PATCH,PROPFIND,COPY,MOVE,CHECKAUTH,LOGOUT"
); );
assert_eq!(resp.headers().get("dav").unwrap(), "1, 2, 3"); assert_eq!(resp.headers().get("dav").unwrap(), "1, 2, 3");
Ok(()) Ok(())