1
0
Fork 0
mirror of https://github.com/mCaptcha/mCaptcha.git synced 2025-05-03 05:32:49 +03:00

feat: track maximum recorded nonce for captcha levels to render progress bar

This commit is contained in:
Aravinth Manivannan 2023-10-29 06:18:01 +05:30
parent 49a8757ead
commit b6497882d7
No known key found for this signature in database
GPG key ID: F8F50389936984FF
12 changed files with 356 additions and 0 deletions

View file

@ -0,0 +1,17 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO\n mcaptcha_track_nonce (level_id, nonce)\n VALUES ((\n SELECT\n level_id\n FROM\n mcaptcha_levels\n WHERE\n config_id = (SELECT config_id FROM mcaptcha_config WHERE key = ($1))\n AND\n difficulty_factor = $2\n AND\n visitor_threshold = $3\n ), $4);",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Int4",
"Int4",
"Int4"
]
},
"nullable": []
},
"hash": "133ee23ab5ac7c664a86b6edfaa8da79281b6d1f5ba33c642a6ea1b0682fe0b0"
}

View file

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT nonce FROM mcaptcha_track_nonce\n WHERE level_id = (\n SELECT\n level_id\n FROM\n mcaptcha_levels\n WHERE\n config_id = (SELECT config_id FROM mcaptcha_config WHERE key = ($1))\n AND\n difficulty_factor = $2\n );",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "nonce",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Text",
"Int4"
]
},
"nullable": [
false
]
},
"hash": "96f1f1e45144d5add6c4ba4cd2df8eda6043bc8cd6952787f92a687fef778a6e"
}

View file

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE mcaptcha_track_nonce SET nonce = $3\n WHERE level_id = (\n SELECT\n level_id\n FROM\n mcaptcha_levels\n WHERE\n config_id = (SELECT config_id FROM mcaptcha_config WHERE key = ($1))\n AND\n difficulty_factor = $2\n )\n AND nonce <= $3;",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Int4",
"Int4"
]
},
"nullable": []
},
"hash": "e33ee14cf76cd09d9a157b8784a3fe25b89eaca105aa30e479d31b756cd5c88b"
}

View file

@ -0,0 +1,6 @@
-- Add migration script here
CREATE TABLE IF NOT EXISTS mcaptcha_track_nonce (
nonce INTEGER NOT NULL DEFAULT 0,
level_id INTEGER references mcaptcha_levels(level_id) ON DELETE CASCADE,
ID SERIAL PRIMARY KEY NOT NULL
);

View file

@ -445,6 +445,38 @@ impl MCDatabase for Database {
futs.push(fut);
}
try_join_all(futs)
.await
.map_err(|e| map_row_not_found_err(e, DBError::CaptchaNotFound))?;
let mut futs = Vec::with_capacity(levels.len());
for level in levels.iter() {
let difficulty_factor = level.difficulty_factor as i32;
let visitor_threshold = level.visitor_threshold as i32;
let fut = sqlx::query!(
"INSERT INTO
mcaptcha_track_nonce (level_id, nonce)
VALUES ((
SELECT
level_id
FROM
mcaptcha_levels
WHERE
config_id = (SELECT config_id FROM mcaptcha_config WHERE key = ($1))
AND
difficulty_factor = $2
AND
visitor_threshold = $3
), $4);",
&captcha_key,
difficulty_factor,
visitor_threshold,
0,
)
.execute(&self.pool);
futs.push(fut);
}
try_join_all(futs)
.await
.map_err(|e| map_row_not_found_err(e, DBError::CaptchaNotFound))?;
@ -1097,6 +1129,68 @@ impl MCDatabase for Database {
Ok(res.drain(0..).map(|r| r.psuedo_id).collect())
}
/// Track maximum nonce received against captcha levels
async fn update_max_nonce_for_level(
&self,
captcha_key: &str,
difficulty_factor: u32,
latest_nonce: u32,
) -> DBResult<()> {
sqlx::query!(
"UPDATE mcaptcha_track_nonce SET nonce = $3
WHERE level_id = (
SELECT
level_id
FROM
mcaptcha_levels
WHERE
config_id = (SELECT config_id FROM mcaptcha_config WHERE key = ($1))
AND
difficulty_factor = $2
)
AND nonce <= $3;",
&captcha_key,
difficulty_factor as i32,
latest_nonce as i32,
)
.execute(&self.pool).await
.map_err(|e| map_row_not_found_err(e, DBError::CaptchaNotFound))?;
Ok(())
}
/// Get maximum nonce tracked so far for captcha levels
async fn get_max_nonce_for_level(
&self,
captcha_key: &str,
difficulty_factor: u32,
) -> DBResult<u32> {
struct X {
nonce: i32,
}
let res = sqlx::query_as!(
X,
"SELECT nonce FROM mcaptcha_track_nonce
WHERE level_id = (
SELECT
level_id
FROM
mcaptcha_levels
WHERE
config_id = (SELECT config_id FROM mcaptcha_config WHERE key = ($1))
AND
difficulty_factor = $2
);",
&captcha_key,
difficulty_factor as i32,
)
.fetch_one(&self.pool).await
.map_err(|e| map_row_not_found_err(e, DBError::CaptchaNotFound))?;
Ok(res.nonce as u32)
}
}
#[derive(Clone)]