Skip to content
Back to skills

Fluentcart Downloads Storage

ASecurity

Implements and audits FluentCart downloadable products, entitlement checks, signed delivery URLs, download limits/expiry logs, Local/S3 storage, custom storage drivers, and Pro R2 behavior. Use when working with ProductDownload, OrderDownloadPermission, generateDownloadFileLink(), FileDownloader, fluent_cart/product_download/can_be_downloaded, fluent_cart/register_storage_drivers, customer download pages, subscription- gated files, private object storage, or preventing raw file-path disclosure.

  • 22 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 5, 2026
ai-agentsphp

Works with

  • cli

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 5, 2026

npx -y skills add Lonsdale201/wp-agent-skills --skill fluentcart-downloads-storage --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fluentcart Downloads Storage?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fluentcart Downloads Storage
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lonsdale201-fluentcart-downloads-storage/badge)](https://www.skillsdirectory.com/skills/lonsdale201-fluentcart-downloads-storage)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: fluentcart-downloads-storage
description: >-
  Implements and audits FluentCart downloadable products, entitlement checks,
  signed delivery URLs, download limits/expiry logs, Local/S3 storage, custom
  storage drivers, and Pro R2 behavior. Use when working with ProductDownload,
  OrderDownloadPermission, generateDownloadFileLink(), FileDownloader,
  fluent_cart/product_download/can_be_downloaded,
  fluent_cart/register_storage_drivers, customer download pages, subscription-
  gated files, private object storage, or preventing raw file-path disclosure.
metadata:
  wp-skills-author: "Soczó Kristóf"
  wp-skills-contact: "mailto:lonsdale201@hotmail.com"
  wp-skills-plugin: "fluent-cart"
  wp-skills-plugin-version-tested: "1.6.0"
  wp-skills-wp-version-tested: "7.0.2"
  wp-skills-php-min: "7.4"
  wp-skills-last-updated: "2026-08-06"
---

# FluentCart downloads and storage

Separate file metadata, commercial entitlement, signed delivery, and download
accounting. Possession of a path, download ID, or signed URL must not create a
new entitlement.

Read [download-delivery.md](references/download-delivery.md) before generating
links, changing access rules, or implementing a driver.

## Preserve the delivery chain

Use ProductDownload records to map product/variation availability to driver
metadata. Use Order::getDownloads() or the customer-profile flow to obtain
entitled files. Generate delivery links with
Helper::generateDownloadFileLink($download, $orderId).

For customer delivery always include the qualifying order ID. The helper signs
download_identifier, valid_till, and order_id. FileDownloader then validates
signature/time, successful payment, a matching product post on one supplied
order, subscription access validity, and the final can_be_downloaded filter
before dispatching to the storage driver.

Do not:

- expose Local file paths, S3/R2 keys, bucket names, or raw file_url values;
- build signed query strings manually;
- use the admin preview's order-less link as a customer entitlement link;
- cache signed URLs beyond their validity;
- assume a successful order grants every variation's files.

## Do not assume the active route enforces limits or login

The customer-profile listing is login/customer scoped before it generates the
URL. The resulting 1.6.0 signed URL is bearer authorization: FileDownloader
does not re-check the current WP user and does not enforce the configured
download_limit/download_expiry or update fct_order_download_permissions.

CustomerHelper contains limit/expiry/accounting code and DownloadService
registers a fluent_cart/before_download_check_permission_and_store_log
listener, but the active FileDownloader path does not emit that action in the
tested source. Treat OrderDownloadPermission accounting as unwired for this
route until a runtime test proves otherwise.

If the addon promises download limits, a customer-bound link, or single-use
delivery, implement an addon-owned atomic claim before issuing/streaming the
file and then delegate to the storage layer. Protect concurrent clicks and do
not increment a count merely for rendering a link. Re-audit core after upgrade
so enforcement is not accidentally duplicated.

Use fluent_cart/product_download/can_be_downloaded only to further constrain or
explicitly extend a verified order context. Inspect orders and download from the
payload; never return true for an unbound public identifier.

## Extend storage drivers

Extend BaseStorageDriver, provide a settings class/fields, hiddenSettingKeys,
driver implementation, connection verification, signed URL/download behavior,
and bucket support if required. Attach the registration listener by
fluentcart_loaded and call the driver instance's init() during
fluent_cart/register_storage_drivers. The action runs on init priority 9, before
fluent_cart/init, so registering its listener from fluent_cart/init is too late.

- Keep credentials in hidden settings and exclude them from REST/UI responses.
- Sanitize settings and verify connectivity without leaking provider errors.
- Enforce least-privilege bucket policy and private objects.
- Set a short provider URL expiry and validate filenames/content disposition.
- Prevent path traversal and cross-bucket/object access.
- Make upload/delete idempotent and distinguish missing from unauthorized.

Free 1.6.0 ships Local and S3. Cloudflare R2 is a Pro driver; Free only exposes a
promo descriptor.

## Subscription and license gates

Subscription downloads depend on Subscription::hasAccessValidity(), not merely
the existence of a subscription row. Pro licensing also filters downloads when
license validity applies. Compose restrictions; do not replace another module's
false decision with true unless the addon deliberately owns that entitlement.

## Test matrix

Test paid/unpaid/refunded order, signed-link reuse without login, wrong product/
variation, expired signature, tampered query, the source-confirmed absence or
presence of core limit/expiry accounting, addon limit concurrency, active/
expired subscription, valid/expired Pro license, missing object, disabled/
misconfigured driver, filename injection, and cached URL after expiry.

## Cross-references

- Use fluentcart-products-inventory for file-to-variation assignment.
- Use fluentcart-subscriptions-renewals for access validity.
- Use fluentcart-licensing-pro for licensed software delivery.

## References

- Verified Free source paths:
  - fluent-cart/app/Models/ProductDownload.php
  - fluent-cart/app/Models/OrderDownloadPermission.php
  - fluent-cart/app/Models/Order.php
  - fluent-cart/app/Http/Controllers/WebController/FileDownloader.php
  - fluent-cart/app/Services/FileSystem/DownloadService.php
  - fluent-cart/app/Helpers/Helper.php
  - fluent-cart/app/Helpers/CustomerHelper.php
  - fluent-cart/app/Hooks/Handlers/GlobalStorageHandler.php
  - fluent-cart/app/Modules/StorageDrivers/
- Verified Pro source path:
  - fluent-cart-pro/app/Modules/StorageDrivers/R2/

Files in this skill

  • SKILL.md5.8 KB
  • agents/openai.yaml305 B
  • references/download-delivery.md2.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…