diff --git a/client/types.d.ts b/client/index.ts similarity index 84% rename from client/types.d.ts rename to client/index.ts index 44ce29a7..9a61ce27 100644 --- a/client/types.d.ts +++ b/client/index.ts @@ -1,3 +1,5 @@ +import Chan from "../src/models/chan"; + declare module "*.vue" { import Vue from "vue"; export default Vue; diff --git a/client/tsconfig.json b/client/tsconfig.json index 2d170111..0d12133f 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -5,7 +5,8 @@ "../src/types/models/channel.d.ts", "js/helpers/simplemap.json", "js/helpers/fullnamemap.json", - "../package.json" + "../package.json", + "./types.d.ts" ], "compilerOptions": { // "paths": { diff --git a/package.json b/package.json index de5beab4..5a1c2022 100644 --- a/package.json +++ b/package.json @@ -13,15 +13,15 @@ "homepage": "https://thelounge.chat/", "scripts": { "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", - "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 \"**/*.*\"", "lint:check-eslint": "eslint-config-prettier .eslintrc.cjs", "lint:eslint": "eslint . --ext .js,.vue --report-unused-disable-directives --color", "lint:prettier": "prettier --list-different \"**/*.*\"", "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:mocha": "webpack --mode=development && nyc --nycrc-path=test/.nycrc-mocha.json mocha --colors --config=test/.mocharc.yml", "watch": "webpack --watch" @@ -101,6 +101,7 @@ "@types/ua-parser-js": "0.7.36", "@types/uuid": "8.3.4", "@types/web-push": "3.3.2", + "@types/webpack-env": "1.16.4", "@types/ws": "8.5.3", "@typescript-eslint/eslint-plugin": "5.22.0", "@typescript-eslint/parser": "5.22.0", diff --git a/src/client.ts b/src/client.ts index c71b3c01..f200b03d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -8,8 +8,8 @@ import crypto from "crypto"; import colors from "chalk"; import log from "./log"; -import Chan from "./models/chan"; -import Msg from "./models/msg"; +import Chan, {ChanType} from "./models/chan"; +import Msg, {MessageType, UserInMessage} from "./models/msg"; import Config from "./config"; import constants from "../client/js/constants"; @@ -17,7 +17,7 @@ import inputs from "./plugins/inputs"; import PublicClient from "./plugins/packages/publicClient"; import SqliteMessageStorage from "./plugins/messageStorage/sqlite"; import TextFileMessageStorage from "./plugins/messageStorage/text"; -import Network from "./models/network"; +import Network, {NetworkWithIrcFramework} from "./models/network"; import ClientManager from "./clientManager"; import {MessageStorage} from "./types/plugins/messageStorage"; @@ -48,6 +48,46 @@ const events = [ "welcome", "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 { awayMessage!: string; lastActiveChannel!: number; @@ -272,12 +312,11 @@ class Client { networks: [network.getFilteredClone(this.lastActiveChannel, -1)], }); - // @ts-ignore it complains because validate expects this to be NetworkWith - if (!network.validate(client)) { + if (!(network as NetworkWithIrcFramework).validate(client)) { return; } - network.createIrcFramework(client); + (network as NetworkWithIrcFramework).createIrcFramework(client); events.forEach(async (plugin) => { (await import(`./plugins/irc-events/${plugin}`)).default.apply(client, [ @@ -413,6 +452,11 @@ class Client { if (inputs.userInputs.has(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)) { connected = true; plugin.input.apply(client, [target.network, target.chan, cmd, args]); @@ -785,3 +829,10 @@ class Client { } export default Client; + +// TODO: this should exist elsewhere? +export type IrcEventHandler = ( + this: Client, + irc: NetworkWithIrcFramework["irc"], + network: NetworkWithIrcFramework +) => void; diff --git a/src/config.ts b/src/config.ts index ccc3c45f..2b49fbd1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -7,7 +7,97 @@ import _ from "lodash"; import colors from "chalk"; import log from "./log"; 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 { values = require(path.resolve( diff --git a/src/helper.ts b/src/helper.ts index 9356ef21..319715bf 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -8,7 +8,12 @@ import fs from "fs"; import net from "net"; import bcrypt from "bcryptjs"; import crypto from "crypto"; -import {Hostmask} from "./types/helper"; + +export type Hostmask = { + nick: string; + ident: string; + hostname: string; +}; const Helper = { expandHome, diff --git a/src/index.d.ts b/src/index.d.ts index 987c29b8..41dcf033 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1 +1 @@ -// / +import "./types"; diff --git a/index.ts b/src/index.ts similarity index 93% rename from index.ts rename to src/index.ts index de72303b..2ac0dea6 100755 --- a/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ process.chdir(__dirname); // Perform node version check before loading any other files or modules // Doing this check as soon as possible allows us to // avoid ES6 parser errors or other issues -import pkg from "./package.json"; +import pkg from "../package.json"; import {satisfies} from "semver"; if (!satisfies(process.version, pkg.engines.node)) { @@ -33,4 +33,4 @@ if (dns.setDefaultResultOrder) { dns.setDefaultResultOrder("verbatim"); } -import "./src/command-line"; +import "./command-line"; diff --git a/src/models/chan.ts b/src/models/chan.ts index e463b6f9..968aba92 100644 --- a/src/models/chan.ts +++ b/src/models/chan.ts @@ -4,12 +4,37 @@ import _ from "lodash"; import log from "../log"; import Config from "../config"; import User from "./user"; -import Msg from "./msg"; +import Msg, {MessageType} from "./msg"; import storage from "../plugins/storage"; import Client from "../client"; import Network from "./network"; 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 { // TODO: don't force existence, figure out how to make TS infer it. id!: number; @@ -298,3 +323,5 @@ function requestZncPlayback(channel, network, from) { } export default Chan; + +export type Channel = Chan; diff --git a/src/models/msg.ts b/src/models/msg.ts index cba07644..f2674ba6 100644 --- a/src/models/msg.ts +++ b/src/models/msg.ts @@ -1,6 +1,48 @@ "use strict"; import _ from "lodash"; +import User from "./user"; + +export type UserInMessage = Partial & { + 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 { from!: UserInMessage; @@ -95,3 +137,5 @@ class Msg { } export default Msg; + +export type Message = Msg; diff --git a/src/models/network.ts b/src/models/network.ts index 5f1e8012..e77f81e5 100644 --- a/src/models/network.ts +++ b/src/models/network.ts @@ -2,14 +2,14 @@ import _ from "lodash"; import {v4 as uuidv4} from "uuid"; -import IrcFramework from "irc-framework"; -import Chan from "./chan"; -import Msg from "./msg"; +import IrcFramework, {Client as IRCClient} from "irc-framework"; +import Chan, {Channel, ChanType} from "./chan"; +import Msg, {MessageType} from "./msg"; import Prefix from "./prefix"; -import Helper from "../helper"; -import Config from "../config"; +import Helper, {Hostmask} from "../helper"; +import Config, {WebIRC} from "../config"; import STSPolicies from "../plugins/sts"; -import ClientCertificate from "../plugins/clientCertificate"; +import ClientCertificate, {ClientCertificateType} from "../plugins/clientCertificate"; import Client from "../client"; /** @@ -22,6 +22,53 @@ const fieldsForClient = { 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; +}; + +type NetworkStatus = { + connected: boolean; + secure: boolean; +}; + +export type IgnoreListItem = Hostmask & { + when?: number; +}; + +type IgnoreList = IgnoreListItem[]; + +type NonNullableIRCWithOptions = NonNullable; + +// eslint-disable-next-line no-use-before-define +export type NetworkWithIrcFramework = Network & { + // eslint-disable-next-line no-use-before-define + irc: NonNullable & { + options: NonNullableIRCWithOptions; + }; +}; + class Network { nick!: string; name!: string; @@ -223,7 +270,7 @@ class Network { return true; } - createIrcFramework(this: Network, client: Client) { + createIrcFramework(this: NetworkWithIrcFramework, client: Client) { this.irc = new IrcFramework.Client({ version: false, // We handle it ourselves outgoing_addr: Config.values.bind, @@ -237,7 +284,6 @@ class Network { auto_reconnect_max_retries: 30, }); - // @ts-ignore TODO: `this` should now be a NetworkWithIrcFramework this.setIrcFrameworkOptions(client); this.irc.requestCap([ diff --git a/src/models/prefix.ts b/src/models/prefix.ts index c0e939ff..263157a8 100644 --- a/src/models/prefix.ts +++ b/src/models/prefix.ts @@ -1,5 +1,12 @@ "use strict"; +type PrefixSymbol = string; + +type PrefixObject = { + symbol: PrefixSymbol; + mode: string; +}; + class Prefix { prefix: PrefixObject[]; modeToSymbol: {[mode: string]: string}; diff --git a/src/plugins/auth.ts b/src/plugins/auth.ts index e560ecc5..e2e9c12b 100644 --- a/src/plugins/auth.ts +++ b/src/plugins/auth.ts @@ -1,8 +1,18 @@ "use strict"; import colors from "chalk"; +import Client from "../client"; +import ClientManager from "../clientManager"; 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. // Always keep 'local' auth plugin at the end of the list; it should always be enabled. const plugins = [import("./auth/ldap"), import("./auth/local")]; diff --git a/src/plugins/auth/ldap.ts b/src/plugins/auth/ldap.ts index 3a6a5a89..e03edeef 100644 --- a/src/plugins/auth/ldap.ts +++ b/src/plugins/auth/ldap.ts @@ -1,10 +1,10 @@ "use strict"; +import ldap, {SearchOptions} from "ldapjs"; +import colors from "chalk"; import log from "../../log"; import Config from "../../config"; -import ldap, {SearchOptions} from "ldapjs"; -import colors from "chalk"; -import {AuthHandler} from "types/plugins/auth"; +import type {AuthHandler} from "../auth"; function ldapAuthCommon( user: string, @@ -191,9 +191,8 @@ function advancedLdapLoadUsers(users: string[], callbackLoadUser) { } res.on("searchEntry", function (entry) { - // @ts-ignore - // TODO - const user = entry.attributes[0]._vals[0].toString(); + // TODO: was _vals. + const user = entry.attributes[0].vals[0].toString(); if (remainingUsers.has(user)) { remainingUsers.delete(user); diff --git a/src/plugins/auth/local.ts b/src/plugins/auth/local.ts index c4a4e7cc..ec3f1e07 100644 --- a/src/plugins/auth/local.ts +++ b/src/plugins/auth/local.ts @@ -3,7 +3,7 @@ import colors from "chalk"; import log from "../../log"; import Helper from "../../helper"; -import {AuthHandler} from "../../types/plugins/auth"; +import type {AuthHandler} from "../auth"; const localAuth: AuthHandler = (manager, client, user, password, callback) => { // If no user is found, or if the client has not provided a password, diff --git a/src/plugins/clientCertificate.ts b/src/plugins/clientCertificate.ts index 4126ce5c..7368d868 100644 --- a/src/plugins/clientCertificate.ts +++ b/src/plugins/clientCertificate.ts @@ -12,7 +12,12 @@ export default { 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) { return null; } @@ -28,7 +33,7 @@ function get(uuid: string): ClientCertificate | null { return { private_key: fs.readFileSync(paths.privateKeyPath, "utf-8"), certificate: fs.readFileSync(paths.certificatePath, "utf-8"), - } as ClientCertificate; + } as ClientCertificateType; } catch (e: any) { log.error("Unable to get certificate", e); } @@ -121,7 +126,7 @@ function generate() { const pem = { private_key: pki.privateKeyToPem(keys.privateKey), certificate: pki.certificateToPem(cert), - } as ClientCertificate; + } as ClientCertificateType; return pem; } diff --git a/src/plugins/dev-server.ts b/src/plugins/dev-server.ts index f2e97859..3344225a 100644 --- a/src/plugins/dev-server.ts +++ b/src/plugins/dev-server.ts @@ -1,6 +1,6 @@ "use strict"; import log from "../log"; -import webpack from "webpack"; +import webpackDevMiddleware from "webpack-dev-middleware"; export default (app) => { log.debug("Starting server in development mode"); @@ -16,12 +16,12 @@ export default (app) => { const compiler = webpack(webpackConfig); app.use( - require("webpack-dev-middleware")(compiler, { + webpackDevMiddleware(compiler, { index: "/", publicPath: webpackConfig.output.publicPath, }) ).use( - require("webpack-hot-middleware")(compiler, { + webpackDevMiddleware(compiler, { path: "/storage/__webpack_hmr", }) ); diff --git a/src/plugins/inputs/action.ts b/src/plugins/inputs/action.ts index 4c11e8d4..22134e93 100644 --- a/src/plugins/inputs/action.ts +++ b/src/plugins/inputs/action.ts @@ -1,6 +1,8 @@ "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"]; diff --git a/src/plugins/inputs/away.ts b/src/plugins/inputs/away.ts index ca982965..ad5cc46d 100644 --- a/src/plugins/inputs/away.ts +++ b/src/plugins/inputs/away.ts @@ -1,6 +1,7 @@ "use strict"; const commands = ["away", "back"]; +import {PluginInputHandler} from "./index"; const input: PluginInputHandler = function (network, chan, cmd, args) { let reason = ""; diff --git a/src/plugins/inputs/ban.ts b/src/plugins/inputs/ban.ts index 53c020d6..47280ea2 100644 --- a/src/plugins/inputs/ban.ts +++ b/src/plugins/inputs/ban.ts @@ -1,6 +1,8 @@ "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"]; diff --git a/src/plugins/inputs/connect.ts b/src/plugins/inputs/connect.ts index 5182f89d..d99af205 100644 --- a/src/plugins/inputs/connect.ts +++ b/src/plugins/inputs/connect.ts @@ -1,6 +1,7 @@ "use strict"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; +import {PluginInputHandler} from "./index"; const commands = ["connect", "server"]; const allowDisconnected = true; diff --git a/src/plugins/inputs/ctcp.ts b/src/plugins/inputs/ctcp.ts index 2620ed3c..4201ff36 100644 --- a/src/plugins/inputs/ctcp.ts +++ b/src/plugins/inputs/ctcp.ts @@ -1,6 +1,7 @@ "use strict"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; +import {PluginInputHandler} from "./index"; const commands = ["ctcp"]; diff --git a/src/plugins/inputs/disconnect.ts b/src/plugins/inputs/disconnect.ts index ba396f08..7cb8a17e 100644 --- a/src/plugins/inputs/disconnect.ts +++ b/src/plugins/inputs/disconnect.ts @@ -1,4 +1,5 @@ "use strict"; +import {PluginInputHandler} from "./index"; const commands = ["disconnect"]; const allowDisconnected = true; diff --git a/src/plugins/inputs/ignore.ts b/src/plugins/inputs/ignore.ts index dae678a9..a9c49143 100644 --- a/src/plugins/inputs/ignore.ts +++ b/src/plugins/inputs/ignore.ts @@ -1,7 +1,10 @@ "use strict"; -import Msg from "../../models/msg"; -import Helper from "helper"; +import Msg, {MessageType} from "../../models/msg"; +import Helper from "../../helper"; +import {PluginInputHandler} from "./index"; +import {IgnoreListItem} from "../../models/network"; +import {ChanType, SpecialChanType} from "../../models/chan"; const commands = ["ignore", "unignore", "ignorelist"]; diff --git a/src/plugins/inputs/index.ts b/src/plugins/inputs/index.ts index c22d7f64..72036491 100644 --- a/src/plugins/inputs/index.ts +++ b/src/plugins/inputs/index.ts @@ -1,5 +1,20 @@ -import Chan from "../../models/chan"; -import Network from "../../models/network"; +import Client from "../../client"; +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"]; @@ -16,7 +31,8 @@ const passThroughCommands = [ "/rs", ]; -const userInputs = [ +const userInputs = new Map(); +const builtInInputs = [ "action", "away", "ban", @@ -39,8 +55,10 @@ const userInputs = [ "topic", "whois", "mute", -].reduce(function (plugins, name) { - const plugin = import(`./${name}`).then( +]; + +for (const input of builtInInputs) { + import(`./${input}`).then( (plugin: { default: { commands: string[]; @@ -48,11 +66,26 @@ const userInputs = [ 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(); diff --git a/src/plugins/inputs/invite.ts b/src/plugins/inputs/invite.ts index 57203ef7..5b0592b8 100644 --- a/src/plugins/inputs/invite.ts +++ b/src/plugins/inputs/invite.ts @@ -1,9 +1,8 @@ "use strict"; -import Network from "../../models/network"; - -import Chan from "../../models/chan"; -import Msg from "../../models/msg"; +import {PluginInputHandler} from "./index"; +import Msg, {MessageType} from "../../models/msg"; +import {ChanType} from "../../models/chan"; const commands = ["invite", "invitelist"]; diff --git a/src/plugins/inputs/kick.ts b/src/plugins/inputs/kick.ts index ca26660c..47715875 100644 --- a/src/plugins/inputs/kick.ts +++ b/src/plugins/inputs/kick.ts @@ -1,6 +1,7 @@ "use strict"; - -import Msg from "../../models/msg"; +import {PluginInputHandler} from "./index"; +import Msg, {MessageType} from "../../models/msg"; +import {ChanType} from "../../models/chan"; const commands = ["kick"]; diff --git a/src/plugins/inputs/kill.ts b/src/plugins/inputs/kill.ts index 2fdae60d..65936ef9 100644 --- a/src/plugins/inputs/kill.ts +++ b/src/plugins/inputs/kill.ts @@ -1,4 +1,5 @@ "use strict"; +import {PluginInputHandler} from "./index"; const commands = ["kill"]; diff --git a/src/plugins/inputs/list.ts b/src/plugins/inputs/list.ts index ff239404..4cb374fe 100644 --- a/src/plugins/inputs/list.ts +++ b/src/plugins/inputs/list.ts @@ -1,4 +1,5 @@ "use strict"; +import {PluginInputHandler} from "./index"; const commands = ["list"]; diff --git a/src/plugins/inputs/mode.ts b/src/plugins/inputs/mode.ts index 9f42784a..afb92ec7 100644 --- a/src/plugins/inputs/mode.ts +++ b/src/plugins/inputs/mode.ts @@ -1,6 +1,8 @@ "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"]; diff --git a/src/plugins/inputs/msg.ts b/src/plugins/inputs/msg.ts index f75d4d68..5962d346 100644 --- a/src/plugins/inputs/msg.ts +++ b/src/plugins/inputs/msg.ts @@ -1,8 +1,7 @@ "use strict"; - -import Network from "../../models/network"; - -import Msg from "../../models/msg"; +import {PluginInputHandler} from "./index"; +import Msg, {MessageType} from "../../models/msg"; +import {ChanType} from "../../models/chan"; const commands = ["query", "msg", "say"]; diff --git a/src/plugins/inputs/mute.ts b/src/plugins/inputs/mute.ts index cf436481..795bf584 100644 --- a/src/plugins/inputs/mute.ts +++ b/src/plugins/inputs/mute.ts @@ -1,8 +1,9 @@ "use strict"; import Chan from "../../models/chan"; import Network from "../../models/network"; +import {PluginInputHandler} from "./index"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; import Client from "../../client"; diff --git a/src/plugins/inputs/nick.ts b/src/plugins/inputs/nick.ts index 3f4f3615..64cca99d 100644 --- a/src/plugins/inputs/nick.ts +++ b/src/plugins/inputs/nick.ts @@ -1,6 +1,7 @@ "use strict"; +import {PluginInputHandler} from "./index"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; const commands = ["nick"]; const allowDisconnected = true; diff --git a/src/plugins/inputs/notice.ts b/src/plugins/inputs/notice.ts index 0ed389f6..ac716226 100644 --- a/src/plugins/inputs/notice.ts +++ b/src/plugins/inputs/notice.ts @@ -1,4 +1,5 @@ "use strict"; +import {PluginInputHandler} from "./index"; const commands = ["notice"]; diff --git a/src/plugins/inputs/part.ts b/src/plugins/inputs/part.ts index ca528ed9..ac20f255 100644 --- a/src/plugins/inputs/part.ts +++ b/src/plugins/inputs/part.ts @@ -1,7 +1,9 @@ "use strict"; +import {PluginInputHandler} from "./index"; -import Msg from "../../models/msg"; -import Config from "config"; +import Msg, {MessageType} from "../../models/msg"; +import Config from "../../config"; +import {ChanType, ChanState} from "../../models/chan"; const commands = ["close", "leave", "part"]; const allowDisconnected = true; diff --git a/src/plugins/inputs/quit.ts b/src/plugins/inputs/quit.ts index 897a1513..4fcf0a89 100644 --- a/src/plugins/inputs/quit.ts +++ b/src/plugins/inputs/quit.ts @@ -1,7 +1,7 @@ "use strict"; - import _ from "lodash"; +import {PluginInputHandler} from "./index"; import ClientCertificate from "../clientCertificate"; const commands = ["quit"]; diff --git a/src/plugins/inputs/raw.ts b/src/plugins/inputs/raw.ts index eee80da9..ee213794 100644 --- a/src/plugins/inputs/raw.ts +++ b/src/plugins/inputs/raw.ts @@ -1,4 +1,5 @@ "use strict"; +import {PluginInputHandler} from "./index"; const commands = ["raw", "send", "quote"]; diff --git a/src/plugins/inputs/rejoin.ts b/src/plugins/inputs/rejoin.ts index add0ce1a..eacde406 100644 --- a/src/plugins/inputs/rejoin.ts +++ b/src/plugins/inputs/rejoin.ts @@ -1,6 +1,8 @@ "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"]; diff --git a/src/plugins/inputs/topic.ts b/src/plugins/inputs/topic.ts index 936e8d24..c00bee8d 100644 --- a/src/plugins/inputs/topic.ts +++ b/src/plugins/inputs/topic.ts @@ -1,6 +1,8 @@ "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"]; diff --git a/src/plugins/inputs/whois.ts b/src/plugins/inputs/whois.ts index 6494b509..52cf4b76 100644 --- a/src/plugins/inputs/whois.ts +++ b/src/plugins/inputs/whois.ts @@ -1,4 +1,5 @@ "use strict"; +import {PluginInputHandler} from "./index"; const commands = ["whois"]; diff --git a/src/plugins/irc-events/away.ts b/src/plugins/irc-events/away.ts index 2dd91d69..f8c36600 100644 --- a/src/plugins/irc-events/away.ts +++ b/src/plugins/irc-events/away.ts @@ -1,6 +1,7 @@ "use strict"; - -import Msg from "../../models/msg"; +import {IrcEventHandler} from "../../client"; +import {ChanType} from "../../models/chan"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/cap.ts b/src/plugins/irc-events/cap.ts index f93665b7..37fc30a4 100644 --- a/src/plugins/irc-events/cap.ts +++ b/src/plugins/irc-events/cap.ts @@ -1,4 +1,5 @@ "use strict"; +import {IrcEventHandler} from "../../client"; import Msg from "../../models/msg"; import STSPolicies from "../sts"; diff --git a/src/plugins/irc-events/chghost.ts b/src/plugins/irc-events/chghost.ts index 72cc0365..4ad4a4c4 100644 --- a/src/plugins/irc-events/chghost.ts +++ b/src/plugins/irc-events/chghost.ts @@ -1,6 +1,7 @@ "use strict"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/connection.ts b/src/plugins/irc-events/connection.ts index 99553a1b..8b399919 100644 --- a/src/plugins/irc-events/connection.ts +++ b/src/plugins/irc-events/connection.ts @@ -1,10 +1,13 @@ "use strict"; import _ from "lodash"; +import {IrcEventHandler} from "../../client"; + import log from "../../log"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; import Helper from "../../helper"; import Config from "../../config"; +import {ChanType, ChanState} from "../../models/chan"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/ctcp.ts b/src/plugins/irc-events/ctcp.ts index c82b30ee..163830ec 100644 --- a/src/plugins/irc-events/ctcp.ts +++ b/src/plugins/irc-events/ctcp.ts @@ -1,10 +1,9 @@ "use strict"; -import Network from "../../models/network"; - import _ from "lodash"; +import {IrcEventHandler} from "../../client"; import Helper from "../../helper"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; import User from "../../models/user"; import pkg from "../../../package.json"; diff --git a/src/plugins/irc-events/error.ts b/src/plugins/irc-events/error.ts index e73323cd..1a13601c 100644 --- a/src/plugins/irc-events/error.ts +++ b/src/plugins/irc-events/error.ts @@ -1,8 +1,8 @@ "use strict"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; import Config from "../../config"; -import Network from "../../models/network"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/help.ts b/src/plugins/irc-events/help.ts index 358443a9..740dc838 100644 --- a/src/plugins/irc-events/help.ts +++ b/src/plugins/irc-events/help.ts @@ -1,8 +1,7 @@ "use strict"; -import Network from "../../models/network"; - -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; +import {IrcEventHandler} from "../../client"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/info.ts b/src/plugins/irc-events/info.ts index e16501b8..6ce32938 100644 --- a/src/plugins/irc-events/info.ts +++ b/src/plugins/irc-events/info.ts @@ -1,6 +1,7 @@ "use strict"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; +import {IrcEventHandler} from "../../client"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/invite.ts b/src/plugins/irc-events/invite.ts index 41995164..05d97938 100644 --- a/src/plugins/irc-events/invite.ts +++ b/src/plugins/irc-events/invite.ts @@ -1,8 +1,8 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/join.ts b/src/plugins/irc-events/join.ts index bf00cd17..32722b00 100644 --- a/src/plugins/irc-events/join.ts +++ b/src/plugins/irc-events/join.ts @@ -1,14 +1,11 @@ "use strict"; -import {ChanState} from "../../types/models/channel"; - -import {Network} from "../../types/models/network"; - -import Chan from "../../models/chan"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; 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 function (irc, network) { const client = this; irc.on("join", function (data) { diff --git a/src/plugins/irc-events/kick.ts b/src/plugins/irc-events/kick.ts index 9901317b..c9cdfe16 100644 --- a/src/plugins/irc-events/kick.ts +++ b/src/plugins/irc-events/kick.ts @@ -1,6 +1,9 @@ "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 function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/link.ts b/src/plugins/irc-events/link.ts index f1fa4e8f..6ceddfb9 100644 --- a/src/plugins/irc-events/link.ts +++ b/src/plugins/irc-events/link.ts @@ -9,15 +9,25 @@ import log from "../../log"; import Config from "../../config"; import {findLinksWithSchema} from "../../../client/js/helpers/ircmessageparser/findLinks"; import storage from "../storage"; -import Client from "../../client"; +import Client, {IrcEventHandler} from "../../client"; import Chan from "../../models/chan"; import Msg from "../../models/msg"; -import {Preview} from "../../types/plugins/preview"; - const currentFetchPromises = new Map(); const imageTypeRegex = /^image\/.+/; 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) { if (!Config.values.prefetch) { 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) => { if (Config.values.disableMediaPreview) { reject(); diff --git a/src/plugins/irc-events/list.ts b/src/plugins/irc-events/list.ts index d0b4c5b8..e22c1a3f 100644 --- a/src/plugins/irc-events/list.ts +++ b/src/plugins/irc-events/list.ts @@ -1,8 +1,8 @@ "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 function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/message.ts b/src/plugins/irc-events/message.ts index 92f09287..b04aa175 100644 --- a/src/plugins/irc-events/message.ts +++ b/src/plugins/irc-events/message.ts @@ -1,10 +1,11 @@ "use strict"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; import LinkPrefetch from "./link"; import cleanIrcMessage from "../../../client/js/helpers/ircmessageparser/cleanIrcMessage"; 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; @@ -204,7 +205,7 @@ export default function (irc, network) { chanId: chan.id, msgId: msg.id, type: msg.type, - time: msg.time, + time: msg.time.getTime(), text: msg.text, from: msg.from, }); diff --git a/src/plugins/irc-events/mode.ts b/src/plugins/irc-events/mode.ts index 1f9b0fc4..77c44ef3 100644 --- a/src/plugins/irc-events/mode.ts +++ b/src/plugins/irc-events/mode.ts @@ -1,9 +1,9 @@ "use strict"; 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 function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/modelist.ts b/src/plugins/irc-events/modelist.ts index 831d4ee9..ccd20e44 100644 --- a/src/plugins/irc-events/modelist.ts +++ b/src/plugins/irc-events/modelist.ts @@ -1,9 +1,9 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; +import {SpecialChanType, ChanType} from "../../models/chan"; -import Chan from "../../models/chan"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/motd.ts b/src/plugins/irc-events/motd.ts index 901ed9d1..832b7a2a 100644 --- a/src/plugins/irc-events/motd.ts +++ b/src/plugins/irc-events/motd.ts @@ -1,8 +1,8 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/names.ts b/src/plugins/irc-events/names.ts index 53137fcc..af622f5e 100644 --- a/src/plugins/irc-events/names.ts +++ b/src/plugins/irc-events/names.ts @@ -1,6 +1,6 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/nick.ts b/src/plugins/irc-events/nick.ts index 8f95291a..75aa0e4f 100644 --- a/src/plugins/irc-events/nick.ts +++ b/src/plugins/irc-events/nick.ts @@ -1,8 +1,8 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/part.ts b/src/plugins/irc-events/part.ts index bee71098..b4d2de81 100644 --- a/src/plugins/irc-events/part.ts +++ b/src/plugins/irc-events/part.ts @@ -1,13 +1,17 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; irc.on("part", function (data) { + if (!data.channel) { + return; + } + const chan = network.getChannel(data.channel); if (typeof chan === "undefined") { diff --git a/src/plugins/irc-events/quit.ts b/src/plugins/irc-events/quit.ts index b321acab..9ea053f0 100644 --- a/src/plugins/irc-events/quit.ts +++ b/src/plugins/irc-events/quit.ts @@ -1,8 +1,8 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/sasl.ts b/src/plugins/irc-events/sasl.ts index c3c2e33a..546afe72 100644 --- a/src/plugins/irc-events/sasl.ts +++ b/src/plugins/irc-events/sasl.ts @@ -1,8 +1,8 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/topic.ts b/src/plugins/irc-events/topic.ts index c429b455..23582e3b 100644 --- a/src/plugins/irc-events/topic.ts +++ b/src/plugins/irc-events/topic.ts @@ -1,6 +1,7 @@ "use strict"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/unhandled.ts b/src/plugins/irc-events/unhandled.ts index 1b94d342..587f0165 100644 --- a/src/plugins/irc-events/unhandled.ts +++ b/src/plugins/irc-events/unhandled.ts @@ -1,8 +1,8 @@ "use strict"; -import Network from "../../models/network"; +import {IrcEventHandler} from "../../client"; -import Msg from "../../models/msg"; +import Msg, {MessageType} from "../../models/msg"; export default function (irc, network) { const client = this; diff --git a/src/plugins/irc-events/welcome.ts b/src/plugins/irc-events/welcome.ts index 7b515a16..b16767ce 100644 --- a/src/plugins/irc-events/welcome.ts +++ b/src/plugins/irc-events/welcome.ts @@ -1,4 +1,5 @@ "use strict"; +import {IrcEventHandler} from "../../client"; import Msg from "../../models/msg"; diff --git a/src/plugins/irc-events/whois.ts b/src/plugins/irc-events/whois.ts index d3e8d9fa..51e2d6c0 100644 --- a/src/plugins/irc-events/whois.ts +++ b/src/plugins/irc-events/whois.ts @@ -1,8 +1,9 @@ "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 function (irc, network) { const client = this; diff --git a/src/plugins/messageStorage/sqlite.ts b/src/plugins/messageStorage/sqlite.ts index 0b274365..2c4cfa9b 100644 --- a/src/plugins/messageStorage/sqlite.ts +++ b/src/plugins/messageStorage/sqlite.ts @@ -6,10 +6,11 @@ import log from "../../log"; import path from "path"; import fs from "fs"; import Config from "../../config"; -import Msg from "../../models/msg"; +import Msg, {Message} from "../../models/msg"; 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 Network from "../../models/network"; // TODO; type let sqlite3: any; diff --git a/src/plugins/messageStorage/text.ts b/src/plugins/messageStorage/text.ts index ec89dd24..d775cea0 100644 --- a/src/plugins/messageStorage/text.ts +++ b/src/plugins/messageStorage/text.ts @@ -7,6 +7,9 @@ import log from "../../log"; import Config from "../../config"; import {MessageStorage} from "../../types/plugins/messageStorage"; import Client from "../../client"; +import Channel from "../../models/chan"; +import {Message, MessageType} from "../../models/msg"; +import Network from "../../models/network"; class TextFileMessageStorage implements MessageStorage { client: Client; diff --git a/src/plugins/packages/index.ts b/src/plugins/packages/index.ts index 77353b86..fcc186e8 100644 --- a/src/plugins/packages/index.ts +++ b/src/plugins/packages/index.ts @@ -14,6 +14,14 @@ import fs from "fs"; import Utils from "../../command-line/utils"; import Client from "../../client"; +type PackageInfo = { + packageName: string; + thelounge?: {supports: any}; + version: string; + type?: string; + files?: string[]; +}; + const stylesheets: string[] = []; const files: string[] = []; diff --git a/src/plugins/packages/publicClient.ts b/src/plugins/packages/publicClient.ts index 55db5c10..b9267f08 100644 --- a/src/plugins/packages/publicClient.ts +++ b/src/plugins/packages/publicClient.ts @@ -1,6 +1,6 @@ import Client from "../../client"; import Chan from "../../models/chan"; -import Msg from "../../models/msg"; +import Msg, {MessageType, UserInMessage} from "../../models/msg"; export default class PublicClient { 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} 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}); } @@ -34,7 +34,7 @@ export default class PublicClient { * @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 */ - sendToBrowser(event, data) { + sendToBrowser(event: string, data) { this.client.emit(event, data); } @@ -42,7 +42,7 @@ export default class PublicClient { * * @param {Number} chanId */ - getChannel(chanId) { + getChannel(chanId: number) { return this.client.find(chanId); } diff --git a/src/plugins/packages/themes.ts b/src/plugins/packages/themes.ts index 0ebadfcb..2abd031b 100644 --- a/src/plugins/packages/themes.ts +++ b/src/plugins/packages/themes.ts @@ -6,7 +6,24 @@ import _ from "lodash"; 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(); export default { addTheme, diff --git a/src/plugins/sts.ts b/src/plugins/sts.ts index a65b2a9d..29989f2b 100644 --- a/src/plugins/sts.ts +++ b/src/plugins/sts.ts @@ -5,7 +5,15 @@ import fs from "fs"; import path from "path"; import log from "../log"; 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>; class STSPolicies { stsFile: string; diff --git a/src/server.ts b/src/server.ts index 89563054..7dfe873d 100644 --- a/src/server.ts +++ b/src/server.ts @@ -16,24 +16,50 @@ import Client from "./client"; import ClientManager from "./clientManager"; import Uploader from "./plugins/uploader"; import Helper from "./helper"; -import Config from "./config"; +import Config, {ConfigType, Defaults} from "./config"; import Identification from "./identification"; import changelog from "./plugins/changelog"; import inputs from "./plugins/inputs"; import Auth from "./plugins/auth"; -import themes from "./plugins/packages/themes"; +import themes, {ThemeForClient} from "./plugins/packages/themes"; themes.loadLocalThemes(); import packages from "./plugins/packages/index"; -import type { - ClientConfiguration, - Defaults, - IndexTemplateConfiguration, - ServerConfiguration, -} from "./types/config"; +import {NetworkWithIrcFramework} from "./models/network"; +import {ChanType} from "./models/chan"; -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 const serverHash = Math.floor(Date.now() * Math.random()); @@ -59,7 +85,7 @@ export default async function ( const app = express(); if (options.dev) { - (await import("./plugins/dev-server.js")).default(app); + (await import("./plugins/dev-server")).default(app); } app.set("env", "production") @@ -85,7 +111,7 @@ export default async function ( const themeName = req.params.theme; const theme = themes.getByName(themeName); - if (theme === undefined) { + if (theme === undefined || theme.filename === undefined) { return res.status(404).send("Not found"); } diff --git a/src/tsconfig.json b/src/tsconfig.json index b4737d0e..fcd5859e 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -6,10 +6,13 @@ "../client/js/helpers/ircmessageparser/findLinks.ts", "../client/js/helpers/ircmessageparser/cleanIrcMessage.ts" ], + "ts-node": { + "files": true + }, // TODO: these should be imported from the base config, // but ts-node doesn't seem to care. - "include": ["**/*"], - "typeRoots": ["./src/types/"], + // "include": ["**/*"], + // "typeRoots": ["./types/"], "compilerOptions": { "types": ["node"], diff --git a/src/types/client.d.ts b/src/types/client.d.ts deleted file mode 100644 index cfc2e8ce..00000000 --- a/src/types/client.d.ts +++ /dev/null @@ -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; -}; diff --git a/src/types/config.d.ts b/src/types/config.d.ts deleted file mode 100644 index 601e15c0..00000000 --- a/src/types/config.d.ts +++ /dev/null @@ -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; -}; diff --git a/src/types/helper.d.ts b/src/types/helper.d.ts deleted file mode 100644 index 3277803d..00000000 --- a/src/types/helper.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type Hostmask = { - nick: string; - ident: string; - hostname: string; -}; diff --git a/src/types/index.d.ts b/src/types/index.d.ts index d2978f1f..18affddd 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1,6 +1,2 @@ -// / -// / -// / -// / -// / -// / +import "./modules"; +import "./plugins"; diff --git a/src/types/models/channel.d.ts b/src/types/models/channel.d.ts deleted file mode 100644 index 373aa7ac..00000000 --- a/src/types/models/channel.d.ts +++ /dev/null @@ -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, - } -} diff --git a/src/types/models/index.d.ts b/src/types/models/index.d.ts deleted file mode 100644 index 562edcd4..00000000 --- a/src/types/models/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -// / -// / -// / -// / -// / diff --git a/src/types/models/message.d.ts b/src/types/models/message.d.ts deleted file mode 100644 index 48027e93..00000000 --- a/src/types/models/message.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -import Msg from "../../models/msg"; - -declare global { - type Message = Msg; - - type UserInMessage = Partial & { - 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", - } -} diff --git a/src/types/models/network.d.ts b/src/types/models/network.d.ts deleted file mode 100644 index 22e12f04..00000000 --- a/src/types/models/network.d.ts +++ /dev/null @@ -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; - - type NetworkWithIrcFramework = Network & { - irc: NonNullable & { - options: NonNullableIRCWithOptions; - }; - }; - - type NetworkStatus = { - connected: boolean; - secure: boolean; - }; - - type IgnoreListItem = Hostmask & { - when?: number; - }; - - type IgnoreList = IgnoreListItem[]; -} diff --git a/src/types/models/prefix.d.ts b/src/types/models/prefix.d.ts deleted file mode 100644 index 53d67cce..00000000 --- a/src/types/models/prefix.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -type PrefixSymbol = string; - -type PrefixObject = { - symbol: PrefixSymbol; - mode: string; -}; diff --git a/src/types/models/user.d.ts b/src/types/models/user.d.ts deleted file mode 100644 index b053ec95..00000000 --- a/src/types/models/user.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import UserClass from "models/user"; -declare global { - export type User = UserClass; -} diff --git a/src/types/modules/irc-framework.d.ts b/src/types/modules/irc-framework.d.ts index 740cd6d4..971ae1c0 100644 --- a/src/types/modules/irc-framework.d.ts +++ b/src/types/modules/irc-framework.d.ts @@ -19,6 +19,83 @@ declare module "irc-framework" { 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 { constructor(options: ClientConstructorParameters); @@ -176,11 +253,11 @@ declare module "irc-framework" { on(eventType: "mode", cb: (event: ModeEventArgs) => any): this; - on(eventType: "socket close", cb: (event: {}) => any): this; + on(eventType: "socket close", cb: (event: Record) => any): this; - on(eventType: "socket connected", cb: (event: {}) => any): this; + on(eventType: "socket connected", cb: (event: Record) => any): this; - on(eventType: "raw socket connected", cb: (event: {}) => any): this; + on(eventType: "raw socket connected", cb: (event: Record) => any): this; on(eventType: "server options", cb: (event: ServerOptionsEventArgs) => any): this; @@ -217,83 +294,7 @@ declare module "irc-framework" { 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 { // /**The current nick you are currently using.*/ // nick: string; diff --git a/src/types/packages/index.d.ts b/src/types/packages/index.d.ts deleted file mode 100644 index f540f314..00000000 --- a/src/types/packages/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -// / -// / diff --git a/src/types/packages/packages.d.ts b/src/types/packages/packages.d.ts deleted file mode 100644 index f4759556..00000000 --- a/src/types/packages/packages.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -type PackageInfo = { - packageName: string; - thelounge?: {supports: any}; - version: string; - type?: string; - files?: string[]; -}; diff --git a/src/types/packages/themes.d.ts b/src/types/packages/themes.d.ts deleted file mode 100644 index 2f920714..00000000 --- a/src/types/packages/themes.d.ts +++ /dev/null @@ -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; -}; diff --git a/src/types/plugins/auth/index.d.ts b/src/types/plugins/auth/index.d.ts deleted file mode 100644 index 720ff048..00000000 --- a/src/types/plugins/auth/index.d.ts +++ /dev/null @@ -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; diff --git a/src/types/plugins/clientCertificate.d.ts b/src/types/plugins/clientCertificate.d.ts deleted file mode 100644 index d65b9723..00000000 --- a/src/types/plugins/clientCertificate.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -type ClientCertificate = { - private_key: string; - certificate: string; -}; diff --git a/src/types/plugins/index.d.ts b/src/types/plugins/index.d.ts index 6ae75468..9020c885 100644 --- a/src/types/plugins/index.d.ts +++ b/src/types/plugins/index.d.ts @@ -1,7 +1 @@ -// / -// / -// / -// / -// / -// / -// / +import "./messageStorage"; diff --git a/src/types/plugins/inputs/index.d.ts b/src/types/plugins/inputs/index.d.ts deleted file mode 100644 index 1645c64a..00000000 --- a/src/types/plugins/inputs/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Client from "../../../client"; - -declare global { - type PluginInputHandler = ( - this: Client, - network: NetworkWithIrcFramework, - chan: Channel, - cmd: string, - args: string[] - ) => void; -} diff --git a/src/types/plugins/irc-events/index.d.ts b/src/types/plugins/irc-events/index.d.ts deleted file mode 100644 index a1aebd55..00000000 --- a/src/types/plugins/irc-events/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Client from "../../client"; - -declare global { - type IrcEventHandler = ( - this: Client, - irc: NetworkWithIrcFramework["irc"], - network: NetworkWithIrcFramework - ) => void; -} diff --git a/src/types/plugins/preview.d.ts b/src/types/plugins/preview.d.ts deleted file mode 100644 index 53fa39b6..00000000 --- a/src/types/plugins/preview.d.ts +++ /dev/null @@ -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; -}; diff --git a/src/types/plugins/sts.d.ts b/src/types/plugins/sts.d.ts deleted file mode 100644 index 59efce21..00000000 --- a/src/types/plugins/sts.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -type PolicyOption = { - port: number; - duration: number; - expires: number; - host: string; -}; - -export type PolicyMap = Map>; diff --git a/src/types/server.d.ts b/src/types/server.d.ts deleted file mode 100644 index 56c70838..00000000 --- a/src/types/server.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type ServerOptions = { - dev: boolean; -}; diff --git a/src/types/utils.d.ts b/src/types/utils.d.ts deleted file mode 100644 index b78ffcf7..00000000 --- a/src/types/utils.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -type RequiredNotNull = { - [P in keyof T]: NonNullable; -}; - -type Ensure = T & RequiredNotNull>; diff --git a/tsconfig.json b/tsconfig.json index ab3fc049..a21d998c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,6 @@ { "extends": "./tsconfig.base.json", - "files": ["index.ts", "./src/index.d.ts", "./webpack.config.ts", "./src/helper.ts"], - "compilerOptions": { - "types": ["node"], - "paths": { - "@src/*": ["src/*"], - "@client/*": ["client/*"] - } - }, - "ts-node": { - "files": true - }, - "exclude": ["./node_modules"], - "include": ["./src/**/*"], + "files": ["./webpack.config.ts", "./babel.config.cjs", "./src/helper.ts"], "references": [ { "path": "./src" diff --git a/yarn.lock b/yarn.lock index c8915641..983f87e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1665,6 +1665,11 @@ dependencies: "@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": version "8.5.3" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"