chore(release): SFTP host verification support (known_hosts or hostpub fingerprint)
This commit is contained in:
parent
4516f9f2a9
commit
a3d0c380ee
2 changed files with 36 additions and 10 deletions
|
|
@ -14,3 +14,8 @@ FTP_USER=your-ftp-username
|
||||||
FTP_PASS=your-ftp-password
|
FTP_PASS=your-ftp-password
|
||||||
# Remote directory to upload signed artifacts (e.g., /addons/archive-org-link-grabber/)
|
# Remote directory to upload signed artifacts (e.g., /addons/archive-org-link-grabber/)
|
||||||
FTP_REMOTE_DIR=/path/on/server
|
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:...
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,14 @@
|
||||||
* FTP_USER=username (required)
|
* FTP_USER=username (required)
|
||||||
* FTP_PASS=password (required)
|
* FTP_PASS=password (required)
|
||||||
* FTP_REMOTE_DIR=/remote/path (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 fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
@ -91,6 +99,11 @@ const user = process.env.FTP_USER;
|
||||||
const pass = process.env.FTP_PASS;
|
const pass = process.env.FTP_PASS;
|
||||||
let remoteDir = process.env.FTP_REMOTE_DIR || '/';
|
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) {
|
if (!host || !user || !pass || !remoteDir) {
|
||||||
console.error('Missing FTP config. Required: FTP_HOST, FTP_USER, FTP_PASS, FTP_REMOTE_DIR');
|
console.error('Missing FTP config. Required: FTP_HOST, FTP_USER, FTP_PASS, FTP_REMOTE_DIR');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
@ -100,9 +113,23 @@ if (!host || !user || !pass || !remoteDir) {
|
||||||
if (!remoteDir.startsWith('/')) remoteDir = '/' + remoteDir;
|
if (!remoteDir.startsWith('/')) remoteDir = '/' + remoteDir;
|
||||||
if (remoteDir.endsWith('/')) remoteDir = remoteDir.slice(0, -1);
|
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}`;
|
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
|
// Prepare or update self-hosted updates.json before upload
|
||||||
function ensureUpdatesJson() {
|
function ensureUpdatesJson() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -164,9 +191,7 @@ for (const file of files) {
|
||||||
const url = `${baseUrl}/${encodeURIComponent(file)}`;
|
const url = `${baseUrl}/${encodeURIComponent(file)}`;
|
||||||
// --ftp-create-dirs ensures remote dirs are created; --fail fails on server errors.
|
// --ftp-create-dirs ensures remote dirs are created; --fail fails on server errors.
|
||||||
const cmd = [
|
const cmd = [
|
||||||
'curl',
|
...curlBase,
|
||||||
'--fail',
|
|
||||||
'--ftp-create-dirs',
|
|
||||||
`--user`, `${user}:${pass}`,
|
`--user`, `${user}:${pass}`,
|
||||||
'--upload-file', JSON.stringify(localPath),
|
'--upload-file', JSON.stringify(localPath),
|
||||||
JSON.stringify(url),
|
JSON.stringify(url),
|
||||||
|
|
@ -181,9 +206,7 @@ try {
|
||||||
const latestUrl = `${baseUrl}/${latestAlias}`;
|
const latestUrl = `${baseUrl}/${latestAlias}`;
|
||||||
console.log(`Uploading latest alias ${latestAlias} -> ${chosenXpi}`);
|
console.log(`Uploading latest alias ${latestAlias} -> ${chosenXpi}`);
|
||||||
const latestCmd = [
|
const latestCmd = [
|
||||||
'curl',
|
...curlBase,
|
||||||
'--fail',
|
|
||||||
'--ftp-create-dirs',
|
|
||||||
`--user`, `${user}:${pass}`,
|
`--user`, `${user}:${pass}`,
|
||||||
'--upload-file', JSON.stringify(localLatestSrc),
|
'--upload-file', JSON.stringify(localLatestSrc),
|
||||||
JSON.stringify(latestUrl),
|
JSON.stringify(latestUrl),
|
||||||
|
|
@ -199,9 +222,7 @@ if (fs.existsSync(updatesPath)) {
|
||||||
const updatesUrl = `${baseUrl}/updates.json`;
|
const updatesUrl = `${baseUrl}/updates.json`;
|
||||||
console.log(`Uploading updates.json to ${updatesUrl}`);
|
console.log(`Uploading updates.json to ${updatesUrl}`);
|
||||||
const cmd = [
|
const cmd = [
|
||||||
'curl',
|
...curlBase,
|
||||||
'--fail',
|
|
||||||
'--ftp-create-dirs',
|
|
||||||
`--user`, `${user}:${pass}`,
|
`--user`, `${user}:${pass}`,
|
||||||
'--upload-file', JSON.stringify(updatesPath),
|
'--upload-file', JSON.stringify(updatesPath),
|
||||||
JSON.stringify(updatesUrl),
|
JSON.stringify(updatesUrl),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue