1
0
mirror of https://github.com/hack-chat/main.git synced 2024-03-22 13:20:33 +08:00
hack-chat-main/scripts/config.js
2022-08-11 09:40:43 -05:00

194 lines
4.3 KiB
JavaScript

/* eslint-disable no-await-in-loop */
/* eslint import/no-unresolved: 0 */
import fs from 'fs';
import { Low, JSONFile } from 'lowdb';
import crypto from 'crypto';
import enquirerPkg from 'enquirer';
const {
Select,
Confirm,
Password,
Input,
} = enquirerPkg;
// required file paths
const SessionLocation = './session.key';
const SaltLocation = './salt.key';
const AppConfigLocation = './config.json';
const TripLength = 10;
// default configuration options
const defaultConfig = {
adminTrip: '',
globalMods: [],
publicChannels: [],
permissions: [],
};
// standard / default channel list
const defaultChannels = [
'lounge',
'meta',
'math',
'physics',
'chemistry',
'technology',
'programming',
'games',
'banana',
];
// load the configuration data
const adapter = new JSONFile(AppConfigLocation);
const config = new Low(adapter);
// check for missing cert, generate if needed
const checkCert = async () => {
if (fs.existsSync(SessionLocation) === false) {
const prompt = new Confirm({
name: 'certDialogue',
message: 'Missing session key, create new?',
});
if (await prompt.run() !== false) {
const data = crypto.randomBytes(4096);
fs.writeFile(SessionLocation, data, (err) => {
if (err) throw err;
});
}
} else {
console.log('Found existing session key.');
}
};
// check for missing or uninitialized config
const checkConfig = async () => {
await config.read();
if (config.data === null) {
config.data = defaultConfig;
await config.write();
}
};
// check for missing or uninitialized salt
const checkTripSalt = async () => {
if (fs.existsSync(SaltLocation) === false) {
const prompt = new Confirm({
name: 'overwrite',
message: 'Missing trip salt, create new?',
});
if (await prompt.run() !== false) {
const data = crypto.randomBytes(4096);
fs.writeFileSync(SaltLocation, data);
}
} else {
console.log('Found existing trip salt.');
}
};
// verify config has an admin account
const checkPermissions = async () => {
if (typeof config.data.adminTrip === 'undefined' || config.data.adminTrip === '') {
const salt = fs.readFileSync(SaltLocation);
const prompt = new Password({
name: 'adminPassword',
message: 'What is your admin password?',
});
const password = await prompt.run();
const sha = crypto.createHash('sha256');
sha.update(password + salt);
config.data.adminTrip = sha.digest('base64').substr(0, TripLength);
await config.write();
} else {
console.log(`Found admin trip: ${config.data.adminTrip}`);
}
};
// prompt user for a channel name
const getChannel = async () => {
const chanPrompt = new Input({
message: 'New channel name:',
});
const chan = await chanPrompt.run();
return chan;
};
// prompt user to save standard channels or input their own
const setupChannels = async () => {
const standardMode = 'Use standard channels';
const manualMode = 'Manual input';
const modePrompt = new Select({
name: 'mode',
message: 'How would you like to setup the public channels?',
choices: [
standardMode,
manualMode,
],
});
const mode = await modePrompt.run();
if (mode === standardMode) {
config.data.publicChannels = defaultChannels;
await config.write();
} else {
const channels = [];
let newChannel = '';
for (;;) {
console.log('(Leave blank to finish) Channels:', channels.join(', '));
newChannel = await getChannel();
if (newChannel === '') {
break;
} else {
channels.push(newChannel);
}
}
config.data.publicChannels = channels;
await config.write();
}
};
// check if pulic channels have been initialized
const checkPublicChannels = async () => {
if (typeof config.data.publicChannels === 'undefined' || config.data.publicChannels.length === 0) {
const prompt = new Confirm({
name: 'addChannels',
message: 'Missing public channels, setup now?',
});
if (await prompt.run() !== false) {
await setupChannels();
}
} else {
console.log('Found existing public channels.');
}
};
// start checking
await checkCert();
await checkConfig();
await checkTripSalt();
await checkPermissions();
await checkPublicChannels();
// done!
console.log('Config completed!');