Skip to content

Commit

Permalink
Merge pull request 'Merge in upstream fixes' (#1) from upstream-fixes…
Browse files Browse the repository at this point in the history
…-202312 into master

Reviewed-on: https://git.supernets.org/supernets/hardlounge/pulls/1
  • Loading branch information
hgw8 committed Dec 3, 2023
2 parents 5eb40f9 + 66e5bc1 commit d66f800
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 172 deletions.
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@supernets/hardlounge",
"description": "The self-hosted Web IRC client",
"version": "4.4.1",
"version": "4.4.1-1",
"preferGlobal": true,
"bin": {
"hardlounge": "index.js"
Expand Down Expand Up @@ -54,13 +54,15 @@
"dependencies": {
"@fastify/busboy": "1.0.0",
"bcryptjs": "2.4.3",
"caniuse-lite": "^1.0.30001561",
"chalk": "4.1.2",
"cheerio": "1.0.0-rc.12",
"commander": "9.0.0",
"content-disposition": "0.5.4",
"express": "4.17.3",
"file-type": "16.5.4",
"filenamify": "4.3.0",
"get-func-name": "2.0.2",
"got": "11.8.5",
"irc-framework": "4.13.1",
"is-utf8": "0.2.1",
Expand Down Expand Up @@ -91,18 +93,18 @@
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@textcomplete/core": "0.1.10",
"@textcomplete/textarea": "0.1.12",
"@types/bcryptjs": "2.4.4",
"@types/bcryptjs": "2.4.5",
"@types/chai": "4.3.5",
"@types/cheerio": "0.22.31",
"@types/content-disposition": "0.5.5",
"@types/cheerio": "0.22.33",
"@types/content-disposition": "0.5.7",
"@types/express": "4.17.13",
"@types/is-utf8": "0.2.1",
"@types/is-utf8": "0.2.2",
"@types/ldapjs": "2.2.2",
"@types/linkify-it": "3.0.3",
"@types/lodash": "4.14.195",
"@types/lodash": "4.14.200",
"@types/mime-types": "2.1.1",
"@types/mocha": "9.1.1",
"@types/mousetrap": "1.6.11",
"@types/mousetrap": "1.6.13",
"@types/node": "17.0.31",
"@types/read": "0.0.29",
"@types/semver": "7.3.9",
Expand Down
38 changes: 25 additions & 13 deletions server/clientManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import fs from "fs";
import path from "path";

import Auth from "./plugins/auth";
import Client, {UserConfig} from "./client";
import Client, { UserConfig } from "./client";
import Config from "./config";
import {NetworkConfig} from "./models/network";
import { NetworkConfig } from "./models/network";
import WebPush from "./plugins/webpush";
import log from "./log";
import {Server} from "socket.io";
import { Server } from "socket.io";

class ClientManager {
clients: Client[];
Expand Down Expand Up @@ -107,17 +107,21 @@ class ClientManager {

// Existing users removed since last time users were loaded
_.difference(loaded, updatedUsers).forEach((name) => {
const client = _.find(this.clients, {name});
const client = _.find(this.clients, { name });

if (client) {
client.quit(true);
this.clients = _.without(this.clients, client);
log.info(`User ${colors.bold(name)} disconnected and removed.`);
log.info(
`User ${colors.bold(
name
)} disconnected and removed.`
);
}
});
},
1000,
{maxWait: 10000}
{ maxWait: 10000 }
)
);
}
Expand Down Expand Up @@ -197,7 +201,8 @@ class ClientManager {
if (
userFolderStat &&
userFileStat &&
(userFolderStat.uid !== userFileStat.uid || userFolderStat.gid !== userFileStat.gid)
(userFolderStat.uid !== userFileStat.uid ||
userFolderStat.gid !== userFileStat.gid)
) {
log.warn(
`User ${colors.green(
Expand Down Expand Up @@ -227,13 +232,16 @@ class ClientManager {
networks: client.networks.map((n) => n.export()),
});
const newUser = JSON.stringify(json, null, "\t");
const newHash = crypto.createHash("sha256").update(newUser).digest("hex");
const newHash = crypto
.createHash("sha256")
.update(newUser)
.digest("hex");

return {newUser, newHash};
return { newUser, newHash };
}

saveUser(client: Client, callback?: (err?: any) => void) {
const {newUser, newHash} = this.getDataToSave(client);
const { newUser, newHash } = this.getDataToSave(client);

// Do not write to disk if the exported data hasn't actually changed
if (client.fileHash === newHash) {
Expand All @@ -254,7 +262,9 @@ class ClientManager {
return callback ? callback() : true;
} catch (e: any) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
log.error(`Failed to update user ${colors.green(client.name)} (${e})`);
log.error(
`Failed to update user ${colors.green(client.name)} (${e})`
);

if (callback) {
callback(e);
Expand All @@ -266,7 +276,9 @@ class ClientManager {
const userPath = Config.getUserConfigPath(name);

if (!fs.existsSync(userPath)) {
log.error(`Tried to remove non-existing user ${colors.green(name)}.`);
log.error(
`Tried to remove non-existing user ${colors.green(name)}.`
);
return false;
}

Expand All @@ -275,7 +287,7 @@ class ClientManager {
return true;
}

private readUserConfig(name: string) {
readUserConfig(name: string) {
const userPath = Config.getUserConfigPath(name);

if (!fs.existsSync(userPath)) {
Expand Down
9 changes: 6 additions & 3 deletions server/command-line/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import log from "../log";
import fs from "fs";
import path from "path";
import colors from "chalk";
import {Command} from "commander";
import { Command } from "commander";
import Helper from "../helper";
import Config from "../config";
import Utils from "./utils";
Expand Down Expand Up @@ -42,6 +42,7 @@ program.addCommand(require("./install").default);
program.addCommand(require("./uninstall").default);
program.addCommand(require("./upgrade").default);
program.addCommand(require("./outdated").default);
program.addCommand(require("./storage").default);

if (!Config.values.public) {
require("./users").default.forEach((command: Command) => {
Expand All @@ -64,7 +65,7 @@ function createPackagesFolder() {
const packagesConfig = path.join(packagesPath, "package.json");

// Create node_modules folder, otherwise yarn will start walking upwards to find one
fs.mkdirSync(path.join(packagesPath, "node_modules"), {recursive: true});
fs.mkdirSync(path.join(packagesPath, "node_modules"), { recursive: true });

// Create package.json with private set to true, if it doesn't exist already
if (!fs.existsSync(packagesConfig)) {
Expand Down Expand Up @@ -99,7 +100,9 @@ function verifyFileOwner() {
);
}

const configStat = fs.statSync(path.join(Config.getHomePath(), "config.js"));
const configStat = fs.statSync(
path.join(Config.getHomePath(), "config.js")
);

if (configStat && configStat.uid !== uid) {
log.warn(
Expand Down
68 changes: 68 additions & 0 deletions server/command-line/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import log from "../log";
import { Command } from "commander";
import ClientManager from "../clientManager";
import Utils from "./utils";
import SqliteMessageStorage from "../plugins/messageStorage/sqlite";

const program = new Command("storage").description(
"various utilities related to the message storage"
);

program
.command("migrate")
.argument("[user]", "migrate a specific user only, all if not provided")
.description("Migrate message storage where needed")
.on("--help", Utils.extraHelp)
.action(function (user) {
runMigrations(user).catch((err) => {
log.error(err.toString());
process.exit(1);
});
});

async function runMigrations(user: string) {
const manager = new ClientManager();
const users = manager.getUsers();

if (user) {
if (!users.includes(user)) {
throw new Error(`invalid user ${user}`);
}

return migrateUser(manager, user);
}

for (const name of users) {
await migrateUser(manager, name);
// if any migration fails we blow up,
// chances are the rest won't complete either
}
}

// runs sqlite migrations for a user, which must exist
async function migrateUser(manager: ClientManager, user: string) {
log.info("handling user", user);

if (!isUserLogEnabled(manager, user)) {
log.info("logging disabled for user", user, ". Skipping");
return;
}

const sqlite = new SqliteMessageStorage(user);
await sqlite.enable(); // enable runs migrations
await sqlite.close();
log.info("user", user, "migrated successfully");
}

function isUserLogEnabled(manager: ClientManager, user: string): boolean {
const conf = manager.readUserConfig(user);

if (!conf) {
log.error("Could not open user configuration of", user);
return false;
}

return conf.log;
}

export default program;
Loading

0 comments on commit d66f800

Please sign in to comment.