diff --git a/.env.example b/.env.example index a8d8c7d..69ada3b 100644 --- a/.env.example +++ b/.env.example @@ -14,3 +14,8 @@ FTP_USER=your-ftp-username FTP_PASS=your-ftp-password # Remote directory to upload signed artifacts (e.g., /addons/archive-org-link-grabber/) FTP_REMOTE_DIR=/path/on/server + +# SFTP host verification (SFTP only; choose one) +# SFTP_KNOWN_HOSTS=/home/you/.ssh/known_hosts +# SFTP_HOST_PUBKEY_SHA256=base64sha256fingerprint +# SFTP_HOST_PUBKEY_MD5=aa:bb:cc:dd:... diff --git a/scripts/release-push.js b/scripts/release-push.js index 6f2214d..b04c209 100644 --- a/scripts/release-push.js +++ b/scripts/release-push.js @@ -9,6 +9,14 @@ * FTP_USER=username (required) * FTP_PASS=password (required) * FTP_REMOTE_DIR=/remote/path (required) + * + * SFTP notes: + * - SFTP requires host verification. Provide one of: + * SFTP_KNOWN_HOSTS=/path/to/known_hosts + * SFTP_HOST_PUBKEY_SHA256=base64_sha256_fingerprint + * SFTP_HOST_PUBKEY_MD5=aa:bb:cc:... (legacy) + * If not provided and no default known_hosts is found, curl will fail with + * "Couldn't find a known_hosts file". */ const fs = require('fs'); const path = require('path'); @@ -91,6 +99,11 @@ const user = process.env.FTP_USER; const pass = process.env.FTP_PASS; let remoteDir = process.env.FTP_REMOTE_DIR || '/'; +// SFTP host verification options (optional) +const sftpKnownHosts = process.env.SFTP_KNOWN_HOSTS || process.env.FTP_SSH_KNOWN_HOSTS; +const sftpHostPubSha256 = process.env.SFTP_HOST_PUBKEY_SHA256 || process.env.FTP_SSH_HOST_PUBKEY_SHA256; +const sftpHostPubMd5 = process.env.SFTP_HOST_PUBKEY_MD5 || process.env.FTP_SSH_HOST_PUBKEY_MD5; + if (!host || !user || !pass || !remoteDir) { console.error('Missing FTP config. Required: FTP_HOST, FTP_USER, FTP_PASS, FTP_REMOTE_DIR'); process.exit(1); @@ -100,9 +113,23 @@ if (!host || !user || !pass || !remoteDir) { if (!remoteDir.startsWith('/')) remoteDir = '/' + remoteDir; if (remoteDir.endsWith('/')) remoteDir = remoteDir.slice(0, -1); -// Construct base URL for FTP upload target +// Construct base URL for FTP/SFTP upload target const baseUrl = `${protocol}://${host}${port ? `:${port}` : ''}${remoteDir}`; +// Prepare common curl flags +const curlBase = ['curl', '--fail', '--ftp-create-dirs']; +if (protocol === 'sftp') { + if (sftpKnownHosts) { + curlBase.push('--knownhosts', JSON.stringify(sftpKnownHosts)); + } else if (sftpHostPubSha256) { + curlBase.push('--hostpubsha256', JSON.stringify(sftpHostPubSha256)); + } else if (sftpHostPubMd5) { + curlBase.push('--hostpubmd5', JSON.stringify(sftpHostPubMd5)); + } else { + console.warn('SFTP: no known_hosts or host public key provided; relying on default known_hosts.'); + } +} + // Prepare or update self-hosted updates.json before upload function ensureUpdatesJson() { try { @@ -164,9 +191,7 @@ for (const file of files) { const url = `${baseUrl}/${encodeURIComponent(file)}`; // --ftp-create-dirs ensures remote dirs are created; --fail fails on server errors. const cmd = [ - 'curl', - '--fail', - '--ftp-create-dirs', + ...curlBase, `--user`, `${user}:${pass}`, '--upload-file', JSON.stringify(localPath), JSON.stringify(url), @@ -181,9 +206,7 @@ try { const latestUrl = `${baseUrl}/${latestAlias}`; console.log(`Uploading latest alias ${latestAlias} -> ${chosenXpi}`); const latestCmd = [ - 'curl', - '--fail', - '--ftp-create-dirs', + ...curlBase, `--user`, `${user}:${pass}`, '--upload-file', JSON.stringify(localLatestSrc), JSON.stringify(latestUrl), @@ -199,9 +222,7 @@ if (fs.existsSync(updatesPath)) { const updatesUrl = `${baseUrl}/updates.json`; console.log(`Uploading updates.json to ${updatesUrl}`); const cmd = [ - 'curl', - '--fail', - '--ftp-create-dirs', + ...curlBase, `--user`, `${user}:${pass}`, '--upload-file', JSON.stringify(updatesPath), JSON.stringify(updatesUrl),