fix: resolve all remaining audit failures across rust, svelte, and java
This commit is contained in:
1 parent
bc12a25a01
commit
590178e41a
35 files changed
+958
-300
No files matched your search
@@ -34,6 +34,49 @@ pub fn level_from_xp(xp: i64) -> (i64, i64, i64, f64) {
|
||||
(lvl, progress_in_lvl, span, pct)
|
||||
}
|
||||
|
||||
/// Award each configured entitlement once in the transaction which earned it.
|
||||
/// Achievement XP is credited automatically via the `achievement_xp` DB trigger;
|
||||
/// this function only processes level-up rewards (titles, badges, item entitlements).
|
||||
pub async fn grant_rewards(tx: &mut sqlx::Transaction<'_, sqlx::Sqlite>, uuid: &str, now: &str) -> AppResult<()> {
|
||||
let xp: i64 = sqlx::query_scalar("SELECT global_xp FROM user_levels WHERE uuid = ?")
|
||||
.bind(uuid).fetch_optional(&mut **tx).await?.unwrap_or(0);
|
||||
let level = level_from_xp(xp).0;
|
||||
sqlx::query("UPDATE user_levels SET global_level = ? WHERE uuid = ?")
|
||||
.bind(level).bind(uuid).execute(&mut **tx).await?;
|
||||
let rewards: Vec<(i64, String, Option<i64>, String, String, String)> = sqlx::query_as(
|
||||
"SELECT r.id, r.level_type, r.server_id, r.reward_type, r.reward_name, r.reward_data FROM level_rewards r
|
||||
WHERE (r.level_type = 'global' AND r.level_req <= ?)
|
||||
OR (r.level_type = 'server' AND EXISTS (SELECT 1 FROM server_levels sl WHERE sl.uuid = ? AND sl.server_id = r.server_id AND sl.server_level >= r.level_req))
|
||||
ORDER BY r.level_req, r.id")
|
||||
.bind(level).bind(uuid).fetch_all(&mut **tx).await?;
|
||||
for (id, scope, server_id, kind, name, data) in rewards {
|
||||
let inserted = sqlx::query("INSERT OR IGNORE INTO granted_rewards(uuid, reward_id, granted_at) VALUES (?, ?, ?)")
|
||||
.bind(uuid).bind(id).bind(now).execute(&mut **tx).await?.rows_affected();
|
||||
if inserted == 0 { continue; }
|
||||
match kind.as_str() {
|
||||
"title" if scope == "global" => {
|
||||
sqlx::query("UPDATE user_levels SET title = ? WHERE uuid = ?").bind(&name).bind(uuid).execute(&mut **tx).await?;
|
||||
}
|
||||
"title" => {
|
||||
sqlx::query("UPDATE server_levels SET rank_name = ? WHERE server_id = ? AND uuid = ?")
|
||||
.bind(&name).bind(server_id).bind(uuid).execute(&mut **tx).await?;
|
||||
}
|
||||
"badge" | "profile_badge" => {
|
||||
let raw: String = sqlx::query_scalar("SELECT badges FROM user_levels WHERE uuid = ?")
|
||||
.bind(uuid).fetch_optional(&mut **tx).await?.unwrap_or_else(|| "[]".into());
|
||||
let mut badges: Vec<String> = serde_json::from_str(&raw).unwrap_or_default();
|
||||
let data: Value = serde_json::from_str(&data).unwrap_or_default();
|
||||
let badge = data["badge"].as_str().unwrap_or(&name).to_string();
|
||||
if !badges.contains(&badge) { badges.push(badge); }
|
||||
sqlx::query("INSERT INTO user_levels(uuid, badges, updated_at) VALUES (?, ?, ?) ON CONFLICT(uuid) DO UPDATE SET badges = excluded.badges")
|
||||
.bind(uuid).bind(serde_json::to_string(&badges)?).bind(now).execute(&mut **tx).await?;
|
||||
}
|
||||
_ => {} // Item/cosmetic entitlements are recorded in granted_rewards.
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct RewardRow {
|
||||
pub id: i64,
|
||||
|
||||
Reference in new issue
Block a user