Skip to main content

Upload Token System

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_file owns 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_count records cumulative finalized files for administrative information only.
  • uses_allowed = 0 is 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

Proven working: Single-file Drupal 11 core managed_file AJAX works on the Pixel, including temporary upload, final submission, permanent file status, success redirect, and reusable token behavior.

Proven upstream capacity: PHP permits 512 MiB uploads and posts, the production HTTP stack accepted a 500 MiB body, real multipart requests totaling approximately 235 MiB succeeded, and a slow multipart upload exceeding one minute succeeded.

Proven multi-file observation: Simultaneous three-file managed_file processing fails even on the pristine Drupal control. The attempted Skyhawk serializer then intercepted the original multi-file change event but substituted synthetic change/click behavior that does not match Drupal 11.4.5 core file.js.

Current boundary: Drupal 11.4.5 core binds change.autoFileUpload and Drupal.file.triggerUploadButton hands the existing managed-file input to its AJAX upload button through the core mousedown event. The next implementation must serialize the browser FileList while preserving this exact core handoff. No custom upload endpoint, synthetic click cycle, synthetic change cycle, or MutationObserver transaction engine is authorized.

Closed branches: token validity, single-file browser selection, server request size, multipart parsing, slow-client timing, token route, final redirect, and reusable-token behavior remain closed unless contradictory evidence appears.

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.