From 460201507d720901b35cf600384705fd1ba1f627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BE=E7=94=B0=E7=B4=94=E5=B9=B3?= Date: Wed, 25 Feb 2026 01:03:19 +0900 Subject: [PATCH] fix: add input validation to reject non-alphanumeric SN codes Add regex pattern validation (^[a-zA-Z0-9]+$) to the SN field across all device schemas (DeviceProperties, DeviceInput, DeviceUpdate, DeviceInfo) and the /v1/devices/sn/{sn} path parameter. This ensures serial numbers only contain ASCII alphanumeric characters, rejecting Unicode characters like Chinese. Closes stayforge/Stayforge-API#3 Co-Authored-By: Claude Opus 4.6 --- openapi.json | 25 +++++++++++++++++++------ openapi.yaml | 13 +++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/openapi.json b/openapi.json index 0eaa63b..f53ff69 100644 --- a/openapi.json +++ b/openapi.json @@ -1384,7 +1384,8 @@ "schema": { "type": "string", "minLength": 1, - "maxLength": 256 + "maxLength": 256, + "pattern": "^[a-zA-Z0-9]+$" }, "description": "Device serial number", "example": "SFVA78RABZ12345678" @@ -7308,7 +7309,10 @@ "sn": { "type": "string", "nullable": true, - "description": "Serial number of the device." + "description": "Serial number of the device.", + "pattern": "^[a-zA-Z0-9]+$", + "minLength": 1, + "maxLength": 256 }, "display_name": { "type": "string", @@ -7447,7 +7451,10 @@ }, "sn": { "type": "string", - "description": "Serial number of the device. This field is required when creating a device." + "description": "Serial number of the device. This field is required when creating a device.", + "pattern": "^[a-zA-Z0-9]+$", + "minLength": 1, + "maxLength": 256 } } }, @@ -7469,7 +7476,10 @@ }, "sn": { "type": "string", - "nullable": true + "nullable": true, + "pattern": "^[a-zA-Z0-9]+$", + "minLength": 1, + "maxLength": 256 }, "display_name": { "type": "string", @@ -7501,7 +7511,10 @@ "sn": { "type": "string", "description": "Device serial number", - "example": "SFVA78RABZ12345678" + "example": "SFVA78RABZ12345678", + "pattern": "^[a-zA-Z0-9]+$", + "minLength": 1, + "maxLength": 256 }, "model_name": { "type": "string", @@ -8255,4 +8268,4 @@ } } } -} \ No newline at end of file +} diff --git a/openapi.yaml b/openapi.yaml index 44affef..0b0efb0 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1044,6 +1044,7 @@ paths: type: string minLength: 1 maxLength: 256 + pattern: ^[a-zA-Z0-9]+$ description: Device serial number example: SFVA78RABZ12345678 get: @@ -5777,6 +5778,9 @@ components: type: string nullable: true description: Serial number of the device. + minLength: 1 + maxLength: 256 + pattern: ^[a-zA-Z0-9]+$ display_name: type: string nullable: true @@ -5942,6 +5946,9 @@ components: type: string description: Serial number of the device. This field is required when creating a device. + minLength: 1 + maxLength: 256 + pattern: ^[a-zA-Z0-9]+$ DeviceUpdate: allOf: - $ref: '#/components/schemas/DeviceProperties' @@ -5962,6 +5969,9 @@ components: sn: type: string nullable: true + minLength: 1 + maxLength: 256 + pattern: ^[a-zA-Z0-9]+$ display_name: type: string nullable: true @@ -5984,6 +5994,9 @@ components: type: string description: Device serial number example: SFVA78RABZ12345678 + minLength: 1 + maxLength: 256 + pattern: ^[a-zA-Z0-9]+$ model_name: type: string description: Device model name