upload: Require POST for token verification
In order to mitigate against MUAs previewing URLs, move the token verification flow to a POST handler, and add a new GET handler which returns a form requiring the user to click an additional time in order to verify their address. The returned form also carries some JavaScript which will attempt to do this for the user, meaning the experience for the user should be almost exactly as before, while mitigating MUA previews. Closes: #53 Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
This commit is contained in:
parent
6b7cbbe1c1
commit
6df212f087
|
@ -0,0 +1,34 @@
|
|||
const container = document.getElementById("container");
|
||||
const postform = document.getElementById("postform");
|
||||
const pleasewait = document.getElementById("pleasewait");
|
||||
const failed = document.getElementById("failed");
|
||||
const form = document.getElementById("postform");
|
||||
const url = form.getAttribute("action");
|
||||
|
||||
fetch(url, { method: "POST" })
|
||||
.then(result => result.text())
|
||||
.then(body => {
|
||||
const frag = document.createElement("div");
|
||||
frag.innerHTML = body;
|
||||
container.appendChild(frag);
|
||||
const result = document.getElementById("verification-result");
|
||||
if (result !== null) {
|
||||
while (result.firstChild) {
|
||||
container.appendChild(result.firstChild);
|
||||
}
|
||||
container.removeChild(frag);
|
||||
} else {
|
||||
// Leave the full content appended since it'll likely be plain text
|
||||
}
|
||||
// Hide the pleasewait too
|
||||
pleasewait.style.display = "none";
|
||||
})
|
||||
.catch(err => {
|
||||
// On error, hide the 'please wait' and show the 'Something went wrong'
|
||||
pleasewait.style.display = "none";
|
||||
failed.textContent = failed.textContent + err;
|
||||
failed.style.display = "block";
|
||||
});
|
||||
// Hide the form and display the 'please wait' block
|
||||
postform.style.display = "none";
|
||||
pleasewait.style.display = "block";
|
|
@ -1,5 +1,5 @@
|
|||
{{#> layout}}
|
||||
<div class="row">
|
||||
<div class="row" id="verification-result">
|
||||
{{#if verified }}
|
||||
<p>
|
||||
Your key
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{{#> layout}}
|
||||
<div class="row" id="container">
|
||||
<form method="POST" action="/verify/{{token}}" id="postform">
|
||||
<p>
|
||||
Please click here to complete the verification process:
|
||||
<input type="submit" value="Validate"/>
|
||||
</p>
|
||||
</form>
|
||||
<p style="display: none" id="pleasewait">
|
||||
Please wait while your email address is verified…
|
||||
</p>
|
||||
<p style="display: none" id="failed">
|
||||
Something went wrong:
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script src="/assets/js/upload-verify.js" type="text/javascript"></script>
|
||||
{{/layout}}
|
|
@ -364,6 +364,7 @@ fn rocket_factory(mut rocket: rocket::Rocket) -> Result<rocket::Rocket> {
|
|||
vks_web::request_verify_form,
|
||||
vks_web::request_verify_form_data,
|
||||
vks_web::verify_confirm,
|
||||
vks_web::verify_confirm_form,
|
||||
vks_web::quick_upload,
|
||||
vks_web::quick_upload_proceed,
|
||||
// Debug
|
||||
|
@ -1095,7 +1096,7 @@ pub mod tests {
|
|||
let pattern = format!("{}(/verify/[^ \t\n]*)", BASE_URI);
|
||||
let confirm_uri = pop_mail_capture_pattern(filemail_path, &pattern);
|
||||
|
||||
let response = client.get(&confirm_uri).dispatch();
|
||||
let response = client.post(&confirm_uri).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,11 @@ mod forms {
|
|||
}
|
||||
|
||||
mod template {
|
||||
#[derive(Serialize)]
|
||||
pub struct VerifyForm {
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Verify {
|
||||
pub verified: bool,
|
||||
|
@ -437,7 +442,7 @@ pub fn request_verify_form_data(
|
|||
MyResponse::upload_response(result)
|
||||
}
|
||||
|
||||
#[get("/verify/<token>")]
|
||||
#[post("/verify/<token>")]
|
||||
pub fn verify_confirm(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
token_service: rocket::State<StatefulTokens>,
|
||||
|
@ -461,3 +466,11 @@ pub fn verify_confirm(
|
|||
}
|
||||
}
|
||||
|
||||
#[get("/verify/<token>")]
|
||||
pub fn verify_confirm_form(
|
||||
token: String,
|
||||
) -> MyResponse {
|
||||
MyResponse::ok("upload/verification-form", template::VerifyForm {
|
||||
token
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue