Upload Token System
Upload Token System
This is the authoritative reference for the generic public upload-token product implemented in skyhawk_site_fixes.
Architecture
- Public route:
/upload/{token}. - Admin route:
/admin/skyhawk/upload-tokens. - The public route is owned by
UploadTokenForm. - Drupal core
managed_fileowns file selection, AJAX transfer, validation, and temporary file entities. - Files are stored under
private://uploads/[token]/. - No custom synthetic mouse event or parallel direct-upload controller participates in the live product.
Token Lifecycle
- A token is valid when it exists, has status
active, and has not expired. - Generated tokens have a minimum lifetime of seven days.
- A token may be used for multiple upload sessions until expiry or explicit administrative revocation.
- A successful upload does not consume or invalidate the token.
uses_countrecords cumulative finalized files for administrative information only.uses_allowed = 0is retained as the unlimited-until-expiry/revocation sentinel for schema compatibility.
Upload Rules
- Multiple files may be selected.
- Maximum individual file size is 511 MiB (535,822,336 bytes).
- The hosting transport ceiling remains 512 MiB for an HTTP POST, so exceptionally large batches may need to be selected/uploaded separately even though each individual file is legal.
- After Drupal receives temporary managed files, final submission makes them permanent, records each file in
skyhawk_upload_file, increments cumulative file accounting, and sends the configured batch notification. - Completion notifications contain only the files finalized in that batch, not every historical file associated with the token.
Administration
- The admin form creates reusable tokens and sends the upload URL by email.
- The admin form can explicitly revoke an active token.
- Existing contact and purpose data are reused.
- The current history table remains operational; conversion to a Drupal View is a later Views-first improvement, not part of the uploader replacement.
Replacement State
The public and admin upload forms were replaced in toto after a discovery audit found contradictory one-use lifecycle logic, a redundant unrouted direct-upload controller, and a custom mobile workaround that duplicated Drupal core behavior.
The old UploadTokenController and upload_token_mobile_fix.js are retired into the timestamped replacement backup rather than destroyed during initial acceptance testing.
Functional acceptance remains pending until the Pixel test verifies: legal multi-file upload, final submission, private storage, history rows, notification, reuse of the same token, explicit revocation, expiry rejection, and oversize rejection.
Current Functional Failure
Product requirement: This remains a generic public upload-token product. File format is not a product restriction. Multiple files may be selected, and the product-level content restriction is the documented maximum individual file size of 511 MiB, subject to the hosting transport ceiling for the complete HTTP POST.
Proven working: Drupal 11.4.5 core managed_file renders and performs AJAX uploads on the public token route. Ordinary PNG and JPG files upload successfully, including multiple accepted files selected together. Single-file upload, reusable-token behavior, final submission, HTTP body capacity, multipart capacity, and slow-client timing have previously been proven and remain closed absent contradictory evidence.
Superseded diagnosis: The earlier three-file failure was not evidence that Drupal could not handle multiple files. The failing test set contained file formats rejected elsewhere in the upload path. Three accepted image files subsequently uploaded together through the pristine Drupal core managed_file control. The custom serializer/queue path is therefore not the product architecture and must not be used to explain or repair arbitrary-content acceptance.
Extension-filter evidence: Drupal core normally supplies a restrictive default FileExtension list when no explicit extension configuration is provided. The product was also temporarily tested with an explicit format allowlist. Both approaches conflict with the generic-upload requirement. Drupal 11.4.5 source proves that FileExtension configured without an extensions member means extension validation is removed. The live product has been moved toward that unrestricted Drupal-native configuration. PNG and JPG still upload, while arbitrary non-image content tested from the device has not yet achieved functional acceptance. Therefore extension-name enumeration is not an acceptable continuing diagnostic or product strategy.
Current evidence boundary: Basic Drupal managed_file transfer works, and extension filtering is no longer a sufficient explanation for the remaining failure. The next investigation must be format-blind and must identify what restriction remains between an arbitrary browser-selected byte stream and creation of its Drupal temporary managed-file entity. Do not isolate MP4, 3GP, ZIP, image, document, archive, or any other individual format as a product category. A failed arbitrary-content test must be investigated at the first unproven generic upload transition.
Architecture guard: Drupal core managed_file continues to own file selection, AJAX transfer, validation, and temporary file entities. No custom synthetic mouse event, serializer, browser-specific queue, MIME taxonomy, extension shotgun, or parallel direct-upload controller belongs in the accepted product unless future evidence proves Drupal core cannot meet a documented requirement.
Current Regression Token
Chatgpt 4 remains the regression token while it is active and unexpired. Do not generate another token merely because an upload test fails.