serverless-ircd 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +6 -1
- package/.gitmodules +3 -0
- package/CHANGELOG.md +214 -0
- package/README.md +110 -23
- package/apps/aws-stack/package.json +1 -1
- package/apps/cf-tcp-container/package.json +1 -1
- package/apps/cf-worker/package.json +1 -1
- package/apps/cf-worker/src/origin-allowlist.ts +99 -0
- package/apps/cf-worker/src/worker.ts +89 -9
- package/apps/cf-worker/tests/fixtures/web-dist/app/index.html +18 -0
- package/apps/cf-worker/tests/fixtures/web-dist/index.html +18 -0
- package/apps/cf-worker/tests/origin-allowlist.test.ts +101 -0
- package/apps/cf-worker/tests/smoke.test.ts +28 -2
- package/apps/cf-worker/tests/ws-origin.test.ts +89 -0
- package/apps/cf-worker/wrangler.test.toml +23 -0
- package/apps/cf-worker/wrangler.toml +54 -0
- package/apps/local-cli/package.json +1 -1
- package/apps/web/landing/index.html +217 -0
- package/apps/web/package.json +28 -0
- package/apps/web/scripts/build.mjs +125 -0
- package/apps/web/src/build-env.ts +43 -0
- package/apps/web/src/config-schema.ts +138 -0
- package/apps/web/static/config.json +28 -0
- package/apps/web/static/config.prod.json +28 -0
- package/apps/web/static/config.staging.json +28 -0
- package/apps/web/tests/build-env.test.ts +63 -0
- package/apps/web/tests/build-smoke.test.ts +103 -0
- package/apps/web/tests/config-schema.test.ts +432 -0
- package/apps/web/tests/workspace.test.ts +12 -0
- package/apps/web/tsconfig.json +10 -0
- package/apps/web/upstream/.browserslistrc +3 -0
- package/apps/web/upstream/.editorconfig +9 -0
- package/apps/web/upstream/.eslintignore +3 -0
- package/apps/web/upstream/.eslintrc.js +90 -0
- package/apps/web/upstream/.github/FUNDING.yml +12 -0
- package/apps/web/upstream/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- package/apps/web/upstream/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/apps/web/upstream/.github/workflows/push.yml +26 -0
- package/apps/web/upstream/.github/workflows/release.yml +33 -0
- package/apps/web/upstream/.github/workflows/release_manual.yml +55 -0
- package/apps/web/upstream/.prettierrc.js +9 -0
- package/apps/web/upstream/.stylelintignore +5 -0
- package/apps/web/upstream/.stylelintrc.js +21 -0
- package/apps/web/upstream/LICENSE +201 -0
- package/apps/web/upstream/README.md +76 -0
- package/apps/web/upstream/babel.config.js +25 -0
- package/apps/web/upstream/crowdin.yml +3 -0
- package/apps/web/upstream/index.html +35 -0
- package/apps/web/upstream/jest.config.js +7 -0
- package/apps/web/upstream/jsdoc.json +22 -0
- package/apps/web/upstream/package.json +80 -0
- package/apps/web/upstream/scripts/pre-commit +43 -0
- package/apps/web/upstream/src/components/App.vue +516 -0
- package/apps/web/upstream/src/components/AppSettings.vue +587 -0
- package/apps/web/upstream/src/components/AutoComplete.vue +284 -0
- package/apps/web/upstream/src/components/Avatar.vue +105 -0
- package/apps/web/upstream/src/components/AwayStatusIndicator.vue +77 -0
- package/apps/web/upstream/src/components/BufferKey.vue +121 -0
- package/apps/web/upstream/src/components/BufferSettings.vue +97 -0
- package/apps/web/upstream/src/components/Captcha.vue +85 -0
- package/apps/web/upstream/src/components/ChannelBanlist.vue +96 -0
- package/apps/web/upstream/src/components/ChannelInfo.vue +159 -0
- package/apps/web/upstream/src/components/ChannelInvitelist.vue +276 -0
- package/apps/web/upstream/src/components/ChannelList.vue +345 -0
- package/apps/web/upstream/src/components/Container.vue +401 -0
- package/apps/web/upstream/src/components/ContainerHeader.vue +522 -0
- package/apps/web/upstream/src/components/ControlInput.vue +1016 -0
- package/apps/web/upstream/src/components/LoadingAnimation.vue +104 -0
- package/apps/web/upstream/src/components/MediaViewer.vue +199 -0
- package/apps/web/upstream/src/components/MessageInfo.vue +192 -0
- package/apps/web/upstream/src/components/MessageList.vue +1028 -0
- package/apps/web/upstream/src/components/MessageListAvatar.vue +20 -0
- package/apps/web/upstream/src/components/MessageListMessageCompact.vue +361 -0
- package/apps/web/upstream/src/components/MessageListMessageInline.vue +257 -0
- package/apps/web/upstream/src/components/MessageListMessageModern.vue +430 -0
- package/apps/web/upstream/src/components/NetworkSettings.vue +528 -0
- package/apps/web/upstream/src/components/Nicklist.vue +309 -0
- package/apps/web/upstream/src/components/NicklistUser.vue +181 -0
- package/apps/web/upstream/src/components/NotConnected.vue +271 -0
- package/apps/web/upstream/src/components/SelfUser.vue +283 -0
- package/apps/web/upstream/src/components/ServerSelector.vue +162 -0
- package/apps/web/upstream/src/components/ServerView.vue +126 -0
- package/apps/web/upstream/src/components/SettingsAdvanced.vue +232 -0
- package/apps/web/upstream/src/components/SettingsAliases.vue +121 -0
- package/apps/web/upstream/src/components/Sidebar.vue +429 -0
- package/apps/web/upstream/src/components/SidebarAboutBuffer.vue +288 -0
- package/apps/web/upstream/src/components/SidebarState.vue +145 -0
- package/apps/web/upstream/src/components/StartupError.vue +35 -0
- package/apps/web/upstream/src/components/StateBrowser.vue +420 -0
- package/apps/web/upstream/src/components/StateBrowserBuffer.vue +124 -0
- package/apps/web/upstream/src/components/StateBrowserNetwork.vue +823 -0
- package/apps/web/upstream/src/components/StateBrowserUsermenu.vue +162 -0
- package/apps/web/upstream/src/components/TypingStatusIndicator.vue +34 -0
- package/apps/web/upstream/src/components/TypingUsersList.vue +56 -0
- package/apps/web/upstream/src/components/UrlEmbed.vue +149 -0
- package/apps/web/upstream/src/components/UserBox.vue +728 -0
- package/apps/web/upstream/src/components/inputtools/Emoji.vue +67 -0
- package/apps/web/upstream/src/components/inputtools/TextStyle.vue +142 -0
- package/apps/web/upstream/src/components/startups/CommonLayout.vue +208 -0
- package/apps/web/upstream/src/components/startups/CustomServer.vue +495 -0
- package/apps/web/upstream/src/components/startups/KiwiBnc.vue +361 -0
- package/apps/web/upstream/src/components/startups/Personal.vue +317 -0
- package/apps/web/upstream/src/components/startups/Welcome.vue +544 -0
- package/apps/web/upstream/src/components/startups/ZncLogin.vue +229 -0
- package/apps/web/upstream/src/components/utils/InputConfirm.vue +68 -0
- package/apps/web/upstream/src/components/utils/InputPrompt.vue +118 -0
- package/apps/web/upstream/src/components/utils/InputText.vue +172 -0
- package/apps/web/upstream/src/components/utils/IrcInput.vue +579 -0
- package/apps/web/upstream/src/components/utils/PluginWrapper.vue +26 -0
- package/apps/web/upstream/src/components/utils/TabbedView.vue +149 -0
- package/apps/web/upstream/src/components/utils/TransitionExpand.vue +97 -0
- package/apps/web/upstream/src/helpers/Colours.js +128 -0
- package/apps/web/upstream/src/helpers/IrcdDiffs.js +26 -0
- package/apps/web/upstream/src/helpers/Md5.js +193 -0
- package/apps/web/upstream/src/helpers/Misc.js +401 -0
- package/apps/web/upstream/src/helpers/TextFormatting.js +237 -0
- package/apps/web/upstream/src/libs/AliasRewriter.js +157 -0
- package/apps/web/upstream/src/libs/AudioManager.js +60 -0
- package/apps/web/upstream/src/libs/BouncerMiddleware.js +247 -0
- package/apps/web/upstream/src/libs/BouncerProvider.js +551 -0
- package/apps/web/upstream/src/libs/ChathistoryMiddleware.js +153 -0
- package/apps/web/upstream/src/libs/ConfigLoader.js +94 -0
- package/apps/web/upstream/src/libs/EmojiProvider.js +46 -0
- package/apps/web/upstream/src/libs/GlobalApi.js +346 -0
- package/apps/web/upstream/src/libs/IPC.js +51 -0
- package/apps/web/upstream/src/libs/InputHandler.js +921 -0
- package/apps/web/upstream/src/libs/IrcClient.js +1506 -0
- package/apps/web/upstream/src/libs/Logger.js +71 -0
- package/apps/web/upstream/src/libs/Message.js +169 -0
- package/apps/web/upstream/src/libs/MessageFormatter.js +364 -0
- package/apps/web/upstream/src/libs/MessageParser.js +249 -0
- package/apps/web/upstream/src/libs/Notifications.js +78 -0
- package/apps/web/upstream/src/libs/ServerConnection.js +270 -0
- package/apps/web/upstream/src/libs/ServerSession.js +102 -0
- package/apps/web/upstream/src/libs/SoundBleep.js +20 -0
- package/apps/web/upstream/src/libs/StatePersistence.js +90 -0
- package/apps/web/upstream/src/libs/ThemeManager.js +128 -0
- package/apps/web/upstream/src/libs/TypingMiddleware.js +105 -0
- package/apps/web/upstream/src/libs/WindowTitle.js +63 -0
- package/apps/web/upstream/src/libs/batchedAdd.js +74 -0
- package/apps/web/upstream/src/libs/bufferTools.js +177 -0
- package/apps/web/upstream/src/libs/polyfill/Element.closest.js +18 -0
- package/apps/web/upstream/src/libs/renderers/Html.js +113 -0
- package/apps/web/upstream/src/libs/settingTools.js +31 -0
- package/apps/web/upstream/src/libs/state/BufferState.js +703 -0
- package/apps/web/upstream/src/libs/state/NetworkState.js +158 -0
- package/apps/web/upstream/src/libs/state/UserState.js +89 -0
- package/apps/web/upstream/src/libs/state/common.js +26 -0
- package/apps/web/upstream/src/libs/state.js +961 -0
- package/apps/web/upstream/src/libs/storage/Local.js +51 -0
- package/apps/web/upstream/src/main.js +566 -0
- package/apps/web/upstream/src/res/autocompleteCommands.js +31 -0
- package/apps/web/upstream/src/res/configTemplates.js +373 -0
- package/apps/web/upstream/src/res/globalStyle.css +277 -0
- package/apps/web/upstream/src/res/kiwiLoadingLogo.png +0 -0
- package/apps/web/upstream/src/res/locales/app.af-ZA.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.ar-SA.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.bg-BG.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.bs-BA.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.ca-ES.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.cs-CZ.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.da-DK.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.de-DE.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.dev.po +1246 -0
- package/apps/web/upstream/src/res/locales/app.el-GR.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.en-US.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.es-419.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.es-AR.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.es-EM.po +536 -0
- package/apps/web/upstream/src/res/locales/app.es-ES.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.es-US.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.eu-ES.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.fi-FI.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.fr-FR.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.gl-ES.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.he-IL.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.hi-IN.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.hu-HU.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.id-ID.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.it-IT.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.ja-JP.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.ko-KR.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.nl-NL.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.no-NO.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.pl-PL.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.pt-BR.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.pt-PT.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.ro-RO.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.ru-RU.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.sl-SI.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.sq-AL.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.sr-SP.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.sv-SE.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.tr-TR.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.uk-UA.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.vi-VN.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.zh-CN.po +1145 -0
- package/apps/web/upstream/src/res/locales/app.zh-TW.po +1145 -0
- package/apps/web/upstream/src/res/localesList.json +27 -0
- package/apps/web/upstream/src/res/logo.png +0 -0
- package/apps/web/upstream/src/thirdparty/about.html +43 -0
- package/apps/web/upstream/src/thirdparty/index.js +5 -0
- package/apps/web/upstream/src/thirdparty/kiwiirccom.vue +185 -0
- package/apps/web/upstream/static/config.json +28 -0
- package/apps/web/upstream/static/emoticons/smile.png +0 -0
- package/apps/web/upstream/static/favicon.png +0 -0
- package/apps/web/upstream/static/highlight.mp3 +0 -0
- package/apps/web/upstream/static/highlight.ogg +0 -0
- package/apps/web/upstream/static/locales/.gitignore +2 -0
- package/apps/web/upstream/static/plugins/customise.html.example +10 -0
- package/apps/web/upstream/static/themes/coffee/theme.css +145 -0
- package/apps/web/upstream/static/themes/common/base.css +1064 -0
- package/apps/web/upstream/static/themes/dark/theme.css +196 -0
- package/apps/web/upstream/static/themes/default/theme.css +92 -0
- package/apps/web/upstream/static/themes/elite/theme.css +248 -0
- package/apps/web/upstream/static/themes/grayfox/theme.css +143 -0
- package/apps/web/upstream/static/themes/nightswatch/theme.css +367 -0
- package/apps/web/upstream/static/themes/osprey/theme.css +115 -0
- package/apps/web/upstream/static/themes/radioactive/theme.css +1211 -0
- package/apps/web/upstream/static/themes/sky/theme.css +107 -0
- package/apps/web/upstream/tests/unit/BatchAdd.spec.js +174 -0
- package/apps/web/upstream/tests/unit/MessageParser.spec.js +125 -0
- package/apps/web/upstream/tests/unit/Misc.spec.js +24 -0
- package/apps/web/upstream/tests/unit/NetworkState.spec.js +58 -0
- package/apps/web/upstream/tests/unit/StartupError.spec.js +20 -0
- package/apps/web/upstream/vue.config.js +150 -0
- package/apps/web/upstream/yarn.lock +9767 -0
- package/apps/web/vitest.config.ts +13 -0
- package/biome.json +1 -0
- package/docs/Home.md +1 -0
- package/docs/WebClientGuide.md +535 -0
- package/package.json +2 -2
- package/packages/aws-adapter/package.json +1 -1
- package/packages/cf-adapter/package.json +1 -1
- package/packages/cf-adapter/tests/cf-harness.ts +12 -1
- package/packages/in-memory-runtime/package.json +1 -1
- package/packages/irc-core/package.json +1 -1
- package/packages/irc-core/reports/mutation/mutation.html +342 -0
- package/packages/irc-core/tests/batch.test.ts +15 -0
- package/packages/irc-core/tests/numerics.test.ts +13 -0
- package/packages/irc-core/tests/parser.test.ts +109 -0
- package/packages/irc-server/package.json +1 -1
- package/packages/irc-test-support/package.json +1 -1
- package/packages/irc-test-support/src/scenarios.ts +24 -2
- package/tools/ci-hardening/package.json +1 -1
- package/tools/load-test/package.json +1 -1
- package/tools/tcp-ws-forwarder/package.json +1 -1
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
'kiwi public';
|
|
2
|
+
|
|
3
|
+
/** @module */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Command input Alias + re-writing
|
|
7
|
+
*
|
|
8
|
+
* Variables used in aliases:
|
|
9
|
+
* - $0 = the command being run
|
|
10
|
+
* - $1 = first param of input
|
|
11
|
+
* - $N = Nth param of input
|
|
12
|
+
* - $1+2 = first param of input and the next 2 words
|
|
13
|
+
* - $2+4 = second param of input and the next 4 words
|
|
14
|
+
* - $2+ = second param of input and all words after
|
|
15
|
+
* - $variable = variable as set in the vars object
|
|
16
|
+
*/
|
|
17
|
+
export default class AliasRewriter {
|
|
18
|
+
constructor() {
|
|
19
|
+
// Max alias recursion depth
|
|
20
|
+
this.recursiveDepth = 3;
|
|
21
|
+
// Current alias recursion depth
|
|
22
|
+
this.depth = 0;
|
|
23
|
+
|
|
24
|
+
this.aliases = {};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Reset the current aliases object from a newline delimited string of aliases */
|
|
28
|
+
importFromString(str) {
|
|
29
|
+
// Clear out the current aliases before adding new ones in
|
|
30
|
+
this.aliases = {};
|
|
31
|
+
|
|
32
|
+
str.split('\n').forEach((line) => {
|
|
33
|
+
if (line[0] !== '/') {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let spaceSep = line.indexOf(' ');
|
|
38
|
+
if (spaceSep === -1) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let command = line.substring(0, spaceSep);
|
|
43
|
+
let actions = line.substring(spaceSep + 1).trim();
|
|
44
|
+
if (!actions) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.aliases[command.toLowerCase()] = actions;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Takes an array of words to process!
|
|
53
|
+
processInput(input, vars) {
|
|
54
|
+
let words = input || [];
|
|
55
|
+
let alias = this.aliases[words[0].toLowerCase()];
|
|
56
|
+
let aliasLen;
|
|
57
|
+
let currentAliasWord = '';
|
|
58
|
+
let currentAliasWordLen = 0;
|
|
59
|
+
let processedConditionals = false;
|
|
60
|
+
let compiled = [];
|
|
61
|
+
|
|
62
|
+
// If an alias wasn't found, return the original input
|
|
63
|
+
if (!alias) return input;
|
|
64
|
+
|
|
65
|
+
// Split the alias up into useable words
|
|
66
|
+
alias = alias.split(' ');
|
|
67
|
+
aliasLen = alias.length;
|
|
68
|
+
|
|
69
|
+
// Iterate over each word and pop them into the final compiled array.
|
|
70
|
+
// Any $ words are processed with the result ending into the compiled array.
|
|
71
|
+
for (let i = 0; i < aliasLen; i++) {
|
|
72
|
+
currentAliasWord = alias[i];
|
|
73
|
+
currentAliasWordLen = currentAliasWord.length;
|
|
74
|
+
|
|
75
|
+
// $var? word makes this command only run if the var exists
|
|
76
|
+
if (
|
|
77
|
+
!processedConditionals &&
|
|
78
|
+
currentAliasWord[0] === '$' && currentAliasWord[currentAliasWordLen - 1] === '?'
|
|
79
|
+
) {
|
|
80
|
+
let checkVar = currentAliasWord.substr(1, currentAliasWordLen - 2);
|
|
81
|
+
if (!vars[checkVar]) {
|
|
82
|
+
compiled = [];
|
|
83
|
+
break;
|
|
84
|
+
} else {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
processedConditionals = true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Non $ word
|
|
92
|
+
if (currentAliasWord[0] !== '$') {
|
|
93
|
+
compiled.push(currentAliasWord);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Refering to an input word ($N)
|
|
98
|
+
if ((currentAliasWord[1] || '').match(/\d/)) {
|
|
99
|
+
let num = currentAliasWord.match(/\$(\d+)(\+)?(\d+)?/);
|
|
100
|
+
|
|
101
|
+
// Did we find anything or does the word it refers to non-existant?
|
|
102
|
+
if (!num || !words[num[1]]) continue;
|
|
103
|
+
|
|
104
|
+
if (num[2] === '+' && num[3]) {
|
|
105
|
+
// Add X number of words
|
|
106
|
+
compiled = compiled.concat(words.slice(
|
|
107
|
+
parseInt(num[1], 10),
|
|
108
|
+
parseInt(num[1], 10) + parseInt(num[3], 10)
|
|
109
|
+
));
|
|
110
|
+
} else if (num[2] === '+') {
|
|
111
|
+
// Add the remaining of the words
|
|
112
|
+
compiled = compiled.concat(words.slice(parseInt(num[1], 10)));
|
|
113
|
+
} else {
|
|
114
|
+
// Add a single word
|
|
115
|
+
compiled.push(words[parseInt(num[1], 10)]);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Refering to a variable
|
|
122
|
+
if (typeof vars[currentAliasWord.substr(1)] !== 'undefined') {
|
|
123
|
+
// Get the variable
|
|
124
|
+
compiled.push(vars[currentAliasWord.substr(1)]);
|
|
125
|
+
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return compiled;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Take a string input, process any aliases and output the finalised string */
|
|
134
|
+
process(input, vars) {
|
|
135
|
+
let line = input || '';
|
|
136
|
+
let words = line.split(' ');
|
|
137
|
+
let firstWord = (words[0] || '').toLowerCase();
|
|
138
|
+
|
|
139
|
+
this.depth++;
|
|
140
|
+
if (this.depth >= this.recursiveDepth) {
|
|
141
|
+
this.depth--;
|
|
142
|
+
return line;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (this.aliases[firstWord]) {
|
|
146
|
+
words = this.processInput(words, vars);
|
|
147
|
+
firstWord = (words[0] || '').toLowerCase();
|
|
148
|
+
|
|
149
|
+
if (this.aliases[firstWord]) {
|
|
150
|
+
words = this.process(words.join(' '), vars).split(' ');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.depth--;
|
|
155
|
+
return words.join(' ');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'kiwi public';
|
|
2
|
+
|
|
3
|
+
/** @module */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Plays alert sounds
|
|
7
|
+
*/
|
|
8
|
+
export class AudioManager {
|
|
9
|
+
constructor(audio) {
|
|
10
|
+
this.lastPlayed = 0;
|
|
11
|
+
this.audio = audio;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Play the alert sound */
|
|
15
|
+
play() {
|
|
16
|
+
// Only play the bleep once every 2 seconds
|
|
17
|
+
if (!this.lastPlayed || Date.now() - this.lastPlayed > 2000) {
|
|
18
|
+
this.audio.play();
|
|
19
|
+
this.lastPlayed = Date.now();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
listen(state) {
|
|
24
|
+
state.$on('audio.bleep', () => {
|
|
25
|
+
this.play();
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Watch the Kiwi state for any message highlights and play an alert */
|
|
30
|
+
watchForMessages(state) {
|
|
31
|
+
state.$on('message.new', (event) => {
|
|
32
|
+
let { message, buffer } = event;
|
|
33
|
+
if (buffer.setting('mute_sound')) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let ignoreTypes = [
|
|
38
|
+
'connection',
|
|
39
|
+
'traffic',
|
|
40
|
+
'mode',
|
|
41
|
+
'nick',
|
|
42
|
+
];
|
|
43
|
+
if (ignoreTypes.indexOf(message.type) > -1) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (message.ignore || buffer.isSpecial()) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let shouldBleep = buffer.getNetwork().nick !== message.nick && ((message.isHighlight && buffer.setting('alert_on') === 'highlight') || buffer.setting('alert_on') === 'message');
|
|
52
|
+
let isActiveBuffer = state.getActiveBuffer() === buffer;
|
|
53
|
+
let inFocus = isActiveBuffer && state.ui.app_has_focus;
|
|
54
|
+
|
|
55
|
+
if (shouldBleep || (buffer.isQuery() && !inFocus)) {
|
|
56
|
+
this.play();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
'kiwi public';
|
|
2
|
+
|
|
3
|
+
/** @module */
|
|
4
|
+
|
|
5
|
+
import { MessageTags } from 'irc-framework';
|
|
6
|
+
import * as Misc from '@/helpers/Misc';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Adds the BOUNCER IRCv3 spec to irc-framework
|
|
10
|
+
*/
|
|
11
|
+
export default function bouncerMiddleware() {
|
|
12
|
+
let networks = [];
|
|
13
|
+
let buffers = {};
|
|
14
|
+
|
|
15
|
+
return function middleware(client, rawEvents, parsedEvents) {
|
|
16
|
+
client.requestCap('bouncer');
|
|
17
|
+
addFunctionsToClient(client);
|
|
18
|
+
rawEvents.use(theMiddleware);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function theMiddleware(command, message, rawLine, client, next) {
|
|
22
|
+
if (command !== 'BOUNCER') {
|
|
23
|
+
next();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let params = message.params;
|
|
28
|
+
|
|
29
|
+
if (params[0] === 'listnetworks' && ['end', 'RPL_OK'].indexOf(params[1]) > -1) {
|
|
30
|
+
client.command_handler.emit('bouncer networks', networks);
|
|
31
|
+
networks = [];
|
|
32
|
+
} else if (params[0] === 'listnetworks') {
|
|
33
|
+
let tags = MessageTags.decode(params[2]);
|
|
34
|
+
networks.push({
|
|
35
|
+
networkId: params[1],
|
|
36
|
+
name: tags.network,
|
|
37
|
+
host: tags.host,
|
|
38
|
+
port: parseInt(tags.port, 10),
|
|
39
|
+
tls: tags.tls === '1',
|
|
40
|
+
connected: tags.state === 'connected',
|
|
41
|
+
nick: tags.nick,
|
|
42
|
+
currentNick: tags.currentNick,
|
|
43
|
+
password: tags.password || '',
|
|
44
|
+
account: tags.account || '',
|
|
45
|
+
account_password: tags.account_password || '',
|
|
46
|
+
});
|
|
47
|
+
} else if (params[0] === 'listbuffers' && ['end', 'RPL_OK'].indexOf(params[2]) > -1) {
|
|
48
|
+
let netId = (params[1] || '');
|
|
49
|
+
let detectedBuffers = buffers[netId] || [];
|
|
50
|
+
delete buffers[netId];
|
|
51
|
+
|
|
52
|
+
client.command_handler.emit('bouncer buffers', detectedBuffers);
|
|
53
|
+
client.command_handler.emit('bouncer buffers ' + netId, detectedBuffers);
|
|
54
|
+
} else if (params[0] === 'listbuffers') {
|
|
55
|
+
let netId = (params[1] || '');
|
|
56
|
+
let tags = MessageTags.decode(params[2]);
|
|
57
|
+
buffers[netId] = buffers[netId] || [];
|
|
58
|
+
buffers[netId].push({
|
|
59
|
+
networkId: netId,
|
|
60
|
+
network: tags.network,
|
|
61
|
+
name: tags.buffer,
|
|
62
|
+
topic: tags.topic,
|
|
63
|
+
joined: tags.joined === '1',
|
|
64
|
+
seen: tags.seen,
|
|
65
|
+
notify: tags.notify || 'highlight',
|
|
66
|
+
});
|
|
67
|
+
} else if (params[0] === 'state') {
|
|
68
|
+
client.command_handler.emit('bouncer state', {
|
|
69
|
+
networkId: params[1],
|
|
70
|
+
network: params[2],
|
|
71
|
+
state: params[3],
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// BOUNCER addnetwork NetID Network1 ERR_NAMEINUSE
|
|
76
|
+
if (params[0] === 'addnetwork' && params[3].substr(0, 4) === 'ERR_') {
|
|
77
|
+
let netName = (params[2] || '').toLowerCase();
|
|
78
|
+
let eventObj = {
|
|
79
|
+
error: params[3],
|
|
80
|
+
reason: params[4] || '',
|
|
81
|
+
};
|
|
82
|
+
client.command_handler.emit('bouncer addnetwork error', eventObj);
|
|
83
|
+
client.command_handler.emit('bouncer addnetwork error ' + netName, eventObj);
|
|
84
|
+
} else if (params[0] === 'addnetwork' && ['end', 'RPL_OK'].indexOf(params[3]) > -1) {
|
|
85
|
+
// BOUNCER addnetwork 5 Network1 RPL_OK
|
|
86
|
+
let netId = (params[1] || '');
|
|
87
|
+
let netName = (params[2] || '').toLowerCase();
|
|
88
|
+
let eventObj = {
|
|
89
|
+
networkId: netId,
|
|
90
|
+
network: netName,
|
|
91
|
+
};
|
|
92
|
+
client.command_handler.emit('bouncer addnetwork ok', eventObj);
|
|
93
|
+
client.command_handler.emit('bouncer addnetwork ok ' + netName, eventObj);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function addFunctionsToClient(client) {
|
|
99
|
+
let bnc = client.bnc = {};
|
|
100
|
+
|
|
101
|
+
bnc.tags = function tags() {
|
|
102
|
+
let token = client.network.supports('bouncer');
|
|
103
|
+
return !token || typeof token !== 'string' ?
|
|
104
|
+
{} :
|
|
105
|
+
MessageTags.decode(token) || {};
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
bnc.hasNetwork = function hasNetwork() {
|
|
109
|
+
let token = client.network.supports('bouncer');
|
|
110
|
+
if (!token || token === true) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let tags = MessageTags.decode(token);
|
|
115
|
+
return tags && !!tags.network;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
bnc.getNetworks = function getNetworks() {
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
client.raw('BOUNCER listnetworks');
|
|
121
|
+
client.once('bouncer networks', (networks) => {
|
|
122
|
+
resolve(networks);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
bnc.getBuffers = function getBuffers(netId) {
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
client.raw('BOUNCER listbuffers ' + netId);
|
|
130
|
+
client.once('bouncer buffers ' + netId, (buffers) => {
|
|
131
|
+
resolve(buffers);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
bnc.closeBuffer = function closeBuffer(netId, bufferName) {
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
client.raw(`BOUNCER delbuffer ${netId} ${bufferName}`);
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
bnc.bufferSeen = function bufferSeen(netId, bufferName, seenTime) {
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
// 1 tells the bouncer to use the current time
|
|
145
|
+
let timeStr = seenTime ? Misc.dateIso(seenTime) : '1';
|
|
146
|
+
client.raw(`BOUNCER changebuffer ${netId} ${bufferName} seen=${timeStr}`);
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
bnc.addNetwork = function addNetwork(netName, host, port, tls, nick, user, password) {
|
|
151
|
+
let tags = {};
|
|
152
|
+
tags.network = netName;
|
|
153
|
+
tags.host = host;
|
|
154
|
+
tags.port = port;
|
|
155
|
+
tags.tls = tls ? 1 : 0;
|
|
156
|
+
tags.nick = nick;
|
|
157
|
+
tags.password = password;
|
|
158
|
+
|
|
159
|
+
if (user) {
|
|
160
|
+
tags.user = user;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let tagString = createTagString(tags);
|
|
164
|
+
return new Promise((resolve, reject) => {
|
|
165
|
+
client.raw('BOUNCER addnetwork ' + tagString);
|
|
166
|
+
client.once('bouncer addnetwork ok ' + netName.toLowerCase(), onOk);
|
|
167
|
+
client.once('bouncer addnetwork error', onError);
|
|
168
|
+
|
|
169
|
+
function onOk(event) {
|
|
170
|
+
client.off('bouncer addnetwork error', onError);
|
|
171
|
+
resolve(event);
|
|
172
|
+
}
|
|
173
|
+
function onError(event) {
|
|
174
|
+
client.off('bouncer addnetwork ok ' + netName.toLowerCase(), onOk);
|
|
175
|
+
reject({
|
|
176
|
+
error: event.error,
|
|
177
|
+
reason: event.reason,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
bnc.removeNetwork = function removeNetwork(netId, bufferName) {
|
|
184
|
+
return new Promise((resolve, reject) => {
|
|
185
|
+
client.raw(`BOUNCER delnetwork ${netId}`);
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
bnc.saveNetwork = function saveNetwork(netId, opts) {
|
|
190
|
+
let tags = {};
|
|
191
|
+
|
|
192
|
+
if (typeof opts.network !== 'undefined') {
|
|
193
|
+
tags.network = opts.network;
|
|
194
|
+
}
|
|
195
|
+
if (typeof opts.host !== 'undefined') {
|
|
196
|
+
tags.host = opts.host;
|
|
197
|
+
}
|
|
198
|
+
if (typeof opts.port !== 'undefined') {
|
|
199
|
+
tags.port = opts.port;
|
|
200
|
+
}
|
|
201
|
+
if (typeof opts.tls !== 'undefined') {
|
|
202
|
+
tags.tls = opts.tls ? 1 : 0;
|
|
203
|
+
}
|
|
204
|
+
if (typeof opts.nick !== 'undefined') {
|
|
205
|
+
tags.nick = opts.nick;
|
|
206
|
+
}
|
|
207
|
+
if (typeof opts.user !== 'undefined') {
|
|
208
|
+
tags.user = opts.user;
|
|
209
|
+
}
|
|
210
|
+
if (typeof opts.password !== 'undefined') {
|
|
211
|
+
tags.password = opts.password;
|
|
212
|
+
}
|
|
213
|
+
if (typeof opts.account_password !== 'undefined') {
|
|
214
|
+
tags.account_password = opts.account_password;
|
|
215
|
+
}
|
|
216
|
+
if (typeof opts.account !== 'undefined') {
|
|
217
|
+
tags.account = opts.account;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let tagString = createTagString(tags);
|
|
221
|
+
return new Promise((resolve, reject) => {
|
|
222
|
+
if (tagString.length === 0) {
|
|
223
|
+
resolve();
|
|
224
|
+
} else {
|
|
225
|
+
client.raw(`BOUNCER changenetwork ${netId} ${tagString}`);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function createTagString(tags) {
|
|
232
|
+
let tagParts = [];
|
|
233
|
+
|
|
234
|
+
Object.keys(tags).forEach((tag) => {
|
|
235
|
+
let val = tags[tag];
|
|
236
|
+
if (typeof val !== 'undefined') {
|
|
237
|
+
val = val.toString()
|
|
238
|
+
.replace(' ', '\\s')
|
|
239
|
+
.replace(';', '\\:');
|
|
240
|
+
tagParts.push(tag + '=' + val);
|
|
241
|
+
} else {
|
|
242
|
+
tagParts.push(tag);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return tagParts.join(';');
|
|
247
|
+
}
|