Files uploaded through the ClientPress Files tab and Deliverables tab are stored in protected directories that cannot be accessed directly via URL. This ensures only authorized portal members can download files.
Where Files Are Stored #
Files are stored in separate protected directories within your WordPress uploads folder:
- Files tab uploads —
/wp-content/uploads/cp-private/{portal_id}/ - Deliverables tab uploads —
/wp-content/uploads/cp-deliverables/{portal_id}/
Each portal gets its own subdirectory identified by its post ID.
How Direct Access Is Blocked #
Each protected directory contains two security files created automatically by ClientPress:
.htaccess— ContainsDeny from all, which blocks all direct HTTP requests to files in the directory on Apache serversindex.php— A blank PHP file that prevents directory listing if.htaccessis not enforced
This means that even if someone knows the exact file path, navigating directly to yoursite.com/wp-content/uploads/cp-private/42/contract.pdf will return a 403 Forbidden error.
How Files Are Served #
When a portal member downloads a file, the request goes through a WordPress rewrite rule rather than directly to the file:
- Files tab: Requests to
yoursite.com/cp-file/{portal_id}/{filename}are intercepted by WordPress - Deliverables tab: Requests to
yoursite.com/cp-deliverable/{portal_id}/{filename}are intercepted by WordPress
Before serving any file, ClientPress runs the following checks:
- Is the user logged in? If not, they are redirected to the login page
- Does the user have access to this portal? If not, they receive a 403 error
- Does the file exist? If not, they receive a 404 error
Only after passing all checks does ClientPress serve the file, with appropriate headers (Content-Type, Content-Disposition, Content-Length).
Nginx Servers #
The .htaccess file only works on Apache. If your server runs Nginx, you will need to add equivalent rules to your Nginx configuration to block direct access to the cp-private and cp-deliverables directories. Contact your hosting provider for assistance if needed.
Cloud File Offloading #
ClientPress integrates with Advanced Media Offloader (AMO) for sites that store uploads in cloud storage (Amazon S3, Cloudflare R2, DigitalOcean Spaces, etc.).
When AMO is active:
- Files are uploaded to your server first
- ClientPress passes the file to AMO, which uploads it to your cloud bucket
- The local copy is deleted from your server
- The file’s cloud storage key is saved in the portal’s metadata
When a portal member downloads the file, ClientPress:
- Retrieves the file from cloud storage on the server side
- Streams it directly to the user’s browser
- Deletes the temporary local copy immediately after
The cloud bucket does not need to be publicly accessible. Files are never served directly from the cloud URL — they always pass through the same access-control checks as locally stored files.
