progress moving types out of types/

This commit is contained in:
Max Leiter 2022-05-04 15:41:57 -07:00
parent aa2e5b6834
commit 6de13b6ff8
No known key found for this signature in database
GPG key ID: A3512F2F2F17EBDA
99 changed files with 668 additions and 640 deletions

View file

@ -1,3 +1,5 @@
import Chan from "../src/models/chan";
declare module "*.vue" { declare module "*.vue" {
import Vue from "vue"; import Vue from "vue";
export default Vue; export default Vue;

View file

@ -5,7 +5,8 @@
"../src/types/models/channel.d.ts", "../src/types/models/channel.d.ts",
"js/helpers/simplemap.json", "js/helpers/simplemap.json",
"js/helpers/fullnamemap.json", "js/helpers/fullnamemap.json",
"../package.json" "../package.json",
"./types.d.ts"
], ],
"compilerOptions": { "compilerOptions": {
// "paths": { // "paths": {

View file

@ -13,15 +13,15 @@
"homepage": "https://thelounge.chat/", "homepage": "https://thelounge.chat/",
"scripts": { "scripts": {
"build:client": "webpack", "build:client": "webpack",
"build:server": "tsc -p src/tsconfig.json index.ts", "build:server": "tsc -p src/tsconfig.json src/index.ts",
"coverage": "run-s test:* && nyc --nycrc-path=test/.nycrc-report.json report", "coverage": "run-s test:* && nyc --nycrc-path=test/.nycrc-report.json report",
"dev": "ts-node --project tsconfig.json index.ts start --dev", "dev": "ts-node --project src/tsconfig.json src/index.ts start --dev",
"format:prettier": "prettier --write \"**/*.*\"", "format:prettier": "prettier --write \"**/*.*\"",
"lint:check-eslint": "eslint-config-prettier .eslintrc.cjs", "lint:check-eslint": "eslint-config-prettier .eslintrc.cjs",
"lint:eslint": "eslint . --ext .js,.vue --report-unused-disable-directives --color", "lint:eslint": "eslint . --ext .js,.vue --report-unused-disable-directives --color",
"lint:prettier": "prettier --list-different \"**/*.*\"", "lint:prettier": "prettier --list-different \"**/*.*\"",
"lint:stylelint": "stylelint --color \"client/**/*.css\"", "lint:stylelint": "stylelint --color \"client/**/*.css\"",
"start": "ts-node index start", "start": "ts-node src/index start",
"test": "run-p --aggregate-output --continue-on-error lint:* test:*", "test": "run-p --aggregate-output --continue-on-error lint:* test:*",
"test:mocha": "webpack --mode=development && nyc --nycrc-path=test/.nycrc-mocha.json mocha --colors --config=test/.mocharc.yml", "test:mocha": "webpack --mode=development && nyc --nycrc-path=test/.nycrc-mocha.json mocha --colors --config=test/.mocharc.yml",
"watch": "webpack --watch" "watch": "webpack --watch"
@ -101,6 +101,7 @@
"@types/ua-parser-js": "0.7.36", "@types/ua-parser-js": "0.7.36",
"@types/uuid": "8.3.4", "@types/uuid": "8.3.4",
"@types/web-push": "3.3.2", "@types/web-push": "3.3.2",
"@types/webpack-env": "1.16.4",
"@types/ws": "8.5.3", "@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.22.0", "@typescript-eslint/eslint-plugin": "5.22.0",
"@typescript-eslint/parser": "5.22.0", "@typescript-eslint/parser": "5.22.0",

View file

@ -8,8 +8,8 @@ import crypto from "crypto";
import colors from "chalk"; import colors from "chalk";
import log from "./log"; import log from "./log";
import Chan from "./models/chan"; import Chan, {ChanType} from "./models/chan";
import Msg from "./models/msg"; import Msg, {MessageType, UserInMessage} from "./models/msg";
import Config from "./config"; import Config from "./config";
import constants from "../client/js/constants"; import constants from "../client/js/constants";
@ -17,7 +17,7 @@ import inputs from "./plugins/inputs";
import PublicClient from "./plugins/packages/publicClient"; import PublicClient from "./plugins/packages/publicClient";
import SqliteMessageStorage from "./plugins/messageStorage/sqlite"; import SqliteMessageStorage from "./plugins/messageStorage/sqlite";
import TextFileMessageStorage from "./plugins/messageStorage/text"; import TextFileMessageStorage from "./plugins/messageStorage/text";
import Network from "./models/network"; import Network, {NetworkWithIrcFramework} from "./models/network";
import ClientManager from "./clientManager"; import ClientManager from "./clientManager";
import {MessageStorage} from "./types/plugins/messageStorage"; import {MessageStorage} from "./types/plugins/messageStorage";
@ -48,6 +48,46 @@ const events = [
"welcome", "welcome",
"whois", "whois",
]; ];
type ClientPushSubscription = {
endpoint: string;
keys: {
p256dh: string;
auth: string;
};
};
type ClientConfig = {
log: boolean;
password: string;
sessions: {
[token: string]: {
lastUse: number;
ip: string;
agent: string;
pushSubscription?: ClientPushSubscription;
};
};
clientSettings: {
[key: string]: any;
};
browser?: {
language?: string;
ip?: string;
hostname?: string;
isSecure?: boolean;
};
};
type Mention = {
chanId: number;
msgId: number;
type: MessageType;
time: number;
text: string;
from: UserInMessage;
};
class Client { class Client {
awayMessage!: string; awayMessage!: string;
lastActiveChannel!: number; lastActiveChannel!: number;
@ -272,12 +312,11 @@ class Client {
networks: [network.getFilteredClone(this.lastActiveChannel, -1)], networks: [network.getFilteredClone(this.lastActiveChannel, -1)],
}); });
// @ts-ignore it complains because validate expects this to be NetworkWith if (!(network as NetworkWithIrcFramework).validate(client)) {
if (!network.validate(client)) {
return; return;
} }
network.createIrcFramework(client); (network as NetworkWithIrcFramework).createIrcFramework(client);
events.forEach(async (plugin) => { events.forEach(async (plugin) => {
(await import(`./plugins/irc-events/${plugin}`)).default.apply(client, [ (await import(`./plugins/irc-events/${plugin}`)).default.apply(client, [
@ -413,6 +452,11 @@ class Client {
if (inputs.userInputs.has(cmd)) { if (inputs.userInputs.has(cmd)) {
const plugin = inputs.userInputs.get(cmd); const plugin = inputs.userInputs.get(cmd);
if (!plugin) {
// should be a no-op
throw new Error(`Plugin ${cmd} not found`);
}
if (typeof plugin.input === "function" && (connected || plugin.allowDisconnected)) { if (typeof plugin.input === "function" && (connected || plugin.allowDisconnected)) {
connected = true; connected = true;
plugin.input.apply(client, [target.network, target.chan, cmd, args]); plugin.input.apply(client, [target.network, target.chan, cmd, args]);
@ -785,3 +829,10 @@ class Client {
} }
export default Client; export default Client;
// TODO: this should exist elsewhere?
export type IrcEventHandler = (
this: Client,
irc: NetworkWithIrcFramework["irc"],
network: NetworkWithIrcFramework
) => void;

View file

@ -7,7 +7,97 @@ import _ from "lodash";
import colors from "chalk"; import colors from "chalk";
import log from "./log"; import log from "./log";
import Helper from "./helper"; import Helper from "./helper";
import {Config as ConfigType} from "./types/config";
// TODO: Type this
export type WebIRC = {
[key: string]: any;
};
type Https = {
enable: boolean;
key: string;
certificate: string;
ca: string;
};
type FileUpload = {
enable: boolean;
maxFileSize: number;
baseUrl?: string;
};
export type Defaults = {
name: string;
host: string;
port: number;
password: string;
tls: boolean;
rejectUnauthorized: boolean;
nick: string;
username: string;
realname: string;
join: string;
leaveMessage: string;
};
type Identd = {
enable: boolean;
port: number;
};
type SearchDN = {
rootDN: string;
rootPassword: string;
filter: string;
base: string;
scope: string;
};
type Ldap = {
enable: boolean;
url: string;
tlsOptions: any;
primaryKey: string;
searchDN: SearchDN;
baseDN?: string;
};
type TlsOptions = any;
type Debug = {
ircFramework: boolean;
raw: boolean;
};
export type ConfigType = {
public: boolean;
host: string | undefined;
port: number;
bind: string | undefined;
reverseProxy: boolean;
maxHistory: number;
https: Https;
theme: string;
prefetch: boolean;
disableMediaPreview: boolean;
prefetchStorage: boolean;
prefetchMaxImageSize: number;
prefetchMaxSearchSize: number;
prefetchTimeout: number;
fileUpload: FileUpload;
transports: string[];
leaveMessage: string;
defaults: Defaults;
lockNetwork: boolean;
messageStorage: string[];
useHexIp: boolean;
webirc?: WebIRC;
identd: Identd;
oidentd?: string;
ldap: Ldap;
debug: Debug;
themeColor: string;
};
class Config { class Config {
values = require(path.resolve( values = require(path.resolve(

View file

@ -8,7 +8,12 @@ import fs from "fs";
import net from "net"; import net from "net";
import bcrypt from "bcryptjs"; import bcrypt from "bcryptjs";
import crypto from "crypto"; import crypto from "crypto";
import {Hostmask} from "./types/helper";
export type Hostmask = {
nick: string;
ident: string;
hostname: string;
};
const Helper = { const Helper = {
expandHome, expandHome,

2
src/index.d.ts vendored
View file

@ -1 +1 @@
// / <reference path="types/index.d.ts" /> import "./types";

View file

@ -7,7 +7,7 @@ process.chdir(__dirname);
// Perform node version check before loading any other files or modules // Perform node version check before loading any other files or modules
// Doing this check as soon as possible allows us to // Doing this check as soon as possible allows us to
// avoid ES6 parser errors or other issues // avoid ES6 parser errors or other issues
import pkg from "./package.json"; import pkg from "../package.json";
import {satisfies} from "semver"; import {satisfies} from "semver";
if (!satisfies(process.version, pkg.engines.node)) { if (!satisfies(process.version, pkg.engines.node)) {
@ -33,4 +33,4 @@ if (dns.setDefaultResultOrder) {
dns.setDefaultResultOrder("verbatim"); dns.setDefaultResultOrder("verbatim");
} }
import "./src/command-line"; import "./command-line";

View file

@ -4,12 +4,37 @@ import _ from "lodash";
import log from "../log"; import log from "../log";
import Config from "../config"; import Config from "../config";
import User from "./user"; import User from "./user";
import Msg from "./msg"; import Msg, {MessageType} from "./msg";
import storage from "../plugins/storage"; import storage from "../plugins/storage";
import Client from "../client"; import Client from "../client";
import Network from "./network"; import Network from "./network";
import Prefix from "./prefix"; import Prefix from "./prefix";
export enum ChanType {
CHANNEL = "channel",
LOBBY = "lobby",
QUERY = "query",
SPECIAL = "special",
}
export enum SpecialChanType {
BANLIST = "list_bans",
INVITELIST = "list_invites",
CHANNELLIST = "list_channels",
IGNORELIST = "list_ignored",
}
export enum ChanState {
PARTED = 0,
JOINED = 1,
}
// eslint-disable-next-line no-use-before-define
export type FilteredChannel = Chan & {
users: [];
totalMessages: number;
};
class Chan { class Chan {
// TODO: don't force existence, figure out how to make TS infer it. // TODO: don't force existence, figure out how to make TS infer it.
id!: number; id!: number;
@ -298,3 +323,5 @@ function requestZncPlayback(channel, network, from) {
} }
export default Chan; export default Chan;
export type Channel = Chan;

View file

@ -1,6 +1,48 @@
"use strict"; "use strict";
import _ from "lodash"; import _ from "lodash";
import User from "./user";
export type UserInMessage = Partial<User> & {
mode: string;
};
export type MessagePreview = {
shown: boolean;
link: string;
body: string;
};
export enum MessageType {
UNHANDLED = "unhandled",
ACTION = "action",
AWAY = "away",
BACK = "back",
ERROR = "error",
INVITE = "invite",
JOIN = "join",
KICK = "kick",
LOGIN = "login",
LOGOUT = "logout",
MESSAGE = "message",
MODE = "mode",
MODE_CHANNEL = "mode_channel",
MODE_USER = "mode_user", // RPL_UMODEIS
MONOSPACE_BLOCK = "monospace_block",
NICK = "nick",
NOTICE = "notice",
PART = "part",
QUIT = "quit",
CTCP = "ctcp",
CTCP_REQUEST = "ctcp_request",
CHGHOST = "chghost",
TOPIC = "topic",
TOPIC_SET_BY = "topic_set_by",
WHOIS = "whois",
RAW = "raw",
PLUGIN = "plugin",
WALLOPS = "wallops",
}
class Msg { class Msg {
from!: UserInMessage; from!: UserInMessage;
@ -95,3 +137,5 @@ class Msg {
} }
export default Msg; export default Msg;
export type Message = Msg;

View file

@ -2,14 +2,14 @@
import _ from "lodash"; import _ from "lodash";
import {v4 as uuidv4} from "uuid"; import {v4 as uuidv4} from "uuid";
import IrcFramework from "irc-framework"; import IrcFramework, {Client as IRCClient} from "irc-framework";
import Chan from "./chan"; import Chan, {Channel, ChanType} from "./chan";
import Msg from "./msg"; import Msg, {MessageType} from "./msg";
import Prefix from "./prefix"; import Prefix from "./prefix";
import Helper from "../helper"; import Helper, {Hostmask} from "../helper";
import Config from "../config"; import Config, {WebIRC} from "../config";
import STSPolicies from "../plugins/sts"; import STSPolicies from "../plugins/sts";
import ClientCertificate from "../plugins/clientCertificate"; import ClientCertificate, {ClientCertificateType} from "../plugins/clientCertificate";
import Client from "../client"; import Client from "../client";
/** /**
@ -22,6 +22,53 @@ const fieldsForClient = {
serverOptions: true, serverOptions: true,
}; };
type NetworkIrcOptions = {
host: string;
port: number;
password: string;
nick: string;
username: string;
gecos: string;
tls: boolean;
rejectUnauthorized: boolean;
webirc: WebIRC;
client_certificate: ClientCertificateType | null;
socks?: {
host: string;
port: number;
user: string;
pass: string;
};
sasl_mechanism?: string;
account?:
| {
account: string;
password: string;
}
| Record<string, never>;
};
type NetworkStatus = {
connected: boolean;
secure: boolean;
};
export type IgnoreListItem = Hostmask & {
when?: number;
};
type IgnoreList = IgnoreListItem[];
type NonNullableIRCWithOptions = NonNullable<IRCClient & {options: NetworkIrcOptions}>;
// eslint-disable-next-line no-use-before-define
export type NetworkWithIrcFramework = Network & {
// eslint-disable-next-line no-use-before-define
irc: NonNullable<Network["irc"]> & {
options: NonNullableIRCWithOptions;
};
};
class Network { class Network {
nick!: string; nick!: string;
name!: string; name!: string;
@ -223,7 +270,7 @@ class Network {
return true; return true;
} }
createIrcFramework(this: Network, client: Client) { createIrcFramework(this: NetworkWithIrcFramework, client: Client) {
this.irc = new IrcFramework.Client({ this.irc = new IrcFramework.Client({
version: false, // We handle it ourselves version: false, // We handle it ourselves
outgoing_addr: Config.values.bind, outgoing_addr: Config.values.bind,
@ -237,7 +284,6 @@ class Network {
auto_reconnect_max_retries: 30, auto_reconnect_max_retries: 30,
}); });
// @ts-ignore TODO: `this` should now be a NetworkWithIrcFramework
this.setIrcFrameworkOptions(client); this.setIrcFrameworkOptions(client);
this.irc.requestCap([ this.irc.requestCap([

View file

@ -1,5 +1,12 @@
"use strict"; "use strict";
type PrefixSymbol = string;
type PrefixObject = {
symbol: PrefixSymbol;
mode: string;
};
class Prefix { class Prefix {
prefix: PrefixObject[]; prefix: PrefixObject[];
modeToSymbol: {[mode: string]: string}; modeToSymbol: {[mode: string]: string};

View file

@ -1,8 +1,18 @@
"use strict"; "use strict";
import colors from "chalk"; import colors from "chalk";
import Client from "../client";
import ClientManager from "../clientManager";
import log from "../log"; import log from "../log";
export type AuthHandler = (
manager: ClientManager,
client: Client,
user: string,
password: string,
callback: (success: boolean) => void
) => void;
// The order defines priority: the first available plugin is used. // The order defines priority: the first available plugin is used.
// Always keep 'local' auth plugin at the end of the list; it should always be enabled. // Always keep 'local' auth plugin at the end of the list; it should always be enabled.
const plugins = [import("./auth/ldap"), import("./auth/local")]; const plugins = [import("./auth/ldap"), import("./auth/local")];

View file

@ -1,10 +1,10 @@
"use strict"; "use strict";
import ldap, {SearchOptions} from "ldapjs";
import colors from "chalk";
import log from "../../log"; import log from "../../log";
import Config from "../../config"; import Config from "../../config";
import ldap, {SearchOptions} from "ldapjs"; import type {AuthHandler} from "../auth";
import colors from "chalk";
import {AuthHandler} from "types/plugins/auth";
function ldapAuthCommon( function ldapAuthCommon(
user: string, user: string,
@ -191,9 +191,8 @@ function advancedLdapLoadUsers(users: string[], callbackLoadUser) {
} }
res.on("searchEntry", function (entry) { res.on("searchEntry", function (entry) {
// @ts-ignore // TODO: was _vals.
// TODO const user = entry.attributes[0].vals[0].toString();
const user = entry.attributes[0]._vals[0].toString();
if (remainingUsers.has(user)) { if (remainingUsers.has(user)) {
remainingUsers.delete(user); remainingUsers.delete(user);

View file

@ -3,7 +3,7 @@
import colors from "chalk"; import colors from "chalk";
import log from "../../log"; import log from "../../log";
import Helper from "../../helper"; import Helper from "../../helper";
import {AuthHandler} from "../../types/plugins/auth"; import type {AuthHandler} from "../auth";
const localAuth: AuthHandler = (manager, client, user, password, callback) => { const localAuth: AuthHandler = (manager, client, user, password, callback) => {
// If no user is found, or if the client has not provided a password, // If no user is found, or if the client has not provided a password,

View file

@ -12,7 +12,12 @@ export default {
remove, remove,
}; };
function get(uuid: string): ClientCertificate | null { export type ClientCertificateType = {
private_key: string;
certificate: string;
};
function get(uuid: string): ClientCertificateType | null {
if (Config.values.public) { if (Config.values.public) {
return null; return null;
} }
@ -28,7 +33,7 @@ function get(uuid: string): ClientCertificate | null {
return { return {
private_key: fs.readFileSync(paths.privateKeyPath, "utf-8"), private_key: fs.readFileSync(paths.privateKeyPath, "utf-8"),
certificate: fs.readFileSync(paths.certificatePath, "utf-8"), certificate: fs.readFileSync(paths.certificatePath, "utf-8"),
} as ClientCertificate; } as ClientCertificateType;
} catch (e: any) { } catch (e: any) {
log.error("Unable to get certificate", e); log.error("Unable to get certificate", e);
} }
@ -121,7 +126,7 @@ function generate() {
const pem = { const pem = {
private_key: pki.privateKeyToPem(keys.privateKey), private_key: pki.privateKeyToPem(keys.privateKey),
certificate: pki.certificateToPem(cert), certificate: pki.certificateToPem(cert),
} as ClientCertificate; } as ClientCertificateType;
return pem; return pem;
} }

View file

@ -1,6 +1,6 @@
"use strict"; "use strict";
import log from "../log"; import log from "../log";
import webpack from "webpack"; import webpackDevMiddleware from "webpack-dev-middleware";
export default (app) => { export default (app) => {
log.debug("Starting server in development mode"); log.debug("Starting server in development mode");
@ -16,12 +16,12 @@ export default (app) => {
const compiler = webpack(webpackConfig); const compiler = webpack(webpackConfig);
app.use( app.use(
require("webpack-dev-middleware")(compiler, { webpackDevMiddleware(compiler, {
index: "/", index: "/",
publicPath: webpackConfig.output.publicPath, publicPath: webpackConfig.output.publicPath,
}) })
).use( ).use(
require("webpack-hot-middleware")(compiler, { webpackDevMiddleware(compiler, {
path: "/storage/__webpack_hmr", path: "/storage/__webpack_hmr",
}) })
); );

View file

@ -1,6 +1,8 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import {PluginInputHandler} from "./index";
import Msg, {MessageType} from "../../models/msg";
import {ChanType} from "../../models/chan";
const commands = ["slap", "me"]; const commands = ["slap", "me"];

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
const commands = ["away", "back"]; const commands = ["away", "back"];
import {PluginInputHandler} from "./index";
const input: PluginInputHandler = function (network, chan, cmd, args) { const input: PluginInputHandler = function (network, chan, cmd, args) {
let reason = ""; let reason = "";

View file

@ -1,6 +1,8 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import {ChanType} from "../../models/chan";
import Msg, {MessageType} from "../../models/msg";
import {PluginInputHandler} from "./index";
const commands = ["ban", "unban", "banlist", "kickban"]; const commands = ["ban", "unban", "banlist", "kickban"];

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import {PluginInputHandler} from "./index";
const commands = ["connect", "server"]; const commands = ["connect", "server"];
const allowDisconnected = true; const allowDisconnected = true;

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import {PluginInputHandler} from "./index";
const commands = ["ctcp"]; const commands = ["ctcp"];

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
const commands = ["disconnect"]; const commands = ["disconnect"];
const allowDisconnected = true; const allowDisconnected = true;

View file

@ -1,7 +1,10 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import Helper from "helper"; import Helper from "../../helper";
import {PluginInputHandler} from "./index";
import {IgnoreListItem} from "../../models/network";
import {ChanType, SpecialChanType} from "../../models/chan";
const commands = ["ignore", "unignore", "ignorelist"]; const commands = ["ignore", "unignore", "ignorelist"];

View file

@ -1,5 +1,20 @@
import Chan from "../../models/chan"; import Client from "../../client";
import Network from "../../models/network"; import Chan, {Channel} from "../../models/chan";
import Network, {NetworkWithIrcFramework} from "../../models/network";
export type PluginInputHandler = (
this: Client,
network: NetworkWithIrcFramework,
chan: Channel,
cmd: string,
args: string[]
) => void;
type Plugin = {
commands: string[];
input: (network: Network, chan: Chan, cmd: string, args: string[]) => void;
allowDisconnected?: boolean | undefined;
};
const clientSideCommands = ["/collapse", "/expand", "/search"]; const clientSideCommands = ["/collapse", "/expand", "/search"];
@ -16,7 +31,8 @@ const passThroughCommands = [
"/rs", "/rs",
]; ];
const userInputs = [ const userInputs = new Map<string, Plugin>();
const builtInInputs = [
"action", "action",
"away", "away",
"ban", "ban",
@ -39,8 +55,10 @@ const userInputs = [
"topic", "topic",
"whois", "whois",
"mute", "mute",
].reduce(function (plugins, name) { ];
const plugin = import(`./${name}`).then(
for (const input of builtInInputs) {
import(`./${input}`).then(
(plugin: { (plugin: {
default: { default: {
commands: string[]; commands: string[];
@ -48,11 +66,26 @@ const userInputs = [
allowDisconnected?: boolean; allowDisconnected?: boolean;
}; };
}) => { }) => {
plugin.default.commands.forEach((command: string) => plugins.set(command, plugin)); plugin.default.commands.forEach((command: string) =>
userInputs.set(command, plugin.default)
);
} }
); );
return plugins; }
}, new Map());
// .reduce(async function (plugins, name) {
// return import(`./${name}`).then(
// (plugin: {
// default: {
// commands: string[];
// input: (network: Network, chan: Chan, cmd: string, args: string[]) => void;
// allowDisconnected?: boolean;
// };
// }) => {
// plugin.default.commands.forEach((command: string) => plugins.set(command, plugin));
// }
// );
// }, Promise.resolve(new Map()));
const pluginCommands = new Map(); const pluginCommands = new Map();

View file

@ -1,9 +1,8 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {PluginInputHandler} from "./index";
import Msg, {MessageType} from "../../models/msg";
import Chan from "../../models/chan"; import {ChanType} from "../../models/chan";
import Msg from "../../models/msg";
const commands = ["invite", "invitelist"]; const commands = ["invite", "invitelist"];

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import {ChanType} from "../../models/chan";
const commands = ["kick"]; const commands = ["kick"];

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
const commands = ["kill"]; const commands = ["kill"];

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
const commands = ["list"]; const commands = ["list"];

View file

@ -1,6 +1,8 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import {ChanType} from "../../models/chan";
const commands = ["mode", "umode", "op", "deop", "hop", "dehop", "voice", "devoice"]; const commands = ["mode", "umode", "op", "deop", "hop", "dehop", "voice", "devoice"];

View file

@ -1,8 +1,7 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
import Network from "../../models/network"; import Msg, {MessageType} from "../../models/msg";
import {ChanType} from "../../models/chan";
import Msg from "../../models/msg";
const commands = ["query", "msg", "say"]; const commands = ["query", "msg", "say"];

View file

@ -1,8 +1,9 @@
"use strict"; "use strict";
import Chan from "../../models/chan"; import Chan from "../../models/chan";
import Network from "../../models/network"; import Network from "../../models/network";
import {PluginInputHandler} from "./index";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import Client from "../../client"; import Client from "../../client";

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
const commands = ["nick"]; const commands = ["nick"];
const allowDisconnected = true; const allowDisconnected = true;

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
const commands = ["notice"]; const commands = ["notice"];

View file

@ -1,7 +1,9 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import Config from "config"; import Config from "../../config";
import {ChanType, ChanState} from "../../models/chan";
const commands = ["close", "leave", "part"]; const commands = ["close", "leave", "part"];
const allowDisconnected = true; const allowDisconnected = true;

View file

@ -1,7 +1,7 @@
"use strict"; "use strict";
import _ from "lodash"; import _ from "lodash";
import {PluginInputHandler} from "./index";
import ClientCertificate from "../clientCertificate"; import ClientCertificate from "../clientCertificate";
const commands = ["quit"]; const commands = ["quit"];

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
const commands = ["raw", "send", "quote"]; const commands = ["raw", "send", "quote"];

View file

@ -1,6 +1,8 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import {ChanType} from "../../models/chan";
const commands = ["cycle", "rejoin"]; const commands = ["cycle", "rejoin"];

View file

@ -1,6 +1,8 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import {ChanType} from "../../models/chan";
const commands = ["topic"]; const commands = ["topic"];

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {PluginInputHandler} from "./index";
const commands = ["whois"]; const commands = ["whois"];

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import {ChanType} from "../../models/chan";
import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg from "../../models/msg";
import STSPolicies from "../sts"; import STSPolicies from "../sts";

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,10 +1,13 @@
"use strict"; "use strict";
import _ from "lodash"; import _ from "lodash";
import {IrcEventHandler} from "../../client";
import log from "../../log"; import log from "../../log";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import Helper from "../../helper"; import Helper from "../../helper";
import Config from "../../config"; import Config from "../../config";
import {ChanType, ChanState} from "../../models/chan";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,10 +1,9 @@
"use strict"; "use strict";
import Network from "../../models/network";
import _ from "lodash"; import _ from "lodash";
import {IrcEventHandler} from "../../client";
import Helper from "../../helper"; import Helper from "../../helper";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import User from "../../models/user"; import User from "../../models/user";
import pkg from "../../../package.json"; import pkg from "../../../package.json";

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import Config from "../../config"; import Config from "../../config";
import Network from "../../models/network";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,8 +1,7 @@
"use strict"; "use strict";
import Network from "../../models/network"; import Msg, {MessageType} from "../../models/msg";
import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import {IrcEventHandler} from "../../client";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,14 +1,11 @@
"use strict"; "use strict";
import {ChanState} from "../../types/models/channel"; import Msg, {MessageType} from "../../models/msg";
import {Network} from "../../types/models/network";
import Chan from "../../models/chan";
import Msg from "../../models/msg";
import User from "../../models/user"; import User from "../../models/user";
import type {IrcEventHandler} from "../../client";
import {ChanState} from "../../models/chan";
module.exports = function (irc: Network["irc"], network: Network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;
irc.on("join", function (data) { irc.on("join", function (data) {

View file

@ -1,6 +1,9 @@
"use strict"; "use strict";
import {IrcEventHandler} from "../../client";
import {ChanState} from "../../models/chan";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import User from "../../models/user";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -9,15 +9,25 @@ import log from "../../log";
import Config from "../../config"; import Config from "../../config";
import {findLinksWithSchema} from "../../../client/js/helpers/ircmessageparser/findLinks"; import {findLinksWithSchema} from "../../../client/js/helpers/ircmessageparser/findLinks";
import storage from "../storage"; import storage from "../storage";
import Client from "../../client"; import Client, {IrcEventHandler} from "../../client";
import Chan from "../../models/chan"; import Chan from "../../models/chan";
import Msg from "../../models/msg"; import Msg from "../../models/msg";
import {Preview} from "../../types/plugins/preview";
const currentFetchPromises = new Map(); const currentFetchPromises = new Map();
const imageTypeRegex = /^image\/.+/; const imageTypeRegex = /^image\/.+/;
const mediaTypeRegex = /^(audio|video)\/.+/; const mediaTypeRegex = /^(audio|video)\/.+/;
type Preview = {
type: string;
head: string;
body: string;
thumb: string;
size: number;
link: string; // Send original matched link to the client
shown: boolean | null;
error: undefined | any;
message: undefined | string;
};
export default function (client: Client, chan: Chan, msg: Msg, cleanText: string) { export default function (client: Client, chan: Chan, msg: Msg, cleanText: string) {
if (!Config.values.prefetch) { if (!Config.values.prefetch) {
return; return;
@ -136,7 +146,7 @@ function parseHtml(preview, res, client: Client) {
}); });
} }
function parseHtmlMedia($: cheerio.CheerioAPI, preview, client) { function parseHtmlMedia($: cheerio.Root, preview, client) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (Config.values.disableMediaPreview) { if (Config.values.disableMediaPreview) {
reject(); reject();

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import {IrcEventHandler} from "../../client";
import Chan from "../../models/chan"; import Chan, {ChanType, SpecialChanType} from "../../models/chan";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,10 +1,11 @@
"use strict"; "use strict";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
import LinkPrefetch from "./link"; import LinkPrefetch from "./link";
import cleanIrcMessage from "../../../client/js/helpers/ircmessageparser/cleanIrcMessage"; import cleanIrcMessage from "../../../client/js/helpers/ircmessageparser/cleanIrcMessage";
import Helper from "../../helper"; import Helper from "../../helper";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import {ChanType} from "../../models/chan";
const nickRegExp = /(?:\x03[0-9]{1,2}(?:,[0-9]{1,2})?)?([\w[\]\\`^{|}-]+)/g; const nickRegExp = /(?:\x03[0-9]{1,2}(?:,[0-9]{1,2})?)?([\w[\]\\`^{|}-]+)/g;
@ -204,7 +205,7 @@ export default <IrcEventHandler>function (irc, network) {
chanId: chan.id, chanId: chan.id,
msgId: msg.id, msgId: msg.id,
type: msg.type, type: msg.type,
time: msg.time, time: msg.time.getTime(),
text: msg.text, text: msg.text,
from: msg.from, from: msg.from,
}); });

View file

@ -1,9 +1,9 @@
"use strict"; "use strict";
import _ from "lodash"; import _ from "lodash";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,9 +1,9 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import {SpecialChanType, ChanType} from "../../models/chan";
import Chan from "../../models/chan"; import Msg, {MessageType} from "../../models/msg";
import Msg from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,6 +1,6 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,13 +1,17 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;
irc.on("part", function (data) { irc.on("part", function (data) {
if (!data.channel) {
return;
}
const chan = network.getChannel(data.channel); const chan = network.getChannel(data.channel);
if (typeof chan === "undefined") { if (typeof chan === "undefined") {

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,6 +1,7 @@
"use strict"; "use strict";
import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,8 +1,8 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -1,4 +1,5 @@
"use strict"; "use strict";
import {IrcEventHandler} from "../../client";
import Msg from "../../models/msg"; import Msg from "../../models/msg";

View file

@ -1,8 +1,9 @@
"use strict"; "use strict";
import Network from "../../models/network"; import {IrcEventHandler} from "../../client";
import {ChanType} from "../../models/chan";
import Msg from "../../models/msg"; import Msg, {MessageType} from "../../models/msg";
export default <IrcEventHandler>function (irc, network) { export default <IrcEventHandler>function (irc, network) {
const client = this; const client = this;

View file

@ -6,10 +6,11 @@ import log from "../../log";
import path from "path"; import path from "path";
import fs from "fs"; import fs from "fs";
import Config from "../../config"; import Config from "../../config";
import Msg from "../../models/msg"; import Msg, {Message} from "../../models/msg";
import Client from "../../client"; import Client from "../../client";
import Chan from "../../models/chan"; import Chan, {Channel} from "../../models/chan";
import type {SqliteMessageStorage as ISqliteMessageStorage} from "../../types/plugins/messageStorage"; import type {SqliteMessageStorage as ISqliteMessageStorage} from "../../types/plugins/messageStorage";
import Network from "../../models/network";
// TODO; type // TODO; type
let sqlite3: any; let sqlite3: any;

View file

@ -7,6 +7,9 @@ import log from "../../log";
import Config from "../../config"; import Config from "../../config";
import {MessageStorage} from "../../types/plugins/messageStorage"; import {MessageStorage} from "../../types/plugins/messageStorage";
import Client from "../../client"; import Client from "../../client";
import Channel from "../../models/chan";
import {Message, MessageType} from "../../models/msg";
import Network from "../../models/network";
class TextFileMessageStorage implements MessageStorage { class TextFileMessageStorage implements MessageStorage {
client: Client; client: Client;

View file

@ -14,6 +14,14 @@ import fs from "fs";
import Utils from "../../command-line/utils"; import Utils from "../../command-line/utils";
import Client from "../../client"; import Client from "../../client";
type PackageInfo = {
packageName: string;
thelounge?: {supports: any};
version: string;
type?: string;
files?: string[];
};
const stylesheets: string[] = []; const stylesheets: string[] = [];
const files: string[] = []; const files: string[] = [];

View file

@ -1,6 +1,6 @@
import Client from "../../client"; import Client from "../../client";
import Chan from "../../models/chan"; import Chan from "../../models/chan";
import Msg from "../../models/msg"; import Msg, {MessageType, UserInMessage} from "../../models/msg";
export default class PublicClient { export default class PublicClient {
private client: Client; private client: Client;
@ -16,7 +16,7 @@ export default class PublicClient {
* @param {String} command - IRC command to run, this is in the same format that a client would send to the server (eg: JOIN #test) * @param {String} command - IRC command to run, this is in the same format that a client would send to the server (eg: JOIN #test)
* @param {String} targetId - The id of the channel to simulate the command coming from. Replies will go to this channel if appropriate * @param {String} targetId - The id of the channel to simulate the command coming from. Replies will go to this channel if appropriate
*/ */
runAsUser(command, targetId) { runAsUser(command: string, targetId: string) {
this.client.inputLine({target: targetId, text: command}); this.client.inputLine({target: targetId, text: command});
} }
@ -34,7 +34,7 @@ export default class PublicClient {
* @param {String} event - Name of the event, must be something the browser will recognise * @param {String} event - Name of the event, must be something the browser will recognise
* @param {Object} data - Body of the event, can be anything, but will need to be properly interpreted by the client * @param {Object} data - Body of the event, can be anything, but will need to be properly interpreted by the client
*/ */
sendToBrowser(event, data) { sendToBrowser(event: string, data) {
this.client.emit(event, data); this.client.emit(event, data);
} }
@ -42,7 +42,7 @@ export default class PublicClient {
* *
* @param {Number} chanId * @param {Number} chanId
*/ */
getChannel(chanId) { getChannel(chanId: number) {
return this.client.find(chanId); return this.client.find(chanId);
} }

View file

@ -6,7 +6,24 @@ import _ from "lodash";
import Config from "../../config"; import Config from "../../config";
const themes = new Map(); type Module = {
type: string;
name: string;
};
type ThemeModule = Module & {
themeColor: string;
css: string;
};
export type ThemeForClient = {
displayName: string;
filename?: string;
name: string;
themeColor: string | null;
};
const themes = new Map<string, ThemeForClient>();
export default { export default {
addTheme, addTheme,

View file

@ -5,7 +5,15 @@ import fs from "fs";
import path from "path"; import path from "path";
import log from "../log"; import log from "../log";
import Config from "../config"; import Config from "../config";
import type {PolicyMap, PolicyOption} from "../types/plugins/sts";
type PolicyOption = {
port: number;
duration: number;
expires: number;
host: string;
};
type PolicyMap = Map<string, Omit<PolicyOption, "host">>;
class STSPolicies { class STSPolicies {
stsFile: string; stsFile: string;

View file

@ -16,24 +16,50 @@ import Client from "./client";
import ClientManager from "./clientManager"; import ClientManager from "./clientManager";
import Uploader from "./plugins/uploader"; import Uploader from "./plugins/uploader";
import Helper from "./helper"; import Helper from "./helper";
import Config from "./config"; import Config, {ConfigType, Defaults} from "./config";
import Identification from "./identification"; import Identification from "./identification";
import changelog from "./plugins/changelog"; import changelog from "./plugins/changelog";
import inputs from "./plugins/inputs"; import inputs from "./plugins/inputs";
import Auth from "./plugins/auth"; import Auth from "./plugins/auth";
import themes from "./plugins/packages/themes"; import themes, {ThemeForClient} from "./plugins/packages/themes";
themes.loadLocalThemes(); themes.loadLocalThemes();
import packages from "./plugins/packages/index"; import packages from "./plugins/packages/index";
import type { import {NetworkWithIrcFramework} from "./models/network";
ClientConfiguration, import {ChanType} from "./models/chan";
Defaults,
IndexTemplateConfiguration,
ServerConfiguration,
} from "./types/config";
import type {ServerOptions} from "./types/server"; type ServerOptions = {
dev: boolean;
};
type ServerConfiguration = ConfigType & {
stylesheets: string[];
};
type IndexTemplateConfiguration = ServerConfiguration & {
cacheBust: string;
};
type ClientConfiguration = Pick<
ConfigType,
"public" | "lockNetwork" | "useHexIp" | "prefetch" | "defaults"
> & {
fileUpload: boolean;
ldapEnabled: boolean;
isUpdateAvailable: boolean;
applicationServerKey: string;
version: string;
gitCommit: string | null;
defaultTheme: string;
themes: ThemeForClient[];
defaults: Defaults & {
sasl?: string;
saslAccount?: string;
saslPassword?: string;
};
fileUploadMaxFileSize?: number;
};
// A random number that will force clients to reload the page if it differs // A random number that will force clients to reload the page if it differs
const serverHash = Math.floor(Date.now() * Math.random()); const serverHash = Math.floor(Date.now() * Math.random());
@ -59,7 +85,7 @@ export default async function (
const app = express(); const app = express();
if (options.dev) { if (options.dev) {
(await import("./plugins/dev-server.js")).default(app); (await import("./plugins/dev-server")).default(app);
} }
app.set("env", "production") app.set("env", "production")
@ -85,7 +111,7 @@ export default async function (
const themeName = req.params.theme; const themeName = req.params.theme;
const theme = themes.getByName(themeName); const theme = themes.getByName(themeName);
if (theme === undefined) { if (theme === undefined || theme.filename === undefined) {
return res.status(404).send("Not found"); return res.status(404).send("Not found");
} }

View file

@ -6,10 +6,13 @@
"../client/js/helpers/ircmessageparser/findLinks.ts", "../client/js/helpers/ircmessageparser/findLinks.ts",
"../client/js/helpers/ircmessageparser/cleanIrcMessage.ts" "../client/js/helpers/ircmessageparser/cleanIrcMessage.ts"
], ],
"ts-node": {
"files": true
},
// TODO: these should be imported from the base config, // TODO: these should be imported from the base config,
// but ts-node doesn't seem to care. // but ts-node doesn't seem to care.
"include": ["**/*"], // "include": ["**/*"],
"typeRoots": ["./src/types/"], // "typeRoots": ["./types/"],
"compilerOptions": { "compilerOptions": {
"types": ["node"], "types": ["node"],

38
src/types/client.d.ts vendored
View file

@ -1,38 +0,0 @@
type ClientConfig = {
log: boolean;
password: string;
sessions: {
[token: string]: {
lastUse: number;
ip: string;
agent: string;
pushSubscription?: ClientPushSubscription;
};
};
clientSettings: {
[key: string]: any;
};
browser?: {
language?: string;
ip?: string;
hostname?: string;
isSecure?: boolean;
};
};
type ClientPushSubscription = {
endpoint: string;
keys: {
p256dh: string;
auth: string;
};
};
type Mention = {
chanId: number;
msgId: number;
type: MessageType;
time: number;
text: string;
from: UserInMessage;
};

118
src/types/config.d.ts vendored
View file

@ -1,118 +0,0 @@
type Config = {
public: boolean;
host: string | undefined;
port: number;
bind: string | undefined;
reverseProxy: boolean;
maxHistory: number;
https: Https;
theme: string;
prefetch: boolean;
disableMediaPreview: boolean;
prefetchStorage: boolean;
prefetchMaxImageSize: number;
prefetchMaxSearchSize: number;
prefetchTimeout: number;
fileUpload: FileUpload;
transports: string[];
leaveMessage: string;
defaults: Defaults;
lockNetwork: boolean;
messageStorage: string[];
useHexIp: boolean;
webirc?: WebIRC;
identd: Identd;
oidentd?: string;
ldap: Ldap;
debug: Debug;
themeColor: string;
};
type ClientConfiguration = Pick<
Config,
"public" | "lockNetwork" | "useHexIp" | "prefetch" | "defaults"
> & {
fileUpload: boolean;
ldapEnabled: boolean;
isUpdateAvailable: boolean;
applicationServerKey: string;
version: string;
gitCommit: string | null;
defaultTheme: string;
themes: ThemeForClient[];
defaults: Defaults & {
sasl?: string;
saslAccount?: string;
saslPassword?: string;
};
fileUploadMaxFileSize?: number;
};
type ServerConfiguration = Config & {
stylesheets: string[];
};
type IndexTemplateConfiguration = ServerConfiguration & {
cacheBust: string;
};
// TODO: Type this
type WebIRC = {
[key: string]: any;
};
type Https = {
enable: boolean;
key: string;
certificate: string;
ca: string;
};
export type FileUpload = {
enable: boolean;
maxFileSize: number;
baseUrl?: string;
};
export type Defaults = {
name: string;
host: string;
port: number;
password: string;
tls: boolean;
rejectUnauthorized: boolean;
nick: string;
username: string;
realname: string;
join: string;
leaveMessage: string;
};
export type Identd = {
enable: boolean;
port: number;
};
export type Ldap = {
enable: boolean;
url: string;
tlsOptions: any;
primaryKey: string;
searchDN: SearchDN;
baseDN?: string;
};
export type TlsOptions = any;
export type SearchDN = {
rootDN: string;
rootPassword: string;
filter: string;
base: string;
scope: string;
};
export type Debug = {
ircFramework: boolean;
raw: boolean;
};

View file

@ -1,5 +0,0 @@
export type Hostmask = {
nick: string;
ident: string;
hostname: string;
};

View file

@ -1,6 +1,2 @@
// / <reference path="models/index.d.ts" /> import "./modules";
// / <reference path="plugins/index.d.ts" /> import "./plugins";
// / <reference path="config.d.ts" />
// / <reference path="helper.d.ts" />
// / <reference path="server.d.ts" />
// / <reference path="client.d.ts" />

View file

@ -1,29 +0,0 @@
import Chan from "../../models/chan";
declare global {
export type Channel = Chan;
export type FilteredChannel = Chan & {
users: [];
totalMessages: number;
};
export enum ChanType {
CHANNEL = "channel",
LOBBY = "lobby",
QUERY = "query",
SPECIAL = "special",
}
export enum SpecialChanType {
BANLIST = "list_bans",
INVITELIST = "list_invites",
CHANNELLIST = "list_channels",
IGNORELIST = "list_ignored",
}
export enum ChanState {
PARTED = 0,
JOINED = 1,
}
}

View file

@ -1,5 +0,0 @@
// / <reference path="channel.d.ts" />
// / <reference path="prefix.d.ts" />
// / <reference path="message.d.ts" />
// / <reference path="user.d.ts" />
// / <reference path="network.d.ts" />

View file

@ -1,46 +0,0 @@
import Msg from "../../models/msg";
declare global {
type Message = Msg;
type UserInMessage = Partial<User> & {
mode: string;
};
type MessagePreview = {
shown: boolean;
link: string;
body: string;
};
export enum MessageType {
UNHANDLED = "unhandled",
ACTION = "action",
AWAY = "away",
BACK = "back",
ERROR = "error",
INVITE = "invite",
JOIN = "join",
KICK = "kick",
LOGIN = "login",
LOGOUT = "logout",
MESSAGE = "message",
MODE = "mode",
MODE_CHANNEL = "mode_channel",
MODE_USER = "mode_user", // RPL_UMODEIS
MONOSPACE_BLOCK = "monospace_block",
NICK = "nick",
NOTICE = "notice",
PART = "part",
QUIT = "quit",
CTCP = "ctcp",
CTCP_REQUEST = "ctcp_request",
CHGHOST = "chghost",
TOPIC = "topic",
TOPIC_SET_BY = "topic_set_by",
WHOIS = "whois",
RAW = "raw",
PLUGIN = "plugin",
WALLOPS = "wallops",
}
}

View file

@ -1,51 +0,0 @@
import NetworkClass from "../../models/network";
import {Client as IRCClient} from "irc-framework";
import {WebIRC} from "../config";
declare global {
export type Network = NetworkClass;
type NetworkIrcOptions = {
host: string;
port: number;
password: string;
nick: string;
username: string;
gecos: string;
tls: boolean;
rejectUnauthorized: boolean;
webirc: WebIRC;
client_certificate: ClientCertificate | null;
socks?: {
host: string;
port: number;
user: string;
pass: string;
};
sasl_mechanism?: string;
account?:
| {
account: string;
password: string;
}
| {};
};
type NonNullableIRCWithOptions = NonNullable<IRCClient & {options: NetworkIrcOptions}>;
type NetworkWithIrcFramework = Network & {
irc: NonNullable<Network["irc"]> & {
options: NonNullableIRCWithOptions;
};
};
type NetworkStatus = {
connected: boolean;
secure: boolean;
};
type IgnoreListItem = Hostmask & {
when?: number;
};
type IgnoreList = IgnoreListItem[];
}

View file

@ -1,6 +0,0 @@
type PrefixSymbol = string;
type PrefixObject = {
symbol: PrefixSymbol;
mode: string;
};

View file

@ -1,4 +0,0 @@
import UserClass from "models/user";
declare global {
export type User = UserClass;
}

View file

@ -19,6 +19,83 @@ declare module "irc-framework" {
end: () => void; end: () => void;
}; };
export interface MessageEventArgs {
account?: any;
group?: any;
hostname: string;
ident: string;
message: string;
nick: string;
reply: (message: string) => void;
tags: {[key: string]: string};
target: string;
time?: any;
type: "privmsg" | "action"; // TODO
}
export interface JoinEventArgs {
// todo: is that wrong?
account: boolean;
channel: string;
gecos: string;
hostname: string;
ident: string;
nick: string;
time?: any;
}
export interface KickEventArgs {
kicked: string;
nick: string;
ident: string;
hostname: string;
channel: string;
message: string;
time: number;
}
export interface RawEventArgs {
from_server: boolean;
line: string;
}
export interface RegisteredEventArgs {
nick: string;
}
export interface QuitEventArgs {
hostname: string;
ident: string;
message: string;
nick: string;
time?: any;
channel?: string;
kicked?: string;
}
interface Mode {
mode: string;
param: string;
}
export interface ModeEventArgs {
modes: Mode[];
nick: string;
raw_modes: string;
raw_params: string[];
target: string;
time?: any;
}
export interface ServerOptionsEventArgs {
options: any;
cap: any;
}
export interface NickInvalidEventArgs {
nick: string;
reason: string;
}
export interface NickInUseEventArgs {
nick: string;
reason: string;
}
export interface IrcErrorEventArgs {
error: string;
channel: string;
reason: string;
}
export class Client extends EventEmitter { export class Client extends EventEmitter {
constructor(options: ClientConstructorParameters); constructor(options: ClientConstructorParameters);
@ -176,11 +253,11 @@ declare module "irc-framework" {
on(eventType: "mode", cb: (event: ModeEventArgs) => any): this; on(eventType: "mode", cb: (event: ModeEventArgs) => any): this;
on(eventType: "socket close", cb: (event: {}) => any): this; on(eventType: "socket close", cb: (event: Record<string, unknown>) => any): this;
on(eventType: "socket connected", cb: (event: {}) => any): this; on(eventType: "socket connected", cb: (event: Record<string, unknown>) => any): this;
on(eventType: "raw socket connected", cb: (event: {}) => any): this; on(eventType: "raw socket connected", cb: (event: Record<string, unknown>) => any): this;
on(eventType: "server options", cb: (event: ServerOptionsEventArgs) => any): this; on(eventType: "server options", cb: (event: ServerOptionsEventArgs) => any): this;
@ -217,83 +294,7 @@ declare module "irc-framework" {
type: string; type: string;
} }
export interface MessageEventArgs {
account?: any;
group?: any;
hostname: string;
ident: string;
message: string;
nick: string;
reply: (message: string) => void;
tags: {[key: string]: string};
target: string;
time?: any;
type: "privmsg" | "action"; // TODO
}
export interface JoinEventArgs {
// todo: is that wrong?
account: boolean;
channel: string;
gecos: string;
hostname: string;
ident: string;
nick: string;
time?: any;
}
export interface KickEventArgs {
kicked: string;
nick: string;
ident: string;
hostname: string;
channel: string;
message: string;
time: number;
}
export interface RawEventArgs {
from_server: boolean;
line: string;
}
export interface RegisteredEventArgs {
nick: string;
}
export interface QuitEventArgs {
hostname: string;
ident: string;
message: string;
nick: string;
time?: any;
channel?: string;
kicked?: string;
}
interface Mode {
mode: string;
param: string;
}
export interface ModeEventArgs {
modes: Mode[];
nick: string;
raw_modes: string;
raw_params: string[];
target: string;
time?: any;
}
export interface ServerOptionsEventArgs {
options: any;
cap: any;
}
export interface NickInvalidEventArgs {
nick: string;
reason: string;
}
export interface NickInUseEventArgs {
nick: string;
reason: string;
}
export interface IrcErrorEventArgs {
error: string;
channel: string;
reason: string;
}
// interface IrcUser { // interface IrcUser {
// /**The current nick you are currently using.*/ // /**The current nick you are currently using.*/
// nick: string; // nick: string;

View file

@ -1,2 +0,0 @@
// / <reference path="themes.d.ts" />
// / <reference path="packages.d.ts" />

View file

@ -1,7 +0,0 @@
type PackageInfo = {
packageName: string;
thelounge?: {supports: any};
version: string;
type?: string;
files?: string[];
};

View file

@ -1,17 +0,0 @@
// TODO: move to index.d.ts when more types are added
type Module = {
type: string;
name: string;
};
type ThemeModule = Module & {
themeColor: string;
css: string;
};
type ThemeForClient = {
displayName: string;
filename?: string;
name: string;
themeColor: string | null;
};

View file

@ -1,10 +0,0 @@
import Client from "../../client";
import ClientManager from "../../clientManager";
type AuthHandler = (
manager: ClientManager,
client: Client,
user: string,
password: string,
callback: (success: boolean) => void
) => void;

View file

@ -1,4 +0,0 @@
type ClientCertificate = {
private_key: string;
certificate: string;
};

View file

@ -1,7 +1 @@
// / <reference path="sts.d.ts" /> import "./messageStorage";
// / <reference path="messageStorage/index.d.ts" />
// / <reference path="clientCertificate.d.ts" />
// / <reference path="preview.d.ts" />
// / <reference path="inputs/index.d.ts" />
// / <reference path="irc-events/index.d.ts" />
// / <reference path="auth/index.d.ts" />

View file

@ -1,11 +0,0 @@
import Client from "../../../client";
declare global {
type PluginInputHandler = (
this: Client,
network: NetworkWithIrcFramework,
chan: Channel,
cmd: string,
args: string[]
) => void;
}

View file

@ -1,9 +0,0 @@
import Client from "../../client";
declare global {
type IrcEventHandler = (
this: Client,
irc: NetworkWithIrcFramework["irc"],
network: NetworkWithIrcFramework
) => void;
}

View file

@ -1,13 +0,0 @@
import Msg from "../../models/msg";
type Preview = {
type: string;
head: string;
body: string;
thumb: string;
size: number;
link: string; // Send original matched link to the client
shown: boolean | null;
error: undefined | any;
message: undefined | string;
};

View file

@ -1,8 +0,0 @@
type PolicyOption = {
port: number;
duration: number;
expires: number;
host: string;
};
export type PolicyMap = Map<string, Omit<PolicyOption, "host">>;

View file

@ -1,3 +0,0 @@
export type ServerOptions = {
dev: boolean;
};

View file

@ -1,5 +0,0 @@
type RequiredNotNull<T> = {
[P in keyof T]: NonNullable<T[P]>;
};
type Ensure<T, K extends keyof T> = T & RequiredNotNull<Pick<T, K>>;

View file

@ -1,18 +1,6 @@
{ {
"extends": "./tsconfig.base.json", "extends": "./tsconfig.base.json",
"files": ["index.ts", "./src/index.d.ts", "./webpack.config.ts", "./src/helper.ts"], "files": ["./webpack.config.ts", "./babel.config.cjs", "./src/helper.ts"],
"compilerOptions": {
"types": ["node"],
"paths": {
"@src/*": ["src/*"],
"@client/*": ["client/*"]
}
},
"ts-node": {
"files": true
},
"exclude": ["./node_modules"],
"include": ["./src/**/*"],
"references": [ "references": [
{ {
"path": "./src" "path": "./src"

View file

@ -1665,6 +1665,11 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/webpack-env@1.16.4":
version "1.16.4"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.4.tgz#1f4969042bf76d7ef7b5914f59b3b60073f4e1f4"
integrity sha512-llS8qveOUX3wxHnSykP5hlYFFuMfJ9p5JvIyCiBgp7WTfl6K5ZcyHj8r8JsN/J6QODkAsRRCLIcTuOCu8etkUw==
"@types/ws@8.5.3": "@types/ws@8.5.3":
version "8.5.3" version "8.5.3"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"