feat: SFTP key file upload, auth type dropdown, security hardening #96

Merged
jmiller merged 2 commits from fix/sftp-key-upload into main 2026-06-23 13:53:04 +00:00
Owner

Summary

Key File Upload

  • Custom SshKeyField with file upload button (uses FileReader API)
  • Key is base64-encoded in JS before storing in hidden field
  • Key content is NEVER rendered as visible text in the form
  • __KEEP_EXISTING__ sentinel preserves DB value on re-save
  • ProfileTable::store() handles sentinel to prevent key leakage

Auth Type Dropdown

  • Three options: Password / Key File / Key File + Passphrase
  • Conditional field visibility via nested showon attributes
  • Required markers on host, username, path, password fields

Security

  • FTP option removed from remote storage dropdown (insecure)
  • Private key stored base64-encoded in database
  • SftpUploader decodes base64 before writing temp file (0600)
  • Key never exposed in HTML, API responses, or form output

Test Plan

  • Select SFTP → auth type dropdown appears
  • Select Key File → upload button + key field shown, password hidden
  • Select Password → password field shown, key fields hidden
  • Upload a key file → status shows filename, save profile, key persists
  • Re-open profile → key shows "loaded" badge, not raw content
  • Save without re-uploading → key preserved (sentinel)
## Summary ### Key File Upload - Custom `SshKeyField` with file upload button (uses FileReader API) - Key is base64-encoded in JS before storing in hidden field - Key content is NEVER rendered as visible text in the form - `__KEEP_EXISTING__` sentinel preserves DB value on re-save - ProfileTable::store() handles sentinel to prevent key leakage ### Auth Type Dropdown - Three options: Password / Key File / Key File + Passphrase - Conditional field visibility via nested `showon` attributes - Required markers on host, username, path, password fields ### Security - FTP option removed from remote storage dropdown (insecure) - Private key stored base64-encoded in database - SftpUploader decodes base64 before writing temp file (0600) - Key never exposed in HTML, API responses, or form output ## Test Plan - [ ] Select SFTP → auth type dropdown appears - [ ] Select Key File → upload button + key field shown, password hidden - [ ] Select Password → password field shown, key fields hidden - [ ] Upload a key file → status shows filename, save profile, key persists - [ ] Re-open profile → key shows "loaded" badge, not raw content - [ ] Save without re-uploading → key preserved (sentinel)
jmiller added the component: enginecomponent: remote labels 2026-06-23 13:52:07 +00:00
jmiller added 1 commit 2026-06-23 13:52:08 +00:00
feat: SFTP key file upload, auth type dropdown, security hardening
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 23s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Universal: PR Check / Secret Scan (pull_request) Successful in 9s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 13s
Universal: Build & Release / Promote to RC (pull_request) Failing after 11s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 34s
d6b3e8cff0
SFTP UX improvements:
- SshKeyField: file upload button (FileReader → base64 → hidden field),
  key never displayed as readable text, __KEEP_EXISTING__ sentinel
  preserves DB value on re-save without re-uploading
- Auth type dropdown: password / key file / key file + passphrase
  with conditional field visibility via showon
- Required field markers on host, username, path, password
- Remove insecure FTP option from remote storage dropdown

Security:
- Private key stored base64-encoded in database
- SftpUploader decodes base64 before writing temp file
- ProfileTable::store() handles sentinel to prevent key leakage
- Key content never rendered in HTML form output
jmiller added 1 commit 2026-06-23 13:52:14 +00:00
chore(version): pre-release bump to 01.35.03-dev [skip ci]
Publish to Composer / Publish Package (release) Failing after 7s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 3s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 20s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 2m33s
e329dbd99b
jmiller merged commit 7826c315b1 into main 2026-06-23 13:53:04 +00:00
jmiller deleted branch fix/sftp-key-upload 2026-06-23 13:53:07 +00:00
Sign in to join this conversation.
No Reviewers
Priority -
Type -
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoSuiteBackup#96