Skip to content

fix: validate price_id field rejects non-Stripe formats#15

Open
Washio20 wants to merge 1 commit intostayforge:mainfrom
Washio20:fix/issue-4-price-id-validation
Open

fix: validate price_id field rejects non-Stripe formats#15
Washio20 wants to merge 1 commit intostayforge:mainfrom
Washio20:fix/issue-4-price-id-validation

Conversation

@Washio20
Copy link

@Washio20 Washio20 commented Feb 24, 2026

Summary

  • Adds regex pattern validation (^price_[a-zA-Z0-9_]+$) to the price_id field in device schemas
  • Ensures price_id values conform to the Stripe pricing ID format

Root Cause

The price_id field had no format validation, allowing any Unicode characters (including Chinese characters like pricdee二hly) to be accepted despite being intended for Stripe pricing IDs.

Changes

  • DeviceProperties.price_id: Added pattern: ^price_[a-zA-Z0-9_]+$
  • DeviceUpdate.price_id: Added pattern: ^price_[a-zA-Z0-9_]+$
  • Updated both openapi.yaml and openapi.json

Testing

  • Invalid price IDs with Chinese characters (e.g., pricdee二hly) will now be rejected with a 422 error
  • Valid Stripe price IDs (e.g., price_1abc2def3) continue to work

Closes #4

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Updated API schemas to enforce validation on price identification fields across device and card resources. Price IDs must now adhere to the specified format pattern.

Add regex pattern validation (^price_[a-zA-Z0-9_]+$) to the price_id
field in DeviceProperties and DeviceUpdate schemas. This ensures
price_id values conform to the Stripe pricing ID format, rejecting
non-ASCII characters like Chinese.

Closes stayforge#4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 24, 2026 16:04
@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Added regex pattern validation ^price_[a-zA-Z0-9_]+$ to price_id fields across OpenAPI schema definitions to enforce Stripe-compatible pricing ID formats, preventing invalid characters such as non-ASCII input from being accepted.

Changes

Cohort / File(s) Summary
Price ID Pattern Validation
openapi.json, openapi.yaml
Added regex pattern constraint ^price_[a-zA-Z0-9_]+$ to price_id field in DeviceProperties, CardProperties, and DeviceUpdate schemas to restrict input to alphanumeric characters and underscores, rejecting non-ASCII characters like Chinese characters.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰✨
A clever constraint now guards the price,
No Chinese characters will slip through twice,
Pattern validation, striped and clean,
The finest regex you've ever seen!
Stripe IDs now safe from every shore,
This little rabbit cheers evermore! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding validation to the price_id field to reject non-Stripe formats using a regex pattern constraint.
Linked Issues check ✅ Passed The PR implements all coding requirements from issue #4: adds regex pattern validation to price_id fields in DeviceProperties, CardProperties, and DeviceUpdate schemas to reject non-Stripe formats while preserving acceptance of other fields with international characters.
Out of Scope Changes check ✅ Passed All changes are directly related to adding price_id validation constraints. The PR applies the pattern to three schemas (DeviceProperties, CardProperties, DeviceUpdate) across both openapi.yaml and openapi.json files, which aligns with the stated objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
openapi.yaml (1)

5786-5791: ⚠️ Potential issue | 🟡 Minor

Remove strict regex validation for Stripe Price IDs.

Line 5790 applies a strict pattern (^price_[a-zA-Z0-9_]+$) to Stripe-generated Price IDs. However, Stripe's official guidance is to treat Price IDs as opaque strings and avoid parsing or validating the format beyond the price_ prefix. Stripe-generated Price IDs are not subject to the alphanumeric + hyphen/underscore restrictions that apply only to user-specified IDs. Strict validation risks rejecting valid IDs if Stripe modifies their format. Consider simplifying to just check the prefix, or removing the pattern entirely.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openapi.yaml` around lines 5786 - 5791, The OpenAPI schema for the property
price_id currently enforces a strict pattern (^price_[a-zA-Z0-9_]+$) which may
reject valid Stripe-generated IDs; update the price_id schema (the price_id
property) to remove the strict regex and either delete the pattern entirely or
relax it to only assert the "price_" prefix (e.g., a simple prefix check like
^price_.*$) so the spec treats Stripe Price IDs as opaque strings while still
optionally ensuring they start with "price_".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openapi.yaml`:
- Around line 5972-5974: The openapi.json is out of sync with openapi.yaml: add
the DeviceUpdate schema and its price_id field (pattern ^price_[a-zA-Z0-9_]+$)
to the generated JSON; regenerate openapi.json from the updated YAML so
DeviceUpdate and price_id (with type string, nullable true, and that pattern)
are present, then commit the regenerated openapi.json to keep the specs
synchronized.

---

Outside diff comments:
In `@openapi.yaml`:
- Around line 5786-5791: The OpenAPI schema for the property price_id currently
enforces a strict pattern (^price_[a-zA-Z0-9_]+$) which may reject valid
Stripe-generated IDs; update the price_id schema (the price_id property) to
remove the strict regex and either delete the pattern entirely or relax it to
only assert the "price_" prefix (e.g., a simple prefix check like ^price_.*$) so
the spec treats Stripe Price IDs as opaque strings while still optionally
ensuring they start with "price_".

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a61a3a4 and 9ab0503.

📒 Files selected for processing (2)
  • openapi.json
  • openapi.yaml

Comment on lines 5972 to +5974
type: string
nullable: true
pattern: ^price_[a-zA-Z0-9_]+$
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate openapi.json
json_file=$(fd -a '^openapi\.json$' . || true)
if [[ -z "${json_file}" ]]; then
  echo "openapi.json not found"
  exit 1
fi

echo "=== Found openapi.json at: $json_file ==="
echo ""

# Show price_id entries and patterns for DeviceUpdate in openapi.json
echo "=== Searching for DeviceUpdate in openapi.json ==="
rg -n '"DeviceUpdate"' "$json_file" -C3 || echo "No DeviceUpdate found"
echo ""

echo "=== Searching for price_id in openapi.json ==="
rg -n '"price_id"' "$json_file" -C3 || echo "No price_id found"
echo ""

echo "=== Searching for price_ pattern in openapi.json ==="
rg -n 'price_[a-zA-Z0-9_]+' "$json_file" -C2 || echo "No price_ pattern found"

Repository: stayforge/Stayforge-API

Length of output: 8884


🏁 Script executed:

#!/bin/bash

# Check if openapi.yaml exists
if [[ ! -f openapi.yaml ]]; then
  echo "openapi.yaml not found in root"
  fd -a '^openapi\.yaml$' . || true
  exit 1
fi

# Show lines around 5972-5974 to see DeviceUpdate context
echo "=== Lines 5970-5980 of openapi.yaml ==="
sed -n '5970,5980p' openapi.yaml

# Search for DeviceUpdate schema definition
echo ""
echo "=== Searching for DeviceUpdate in openapi.yaml ==="
rg -n 'DeviceUpdate' openapi.yaml -B2 -A10 | head -50

# Confirm no price_id elsewhere in the JSON
echo ""
echo "=== File size and basic stats ==="
wc -l openapi.yaml
wc -l /home/jailuser/git/openapi.json || true

Repository: stayforge/Stayforge-API

Length of output: 1543


Regenerate openapi.json to include the price_id pattern for DeviceUpdate.

The YAML spec at lines 5972-5974 defines price_id with pattern ^price_[a-zA-Z0-9_]+$ as part of the DeviceUpdate schema, but openapi.json currently lacks both the DeviceUpdate schema and the price_id field. Regenerate the JSON spec from the updated YAML to maintain sync.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openapi.yaml` around lines 5972 - 5974, The openapi.json is out of sync with
openapi.yaml: add the DeviceUpdate schema and its price_id field (pattern
^price_[a-zA-Z0-9_]+$) to the generated JSON; regenerate openapi.json from the
updated YAML so DeviceUpdate and price_id (with type string, nullable true, and
that pattern) are present, then commit the regenerated openapi.json to keep the
specs synchronized.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds regex pattern validation to the price_id field in device schemas to ensure values conform to the Stripe pricing ID format. The change addresses an issue where the field previously accepted any Unicode characters, including non-Latin characters that are invalid for Stripe price IDs.

Changes:

  • Added pattern validation (^price_[a-zA-Z0-9_]+$) to DeviceProperties.price_id and DeviceUpdate.price_id
  • Updated both openapi.yaml and openapi.json to maintain consistency

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
openapi.yaml Added regex pattern validation to price_id field in DeviceProperties schema (line 5790) and DeviceUpdate schema (line 5974)
openapi.json Added regex pattern validation to price_id field in DeviceProperties schema (line 7324) and DeviceUpdate schema (line 7484)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

type: string
nullable: true
description: Stripe price ID for billing purposes.
pattern: ^price_[a-zA-Z0-9_]+$
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern ^price_[a-zA-Z0-9_]+$ is overly permissive. Stripe price IDs follow the format price_ followed by alphanumeric characters only, without additional underscores. The pattern should be ^price_[a-zA-Z0-9]+$ (removing the underscore from the character class). This would correctly reject IDs like price_abc_def while still accepting valid IDs like price_1abc2def3.

Suggested change
pattern: ^price_[a-zA-Z0-9_]+$
pattern: ^price_[a-zA-Z0-9]+$

Copilot uses AI. Check for mistakes.
price_id:
type: string
nullable: true
pattern: ^price_[a-zA-Z0-9_]+$
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern ^price_[a-zA-Z0-9_]+$ is overly permissive. Stripe price IDs follow the format price_ followed by alphanumeric characters only, without additional underscores. The pattern should be ^price_[a-zA-Z0-9]+$ (removing the underscore from the character class). This would correctly reject IDs like price_abc_def while still accepting valid IDs like price_1abc2def3.

Suggested change
pattern: ^price_[a-zA-Z0-9_]+$
pattern: ^price_[a-zA-Z0-9]+$

Copilot uses AI. Check for mistakes.
"nullable": true,
"description": "Stripe price ID for billing purposes."
"description": "Stripe price ID for billing purposes.",
"pattern": "^price_[a-zA-Z0-9_]+$"
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern ^price_[a-zA-Z0-9_]+$ is overly permissive. Stripe price IDs follow the format price_ followed by alphanumeric characters only, without additional underscores. The pattern should be ^price_[a-zA-Z0-9]+$ (removing the underscore from the character class). This would correctly reject IDs like price_abc_def while still accepting valid IDs like price_1abc2def3.

Suggested change
"pattern": "^price_[a-zA-Z0-9_]+$"
"pattern": "^price_[a-zA-Z0-9]+$"

Copilot uses AI. Check for mistakes.
"type": "string",
"nullable": true
"nullable": true,
"pattern": "^price_[a-zA-Z0-9_]+$"
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern ^price_[a-zA-Z0-9_]+$ is overly permissive. Stripe price IDs follow the format price_ followed by alphanumeric characters only, without additional underscores. The pattern should be ^price_[a-zA-Z0-9]+$ (removing the underscore from the character class). This would correctly reject IDs like price_abc_def while still accepting valid IDs like price_1abc2def3.

Suggested change
"pattern": "^price_[a-zA-Z0-9_]+$"
"pattern": "^price_[a-zA-Z0-9]+$"

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]price_id Field Accepts Chinese Characters (Invalid Input Not Rejected)

2 participants