451-tools
Version:
Censorship resilient and distributed publishing: informed by the needs of publishers and their audiences, More Mirrors implements a set of offline fallback strategies for censorship resilient websites.
89 lines (80 loc) • 2.52 kB
JavaScript
import fs from 'fs';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import {
generateKeyPair,
generateSignedLink,
saveKeyToFile
} from './src/lib/crypto.js';
yargs(hideBin(process.argv))
.scriptName('451-tools')
.command(
'generate-keys',
'Generate an ECDSA key pair and save the private key',
{},
async () => {
try {
const { publicKey, privateKey } = await generateKeyPair();
await saveKeyToFile('privateKey.pem', privateKey, { mode: 0o600 });
console.log('Private key saved to privateKey.pem');
console.log('Public Key (Base64):');
console.log(publicKey);
} catch (error) {
console.error(`An error occurred: ${error.message}`);
}
}
)
.command(
'generate-mirror-link',
'Generate a sharable signed link for adding a mirror',
(yargs) => {
return yargs
.positional('baseUrl', {
describe: 'The base URL to which the parameters and their signature will be appended',
type: 'string',
demandOption: true,
})
.option('privateKeyPath', {
alias: 'pk',
type: 'string',
default: 'privateKey.pem',
describe: 'Path to the private key file',
})
.option('params', {
alias: 'p',
type: 'array',
describe: 'Key-value pairs for the parameters (e.g., --params url=https://mirror.com)',
demandOption: true,
});
},
async ({ _, privateKeyPath, params }) => {
try {
const privateKey = fs.readFileSync(privateKeyPath, 'utf-8');
const parsedParams = params.reduce((acc, pair) => {
const [key, value] = pair.split('=');
if (!key || !value) {
throw new Error(`Invalid parameter format: ${pair}. Use key=value.`);
}
acc[key] = value;
return acc;
}, {});
if (!parsedParams.url) {
throw new Error('The "params" must include a "url" property pointing to the mirror.');
}
const url = new URL('/451-tools/add-mirror/', _[1]);
const signedLink = await generateSignedLink(
url,
parsedParams,
privateKey
);
console.log('Signed Link:');
console.log(signedLink);
} catch (error) {
console.error(`An error occurred: ${error.message}`);
}
}
)
.demandCommand(1, 'You need to specify a command')
.help()
.parse();