🐛 Fixes CORS and creating triggers

This commit is contained in:
2025-10-30 10:45:24 +01:00
parent 0717f1694f
commit 7f03d83f72
4 changed files with 67 additions and 11 deletions

View File

@@ -52,8 +52,8 @@ pub async fn get(id: &str, meta: ReqMeta, state: &State<AppState>) -> Result<Nam
None => return Err(Status::BadRequest), None => return Err(Status::BadRequest),
}; };
let mut tracker: Option<Tracker> = None; let tracker: Option<Tracker>;
let mut result: Option<QueryResult<usize>> = None; let result: Option<QueryResult<usize>>;
let now = Utc::now().naive_utc(); let now = Utc::now().naive_utc();
{ {

View File

@@ -1,6 +1,7 @@
use rocket::Request; use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::Status; use rocket::http::{Header, Status};
use rocket::request::{FromRequest, Outcome}; use rocket::request::{FromRequest, Outcome};
use rocket::{Request, Response};
use std::env; use std::env;
pub struct Authenticated; pub struct Authenticated;
@@ -22,3 +23,25 @@ impl<'r> FromRequest<'r> for Authenticated {
} }
} }
} }
pub struct CORS;
#[rocket::async_trait]
impl Fairing for CORS {
fn info(&self) -> Info {
Info {
name: "Add CORS headers to responses",
kind: Kind::Response,
}
}
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
response.set_header(Header::new(
"Access-Control-Allow-Methods",
"GET, POST, DELETE, OPTIONS",
));
response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
}
}

View File

@@ -7,6 +7,7 @@ mod schema;
use crate::api::hit; use crate::api::hit;
use crate::api::image; use crate::api::image;
use crate::api::tracker; use crate::api::tracker;
use crate::auth::CORS;
use crate::models::{AppState, GotifyState}; use crate::models::{AppState, GotifyState};
use chrono::Local; use chrono::Local;
use diesel::{Connection, PgConnection}; use diesel::{Connection, PgConnection};
@@ -68,13 +69,18 @@ fn rocket() -> _ {
.expect(&format!("Error connecting to {}", database_url)); .expect(&format!("Error connecting to {}", database_url));
let gotify_data = GotifyState { let gotify_data = GotifyState {
url: gotify_url, url: gotify_url.clone(),
token: gotify_token, token: gotify_token,
enabled: gotify_enabled enabled: gotify_enabled,
}; };
if gotify_enabled {
info!("Gotify alerts enabled with url {}", gotify_url);
}
let app_data = AppState::new(db, static_dir, gotify_data); let app_data = AppState::new(db, static_dir, gotify_data);
rocket::build() rocket::build()
.manage(app_data) .manage(app_data)
.attach(CORS {})
.mount("/", routes![index]) .mount("/", routes![index])
.mount( .mount(
"/tracker", "/tracker",

View File

@@ -162,7 +162,7 @@
<div class="container"> <div class="container">
<h1>Setra</h1> <h1>Setra</h1>
<form class="create-form"> <form onsubmit="createTrigger(event)" class="create-form">
<label for="name-input">Name:</label> <label for="name-input">Name:</label>
<input id="name-input" type="text"> <input id="name-input" type="text">
@@ -174,7 +174,6 @@
<th>ID</th> <th>ID</th>
<th>Name</th> <th>Name</th>
<th>Created at</th> <th>Created at</th>
<th></th>
</tr> </tr>
</table> </table>
@@ -190,7 +189,7 @@
</table> </table>
<div class="dialog" id="dialog"> <div class="dialog" id="dialog">
<form onsubmit="saveAPIKey(Event)"> <form onsubmit="saveAPIKey(event)">
<label for="api-key-input">API key:</label> <label for="api-key-input">API key:</label>
<input id="api-key-input" type="password"> <input id="api-key-input" type="password">
@@ -221,13 +220,20 @@
return; return;
} }
fetch("http://localhost:8000/tracker", { fetch(`${window.location.origin}/tracker`, {
method: "GET", method: "GET",
headers: { headers: {
Authorization: apiKey, Authorization: apiKey,
} }
}).then((res) => { }).then((res) => {
res.json().then((trackers) => { res.json().then((trackers) => {
document.getElementById("tracker-table").innerHTML = `
<tr>
<th>ID</th>
<th>Name</th>
<th>Created at</th>
</tr>`;
trackers.forEach((tracker) => { trackers.forEach((tracker) => {
document.getElementById("tracker-table").innerHTML += ` document.getElementById("tracker-table").innerHTML += `
<tr> <tr>
@@ -255,7 +261,7 @@
return; return;
} }
fetch(`http://localhost:8000/tracker/${id}/hits`, { fetch(`${window.location.origin}/tracker/${id}/hits`, {
method: "GET", method: "GET",
headers: { headers: {
Authorization: apiKey, Authorization: apiKey,
@@ -286,6 +292,27 @@
}).catch((err) => alert(`Couldn't fetch hits: ${err}`)); }).catch((err) => alert(`Couldn't fetch hits: ${err}`));
} }
function createTrigger(event) {
event.preventDefault();
const apiKey = localStorage.getItem("api-key");
if (!apiKey) {
return;
}
const name = document.getElementById("name-input").value;
fetch(`${window.location.origin}/tracker`, {
method: "POST",
body: JSON.stringify({name: name}),
headers: {
Authorization: apiKey,
"Content-Type": "application/json",
}
}).then(async (res) => {
console.log(await res.text());
loadTriggers();
}).catch((err) => alert(`Couldn't create trigger: ${err}`));
}
function copyLink(id) { function copyLink(id) {
navigator.clipboard.writeText(`http://localhost:8000/image/${id}`).catch((err) => alert(`Couldn't copy: ${err}`)); navigator.clipboard.writeText(`http://localhost:8000/image/${id}`).catch((err) => alert(`Couldn't copy: ${err}`));
} }