merge upstream
All checks were successful
mnemo-build-and-publish / gractwo-mnemo-build (push) Successful in 1m7s

This commit is contained in:
2026-04-30 20:02:34 +00:00
3 changed files with 57 additions and 5 deletions

View File

@@ -23,6 +23,33 @@ impl MnemoConf {
pub fn new() -> Self { pub fn new() -> Self {
MnemoConf::default() MnemoConf::default()
} }
pub async fn load(conn: &mut sqlx::PgConnection) -> Result<Self, sqlx::Error> {
let row: Option<serde_json::Value> =
sqlx::query_scalar("SELECT config FROM mnemoconf LIMIT 1")
.fetch_optional(&mut *conn)
.await?;
Ok(match row {
Some(val) => serde_json::from_value(val).unwrap_or_default(),
None => {
let conf = MnemoConf::default();
conf.save(conn).await?;
conf
}
})
}
pub async fn save(&self, conn: &mut sqlx::PgConnection) -> Result<(), sqlx::Error> {
let val = serde_json::to_value(self).unwrap();
sqlx::query("DELETE FROM mnemoconf")
.execute(&mut *conn)
.await?;
sqlx::query("INSERT INTO mnemoconf (config) VALUES ($1)")
.bind(val)
.execute(&mut *conn)
.await?;
Ok(())
}
} }
impl Default for MnemoConf { impl Default for MnemoConf {
fn default() -> Self { fn default() -> Self {

View File

@@ -34,7 +34,9 @@ async fn main() -> Result<(), Box<dyn Error>> {
let pool = config::init_pool().await?; let pool = config::init_pool().await?;
sqlx::migrate!("src/database/migrations").run(&pool).await?; sqlx::migrate!("src/database/migrations").run(&pool).await?;
log::info!("Migrations applied successfully."); log::info!("Migrations applied successfully.");
let conf = Arc::new(RwLock::new(MnemoConf::new())); let conf = Arc::new(RwLock::new(
MnemoConf::load(&mut *pool.acquire().await?).await?,
));
users::auth::init_password_dummies(); users::auth::init_password_dummies();
users::setup::initialise_reserved_users_if_needed(&pool).await?; users::setup::initialise_reserved_users_if_needed(&pool).await?;

View File

@@ -27,10 +27,21 @@ pub async fn page(
) -> Result<Response, CompositeError> { ) -> Result<Response, CompositeError> {
let mut conn = state.pool.acquire().await?; let mut conn = state.pool.acquire().await?;
let u = match User::authenticate(&mut *conn, req.headers()).await? { let u = match User::authenticate(&mut *conn, req.headers()).await? {
Some(u) => Some(u), Some(u) => u,
None => return Ok(Redirect::to(&format!("/login?r={}", req.uri().path())).into_response()), None => return Ok(Redirect::to(&format!("/login?r={}", req.uri().path())).into_response()),
}; };
if !u
.has_permission(&mut *conn, Permission::ConfigureInstance)
.await?
{
return Ok((
StatusCode::FORBIDDEN,
"You do not have permission to view this page.",
)
.into_response());
}
let (current_name, current_webhook) = { let (current_name, current_webhook) = {
let conf = state.conf.read().await; let conf = state.conf.read().await;
let current_name = conf.instance_name.clone(); let current_name = conf.instance_name.clone();
@@ -45,7 +56,7 @@ pub async fn page(
Ok(base( Ok(base(
"Instance Config | Mnemosyne", "Instance Config | Mnemosyne",
html!( html!(
(nav(u.as_ref(), req.uri().path())) (nav(Some(&u), req.uri().path()))
div class="max-w-4xl mx-auto px-2" { div class="max-w-4xl mx-auto px-2" {
div class="mx-auto max-w-4xl my-4 mb-8" { div class="mx-auto max-w-4xl my-4 mb-8" {
@@ -143,18 +154,25 @@ pub async fn change_name(
return Ok((StatusCode::BAD_REQUEST, "Instance name cannot be empty.").into_response()); return Ok((StatusCode::BAD_REQUEST, "Instance name cannot be empty.").into_response());
} }
let new_name = form.instance_name.trim().to_string();
LogEntry::new( LogEntry::new(
&mut tx, &mut tx,
u, u,
LogAction::ChangeInstanceName { LogAction::ChangeInstanceName {
old: state.conf.read().await.instance_name.clone(), old: state.conf.read().await.instance_name.clone(),
new: form.instance_name.trim().to_string(), new: new_name.clone(),
}, },
) )
.await?; .await?;
let mut new_conf = state.conf.read().await.clone();
new_conf.instance_name = new_name.clone();
new_conf.save(&mut tx).await?;
tx.commit().await?; tx.commit().await?;
state.conf.write().await.instance_name = form.instance_name.trim().to_string();
state.conf.write().await.instance_name = new_name;
Ok(Redirect::to("/instance-config").into_response()) Ok(Redirect::to("/instance-config").into_response())
} }
@@ -203,7 +221,12 @@ pub async fn change_webhook(
) )
.await?; .await?;
let mut new_conf = state.conf.read().await.clone();
new_conf.discord_webhook = new_webhook.clone();
new_conf.save(&mut tx).await?;
tx.commit().await?; tx.commit().await?;
state.conf.write().await.discord_webhook = new_webhook; state.conf.write().await.discord_webhook = new_webhook;
Ok(Redirect::to("/instance-config").into_response()) Ok(Redirect::to("/instance-config").into_response())
} }