- Display user email in top right of header bar - Update header layout with flexbox - Show email in yellow (#FFC407) color - Always visible regardless of SSO mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|---|---|---|
| css | ||
| js | ||
| .gitignore | ||
| AuthMiddleware.php | ||
| BoxService.php | ||
| composer.json | ||
| config.php | ||
| date-form.html | ||
| index.php | ||
| README.md | ||
| submit.php | ||
| validate-box.php | ||
L'Oréal Box Asset Submission Form
A PHP web application for submitting Box asset information with real-time validation, SSO authentication, and webhook integration.
Features
- Box API Integration: Real-time validation and preview of Box folders
- SSO Authentication: Microsoft Azure AD SSO with local development mode
- Auto-population: Master Campaign Number automatically retrieved from Box folder hierarchy
- Real-time Preview: Display folder contents before submission
- Webhook Integration: Submit data to Make.com webhook with response handling
- Responsive Design: Modern UI with Montserrat font and L'Oréal brand colors
Requirements
- PHP 7.4 or higher
- Composer
- Box JWT credentials
- Web server (Apache/Nginx) or MAMP for local development
Installation
1. Install Dependencies
composer install
2. Configuration
The application uses config.php for all configuration:
Local Development Mode (Default)
'sso' => [
'enabled' => false, // Local mode
'local_user' => [
'name' => 'Dave Porter',
'email' => 'daveporter@oliver.agency'
]
]
Production Mode with SSO
'sso' => [
'enabled' => true, // Enable SSO
'tenant_id' => 'your-azure-tenant-id',
'client_id' => 'your-azure-client-id'
]
3. Box JWT Configuration
The Box JWT configuration file (43984435_77m2ujl3_config.json) must be present in the root directory. This file is already configured and should not be committed to version control (it's in .gitignore).
4. Webhook Configuration
The webhook is pre-configured in config.php:
'webhook' => [
'url' => 'https://hook.us1.make.celonis.com/ddxrhuykysnbxqvb25uxsg0pjngqytiv',
'api_key' => 'E4P9923eBaUTKrEr.iqvHtVHcZ6L!WH'
]
Project Structure
Loreal-master-Entry/
├── config.php # Application configuration
├── AuthMiddleware.php # SSO authentication handler
├── BoxService.php # Box API integration
├── index.php # Main form page
├── validate-box.php # AJAX endpoint for Box validation
├── submit.php # Form submission handler
├── css/
│ └── styles.css # Application styles
├── js/
│ └── app.js # Frontend JavaScript
├── vendor/ # Composer dependencies
└── 43984435_77m2ujl3_config.json # Box JWT config (not in git)
Usage
Local Development (MAMP)
- Place the project in your MAMP
htdocsdirectory - Ensure
config.phphas'enabled' => falsefor SSO - Access via
http://localhost:8888/Loreal-master-Entry/
Production Deployment
- Upload to Apache server
- Update
config.php:- Set
'enabled' => truefor SSO - Add Azure tenant and client IDs
- Set
'debug' => false
- Set
- Ensure
.htaccessis configured if needed - Verify Box JWT config file is present
How It Works
1. User Authentication
- Local Mode: Automatically logs in as configured local user
- SSO Mode: Redirects to Microsoft login, validates JWT token
2. Box ID Validation
When a user enters a Box ID:
- Frontend debounces input (800ms delay)
- AJAX call to
validate-box.php - Backend:
- Authenticates with Box using JWT
- Validates folder exists
- Retrieves folder two levels up (Master Campaign)
- Lists all folder contents
- Frontend displays preview in right column
3. Form Submission
When the form is submitted:
- Validates all required fields
- Formats dates to
DD/MM/YYYY 00:00 - Sends to
submit.phpwith:- User email
- Box ID
- Master Campaign Number (auto-populated)
- Master Campaign ID (auto-populated)
- Three dates
- Box contents list
submit.phpforwards to webhook- Displays webhook response to user
API Endpoints
validate-box.php
Method: POST Content-Type: application/json
Request:
{
"boxId": "123456789"
}
Response (Success):
{
"success": true,
"data": {
"boxId": "123456789",
"folderName": "Asset Folder",
"masterCampaignNumber": "Campaign Name",
"masterCampaignId": "987654321",
"contents": {
"total": 15,
"folders": [...],
"files": [...]
}
}
}
submit.php
Method: POST Content-Type: application/json
Request:
{
"boxId": "123456789",
"supplyDate": "24/03/2025 00:00",
"liveDate": "31/03/2025 00:00",
"endDate": "07/04/2025 00:00",
"boxData": {
"masterCampaignNumber": "Campaign Name",
"masterCampaignId": "987654321",
"contents": {...}
}
}
Response:
{
"success": true,
"message": "Submission successful",
"webhookResponse": {...},
"webhookStatus": 200
}
Security Features
- httpOnly Cookies: Authentication tokens stored securely
- JWT Validation: Box API uses signed JWT for authentication
- Input Sanitization: All user inputs are validated and escaped
- CSRF Protection: SameSite cookie attribute
- XSS Prevention: HTML escaping in frontend
- Sensitive Data: JWT config excluded from version control
Troubleshooting
Box Authentication Fails
- Verify
43984435_77m2ujl3_config.jsonis present - Check private key passphrase is correct
- Ensure Box app has proper permissions
SSO Not Working
- Verify Azure tenant and client IDs
- Check redirect URI matches your domain
- Ensure HTTPS is enabled in production
Webhook Fails
- Check webhook URL is accessible
- Verify API key is correct
- Check webhook timeout setting (default 30s)
Development
Testing Locally
Set SSO to disabled in config.php for instant local access without Azure AD setup.
Debugging
Enable debug mode in config.php:
'app' => [
'debug' => true // Shows detailed error messages
]
Note: Disable in production!
Author
Dave Porter (daveporter@oliver.agency)
Repository
https://bitbucket.org/zlalani/loreal-global-kickoff
License
Proprietary - L'Oréal/Oliver Agency