From ef7d296eaadda44bddc11e0bf22f45db4c6d981d Mon Sep 17 00:00:00 2001 From: Chris Haumesser <5400416-wryfi@users.noreply.gitlab.com> Date: Fri, 12 Jun 2026 15:17:09 -0600 Subject: [PATCH] Fixes #7287: /api/v1/add/time_limited_alias - missing 'description' field in OpenAPI spec - incorrect http/200 when omitting 'description' - adds validity and permanent fields to OpenAPI spec - fixes bug that always set validity to 8760 regardless of supplied value --- data/web/api/openapi.yaml | 13 +++++++ data/web/inc/functions.mailbox.inc.php | 52 ++++++++++++++++++-------- data/web/lang/lang.en-gb.json | 3 +- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/data/web/api/openapi.yaml b/data/web/api/openapi.yaml index 77c58b609..6e25da309 100644 --- a/data/web/api/openapi.yaml +++ b/data/web/api/openapi.yaml @@ -185,6 +185,7 @@ paths: example: username: info@domain.tld domain: domain.tld + description: my time limited alias properties: username: description: 'the mailbox an alias should be created for' @@ -192,6 +193,18 @@ paths: domain: description: "the domain" type: string + description: + description: "a description for the alias" + type: string + validity: + description: "validity period in hours (1-87600); defaults to 8760 (1 year) if omitted" + type: integer + permanent: + description: "if true, the alias never expires" + type: boolean + required: + - domain + - description type: object summary: Create time limited alias /api/v1/add/app-passwd: diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index a9f17705d..ad29a1f24 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -41,13 +41,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { else { $username = $_SESSION['mailcow_cc_username']; } - if (isset($_data["validity"]) && !filter_var($_data["validity"], FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 87600)))) { - $_SESSION['return'][] = array( - 'type' => 'danger', - 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), - 'msg' => 'validity_missing' - ); - return false; + if (isset($_data["validity"])) { + if (!filter_var($_data["validity"], FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 87600)))) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'validity_missing' + ); + return false; + } } else { // Default to 1 yr @@ -60,6 +62,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $permanent = 0; } $domain = $_data['domain']; + if (!isset($_data['description']) || empty(trim($_data['description']))) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'description_missing' + ); + return false; + } $description = $_data['description']; $valid_domains[] = mailbox('get', 'mailbox_details', $username)['domain']; $valid_alias_domains = user_get_alias_details($username)['alias_domains']; @@ -75,15 +85,25 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { return false; } $validity = strtotime("+" . $_data["validity"] . " hour"); - $stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `description`, `goto`, `validity`, `permanent`) VALUES - (:address, :description, :goto, :validity, :permanent)"); - $stmt->execute(array( - ':address' => readable_random_string(rand(rand(3, 9), rand(3, 9))) . '.' . readable_random_string(rand(rand(3, 9), rand(3, 9))) . '@' . $domain, - ':description' => $description, - ':goto' => $username, - ':validity' => $validity, - ':permanent' => $permanent - )); + try { + $stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `description`, `goto`, `validity`, `permanent`) VALUES + (:address, :description, :goto, :validity, :permanent)"); + $stmt->execute(array( + ':address' => readable_random_string(rand(rand(3, 9), rand(3, 9))) . '.' . readable_random_string(rand(rand(3, 9), rand(3, 9))) . '@' . $domain, + ':description' => $description, + ':goto' => $username, + ':validity' => $validity, + ':permanent' => $permanent + )); + } + catch (PDOException $e) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => array('mysql_error', $e) + ); + return false; + } $_SESSION['return'][] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json index d2412fbf7..d4a3b3726 100644 --- a/data/web/lang/lang.en-gb.json +++ b/data/web/lang/lang.en-gb.json @@ -435,6 +435,7 @@ "defquota_empty": "Default quota per mailbox must not be 0.", "demo_mode_enabled": "Demo Mode is enabled", "description_invalid": "Resource description for %s is invalid", + "description_missing": "Please provide a description", "dkim_domain_or_sel_exists": "A DKIM key for \"%s\" exists and will not be overwritten", "dkim_domain_or_sel_invalid": "DKIM domain or selector invalid: %s", "domain_cannot_match_hostname": "Domain cannot match hostname", @@ -556,7 +557,7 @@ "unknown_tfa_method": "Unknown TFA method", "unlimited_quota_acl": "Unlimited quota prohibited by ACL", "username_invalid": "Username %s cannot be used", - "validity_missing": "Please assign a period of validity", + "validity_missing": "Please assign a period of validity between 1-87600", "value_missing": "Please provide all values", "version_invalid": "Version %s is invalid", "yotp_verification_failed": "Yubico OTP verification failed: %s"