Bump: 0.5.2 : label charset tightened; password/custom-id validation
This commit is contained in:
@@ -16,7 +16,13 @@ use regex::Regex;
|
||||
// cannot be ported verbatim. The `(?=.*[A-Za-z])` lookahead only means
|
||||
// "must contain at least one letter" — we drop it from the pattern and
|
||||
// enforce that condition with a separate `.chars().any(..)` check below.
|
||||
static KEY_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^[A-Za-z0-9 _-]{1,67}$").unwrap());
|
||||
static KEY_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^[A-Za-z0-9'-]{1,67}$").unwrap());
|
||||
|
||||
// Allowed charset for stream-key passwords and custom IDs: letters, numbers,
|
||||
// dashes and apostrophes only — no spaces. Mirrors the frontend
|
||||
// `/^[A-Za-z0-9'-]{0,67}$/` used by the keys-page popups; empty clears the value.
|
||||
static PASSWORD_RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"^[A-Za-z0-9'-]{0,67}$").unwrap());
|
||||
|
||||
use axum::{
|
||||
Json, Router,
|
||||
@@ -166,7 +172,7 @@ async fn edit_stream_key(
|
||||
) -> Result<impl IntoResponse, HttpError> {
|
||||
// Trim surrounding whitespace so labels aren't stored with leading/trailing spaces.
|
||||
let new_label = payload.new.as_deref().map(str::trim);
|
||||
// Length (1..=67) and allowed charset ([A-Za-z0-9 _-], space included).
|
||||
// Length (1..=67) and allowed charset ([A-Za-z0-9'-], no spaces).
|
||||
if let Some(label) = new_label {
|
||||
if !KEY_RE.is_match(label) {
|
||||
return Err(HttpError::BadRequest("invalid label".into()));
|
||||
@@ -176,6 +182,18 @@ async fn edit_stream_key(
|
||||
return Err(HttpError::BadRequest("label must contain a letter".into()));
|
||||
}
|
||||
}
|
||||
// Custom IDs and passwords share a charset: letters, numbers, dashes,
|
||||
// apostrophes — no spaces. Empty values are allowed (they clear the field).
|
||||
if let Some(custom_id) = payload.custom_id.as_deref() {
|
||||
if !custom_id.is_empty() && !PASSWORD_RE.is_match(custom_id) {
|
||||
return Err(HttpError::BadRequest("invalid custom id".into()));
|
||||
}
|
||||
}
|
||||
if let Some(pwd) = payload.password.as_deref() {
|
||||
if !pwd.is_empty() && !PASSWORD_RE.is_match(pwd) {
|
||||
return Err(HttpError::BadRequest("invalid password".into()));
|
||||
}
|
||||
}
|
||||
|
||||
let stream_key = stream_key::Entity::find_by_id(payload.id)
|
||||
.one(&state.db)
|
||||
|
||||
Reference in New Issue
Block a user