Skip to content

Refactor clone store functionality and enhance vendor autologin#25

Merged
willymwai merged 10 commits into
mainfrom
feat/upgrade
May 4, 2026
Merged

Refactor clone store functionality and enhance vendor autologin#25
willymwai merged 10 commits into
mainfrom
feat/upgrade

Conversation

@kipsang01

@kipsang01 kipsang01 commented May 2, 2026

Copy link
Copy Markdown
Contributor
  • Updated CloneRequestCreator to resolve source store more efficiently.
  • Improved ShippingCategories and StockLocations duplicators to use global queries instead of vendor-specific ones.
  • Introduced tests for CloneStoresController, CloneRequestProvisioner.
  • Updated existing tests to cover new functionality and ensure proper vendor and admin user handling.

- Updated CloneRequestCreator to resolve source store more efficiently.
- Enhanced CloneRequestPresenter to include vendor metadata and auto-login details.
- Modified CloneRequestProvisioner to provision admin users and link them to vendors for autologin.
- Improved ShippingCategories and StockLocations duplicators to use global queries instead of vendor-specific ones.
- Added new routes for AI theme management including theme creation, preview, and publishing.
- Introduced tests for CloneStoresController, CloneRequestProvisioner, and AI theme synchronization.
- Updated existing tests to cover new functionality and ensure proper vendor and admin user handling.
@qodo-code-review

Copy link
Copy Markdown
ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one.

@willymwai

Copy link
Copy Markdown
Member

/agentic_describe

@qodo-code-review

qodo-code-review Bot commented May 2, 2026

Copy link
Copy Markdown

Review Summary by Qodo

(Agentic_describe updated until commit cef8cf3)

Add AI theme management API and enhance vendor autologin with admin user provisioning

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Added AI theme management API with create, preview, publish endpoints
• Enhanced vendor autologin with admin user provisioning and metadata
• Improved clone store to support admin users and vendor linking
• Added comprehensive tests for AI theme sync and clone operations
• Fixed shipping categories and stock locations to use global queries
Diagram
flowchart LR
  A["Clone Store Request"] -->|"Create Admin User"| B["Admin User"]
  B -->|"Link to Vendor"| C["Vendor User"]
  A -->|"Provision"| D["Store"]
  D -->|"Associate"| C
  E["AI Theme API"] -->|"Create/Preview/Publish"| F["Theme"]
  F -->|"Sync Pages"| G["Pages"]
  G -->|"Sync Sections"| H["Sections"]
  H -->|"Sync Blocks"| I["Blocks"]
Loading

Grey Divider

File Changes

1. app/controllers/spree/api/v2/platform/ai/base_controller.rb ✨ Enhancement +117/-0

New base controller for AI theme API endpoints

app/controllers/spree/api/v2/platform/ai/base_controller.rb


2. app/controllers/spree/api/v2/platform/ai/themes_controller.rb ✨ Enhancement +100/-0

Theme creation, preview, and publishing endpoints

app/controllers/spree/api/v2/platform/ai/themes_controller.rb


3. app/controllers/spree/api/v2/platform/ai/theme_pages_controller.rb ✨ Enhancement +64/-0

Theme pages creation and synchronization endpoint

app/controllers/spree/api/v2/platform/ai/theme_pages_controller.rb


View more (22)
4. app/controllers/spree/api/v2/platform/ai/theme_versions_controller.rb ✨ Enhancement +43/-0

Theme version snapshot creation endpoint

app/controllers/spree/api/v2/platform/ai/theme_versions_controller.rb


5. app/controllers/spree/api/v2/platform/ai/page_sections_controller.rb ✨ Enhancement +57/-0

Page sections creation and synchronization endpoint

app/controllers/spree/api/v2/platform/ai/page_sections_controller.rb


6. app/services/spree/olitt/clone_store/ai_theme/sync.rb ✨ Enhancement +528/-0

Comprehensive AI theme synchronization service

app/services/spree/olitt/clone_store/ai_theme/sync.rb


7. app/models/spree/ai_theme_store_decorator.rb ✨ Enhancement +14/-0

Store preferences for AI theme state management

app/models/spree/ai_theme_store_decorator.rb


8. app/controllers/spree/olitt/clone_store/clone_store_controller.rb ✨ Enhancement +46/-12

Enhanced vendor autologin with admin user provisioning

app/controllers/spree/olitt/clone_store/clone_store_controller.rb


9. app/models/spree/olitt/clone_store/clone_request.rb ✨ Enhancement +13/-5

Updated to use admin_user with backward compatibility

app/models/spree/olitt/clone_store/clone_request.rb


10. app/services/spree/olitt/clone_store/clone_request_creator.rb ✨ Enhancement +8/-1

Improved source store resolution with default fallback

app/services/spree/olitt/clone_store/clone_request_creator.rb


11. app/services/spree/olitt/clone_store/clone_request_presenter.rb ✨ Enhancement +32/-2

Added vendor metadata and autologin details to response

app/services/spree/olitt/clone_store/clone_request_presenter.rb


12. app/services/spree/olitt/clone_store/clone_request_provisioner.rb ✨ Enhancement +61/-23

Admin user provisioning and vendor user linking

app/services/spree/olitt/clone_store/clone_request_provisioner.rb


13. app/helpers/spree/olitt/clone_store/clone_store_helpers.rb ✨ Enhancement +1/-1

Source store ID resolution with default fallback

app/helpers/spree/olitt/clone_store/clone_store_helpers.rb


14. app/helpers/spree/olitt/clone_store/product_helpers.rb 🐞 Bug fix +1/-1

Fixed blank price assignment in variant duplication

app/helpers/spree/olitt/clone_store/product_helpers.rb


15. app/services/spree/olitt/clone_store/duplicators/shipping_categories_duplicator.rb ✨ Enhancement +1/-1

Changed to use global shipping categories query

app/services/spree/olitt/clone_store/duplicators/shipping_categories_duplicator.rb


16. app/services/spree/olitt/clone_store/duplicators/stock_locations_duplicator.rb ✨ Enhancement +2/-2

Changed to use global stock locations query

app/services/spree/olitt/clone_store/duplicators/stock_locations_duplicator.rb


17. config/routes.rb ⚙️ Configuration changes +13/-0

Added AI theme management routes and nested resources

config/routes.rb


18. spec/controllers/spree/api/v2/platform/clone_stores_controller_spec.rb 🧪 Tests +72/-0

Tests for clone store with vendor autologin details

spec/controllers/spree/api/v2/platform/clone_stores_controller_spec.rb


19. spec/controllers/spree/olitt/clone_store/clone_store_controller_spec.rb 🧪 Tests +7/-0

Tests for source store ID fallback to default

spec/controllers/spree/olitt/clone_store/clone_store_controller_spec.rb


20. spec/services/spree/olitt/clone_store/ai_theme/sync_spec.rb 🧪 Tests +253/-0

Comprehensive tests for AI theme synchronization

spec/services/spree/olitt/clone_store/ai_theme/sync_spec.rb


21. spec/services/spree/olitt/clone_store/clone_request_presenter_spec.rb 🧪 Tests +16/-1

Tests for vendor metadata in clone request response

spec/services/spree/olitt/clone_store/clone_request_presenter_spec.rb


22. spec/services/spree/olitt/clone_store/clone_request_provisioner_spec.rb 🧪 Tests +32/-0

Tests for admin user and vendor user provisioning

spec/services/spree/olitt/clone_store/clone_request_provisioner_spec.rb


23. spec/helpers/spree/olitt/clone_store/product_helpers_spec.rb 🧪 Tests +21/-0

Tests for blank price handling in variant assignment

spec/helpers/spree/olitt/clone_store/product_helpers_spec.rb


24. spec/services/spree/olitt/clone_store/duplicators/shipping_categories_duplicator_spec.rb 🧪 Tests +7/-1

Updated tests for global shipping categories query

spec/services/spree/olitt/clone_store/duplicators/shipping_categories_duplicator_spec.rb


25. spec/services/spree/olitt/clone_store/duplicators/stock_locations_duplicator_spec.rb 🧪 Tests +14/-6

Updated tests for global stock locations query

spec/services/spree/olitt/clone_store/duplicators/stock_locations_duplicator_spec.rb


Grey Divider

Qodo Logo

@willymwai

Copy link
Copy Markdown
Member

/agentic_describe

@willymwai

Copy link
Copy Markdown
Member

/agentic_review

@qodo-code-review

qodo-code-review Bot commented May 2, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Password exposed in response🐞 Bug ⛨ Security
Description
CloneRequestPresenter returns the vendor password in JSON and also embeds it into auto_login_url
query params, which can leak through logs, caches, and referers. This turns a long-lived credential
into a replayable URL and exposes secrets to any caller that can hit the clone-store platform
endpoint.
Code

app/services/spree/olitt/clone_store/clone_request_presenter.rb[R45-69]

+        def vendor_metadata
+          {
+            vendor_id: @clone_request.vendor_id,
+            vendor_slug: @clone_request.vendor&.slug,
+            admin_user_id: @clone_request.admin_user&.id,
+            email: @clone_request.vendor_email,
+            password: @clone_request.vendor_password,
+            auto_login_path: auto_login_path,
+            auto_login_url: auto_login_url,
+            next_path: admin_dashboard_path
+          }
+        end
+
+        def auto_login_path
+          '/admin/auto_login'
+        end
+
+        def admin_dashboard_path
+          '/admin'
+        end
+
+        def auto_login_url
+          query = Rack::Utils.build_query(email: @clone_request.vendor_email, password: @clone_request.vendor_password, next: admin_dashboard_path)
+          "#{auto_login_path}?#{query}"
+        end
Evidence
The presenter explicitly includes vendor_password in the API response payload and constructs
auto_login_url with password in the query string; the new controller spec asserts this behavior,
confirming it is intentionally exposed.

app/services/spree/olitt/clone_store/clone_request_presenter.rb[45-69]
spec/controllers/spree/api/v2/platform/clone_stores_controller_spec.rb[62-71]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The clone-store API currently returns vendor credentials (including plaintext password) and embeds the password in an auto-login URL query string. Query strings are commonly logged (Rails logs, reverse proxies, CDNs), cached, and can leak via Referer headers.

### Issue Context
This response is produced by `CloneRequestPresenter` and returned by the platform clone-store API.

### Fix Focus Areas
- app/services/spree/olitt/clone_store/clone_request_presenter.rb[45-69]
- spec/controllers/spree/api/v2/platform/clone_stores_controller_spec.rb[62-71]

### What to change
- Stop returning `vendor_password` in API responses.
- Stop placing secrets in URL query params.
- Replace with a short-lived, single-use auto-login token (server-generated) and return only that token (or a URL containing only that token). Ensure the token is scoped (vendor/admin user), expires quickly, and is rotated/invalidated after use.
- Update specs to assert the token-based behavior instead of password presence.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unsafe class resolution 🐞 Bug ⛨ Security
Description
AI theme sync resolves page/section/block classes from user-controlled class_name/type using
safe_constantize without enforcing an inheritance/allowlist. This allows authenticated callers to
instantiate arbitrary constants (and potentially hit unexpected code paths or cause errors/DoS) by
supplying crafted class names.
Code

app/services/spree/olitt/clone_store/ai_theme/sync.rb[R347-368]

+          def resolve_page_class(payload)
+            class_name = class_name_for(payload[:class_name] || payload[:type], PAGE_KIND_CLASS_MAP, Spree::Page)
+            class_name.safe_constantize || Spree::Page
+          end
+
+          def resolve_section_class(payload)
+            class_name = class_name_for(payload[:class_name] || payload[:type], {}, Spree::PageSection)
+            class_name.safe_constantize || Spree::PageSection
+          end
+
+          def resolve_block_class(payload)
+            class_name = class_name_for(payload[:class_name] || payload[:type], {}, Spree::PageBlock)
+            class_name.safe_constantize || Spree::PageBlock
+          end
+
+          def class_name_for(raw_value, mapping, default_class)
+            value = raw_value.to_s.strip
+            return default_class.name if value.blank?
+            return value if value.include?('::')
+
+            mapping.fetch(value, default_class.name)
+          end
Evidence
Controllers permit :class_name/:type from request parameters, and the sync service accepts
values containing :: verbatim and safe_constantizes them into classes. No check ensures the
resolved class is a subclass of the expected base (e.g., Spree::Page / Spree::PageSection /
Spree::PageBlock).

app/controllers/spree/api/v2/platform/ai/themes_controller.rb[62-85]
app/services/spree/olitt/clone_store/ai_theme/sync.rb[347-368]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
User-controlled `class_name`/`type` is converted into a Ruby constant via `safe_constantize` and used to create records. Without validation, callers can request arbitrary constants (especially any string containing `::`), leading to unexpected instantiation, crashes, or abuse.

### Issue Context
The API permits these fields and the sync service treats `"Foo::Bar"` as authoritative.

### Fix Focus Areas
- app/services/spree/olitt/clone_store/ai_theme/sync.rb[347-368]
- app/controllers/spree/api/v2/platform/ai/themes_controller.rb[62-85]

### What to change
- Enforce an allowlist of permitted classes for pages/sections/blocks (explicit mapping), or
- Enforce inheritance checks after constantization, e.g.:
 - page_klass <= Spree::Page
 - section_klass <= Spree::PageSection
 - block_klass <= Spree::PageBlock
 and fall back (or reject with 422) if invalid.
- Consider ignoring `class_name` entirely and using only `kind`/known `type` mapping.
- Add request specs to ensure invalid `class_name` is rejected (422) and does not instantiate arbitrary constants.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread app/services/spree/olitt/clone_store/clone_request_presenter.rb Outdated
Comment thread app/services/spree/olitt/clone_store/ai_theme/sync.rb Outdated
@willymwai willymwai merged commit 1415f48 into main May 4, 2026
3 checks passed
@willymwai willymwai deleted the feat/upgrade branch May 4, 2026 09:56
@kipsang01 kipsang01 restored the feat/upgrade branch May 5, 2026 09:19
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.

2 participants