You are previewing your page. Press Back
@@ -38,7 +38,7 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -47,7 +47,7 @@ to return to editing it.
this.styledata.text +
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue.js
index 12738555..85a578a0 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue.js
@@ -22,7 +22,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -37,7 +37,7 @@ to return to editing it.
`;
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -47,7 +47,7 @@ to return to editing it.
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue_Sands.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue_Sands.js
index a5d4ea57..883bb55a 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue_Sands.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Blue_Sands.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
// Do some templating here for some fucking reason
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
@@ -33,7 +33,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -43,7 +43,7 @@ to return to editing it.
this.styledata.titheader += `
${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Cats.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Cats.js
index 362a606c..e155c1d5 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Cats.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Cats.js
@@ -21,7 +21,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -34,13 +34,13 @@ to return to editing it.
`;
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader += `
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Channukah.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Channukah.js
index 578ecc45..17efb83c 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Channukah.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Channukah.js
@@ -50,13 +50,13 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader += `${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Christmas.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Christmas.js
index f0c13317..9856864b 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Christmas.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Christmas.js
@@ -46,7 +46,7 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -55,7 +55,7 @@ to return to editing it.
this.styledata.text +
`>${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Democratic.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Democratic.js
index f87c22d5..d8b231a6 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Democratic.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Democratic.js
@@ -26,7 +26,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -35,7 +35,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -44,7 +44,7 @@ to return to editing it.
this.styledata.text +
`>${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Easter.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Easter.js
index e2f987fe..f5ab441a 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Easter.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Easter.js
@@ -61,13 +61,13 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader += `${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Eyeballs.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Eyeballs.js
index d2ca874d..691a57be 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Eyeballs.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Eyeballs.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Finance.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Finance.js
index 8e2ba614..cb87e504 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Finance.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Finance.js
@@ -26,7 +26,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -42,7 +42,7 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -51,7 +51,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Flowers.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Flowers.js
index 3c445739..eed4883b 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Flowers.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Flowers.js
@@ -22,7 +22,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -34,13 +34,13 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader += `${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Football.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Football.js
index 5f76b111..08462aab 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Football.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Football.js
@@ -26,7 +26,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -35,7 +35,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -44,7 +44,7 @@ to return to editing it.
this.styledata.text +
`>${title}`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green.js
index b274203a..862c7698 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green.js
@@ -22,7 +22,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -38,7 +38,7 @@ to return to editing it.
`;
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -48,7 +48,7 @@ to return to editing it.
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green_Paper.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green_Paper.js
index 542ee9e5..6611dfc7 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green_Paper.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Green_Paper.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Grey.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Grey.js
index d16642c7..4862e52b 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Grey.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Grey.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Halloween.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Halloween.js
index 3d2eec5d..cb39f8d8 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Halloween.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Halloween.js
@@ -47,7 +47,7 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -56,7 +56,7 @@ to return to editing it.
this.styledata.text +
`>${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Boy.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Boy.js
index 507a79d5..61e2c27f 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Boy.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Boy.js
@@ -22,7 +22,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -34,13 +34,13 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader += `${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Girl.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Girl.js
index 8135af18..d908b010 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Girl.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Its_a_Girl.js
@@ -22,7 +22,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -34,13 +34,13 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader += `${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Marble.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Marble.js
index 7de43254..3f3e00a4 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Marble.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Marble.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/New_Wave.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/New_Wave.js
index 5a3fd066..561f10cb 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/New_Wave.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/New_Wave.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -42,7 +42,7 @@ to return to editing it.
this.styledata.text +
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ocean.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ocean.js
index cdd301ac..ec75c730 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ocean.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ocean.js
@@ -26,7 +26,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -35,7 +35,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -47,7 +47,7 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
this.styledata.titheader +=
@@ -56,7 +56,7 @@ to return to editing it.
this.styledata.text +
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
this.styledata.titheader += `
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Paisley.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Paisley.js
index c5a8ce16..deafcdfa 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Paisley.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Paisley.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Red.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Red.js
index 3192b602..846a9d28 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Red.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Red.js
@@ -22,7 +22,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -38,7 +38,7 @@ to return to editing it.
`;
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -48,7 +48,7 @@ to return to editing it.
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Republican.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Republican.js
index 99e8febc..f167cc7f 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Republican.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Republican.js
@@ -26,7 +26,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -35,7 +35,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -44,7 +44,7 @@ to return to editing it.
this.styledata.text +
`>${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ringbinder.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ringbinder.js
index 5bb016be..eeffb511 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ringbinder.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Ringbinder.js
@@ -22,7 +22,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -37,13 +37,13 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader +=
`${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Rivets.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Rivets.js
index a3095a4f..fea664c8 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Rivets.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Rivets.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/South_Beach.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/South_Beach.js
index 2c283b89..70f9d439 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/South_Beach.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/South_Beach.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Space.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Space.js
index 01a1d9c3..e49313eb 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Space.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Space.js
@@ -21,7 +21,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -30,7 +30,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -49,7 +49,7 @@ ${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Stone.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Stone.js
index 4b6a2908..bcd721b8 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Stone.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Stone.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -42,7 +42,7 @@ to return to editing it.
this.styledata.text +
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Tan.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Tan.js
index fb67724f..8467b9fd 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Tan.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Tan.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -42,7 +42,7 @@ to return to editing it.
this.styledata.text +
`>${title}
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Water.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Water.js
index d41b53c3..557ba079 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Water.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Water.js
@@ -23,7 +23,7 @@ class PBTemplate {
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -32,7 +32,7 @@ to return to editing it.
`;
}
this.styledata.titheader = ``;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
@@ -41,7 +41,7 @@ to return to editing it.
${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ` `;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Wedding.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Wedding.js
index 12290bef..6c5981e5 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Wedding.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-author/styles/Wedding.js
@@ -26,7 +26,7 @@ class PBTemplate {
${title}
`;
- if (state == "previewing") {
+ if (state === "previewing") {
this.styledata.header += `
You are previewing your page. Press Back
@@ -40,13 +40,13 @@ to return to editing it.
`;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += `
`;
}
this.styledata.titheader += `${title} `;
- if (state == "editing") {
+ if (state === "editing") {
this.styledata.titheader += ``;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-guide/prerendered/Tips/Options/Send.js b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-guide/prerendered/Tips/Options/Send.js
index 4dee1294..ea6cb07e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-guide/prerendered/Tips/Options/Send.js
+++ b/zefie_wtvp_minisrv/includes/ServiceDeps/templates/wtv-guide/prerendered/Tips/Options/Send.js
@@ -64,7 +64,7 @@ the page's address.
`;
- } else if (request_headers.query.cmd == "ssid") {
+ } else if (request_headers.query.cmd === "ssid") {
const ssid = request_headers.query.ssid;
if (!ssid) {
redirectmsg = `An SSID is required for the ${request_headers.query.cmd} command.`;
@@ -78,7 +78,7 @@ function validateSelection(cmd, ssid, friendlymsg) {
if (Object.keys(user_info.account_users).length > 1) {
data += `Additional Users: `;
Object.keys(user_info.account_users).forEach(function (k) {
- if (k == "subscriber") return;
+ if (k === "subscriber") return;
data += user_info.account_users[k].subscriber_username + " ";
})
data += ` `
@@ -91,7 +91,7 @@ function validateSelection(cmd, ssid, friendlymsg) {
data += "The SSID does not exist in the SessionStore."
}
}
- } else if (request_headers.query.cmd == "delete") {
+ } else if (request_headers.query.cmd === "delete") {
redirectmsg = "";
const ssid = request_headers.query.ssid;
if (ssid) {
@@ -102,7 +102,7 @@ function validateSelection(cmd, ssid, friendlymsg) {
redirectmsg = `An SSID is required for the ${request_headers.query.cmd} command.`;
}
headers = "302 OK\nLocation: /admin/?cmd=list&msg=" + encodeURI(redirectmsg);
- } else if (request_headers.query.cmd == "ban") {
+ } else if (request_headers.query.cmd === "ban") {
redirectmsg = "";
const ssid = request_headers.query.ssid;
if (ssid) {
@@ -110,7 +110,7 @@ function validateSelection(cmd, ssid, friendlymsg) {
if (result === wtva.SUCCESS) {
reloadConfig();
redirectmsg = "The SSID is now banned.";
- } else if (result == wtva.REASON_EXISTS) {
+ } else if (result === wtva.REASON_EXISTS) {
redirectmsg = "The SSID was already banned.";
} else {
redirectmsg = "Unknown response " + result.toString();
@@ -119,7 +119,7 @@ function validateSelection(cmd, ssid, friendlymsg) {
redirectmsg = `An SSID is required for the ${request_headers.query.cmd} command.`;
}
headers = "302 OK\nLocation: /admin/?cmd=ssid&ssid=" + encodeURI(ssid) + "&msg=" + encodeURI(redirectmsg);
- } else if (request_headers.query.cmd == "unban") {
+ } else if (request_headers.query.cmd === "unban") {
redirectmsg = "The SSID was not banned, so it could not be unbanned.";
const ssid = request_headers.query.ssid;
if (ssid) {
@@ -127,7 +127,7 @@ function validateSelection(cmd, ssid, friendlymsg) {
if (result === wtva.SUCCESS) {
reloadConfig();
redirectmsg = "The SSID is now unbanned.";
- } else if (result == wtva.REASON_EXISTS) {
+ } else if (result === wtva.REASON_EXISTS) {
redirectmsg = "The SSID was not banned.";
} else {
redirectmsg = "Unknown response " + result.toString();
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js b/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js
index 1ff5c9ed..c47bae16 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/http_pc/viewergen/index.js
@@ -74,7 +74,7 @@ const patch_limits = {
function getPatchDataType(type, invert = false) {
let patch_data = false;
- if ((type == "wtv-incarnation" && !invert) || (type == "wtv-encryption" && invert)) {
+ if ((type === "wtv-incarnation" && !invert) || (type === "wtv-encryption" && invert)) {
patch_data = "wtv-client-serial-number: %s\r\n"
patch_data += "wtv-user-requested-upgrade: %s\r\n";
patch_data += "wtv-system-cpuprid: %s\r\n";
@@ -87,7 +87,7 @@ function getPatchDataType(type, invert = false) {
patch_data += "wtv-system-chipversion: %s\r\n";
patch_data += "User-Agent: %s\r\n";
}
- else if ((type == "wtv-encryption" && !invert) || (type == "wtv-incarnation" && invert) ) {
+ else if ((type === "wtv-encryption" && !invert) || (type === "wtv-incarnation" && invert) ) {
patch_data = "wtv-tourist-enabled: %s\r\n";
patch_data += "wtv-demo-enabled: %s\r\n";
patch_data += "wtv-default-client-scriptprops: %s\r\n";
@@ -106,7 +106,7 @@ function getPatchDataType(type, invert = false) {
function getResData(file) {
let res_data = null;
- if (file.slice(-2, 2).toLowerCase() == "gz") {
+ if (file.slice(-2, 2).toLowerCase() === "gz") {
const res_gz_data = wtvshared.getServiceDep("/viewergen/" + file);
res_data = zlib.gunzipSync(res_gz_data);
} else {
@@ -227,14 +227,14 @@ function getPatchData(fname, client_data_obj, start_url = "client:GoToConn", def
const val = customized_patch_data[idx];
if (typeof val === 'string') {
// start url override
- if (start_url != patch_defaults.start_url && start_url.length <= patch_limits.start_url) {
- if (val.slice(0, patch_defaults.start_url.length) == patch_defaults.start_url)
+ if (start_url !== patch_defaults.start_url && start_url.length <= patch_limits.start_url) {
+ if (val.slice(0, patch_defaults.start_url.length) === patch_defaults.start_url)
customized_patch_data[idx] = start_url + "\x00";
}
// default service ip override
- if (default_ip != patch_defaults.default_ip && default_ip.length <= patch_limits.default_ip) {
- if (val.slice(0, patch_defaults.default_ip.length) == patch_defaults.default_ip)
+ if (default_ip !== patch_defaults.default_ip && default_ip.length <= patch_limits.default_ip) {
+ if (val.slice(0, patch_defaults.default_ip.length) === patch_defaults.default_ip)
customized_patch_data[idx] = default_ip + "\x00";
}
} else {
@@ -242,7 +242,7 @@ function getPatchData(fname, client_data_obj, start_url = "client:GoToConn", def
// not a buffer object
let patch_data_string = "";
const block_length = val['length'];
- const patch_data = getPatchDataType(val['type'], (fname.slice(12, 3) != "1.1"));
+ const patch_data = getPatchDataType(val['type'], (fname.slice(12, 3) !== "1.1"));
if (patch_data) {
const patch_data_array = patch_data.split("\r\n");
@@ -256,7 +256,7 @@ function getPatchData(fname, client_data_obj, start_url = "client:GoToConn", def
}
});
}
- if (fname.slice(12, 3) != "2.5") {
+ if (fname.slice(12, 3) !== "2.5") {
const length_difference = block_length - patch_data_string.length;
if (length_difference > 0)
patch_data_string += "\x00".repeat(length_difference - (val['type'].length + 1));
@@ -292,7 +292,7 @@ function patchBinary(patchDataObject) {
function generateSSID() {
const ssid_template = "91xxxxxxaeb002";
let ssid = ssid_template;
- while (ssid.indexOf("x") != -1) {
+ while (ssid.indexOf("x") !== -1) {
// random hex char from 0-F
ssid = ssid.replace("x", Math.floor(Math.random() * 16).toString(16))
}
@@ -458,7 +458,7 @@ if (request_headers.query.viewer &&
const viewer_gz_data = wtvshared.getServiceDep("/viewergen/" + viewer_file + ".gz");
const viewer_data = zlib.gunzipSync(viewer_gz_data);
const viewer_md5 = crypto.createHash('md5').update(viewer_data).digest("hex");
- if (viewer_md5 != viewer_stock_md5s[viewer_file]) {
+ if (viewer_md5 !== viewer_stock_md5s[viewer_file]) {
console.error(viewer_file, "md5sum error. expected:", viewer_stock_md5s[viewer_file], ", got:", viewer_md5)
const errpage = wtvshared.doErrorPage("500", null, socket.minisrv_pc_mode)
headers = errpage[0];
@@ -514,7 +514,7 @@ Content-Disposition: attachment; filename="${viewer_file.replace(".exe", ".zip")
console.log(request_headers)
let update_str = "http://" + request_headers.host + request_headers.request_url.split('?')[0] + "?ssid=" + client_ssid;
Object.keys(request_headers.query).forEach((k) => {
- if (k != "random_ssid") {
+ if (k !== "random_ssid") {
update_str += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(request_headers.query[k]);
}
});
@@ -525,7 +525,7 @@ Content-Disposition: attachment; filename="${viewer_file.replace(".exe", ".zip")
const romset_zip = new AdmZip(wtvshared.getServiceDep("/viewergen/" + viewer_file.replace(".exe", "").replace("WebTVIntel", "AppData") + ".zip", true));
const zipEntries = romset_zip.getEntries();
zipEntries.forEach(function (zipEntry) {
- if (zipEntry.entryName == "Setup.bmp" && request_headers.query.logo) {
+ if (zipEntry.entryName === "Setup.bmp" && request_headers.query.logo) {
const logo_file = logos[parseInt(request_headers.query.logo) || 0];
if (logo_file) {
const logo_gz_data = wtvshared.getServiceDep("/viewergen/" + logo_file + ".gz");
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/noflash.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/noflash.js
index 97aff745..cc88f3a8 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/noflash.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/noflash.js
@@ -1,12 +1,12 @@
const minisrv_service_file = true;
let wtvsec_login;
-if (socket.ssid != null && !session_data.get("wtvsec_login")) {
+if (socket.ssid !== null && !session_data.get("wtvsec_login")) {
wtvsec_login = session_data.createWTVSecSession();
wtvsec_login.IssueChallenge();
if (request_headers["wtv-incarnation"]) wtvsec_login.set_incarnation(request_headers["wtv-incarnation"]);
session_data.set("wtvsec_login", wtvsec_login);
-} else if (socket.ssid != null) {
+} else if (socket.ssid !== null) {
wtvsec_login = session_data.get("wtvsec_login");
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/preregister.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/preregister.js
index a92e91e7..78bb1db1 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/preregister.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-1800/preregister.js
@@ -3,9 +3,9 @@ let gourl = "wtv-head-waiter:/login?";
let file_path = null;
if (session_data) {
- if (session_data.loadSessionData() == true) {
+ if (session_data.loadSessionData() === true) {
console.log(" * Loaded session data from disk for", wtvshared.filterSSID(socket.ssid))
- session_data.setSessionData("registered", (session_data.getSessionData("registered") == true) ? true : false);
+ session_data.setSessionData("registered", (session_data.getSessionData("registered") === true) ? true : false);
} else {
session_data.session_data = {};
session_data.setSessionData("registered", false);
@@ -14,8 +14,8 @@ if (session_data) {
if (session_data.data_store.sockets) {
let i = 0;
session_data.data_store.sockets.forEach(function (k) {
- if (typeof k != "undefined") {
- if (k != socket) {
+ if (typeof k !== "undefined") {
+ if (k !== socket) {
k.destroy();
session_data.data_store.sockets.delete(k);
i++;
@@ -59,7 +59,7 @@ if (session_data.data_store.wtvsec_login) {
let send_tellyscript = (minisrv_config.services[service_name].send_tellyscripts && !request_headers.query.relogin && !bootrom !== 0);
const wtv_script_id = parseInt(session_data.get("wtv-script-id"));
const wtv_script_mod = parseInt(session_data.get("wtv-script-mod"));
- if ((request_headers.query.reconnect || request_headers.query.relogin) && wtv_script_id != 0) send_tellyscript = false;
+ if ((request_headers.query.reconnect || request_headers.query.relogin) && wtv_script_id !== 0) send_tellyscript = false;
if (wtv_script_id !== 0 && wtv_script_mod !== 0) send_tellyscript = false;
if (!minisrv_config.services[service_name].send_tellyscript_to_mame) {
if (wtvshared.parseSSID(socket.ssid).boxType === "MAME") {
@@ -68,7 +68,7 @@ if (session_data.data_store.wtvsec_login) {
}
if (minisrv_config.services[service_name].tellyscript_ssid_blacklist) {
- send_tellyscript = (minisrv_config.services[service_name].tellyscript_ssid_blacklist.findIndex(element => element == socket.ssid) == -1)
+ send_tellyscript = (minisrv_config.services[service_name].tellyscript_ssid_blacklist.findIndex(element => element === socket.ssid) === -1)
}
if (send_tellyscript) {
@@ -157,8 +157,8 @@ if (session_data.data_store.wtvsec_login) {
if (request_headers.query.reconnect) gourl = null;
- if (file_path != null && send_tellyscript && !minisrv_config.config.debug_flags.quiet) console.log(" * Sending TellyScript", file_path, "on socket", socket.id);
- if (template != null && send_tellyscript && !minisrv_config.config.debug_flags.quiet) console.log(" * Generating TellyScript on socket", socket.id);
+ if (file_path !== null && send_tellyscript && !minisrv_config.config.debug_flags.quiet) console.log(" * Sending TellyScript", file_path, "on socket", socket.id);
+ if (template !== null && send_tellyscript && !minisrv_config.config.debug_flags.quiet) console.log(" * Generating TellyScript on socket", socket.id);
headers = "200 OK\n"
@@ -181,7 +181,7 @@ if (session_data.data_store.wtvsec_login) {
headers += "wtv-boot-url: wtv-head-waiter:/login?relogin=true";
headers += "\n";
}
- if (gourl != null) headers += "wtv-visit: " + gourl + "\n";
+ if (gourl !== null) headers += "wtv-visit: " + gourl + "\n";
if (!bf0app_update && session_data.get("wtv-open-access")) headers += "wtv-open-isp-disabled: false\n";
headers += "wtv-client-time-zone: GMT -0000\n";
headers += "wtv-client-time-dst-rule: GMT\n"
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/admin.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/admin.js
index 9af9e026..73304625 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/admin.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/admin.js
@@ -7,7 +7,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/ban.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/ban.js
index 0b07005a..6837ec29 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/ban.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/ban.js
@@ -7,7 +7,7 @@ if (auth === true) {
let result, ssid, password;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
@@ -44,10 +44,10 @@ wtv-expire-all: wtv-admin:/ban`;
`
if (request_headers.query.ssid) {
- if (result == wtva.REASON_SELF) {
+ if (result === wtva.REASON_SELF) {
data += "Cannot ban yourself. "
} else {
- if (result == wtva.REASON_EXISTS) {
+ if (result === wtva.REASON_EXISTS) {
data += "SSID " + request_headers.query.ssid + " is already in the ban list. ";
} else if (result === wtva.SUCCESS) {
reloadConfig();
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteaccount.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteaccount.js
index 9bc64a6c..ad4b258e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteaccount.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteaccount.js
@@ -8,7 +8,7 @@ if (auth === true) {
let ssid_match = false;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
@@ -19,7 +19,7 @@ if (auth === true) {
user_info = wtva.getAccountInfoBySSID(ssid);
if (request_headers.query.confirm_delete) {
user_info = null;
- if (ssid == socket.ssid) {
+ if (ssid === socket.ssid) {
ssid_match = true;
} else {
// delete
@@ -63,7 +63,7 @@ wtv-noback-all: wtv-admin:/deleteaccount`;
if (Object.keys(user_info.account_users).length > 1) {
data += `Additional Users: `;
Object.keys(user_info.account_users).forEach(function (k) {
- if (k == "subscriber") return;
+ if (k === "subscriber") return;
data += user_info.account_users[k].subscriber_username + " ";
})
data += ` `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteuser.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteuser.js
index 16ac6692..cc957cb8 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteuser.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/deleteuser.js
@@ -12,7 +12,7 @@ if (auth === true) {
const show_box_was_unregistered = false;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
@@ -22,7 +22,7 @@ if (auth === true) {
user_info = wtva.getAccountInfo(request_headers.query.username.toLowerCase()); // username search
if (user_info) {
- if (user_info.ssid == socket.ssid) {
+ if (user_info.ssid === socket.ssid) {
show_cannot_modify_self = true;
}
if (request_headers.query.confirm_delete) {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/findaccount.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/findaccount.js
index 482a1003..a8d54d50 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/findaccount.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/findaccount.js
@@ -8,7 +8,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
@@ -53,7 +53,7 @@ wtv-noback-all: wtv-admin:/findaccount`;
if (Object.keys(user_info.account_users).length > 1) {
data += `Additional Users: `;
Object.keys(user_info.account_users).forEach(function (k) {
- if (k == "subscriber") return;
+ if (k === "subscriber") return;
data += user_info.account_users[k].subscriber_username + " ";
})
data += ` `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/operatortweaks.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/operatortweaks.js
index 7d83e7ae..cf38d846 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/operatortweaks.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/operatortweaks.js
@@ -20,15 +20,15 @@ function generateFormField(type, confvar, options = null) {
confvar_value = user_config.config[confvar] || minisrv_config.config[confvar];
}
- if (type == "input")
+ if (type === "input")
return ` `
- if (type == "checkbox")
+ if (type === "checkbox")
return ` \n `
- if (type == "select") {
+ if (type === "select") {
let out = `\n`
if (options) {
Object.keys(options).forEach((k) => {
- out += `${options[k].name} \n`
+ out += `${options[k].name} \n`
});
}
return out + " ";
@@ -39,7 +39,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/polyzoot.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/polyzoot.js
index 56786389..5c25b144 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/polyzoot.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/polyzoot.js
@@ -8,7 +8,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
@@ -79,7 +79,7 @@ data += `
`
if (request_headers.query.username) {
if (user_info && !request_headers.query.confirm && !request_headers.query.reset) {
- if (user_info.username == session_data.getSessionData("subscriber_username")) {
+ if (user_info.username === session_data.getSessionData("subscriber_username")) {
data += `Are you sure you want to Polyzoot yourself ? Are you a masochist?`;
} else {
data += `Are you sure you want to Polyzoot ${user_info.username} ? Are you a sadist?`;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/regenfavs.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/regenfavs.js
index 68c16409..e50c8ed1 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/regenfavs.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/regenfavs.js
@@ -8,7 +8,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/reloadconfig.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/reloadconfig.js
index 481bb24a..f2f1bc0d 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/reloadconfig.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/reloadconfig.js
@@ -7,7 +7,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/removeuserpasswd.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/removeuserpasswd.js
index b9b9d87c..7de85c2e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/removeuserpasswd.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/removeuserpasswd.js
@@ -10,7 +10,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
@@ -19,7 +19,7 @@ if (auth === true) {
if (request_headers.query.username) {
user_info = wtva.getAccountInfo(request_headers.query.username.toLowerCase()); // username search
if (user_info) {
- if (user_info.ssid == socket.ssid) {
+ if (user_info.ssid === socket.ssid) {
show_cannot_modify_self = true;
}
const userAccount = wtva.getAccountBySSID(user_info.ssid);
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/unban.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/unban.js
index 79e461fe..b2cbdee1 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/unban.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/unban.js
@@ -10,7 +10,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
@@ -22,7 +22,7 @@ if (auth === true) {
if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = [];
if (typeof request_headers.query.unban_ssid === 'string') {
Object.keys(fake_config.config.ssid_block_list).forEach(function (k) {
- if (fake_config.config.ssid_block_list[k] == request_headers.query.unban_ssid) {
+ if (fake_config.config.ssid_block_list[k] === request_headers.query.unban_ssid) {
fake_config.config.ssid_block_list.splice(k, 1);
ssids_removed.push(request_headers.query.unban_ssid)
config_changed = true;
@@ -30,9 +30,9 @@ if (auth === true) {
});
} else {
Object.keys(fake_config.config.ssid_block_list).forEach(function (k) {
- Object.keys(request_headers.query.unban_ssid).forEach(function (j) {
- if (fake_config.config.ssid_block_list[k] == request_headers.query.unban_ssid[j]) {
- fake_config.config.ssid_block_list.splice(k,1);
+ Object.keys(request_headers.query.unban_ssid).forEach(function (j) {
+ if (fake_config.config.ssid_block_list[k] === request_headers.query.unban_ssid[j]) {
+ fake_config.config.ssid_block_list.splice(k, 1);
ssids_removed.push(request_headers.query.unban_ssid[j])
config_changed = true;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/validate-operator-tweaks.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/validate-operator-tweaks.js
index f140f617..e482ab86 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/validate-operator-tweaks.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-admin/validate-operator-tweaks.js
@@ -8,7 +8,7 @@ if (auth === true) {
let password = null;
if (request_headers.Authorization) {
const authheader = request_headers.Authorization.split(' ');
- if (authheader[0] == "Basic") {
+ if (authheader[0] === "Basic") {
password = Buffer.from(authheader[1], 'base64').toString();
if (password) password = password.split(':')[1];
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/add-media-to-block.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/add-media-to-block.js
index c2b72ac0..ce6d23d0 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/add-media-to-block.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/add-media-to-block.js
@@ -10,7 +10,7 @@ const oldPosition = request_headers.query.oldBlockNum;
const editing = request_headers.query.editing;
let page;
-if (editing == "true"){
+if (editing === "true"){
session_data.pagestore.editPhotoBlock(docName, request_headers.query.blockNum, request_headers.query.newBlockNum, null, null, request_headers.query.blockTitle, request_headers.query.photoBlockCaption);
headers = `300 OK
wtv-expire-all: wtv-author:/block-preview
@@ -22,14 +22,14 @@ Location: wtv-author:/show-blocks?docName=${docName}`
} else {
const page = session_data.pagestore.loadPage(docName);
const blockNum = request_headers.query.blockNum;
- if (request_headers.query.scrapbookID != undefined) {
+ if (request_headers.query.scrapbookID !== undefined) {
const image = session_data.pagestore.getScrapbookImage(parseInt(request_headers.query.scrapbookID));
- if (page.blocks[blockNum] != undefined)
+ if (page.blocks[blockNum] !== undefined)
session_data.pagestore.editPhotoBlock(docName, request_headers.query.blockNum, request_headers.query.blockNum, image, "scrapbook", null, null);
else
session_data.pagestore.createPhotoBlock(docName, image, "scrapbook");
} else {
- if (page.blocks[blockNum] != undefined)
+ if (page.blocks[blockNum] !== undefined)
session_data.pagestore.editPhotoBlock(docName, request_headers.query.blockNum, request_headers.query.blockNum, request_headers.query.mediaPath, "clipart", null, null);
else
session_data.pagestore.createPhotoBlock(docName, request_headers.query.mediaPath, "clipart");
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/doc-info.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/doc-info.js
index bcb17f9d..57f752e7 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/doc-info.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/doc-info.js
@@ -3,7 +3,7 @@ const minisrv_service_file = true;
const pagestore_exists = session_data.pagestore.pagestoreExists();
const docName = request_headers.query.docName;
-if (pagestore_exists != true)
+if (pagestore_exists !== true)
{
session_data.pagestore.createPagestore();
headers = `300 OK
@@ -129,7 +129,7 @@ ${page.title}
`
-if (page.published == true)
+if (page.published === true)
data += `published ${page.publishdate}`
else
data += "not published"
@@ -163,7 +163,7 @@ Change how your page is listed
`
- if (page.published != true)
+ if (page.published !== true)
data += `Publish page
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/documents.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/documents.js
index e855cec0..f18fc4f6 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/documents.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/documents.js
@@ -4,7 +4,7 @@ const pagestore_exists = session_data.pagestore.pagestoreExists();
const site = session_data.pagestore.getPublishDomain();
-if (pagestore_exists != true)
+if (pagestore_exists !== true)
session_data.pagestore.createPagestore();
const pagearray = session_data.pagestore.listPages();
@@ -163,7 +163,7 @@ data = `
`
for (let i = 0; i < numofpages; i++) {
data += ` `
- if (i == 0)
+ if (i === 0)
data += `
`
@@ -181,7 +181,7 @@ ${pagearray[i].description}
`
-if (pagearray[i].published == true)
+if (pagearray[i].published === true)
data += `published ${pagearray[i].publishdate}`
else
data += "not published"
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-block.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-block.js
index dce72075..3b490f24 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-block.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-block.js
@@ -203,7 +203,7 @@ Add text to your document
Text size:`
const textsize = pagedata.blocks[oldBlockNum].size
-if (textsize == "-1")
+if (textsize === "-1")
{
data += `
Small
@@ -211,7 +211,7 @@ if (textsize == "-1")
Medium
Large `
-} else if (textsize == "+1")
+} else if (textsize === "+1")
{
data += `
Small
@@ -233,7 +233,7 @@ data += `
Text style:`
const textstyle = pagedata.blocks[oldBlockNum].style
-if (textstyle == "B")
+if (textstyle === "B")
{
data += `
@@ -243,7 +243,7 @@ Plain
Italic
`
-} else if (textstyle == "I") {
+} else if (textstyle === "I") {
data += `
Plain
@@ -461,11 +461,11 @@ if (showIt)
{ document.viewOptionEmbed.document.write('
`
-if (blockType == "snapshot" || blockType == "scrapbook") {
+if (blockType === "snapshot" || blockType === "scrapbook") {
data += `View this picture
`
-} else if (blockType == "clipart")
+} else if (blockType === "clipart")
data += `View this picture
`
@@ -551,9 +551,9 @@ vspace=0
`
-if (blockType == "snapshot") {
+if (blockType === "snapshot") {
data += ` `
-} else if (blockType == "clipart") {
+} else if (blockType === "clipart") {
data += ` `
}
data += `
@@ -579,7 +579,7 @@ DisplayViewOption(true);
@@ -597,7 +597,7 @@ autohiragana
growable
width=100%
value="`
-if (pagedata.blocks[oldBlockNum].caption != null)
+if (pagedata.blocks[oldBlockNum].caption !== null)
data += `${pagedata.blocks[oldBlockNum].caption}`
data += `"
cols=45 rows=3>
@@ -837,14 +837,14 @@ Add a heading to your document
Text size:`
- if (pagedata.blocks[oldBlockNum].size == "H3")
+ if (pagedata.blocks[oldBlockNum].size === "H3")
data += `
Small
Medium
Large `
- else if (pagedata.blocks[oldBlockNum].size == "H1")
+ else if (pagedata.blocks[oldBlockNum].size === "H1")
data += `
Small
@@ -862,7 +862,7 @@ data += `
Add a divider line:
Before the heading
@@ -870,7 +870,7 @@ Before the heading
After the heading
@@ -1204,7 +1204,7 @@ function SetListItems()
for (let i = 0; i < pagedata.blocks[oldBlockNum].items.length; i++) {
data += `ListElements[${i}] = new Object;`
- if (pagedata.blocks[oldBlockNum].items[i].name == undefined)
+ if (typeof pagedata.blocks[oldBlockNum].items[i].name === 'undefined')
data += `ListElements[${i}].desc = "";`
else
data += `ListElements[${i}].desc = "${pagedata.blocks[oldBlockNum].items[i].name}";`
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-title.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-title.js
index c2ea3d16..4adf301b 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-title.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/edit-title.js
@@ -7,7 +7,7 @@ headers = `200 OK
Connection: Keep-Alive
Content-Type: text/html`
-if (request_headers.query.publishing == "true") {
+if (request_headers.query.publishing === "true") {
data = `
@@ -110,7 +110,7 @@ cols=45 rows=4 MAXLENGTH=128>
`
-} else if (request_headers.query.titleOnly == "true") {
+} else if (request_headers.query.titleOnly === "true") {
data = `
@@ -194,7 +194,7 @@ as well as in the list of your pages.
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/publish.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/publish.js
index 528606e5..3f1b5f98 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/publish.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/publish.js
@@ -4,7 +4,7 @@ const docName = request_headers.query.docName;
const page = session_data.pagestore.loadPage(docName);
const site = session_data.pagestore.getPublishDomain();
-if (request_headers.query.publishStage == "1") {
+if (request_headers.query.publishStage === "1") {
headers = `200 OK
Content-Type: text/html`
@@ -77,7 +77,7 @@ Your public list of pages will be at:
Include in public list
@@ -116,24 +116,24 @@ Include in public list
`
-} else if (request_headers.query.publishStage == "2") {
+} else if (request_headers.query.publishStage === "2") {
let inlist;
- if (request_headers.query.includeInPublicList != undefined) {
+ if (typeof request_headers.query.includeInPublicList !== 'undefined') {
inlist = true;
} else {
inlist = false;
}
const result = session_data.pagestore.publishPage(docName, inlist);
- if (result == true) {
+ if (result === true) {
headers = `300 OK
wtv-expire-all: wtv-author:/documents
Location: wtv-author:/congrats?docName=${docName}`
} else {
headers = `400 ${result}`
}
-} else if (request_headers.query.unpublish == "1") {
+} else if (request_headers.query.unpublish === "1") {
const result = session_data.pagestore.unpublishPage(docName);
- if (result == true) {
+ if (result === true) {
headers = `300 OK
wtv-expire-all: wtv-author:/documents
wtv-expire-all: wtv-author:/doc-info
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-block.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-block.js
index 940f3128..9865772e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-block.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-block.js
@@ -11,9 +11,9 @@ const editing = request_headers.query.editing;
const blockClass = request_headers.query.blockClass;
switch(blockClass) {
case "23":
- if (editing == "true") {
+ if (editing === "true") {
const photo = request_headers.query.photoBlockPhoto;
- if (request_headers.query.toSnapshot == "true")
+ if (request_headers.query.toSnapshot === "true")
session_data.pagestore.editPhotoBlock(docName, request_headers.query.blockNum, request_headers.query.newBlockNum, photo, "snapshot", request_headers.query.blockTitle, request_headers.query.photoBlockCaption);
else
session_data.pagestore.editPhotoBlock(docName, request_headers.query.blockNum, request_headers.query.newBlockNum, null, null, request_headers.query.blockTitle, request_headers.query.photoBlockCaption);
@@ -36,14 +36,14 @@ Location: ${request_headers.query.returnPageURL + "&numOfBlocks=" + page.blocks.
}
break;
case "21":
- if (caption.length == 0) {
+ if (caption.length === 0) {
headers = "400 You must enter a caption. Please enter a caption and try again."
} else {
- if (editing == "true") {
- if (size.length == 0)
+ if (editing === "true") {
+ if (size.length === 0)
size = null;
-
- if (style.length == 0)
+
+ if (style.length === 0)
style = null;
session_data.pagestore.editTextBlock(docName, title, caption, size, style, position, oldPosition);
headers = `300 OK
@@ -53,10 +53,10 @@ Location: ${request_headers.query.returnPageURL + "&numOfBlocks=" + page.blocks.
wtv-expire-all: wtv-author:/edit-block
Location: wtv-author:/show-blocks?docName=${docName}`
} else {
- if (size.length == 0)
+ if (size.length === 0)
size = null;
-
- if (style.length == 0)
+
+ if (style.length === 0)
style = null;
session_data.pagestore.createTextBlock(docName, title, caption, size, style, position);
headers = `300 OK
@@ -72,10 +72,10 @@ Location: ${request_headers.query.returnPageURL + "&numOfBlocks=" + page.blocks.
size = request_headers.query.headingBlockSize
const dividerBefore = request_headers.query.headingBlockDividerBefore
const dividerAfter = request_headers.query.headingBlockDividerAfter
- if (header.length == 0) {
+ if (header.length === 0) {
headers = "400 You must enter a header. Please enter a header and try again."
} else {
- if (editing == "true") {
+ if (editing === "true") {
session_data.pagestore.editHeaderBlock(docName, header, size, dividerBefore, dividerAfter, position, request_headers.query.blockNum);
headers = `300 OK
wtv-expire-all: wtv-author:/block-preview
@@ -94,7 +94,7 @@ Location: wtv-author:/show-blocks?docName=${docName}`
}
break;
case "24":
- if (editing == "true") {
+ if (editing === "true") {
const listItems = request_headers.query.listItemText.filter(function(e){ return e.replace(/(\r\n|\n|\r)/gm,"")});
session_data.pagestore.editListBlock(docName, title, listItems, position, request_headers.query.blockNum);
headers = `300 OK
@@ -114,7 +114,7 @@ Location: wtv-author:/show-blocks?docName=${docName}`
}
break;
case "25":
- if (editing == "true") {
+ if (editing === "true") {
const listItems = request_headers.query.listItemText;
const linkItems = request_headers.query.linkItemURL;
session_data.pagestore.editLinkBlock(docName, title, listItems, linkItems, position, request_headers.query.blockNum);
@@ -137,7 +137,7 @@ Location: wtv-author:/show-blocks?docName=${docName}`
break;
case "27":
- if (editing == "true") {
+ if (editing === "true") {
session_data.pagestore.editBreakBlock(docName, position, request_headers.query.blockNum);
headers = `300 OK
wtv-expire-all: wtv-author:/block-preview
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-title.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-title.js
index d798a34c..870115e3 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-title.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/save-title.js
@@ -3,7 +3,7 @@ const minisrv_service_file = true;
const docName = request_headers.query.docName;
const docTitle = request_headers.query.docTitle;
-if (docTitle.length == 0) {
+if (docTitle.length === 0) {
headers = "400 You must enter a title for your page. Please enter a title and try again."
} else {
const pagedata = session_data.pagestore.loadPage(docName);
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js
index 207f3d96..4a4cc92b 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-author/scrapbook-add.js
@@ -48,7 +48,7 @@ if (!request_headers.query.mediaData && !request_headers.query.mediaPath) {
function isValidImageType(contentType, url) {
// Check content-type header or file extension
if (contentType) {
- return contentType === 'image/jpeg' || contentType == 'image/jpg' || contentType === 'image/gif';
+ return contentType === 'image/jpeg' || contentType === 'image/jpg' || contentType === 'image/gif';
}
return url.endsWith('.jpg') || url.endsWith('.jpeg') || url.endsWith('.gif');
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-chat/home.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-chat/home.js
index eb431618..c21edab8 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-chat/home.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-chat/home.js
@@ -109,12 +109,12 @@ Chat Home
Server:
-
+
Port:
-
+
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js
index 07638031..a6e476d8 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/content/DownloadScreen.tmpl.js
@@ -12,7 +12,7 @@ let diskmap_data = {};
if (!request_headers.query.url) {
Object.keys(service_vaults).forEach(function (g) {
- if (diskmap_json_file != null) return;
+ if (diskmap_json_file !== null) return;
diskmap_json_file = service_vaults[g] + "/" + service_name + "/" + diskmap_dir + diskmap + ".json";
if (!fs.existsSync(diskmap_json_file)) diskmap_json_file = null;
});
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js
index 1a9ab904..aae49370 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-disk/sync.js
@@ -3,12 +3,12 @@ const minisrv_service_file = true;
const diskmap = request_headers.query[wtvshared.getCaseInsensitiveKey("DiskMap", request_headers.query)];
const wtvdl = new WTVDisk(minisrv_config, service_name);
-const force_update = (request_headers.query.force == "true") ? true : false;
-const no_delete = (request_headers.query.dont_delete_files == "true") ? true : false;
+const force_update = (request_headers.query.force === "true") ? true : false;
+const no_delete = (request_headers.query.dont_delete_files === "true") ? true : false;
const content_dir = "content/"
const diskmap_dir = content_dir + "diskmaps/";
-if (request_headers['wtv-request-type'] == 'download') {
+if (request_headers['wtv-request-type'] === 'download') {
function generateDownloadList(diskmap_group_name, update_list, diskmap_group_data) {
wtvdl.reset();
@@ -34,7 +34,7 @@ if (request_headers['wtv-request-type'] == 'download') {
if (force_update && !no_delete) {
// don't delete Browser partition, ever, but allow deleting of Browser partition subdirs
if (!diskmap_group_data.base.match(/disk\/browser(\/)?$/i)) {
- if (diskmap_group_data.client_group_data.path.toLowerCase() == diskmap_group_data.base.toLowerCase()) {
+ if (diskmap_group_data.client_group_data.path.toLowerCase() === diskmap_group_data.base.toLowerCase()) {
wtvdl.delete(diskmap_group_data.base, null);
} else {
wtvdl.delete(diskmap_group_data.base, diskmap_group_data.client_group_data.group);
@@ -60,7 +60,7 @@ if (request_headers['wtv-request-type'] == 'download') {
Object.keys(update_list).forEach(function (k) {
// file { "action": "delete" }
// Useful to purge files we no longer want on the client
- if (update_list[k].action != "DELETE" && update_list[k].action != "DELETEONLY") {
+ if (update_list[k].action !== "DELETE" && update_list[k].action !== "DELETEONLY") {
// skip deleting valid files if we aren't specifically requesting their deletion
if (update_list[k].checksum_match && !force_update) return;
if (!update_list[k].invalid && !force_update) return;
@@ -75,7 +75,7 @@ if (request_headers['wtv-request-type'] == 'download') {
Object.keys(update_list).forEach(function (k) {
if (update_list[k].checksum_match && !force_update) return;
if (!update_list[k].invalid && !force_update) return;
- if (update_list[k].action == "DELETEONLY") return;
+ if (update_list[k].action === "DELETEONLY") return;
if (update_list[k].display) wtvdl.display(update_list[k].display);
switch (update_list[k].action) {
case "PUT":
@@ -98,7 +98,7 @@ if (request_headers['wtv-request-type'] == 'download') {
Object.keys(update_list).forEach(function (k) {
if (update_list[k].checksum_match && !force_update) return;
if (!update_list[k].invalid && !force_update) return;
- if (update_list[k].action == "DELETEONLY") return;
+ if (update_list[k].action === "DELETEONLY") return;
wtvdl.rename(update_list[k].file.replace(diskmap_group_data.base, ""), update_list[k].file.replace(diskmap_group_data.base, ""), diskmap_group_name, diskmap_group_name, update_list[k].rename || update_list[k].original_filename || null);
});
@@ -143,7 +143,7 @@ if (request_headers['wtv-request-type'] == 'download') {
let post_data_current_checksum = false;
let post_data_last_checkup_time = 0;
Object.keys(post_data).forEach(function (k) {
- if (post_data[k].slice(0, 7) == "file://") {
+ if (post_data[k].slice(0, 7) === "file://") {
entry_type = "folder";
post_data_current_file = false;
post_data_current_version = false;
@@ -185,13 +185,13 @@ if (request_headers['wtv-request-type'] == 'download') {
break;
}
} else {
- if (!entry_type && post_data[k] != "") {
+ if (!entry_type && post_data[k] !== "") {
entry_type = "file";
post_data_current_file = post_data[k];
}
- if (post_data[k] == "" && entry_type) {
- const post_data_current_path = ((entry_type == "file") ? (post_data_current_directory + post_data_current_file) : post_data_current_directory);
+ if (post_data[k] === "" && entry_type) {
+ const post_data_current_path = ((entry_type === "file") ? (post_data_current_directory + post_data_current_file) : post_data_current_directory);
const index = post_data_current_path.replace(/[\:\/]/g, "_").toLowerCase() + "_" + post_data_current_group;
if (index.match(/\/$/)) entry_type = "folder";
if (!post_data_fileinfo[index]) post_data_fileinfo[index] = {};
@@ -215,7 +215,7 @@ if (request_headers['wtv-request-type'] == 'download') {
if (!diskmap_group_data.files[k].location) diskmap_group_data.files[k].location = wtvshared.makeSafePath(diskmap_group_data.location,diskmap_group_data.files[k].file.replace(diskmap_group_data.base, ""), true);
let diskmap_data_file = null;
Object.keys(service_vaults).forEach(function (g) {
- if (diskmap_data_file != null) return;
+ if (diskmap_data_file !== null) return;
diskmap_data_file = service_vaults[g] + "/" + service_name + "/" + diskmap_group_data.files[k].location;
if (!fs.existsSync(diskmap_data_file) || !fs.lstatSync(diskmap_data_file).isFile()) diskmap_data_file = null;
});
@@ -232,7 +232,7 @@ if (request_headers['wtv-request-type'] == 'download') {
diskmap_group_data.files[k].action = (diskmap_group_data.files[k].action) ? diskmap_group_data.files[k].action.toUpperCase() : "GET";
// we need the checksum of the uncompressed data
- if (wtvshared.getFileExt(diskmap_data_file).toLowerCase() == "gz") {
+ if (wtvshared.getFileExt(diskmap_data_file).toLowerCase() === "gz") {
const diskmap_data_filename = path.basename(diskmap_data_file);
const gunzipped = zlib.gunzipSync(diskmap_file_data);
diskmap_group_data.files[k].checksum = CryptoJS.MD5(CryptoJS.lib.WordArray.create(gunzipped)).toString(CryptoJS.enc.Hex).toLowerCase();
@@ -256,14 +256,14 @@ if (request_headers['wtv-request-type'] == 'download') {
Object.keys(wtv_download_list).forEach(function (k) {
wtv_download_list[k].version = newest_file_epoch;
Object.keys(post_data_fileinfo).forEach(function (g) {
- if (post_data_fileinfo[g].file == wtv_download_list[k].file || post_data_fileinfo[g].file == wtv_download_list[k].base) {
+ if (post_data_fileinfo[g].file === wtv_download_list[k].file || post_data_fileinfo[g].file === wtv_download_list[k].base) {
diskmap_group_data.group_exists = true;
- if (wtv_download_list[k].checksum && wtv_download_list[k].checksum.toLowerCase() == post_data_fileinfo[g].checksum) wtv_download_list[k].invalid = false;
- else if (post_data_fileinfo[g].version == wtv_download_list[k].version && post_data_fileinfo[g].state !== "invalid") wtv_download_list[k].invalid = false;
+ if (wtv_download_list[k].checksum && wtv_download_list[k].checksum.toLowerCase() === post_data_fileinfo[g].checksum) wtv_download_list[k].invalid = false;
+ else if (post_data_fileinfo[g].version === wtv_download_list[k].version && post_data_fileinfo[g].state !== "invalid") wtv_download_list[k].invalid = false;
}
});
});
- const diskmap_group_name = (diskmap_subgroup == null) ? diskmap_primary_group : diskmap_primary_group + "-" + diskmap_subgroup;
+ const diskmap_group_name = (diskmap_subgroup === null) ? diskmap_primary_group : diskmap_primary_group + "-" + diskmap_subgroup;
diskmap_group_data.client_group_data = client_group_data[diskmap_group_name] || null;
output_data = generateDownloadList(diskmap_group_name, wtv_download_list, diskmap_group_data);
return output_data;
@@ -272,12 +272,12 @@ if (request_headers['wtv-request-type'] == 'download') {
if (diskmap && request_headers.query.group) {
let diskmap_json_file = null;
Object.keys(service_vaults).forEach(function (g) {
- if (diskmap_json_file != null) return;
+ if (diskmap_json_file !== null) return;
diskmap_json_file = service_vaults[g] + "/" + service_name + "/" + diskmap_dir + diskmap + ".json";
if (!fs.existsSync(diskmap_json_file)) diskmap_json_file = null;
});
- if (diskmap_json_file != null) {
+ if (diskmap_json_file !== null) {
try {
// read diskmap
const json_stats = fs.lstatSync(diskmap_json_file);
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/add.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/add.js
index 42be1b59..79b40392 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/add.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/add.js
@@ -24,7 +24,7 @@ if (request_headers.post_data) {
function getTitle(url) {
return new Promise(function (resolve, reject) {
let page_title = "Web Page";
- const request_type = (url.slice(0, 5) == "https") ? "https" : "http";
+ const request_type = (url.slice(0, 5) === "https") ? "https" : "http";
let proxy_agent = null;
switch (request_type) {
case "https":
@@ -40,7 +40,7 @@ function getTitle(url) {
}
const request = proxy_agent.get(url, options, (response) => {
let req_data = '';
- if (response.statusCode == 301 || response.statusCode == 302) {
+ if (response.statusCode === 301 || response.statusCode === 302) {
redirects++;
if (redirects < max_redirects) resolve(getTitle(response.headers.location));
else reject(`Too many redirects. Max: ${max_redirects}, Current: ${redirects}`);
@@ -107,7 +107,7 @@ async function saveFavorite(favstore, title, folder, imagetype, favurl) {
image = "canned/favorite_default.gif"
}
- if (favoritenum == minisrv_config.services[service_name].max_favorites_per_folder) {
+ if (favoritenum === minisrv_config.services[service_name].max_favorites_per_folder) {
headers = `400 You can only have ${minisrv_config.services[service_name].max_favorites_per_folder} favorites in a folder. Discard some favorites or choose a different folder, then try again.`
} else {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-favorites.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-favorites.js
index ebd3d4e0..386583ba 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-favorites.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-favorites.js
@@ -6,11 +6,11 @@ const query = request_headers.query
const discardAll = request_headers.query.DiscardAll
let strName;
-if (discardAll != "Discard All")
+if (discardAll !== "Discard All")
{
for(strName in query)
{
- if (strName != "favorite_folder_name")
+ if (strName !== "favorite_folder_name")
break;
}
@@ -24,7 +24,7 @@ if (request_headers.query.ForwardToBrowser)
Connection: Keep-Alive
Content-Type: text/html
Location: wtv-favorite:/serve-browser?favorite_folder_name=${folder}`
-} else if (strName != "getCaseInsensitiveKey") {
+} else if (strName !== "getCaseInsensitiveKey") {
const favorite = session_data.favstore.getFavorite(folder, strName);
if (errpage) {
@@ -33,7 +33,7 @@ Location: wtv-favorite:/serve-browser?favorite_folder_name=${folder}`
} else {
if (!request_headers.query.confirm_remove) {
let message, removeurl;
- if (discardAll == "Discard All")
+ if (discardAll === "Discard All")
{
message = `Are you sure you want to discard all favorites in this folder?`;
removeurl = request_headers.request_url + "&confirm_remove=true&DiscardAll=Discard All";
@@ -58,7 +58,7 @@ Location: ${confirmAlert}`
} else {
const gourl = `wtv-favorite:/serve-discard-favorites?favorite_folder_name=${folder}`;
- if (discardAll == "Discard All")
+ if (discardAll === "Discard All")
{
session_data.favstore.clearFolder(folder);
} else {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-folders.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-folders.js
index 75ea5c0c..5c9c21fb 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-folders.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-discard-folders.js
@@ -33,7 +33,7 @@ Location: wtv-favorite:/favorite`
} else {
if (!request_headers.query.confirm_remove) {
let message = '';
- if (numoffavorites == 0) {
+ if (numoffavorites === 0) {
message = `Are you sure you want to remove ${folder} ?`;
} else {
message = `Removing ${folder} will also remove the ${numoffavorites} favorites it contains.`;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-move-favorites.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-move-favorites.js
index 35b67d12..9f805114 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-move-favorites.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-move-favorites.js
@@ -12,14 +12,14 @@ else {
// one favorite
const favid = request_headers.query.favoriteid;
const favfolder = request_headers.query.favoritefolder;
- if (folder != favfolder) session_data.favstore.moveFavorite(folder, favfolder, favid);
+ if (folder !== favfolder) session_data.favstore.moveFavorite(folder, favfolder, favid);
} else {
- if (request_headers.query.favoriteid.length == request_headers.query.favoritefolder.length) {
- // both queries should have the same number of entries
+ if (request_headers.query.favoriteid.length === request_headers.query.favoritefolder.length) {
+ // both queries should have the same number of entries
Object.keys(request_headers.query.favoriteid).forEach(function (k) {
const favid = request_headers.query.favoriteid[k];
const favfolder = request_headers.query.favoritefolder[k];
- if (folder != favfolder) session_data.favstore.moveFavorite(folder, favfolder, favid);
+ if (folder !== favfolder) session_data.favstore.moveFavorite(folder, favfolder, favid);
})
} else {
error_occured = true;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-samples-page.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-samples-page.js
index a418aea4..d3685f63 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-samples-page.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/commit-samples-page.js
@@ -13,23 +13,22 @@ totalfavorites = folder_array.length;
if (totalfavorites < 14)
{
- if (createFun == "true")
+ if (createFun === "true")
session_data.favstore.createTemplateFolder("Fun");
- if (createMoney == "true")
+ if (createMoney === "true")
session_data.favstore.createTemplateFolder("Money");
- if (createMovies == "true")
+ if (createMovies === "true")
session_data.favstore.createTemplateFolder("Movies");
- if (createNews == "true")
+ if (createNews === "true")
session_data.favstore.createTemplateFolder("News");
- if (createRecommended == "true")
+ if (createRecommended === "true")
session_data.favstore.createTemplateFolder("Recommended");
- console.log("FUGHFVJSGHJFDGIJUFDSHGFJDSKHJKLGFHJKHDJKHJKLGF " + createRecommended)
- if (createReference == "true")
+ if (createReference === "true")
session_data.favstore.createTemplateFolder("Reference");
headers = `300 OK
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite-index.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite-index.js
index 1cb88a3f..268584ec 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite-index.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite-index.js
@@ -2,7 +2,7 @@ const minisrv_service_file = true;
const favstore_exists = session_data.favstore.favstoreExists();
-if (favstore_exists != true)
+if (favstore_exists !== true)
{
session_data.favstore.createFavstore();
headers = `300 OK
@@ -13,7 +13,7 @@ const folder_array = session_data.favstore.getFolders();
const url = request_headers.request;
const key = url.split('?')[1]
const scfav = session_data.favstore.getShortcutKey(key);
-if (!scfav.id || scfav.id == "none") {
+if (!scfav.id || scfav.id === "none") {
headers = `400 You have not assigned a favorite to ${key}`
} else {
const fav = session_data.favstore.getFavorite(scfav.folder, scfav.id);
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite.js
index 9bc5b220..834d78f2 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/favorite.js
@@ -2,16 +2,15 @@ const minisrv_service_file = true;
const favstore_exists = session_data.favstore.favstoreExists();
-if (favstore_exists != true)
+if (favstore_exists !== true)
{
session_data.favstore.createFavstore();
headers = `300 OK
+wtv-expire-all: wtv-favorite:/favorite
Location: wtv-favorite:/favorite`
} else {
const folder_array = session_data.favstore.getFolders();
-const totalfavorites = folder_array.length;
-const stopdrawing = false;
headers = `200 OK
Connection: Keep-Alive
@@ -151,8 +150,8 @@ for ${session_data.getSessionData("subscriber_username") || "You"}
let kval = 0;
// process evens
Object.keys(folder_array).forEach(function (k) {
- if (k == 0) return; // skip 0 since it was processed above
- if (parseInt(k) % 2 == 0) {
+ if (parseInt(k)=== 0) return; // skip 0 since it was processed above
+ if (parseInt(k) % 2 === 0) {
// even
// Left Middle
data += `
@@ -171,7 +170,7 @@ for ${session_data.getSessionData("subscriber_username") || "You"}
// process end if total is even
if (folder_array.length > 1) {
- if (folder_array.length % 2 == 0) {
+ if (folder_array.length % 2 === 0) {
data += `
@@ -182,7 +181,7 @@ for ${session_data.getSessionData("subscriber_username") || "You"}
}
// process middle (folder 2 (id 1))
- if (folder_array.length == 1) {
+ if (folder_array.length === 1) {
// no folder 2
data += `
@@ -223,8 +222,8 @@ for ${session_data.getSessionData("subscriber_username") || "You"}
// process odds
Object.keys(folder_array).forEach(function (k) {
- if (k == 1) return; // skip 1 since it was processed above
- if (parseInt(k) % 2 != 0) {
+ if (parseInt(k) === 1) return; // skip 1 since it was processed above
+ if (parseInt(k) % 2 !== 0) {
// odd
// Right Middle
data += `
@@ -242,7 +241,7 @@ for ${session_data.getSessionData("subscriber_username") || "You"}
// process end if total is odd
if (folder_array.length > 1) {
- if (folder_array.length % 2 != 0) {
+ if (folder_array.length % 2 !== 0) {
data += `
`;
- if ((parseInt(k) + 1) % 3 == 0) {
+ if ((parseInt(k) + 1) % 3 === 0) {
// every 3 objects
data += `
`
-if (favoritenum == 0)
+if (favoritenum === 0)
{
data += " There are no favorites to discard in this folder. ";
} else {
@@ -133,7 +133,7 @@ for (let i = 0; i < favoritenum; i++) {
data += `
`
}
-if (totalfavorites == 1)
+if (totalfavorites === 1)
data += `
@@ -175,7 +175,7 @@ data += `
`
-if (totalfavorites == 1)
+if (totalfavorites === 1)
data += " You cannot delete your last folder. "
data += `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-move-favorites.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-move-favorites.js
index 4608f6c0..e61ef36e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-move-favorites.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-move-favorites.js
@@ -12,7 +12,7 @@ let folderlist = `
${foldername}
`
for (let i = 0; i < foldernum; i++) {
- if (folder_array[i] == foldername)
+ if (folder_array[i] === foldername)
{
} else {
folderlist += `${folder_array[i]}
@@ -140,7 +140,7 @@ Move favorites
`
-if (favoritenum == 0)
+if (favoritenum === 0)
{
data += " There are no favorites to move in this folder. ";
} else {
@@ -148,7 +148,7 @@ for (let i = 0; i < favoritenum; i++) {
data += `
`
-if (favarray[i].imagetype == "url")
+if (favarray[i].imagetype === "url")
data += ` `
else
data += ` `
@@ -165,7 +165,7 @@ data += `
${foldername}
`
for (let i = 0; i < foldernum; i++) {
- if (folder_array[i] == foldername)
+ if (folder_array[i] === foldername)
{
} else {
data += `${folder_array[i]}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-rename-favorites.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-rename-favorites.js
index b89a08b3..989aafff 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-rename-favorites.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-rename-favorites.js
@@ -126,7 +126,7 @@ Rename favorites
`
-if (favoritenum == 0)
+if (favoritenum === 0)
{
data += " There are no favorites to rename in this folder. ";
} else {
@@ -134,7 +134,7 @@ for (let i = 0; i < favoritenum; i++) {
data += `
`
-if (favarray[i].imagetype == "url")
+if (favarray[i].imagetype === "url")
data += ` `
else
data += ` `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-samples-page.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-samples-page.js
index 9ee03408..15d107db 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-samples-page.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-samples-page.js
@@ -104,7 +104,7 @@ by going to the folder and choosing Organize .
`
-if (session_data.favstore.folderExists("Fun") == true)
+if (session_data.favstore.folderExists("Fun") === true)
{
data += `
@@ -124,7 +124,7 @@ if (session_data.favstore.folderExists("Fun") == true)
Fun
`
}
-if (session_data.favstore.folderExists("Money") == true)
+if (session_data.favstore.folderExists("Money") === true)
{
data += `
@@ -147,7 +147,7 @@ if (session_data.favstore.folderExists("Money") == true)
`
-if (session_data.favstore.folderExists("Movies") == true)
+if (session_data.favstore.folderExists("Movies") === true)
{
data += `
@@ -167,7 +167,7 @@ if (session_data.favstore.folderExists("Movies") == true)
Movies
`
}
-if (session_data.favstore.folderExists("News") == true)
+if (session_data.favstore.folderExists("News") === true)
{
data += `
@@ -191,7 +191,7 @@ data += `
`
-if (session_data.favstore.folderExists("Recommended") == true)
+if (session_data.favstore.folderExists("Recommended") === true)
{
data += `
@@ -211,7 +211,7 @@ if (session_data.favstore.folderExists("Recommended") == true)
Recommended
`
}
-if (session_data.favstore.folderExists("Reference") == true)
+if (session_data.favstore.folderExists("Reference") === true)
{
data += `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcut-list.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcut-list.js
index d1a8d454..b2b797eb 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcut-list.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcut-list.js
@@ -77,7 +77,7 @@ let fav;
for (let i = 1; i <= 8; i++) {
const key = "F" + i;
const scfav = session_data.favstore.getShortcutKey(key);
- if (scfav && scfav.id != "none") {
+ if (scfav && scfav.id !== "none") {
fav = session_data.favstore.getFavorite(scfav.folder, scfav.id);
} else {
fav = { image: "wtv-home:/ROMCache/Spacer.gif", title: "Not assigned" };
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcuts-favorites.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcuts-favorites.js
index 1dd8d1c2..5145d9da 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcuts-favorites.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-favorite/serve-shortcuts-favorites.js
@@ -113,7 +113,7 @@ Assign shortcut to favorite
`
-if (favoritenum == 0)
+if (favoritenum === 0)
{
data += " There are no favorites to move in this folder. ";
} else {
@@ -141,7 +141,7 @@ for (let i = 0; i < favoritenum; i++) {
`
-if (favarray[i].imagetype == "url")
+if (favarray[i].imagetype === "url")
data += ` `
else
data += ` `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/content/content-serve.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/content/content-serve.js
index f1ac736e..068cc40d 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/content/content-serve.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/content/content-serve.js
@@ -6,7 +6,7 @@ const request_path = request_headers.request_url.replace(service_name + ":/", ""
const romtype = session_data.get("wtv-client-rom-type");
const bootver = session_data.get("wtv-client-bootrom-version")
-if ((romtype == "bf0app" || !romtype) && (bootver == "105" || !bootver)) {
+if ((romtype === "bf0app" || !romtype) && (bootver === "105" || !bootver)) {
// assume old classic in flash mode, override user setting and send tellyscript
// because it is required to proceed in flash mode
bf0app_update = true;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/current-noflash.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/current-noflash.js
index f621026e..eeb4ecd6 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/current-noflash.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/current-noflash.js
@@ -15,7 +15,7 @@ let bf0app_update = true;
if (request_headers.query.path) request_path = request_headers.query.path;
else request_path = default_build_to_send;
-if (session_data.get("wtv-client-rom-type") == "bf0app" && session_data.get("wtv-client-bootrom-version") == "105") {
+if (session_data.get("wtv-client-rom-type") === "bf0app" && session_data.get("wtv-client-bootrom-version") === "105") {
// assume old classic in flash mode, override user setting and send tellyscript
// because it is required to proceed in flash mode
bf0app_update = true;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-by-path.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-by-path.js
index cc717105..3761c35b 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-by-path.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-by-path.js
@@ -7,7 +7,7 @@ const request_path = request_headers.query.path;
const romtype = session_data.get("wtv-client-rom-type");
const bootver = session_data.get("wtv-client-bootrom-version");
-if ((romtype == "bf0app" || !romtype) && (bootver == "105" || !bootver)) {
+if ((romtype === "bf0app" || !romtype) && (bootver === "105" || !bootver)) {
// assume old classic in flash mode, override user setting and send tellyscript
// because it is required to proceed in flash mode
bf0app_update = true;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js
index a312ec33..876c10cd 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/get-lc2-page.js
@@ -7,7 +7,7 @@ if (!request_headers.query.path) {
headers = errpage[0];
data = errpage[1];
} else {
- if (request_headers.Referer == service_name + ":/lc2-download-complete?") {
+ if (request_headers.Referer === service_name + ":/lc2-download-complete?") {
headers = `200 OK
Content-type: text/html
minisrv-no-mail-count: true
@@ -34,7 +34,7 @@ async function processLC2DownloadPage(flashrom_info, headers, numparts = null) {
sendToClient(socket, headers, data);
return false;
}
- if (numparts != null) flashrom_info.part_count = parseInt(numparts);
+ if (numparts !== null) flashrom_info.part_count = parseInt(numparts);
if (!flashrom_info.part_count) flashrom_info.part_count = parseInt(flashrom_info.message.slice(flashrom_info.message.length - 4).replace(/\D/g, ''));
if (parseInt(flashrom_info.part_number) >= 0 && flashrom_info.rompath && flashrom_info.next_rompath) {
if (!flashrom_info.message && flashrom_info.is_bootrom) {
@@ -129,7 +129,7 @@ Your ${session_data.getBoxName()} is being updated automatically.
This will take about ${downloadTime} minutes and then you can use your ${session_data.getBoxName()} again.
`;
- if (flashrom_info.is_bootrom && flashrom_info.part_number == (flashrom_info.part_count - 1)) {
+ if (flashrom_info.is_bootrom && flashrom_info.part_number === (flashrom_info.part_count - 1)) {
data += `
The system will pause for about 30 seconds at the end of this
update. Please do not interrupt the system
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js
index 7531c1c0..a800dca9 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/initiate-lc2-download.js
@@ -3,7 +3,7 @@ const minisrv_service_file = true;
if (request_headers.query.path) {
let url = service_name + ":/get-lc2-page?path=" + encodeURIComponent(request_headers.query.path);
const romtype = session_data.get("wtv-client-rom-type");
- if (romtype == "bf0app") {
+ if (romtype === "bf0app") {
url = "client:updateflash?ipaddr=" + minisrv_config.services[service_name].host + "&port=" + minisrv_config.services[service_name].port + "&path=" + encodeURIComponent(service_name + ":/" + request_headers.query.path);
if (request_headers.query.numparts) url += encodeURIComponent("?numparts=" + request_headers.query.numparts);
} else {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/noflash.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/noflash.js
index e3f52f01..7678be71 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/noflash.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-flashrom/noflash.js
@@ -15,7 +15,7 @@ const bf0app_update = true;
if (request_headers.query.path) request_path = request_headers.query.path;
else request_path = default_build_to_send;
-if (session_data.get("wtv-client-rom-type") == "bf0app" && session_data.get("wtv-client-bootrom-version") == "105") {
+if (session_data.get("wtv-client-rom-type") === "bf0app" && session_data.get("wtv-client-bootrom-version") === "105") {
// assume old classic in flash mode, override user setting and send tellyscript
// because it is required to proceed in flash mode
session_data.set("bf0app_update", bf0app_update);
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/ValidateLogin.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/ValidateLogin.js
index 7a45c257..8272c7be 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/ValidateLogin.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/ValidateLogin.js
@@ -5,7 +5,7 @@ let challenge_response, gourl, wtvsec_login;
const hasPendingTransfer = session_data.hasPendingTransfer()
if (hasPendingTransfer) {
- if (hasPendingTransfer.type == "target") {
+ if (hasPendingTransfer.type === "target") {
const xferSession = new WTVClientSessionData(minisrv_config, hasPendingTransfer.ssid);
xferSession.user_id = 0
const primary_username = xferSession.listPrimaryAccountUsers()['subscriber']['subscriber_username'];
@@ -21,7 +21,7 @@ if (hasPendingTransfer) {
const errpage = wtvshared.doRedirect(transferPendingDest);
headers = errpage[0];
data = errpage[1];
- } else if (hasPendingTransfer.type == "source") {
+ } else if (hasPendingTransfer.type === "source") {
const transferPendingSrc = new clientShowAlert({
'image': minisrv_config.config.service_logo,
'message': "There is a pending transfer of this account to " + hasPendingTransfer.ssid + " . In order to use this box, you need to complete or cancel the transfer.",
@@ -58,11 +58,11 @@ wtv-visit: client:hangupphone`
}
let errpage;
if (socket.ssid !== null) {
- if (wtvsec_login.ticket_b64 == null) {
+ if (wtvsec_login.ticket_b64 === null) {
challenge_response = wtvsec_login.challenge_response;
client_challenge_response = request_headers["wtv-challenge-response"] || null;
if (challenge_response && client_challenge_response) {
- if (challenge_response.toString(CryptoJS.enc.Base64) == client_challenge_response) {
+ if (challenge_response.toString(CryptoJS.enc.Base64) === client_challenge_response) {
console.log(" * wtv-challenge-response success for " + wtvshared.filterSSID(socket.ssid));
wtvsec_login.PrepareTicket();
gourl = "wtv-head-waiter:/login-stage-two?";
@@ -84,8 +84,8 @@ wtv-visit: client:hangupphone`
}
}
if (!errpage) {
- if (user_id != null && !request_headers.query.initial_login && !request_headers.query.user_login && !request_headers.query.relogin && !request_headers.query.reconnect) {
- if (request_headers.query.password == "") {
+ if (user_id !== null && !request_headers.query.initial_login && !request_headers.query.user_login && !request_headers.query.relogin && !request_headers.query.reconnect) {
+ if (request_headers.query.password === "") {
headers = `403 Please enter your password and try again
minisrv-no-mail-count: true`;
} else if (session_data.validateUserPassword(request_headers.query.password)) {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/choose-user.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/choose-user.js
index c15c5638..4f254236 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/choose-user.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/choose-user.js
@@ -82,10 +82,10 @@ let accounts_listed = 0;
for (const [key, value] of Object.entries(accounts)) {
let user_id;
data += "
";
- if (key == "subscriber") user_id = 0;
+ if (key === "subscriber") user_id = 0;
else user_id = key.replace("user", '');
data += ``;
- if (key == "subscriber") data += `${value['subscriber_username']} `;
+ if (key === "subscriber") data += `${value['subscriber_username']} `;
else data += `${value['subscriber_username']} `
data += " ";
const userSession = new WTVClientSessionData(minisrv_config, socket.ssid);
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/finalize-security.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/finalize-security.js
index 3b1ed3ee..4a16065f 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/finalize-security.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/finalize-security.js
@@ -7,7 +7,7 @@ if (socket.ssid && session_data) {
socket_sessions[socket.id].wtvsec.ticket_b64 = request_headers["wtv-ticket"];
//socket_sessions[socket.id].secure == true;
}
- } else if (socket_sessions[socket.id].wtvsec.ticket_b64 == null) {
+ } else if (socket_sessions[socket.id].wtvsec.ticket_b64 === null) {
// TODO: client should have a ticket and send it back by now, if not we should handle this correctly
}
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login-stage-two.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login-stage-two.js
index 7a1488c3..60b5e26e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login-stage-two.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login-stage-two.js
@@ -54,7 +54,7 @@ else {
if (session_data.getSessionData("subscriber_smtp_password") === null) {
session_data.setUserSMTPPassword(wtvshared.generatePassword(16));
}
- if (session_data.user_id == 0) {
+ if (session_data.user_id === 0) {
const accounts = session_data.listPrimaryAccountUsers();
let offline_user_list_str = "\n";
let i = 0;
@@ -167,7 +167,7 @@ wtv-inactive-timeout: 1440
headers += "wtv-home-url: " + home_url + "\n";
}
- if (session_data.get('wtv-need-upgrade') != 'true' && !request_headers.query.reconnect && !limitedLogin && !limitedLoginRegistered)
+ if (session_data.get('wtv-need-upgrade') !== 'true' && !request_headers.query.reconnect && !limitedLogin && !limitedLoginRegistered)
headers += "wtv-settings-url: wtv-setup:/get\n";
if (!limitedLogin && !limitedLoginRegistered) {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login.js
index 80fd3a27..034ea042 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-head-waiter/login.js
@@ -14,7 +14,7 @@ let send_to_relogin = true;
if (session_data) {
if (request_headers["wtv-ticket"]) {
- if (session_data.data_store.wtvsec_login.ticket_b64 == null) {
+ if (session_data.data_store.wtvsec_login.ticket_b64 === null) {
if (request_headers["wtv-ticket"].length > 8) {
session_data.data_store.wtvsec_login.DecodeTicket(request_headers["wtv-ticket"]);
session_data.data_store.wtvsec_login.ticket_b64 = request_headers["wtv-ticket"];
@@ -25,7 +25,7 @@ if (session_data) {
if (session_data.data_store.wtvsec_login) {
const client_challenge_response = request_headers["wtv-challenge-response"] || null;
if (challenge_response && client_challenge_response) {
- if (challenge_response.toString(CryptoJS.enc.Base64).slice(0, 85) == client_challenge_response.slice(0, 85)) {
+ if (challenge_response.toString(CryptoJS.enc.Base64).slice(0, 85) === client_challenge_response.slice(0, 85)) {
console.log(" * wtv-challenge-response success for " + socket.ssid);
session_data.data_store.wtvsec_login.PrepareTicket();
send_to_relogin = false;
@@ -50,7 +50,7 @@ Expires: Wed, 09 Oct 1991 22:00:00 GMT
wtv-expire-all: wtv-head-waiter:
`+ getServiceString('wtv-log') + `
wtv-log-url: wtv-log:/log`;
- if (challenge_header != "") headers += "\n" + challenge_header;
+ if (challenge_header !== "") headers += "\n" + challenge_header;
headers += `
wtv-country: US
wtv-language-header: en-US,en
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addressbook.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addressbook.js
index 49fddf88..504f1d35 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addressbook.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addressbook.js
@@ -4,7 +4,7 @@ const action = request_headers.query.action;
let address_book = null
address_book = session_data.getSessionData("address_book")
-if (address_book == null) {
+if (address_book === null) {
session_data.setSessionData("address_book", [])
address_book = [];
}
@@ -625,9 +625,9 @@ text="E7CE4A"
font=proportional
name="nickname"
value="`;
- if (action == 'editfromheader') {
+ if (action === 'editfromheader') {
data += request_headers.query.nickname
- } else if (action == 'edit' && request_headers.query.id) {
+ } else if (action === 'edit' && request_headers.query.id) {
data += address_book[request_headers.query.id].name
}
data += `"
@@ -652,9 +652,9 @@ font=proportional
nosoftbreaks nohardbreaks
name="address"
value="`;
- if (action == 'editfromheader') {
+ if (action === 'editfromheader') {
data += request_headers.query.address
- } else if (action == 'edit' && request_headers.query.id) {
+ } else if (action === 'edit' && request_headers.query.id) {
data += address_book[request_headers.query.id].address
}
data += `"
@@ -784,7 +784,7 @@ Location: wtv-mail:/addressbook`;
break;
case "discard":
- if (address_book.length == 1) {
+ if (address_book.length === 1) {
address_book = []
} else {
address_book.splice(request_headers.query.id, 1)
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addresslist.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addresslist.js
index 6cc336c8..5c44d681 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addresslist.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/addresslist.js
@@ -8,7 +8,7 @@ minisrv-no-mail-count: true`;
const address_book = session_data.getSessionData("address_book")
-if (session_data.getSessionData("address_book") != null) {
+if (session_data.getSessionData("address_book") !== null) {
data = ``
for (let i = 0; i < address_book.length; i++) {
data += address_book[i].name + '\0' + address_book[i].address + '\0'
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/get-attachment.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/get-attachment.js
index ae828dcf..4b0c3d4a 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/get-attachment.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/get-attachment.js
@@ -2,8 +2,8 @@ const minisrv_service_file = true;
let errpage, message;
const messageid = request_headers.query.message_id;
-const attachment_id = request_headers.query.attachment_id;
-if (!attachment_id && attachment_id != 0) errpage = wtvshared.doErrorPage(400, "Attachment ID required.");
+const attachment_id = parseInt(request_headers.query.attachment_id);
+if (!attachment_id && attachment_id !== 0) errpage = wtvshared.doErrorPage(400, "Attachment ID required.");
else {
message = session_data.mailstore.getMessageByID(messageid);
if (!message) errpage = wtvshared.doErrorPage(400, "Invalid Message ID");
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/listmail.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/listmail.js
index 00ce9bf4..c20e6384 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/listmail.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/listmail.js
@@ -58,14 +58,14 @@ if (!intro_seen && !request_headers.query.intro_seen) {
const total_unread_message_count = session_data.mailstore.countUnreadMessages(mailbox);
let message_list_string = null;
- if (total_message_count == 0) {
+ if (total_message_count === 0) {
message_list_string = "No new mail messages for ";
} else {
if (total_unread_message_count > 0) {
- message_list_string = total_unread_message_count + " new mail message" + ((total_message_count != 1) ? 's' : '');
- if (total_message_count - total_unread_message_count > 0) message_list_string += ", " + (total_message_count - total_unread_message_count) + " mail message" + (((total_message_count - total_unread_message_count) != 1) ? 's' : '') + " for ";
- } else {
- message_list_string = total_message_count + " mail message" + ((total_message_count != 1) ? 's' : '') + " for ";
+ message_list_string = total_unread_message_count + " new mail message" + ((total_message_count !== 1) ? 's' : '');
+ if (total_message_count - total_unread_message_count > 0) message_list_string += ", " + (total_message_count - total_unread_message_count) + " mail message" + (((total_message_count - total_unread_message_count) !== 1) ? 's' : '') + " for ";
+ } else {
+ message_list_string = total_message_count + " mail message" + ((total_message_count !== 1) ? 's' : '') + " for ";
}
}
@@ -281,7 +281,7 @@ ${username}@${minisrv_config.config.service_name}
`;
Object.keys(message_list).forEach(function (k) {
const message = message_list[k];
- if (typeof message.subject == "object" && message.subject) message.subject = wtvshared.decodeBufferText(message.subject);
+ if (typeof message.subject === "object" && message.subject) message.subject = wtvshared.decodeBufferText(message.subject);
message.known_sender = session_data.isAddressInAddressBook(message.from_addr);
let message_font_open = "";
let message_font_close = " ";
@@ -319,7 +319,7 @@ ${message_font_close}
});
} else {
data += `
- No ${(mailbox_name == "Inbox") ? `new e-mail messages for
+ No ${(mailbox_name === "Inbox") ? `new e-mail messages for
${username}@${minisrv_config.config.service_name}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js
index 145534dd..f6420671 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/readmail.js
@@ -47,7 +47,7 @@ Content-type: text/html`;
}
if (message.signature) message_colors = session_data.mailstore.getSignatureColors(message.signature);
- if (typeof message.subject == "object" && message.subject) message.subject = wtvshared.decodeBufferText(message.subject);
+ if (typeof message.subject === "object" && message.subject) message.subject = wtvshared.decodeBufferText(message.subject);
data = `
`;
- if (message.from_name != message.from_addr) {
+ if (message.from_name !== message.from_addr) {
data += `${wtvshared.htmlEntitize(message.from_addr)} (${wtvshared.htmlEntitize(message.from_name)}) `;
} else {
data += `${wtvshared.htmlEntitize(message.from_addr)}`;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js
index 750ad814..5622ac90 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/sendmail.js
@@ -7,7 +7,7 @@ const intro_seen = session_data.mailstore.checkMailIntroSeen();
if (!intro_seen && !request_headers.query.intro_seen) {
// user is trying to bypass the intro screen
headers = "300 OK\nLocation: wtv-mail:/DiplomaMail?came-from=" + encodeURIComponent(request_headers.request_url);
-} else if (request_headers.query.clear == "true") {
+} else if (request_headers.query.clear === "true") {
let gourl;
if (request_headers.Referer)
gourl = request_headers.Referer.replace(/[\?\&]clear\=true/, '');
@@ -105,8 +105,8 @@ Location: ${gourl}`;
}
}
- if (request_headers.query.togglesign == "true") no_signature = false;
- if (request_headers.query.togglesign == "false") no_signature = true;
+ if (request_headers.query.togglesign === "true") no_signature = false;
+ if (request_headers.query.togglesign === "false") no_signature = true;
if (mail_draft_attachments) {
if (mail_draft_attachments.message_snapshot_data) message_snapshot_data = mail_draft_attachments.message_snapshot_data;
@@ -136,10 +136,10 @@ Content-Type: audio/wav`;
'noback': true,
}).getURL();
- if ((typeof request_headers.query.sendoff !== 'undefined' && request_headers.query.sendoff != false) || request_headers.query.saveoff || request_headers.query.get_snap || request_headers.query.get_gab) {
+ if ((typeof request_headers.query.sendoff !== 'undefined' && request_headers.query.sendoff !== false) || request_headers.query.saveoff || request_headers.query.get_snap || request_headers.query.get_gab) {
let from_addr = address;
const signature = session_data.getSessionData("subscriber_signature") || null;
- if (typeof request_headers.query.sendoff !== 'undefined' && request_headers.query.sendoff != false) {
+ if (typeof request_headers.query.sendoff !== 'undefined' && request_headers.query.sendoff !== false) {
const attachments = [];
@@ -148,7 +148,7 @@ Content-Type: audio/wav`;
'mime': 'image/jpeg',
'filename': 'snapshot.jpg'
}
- if (typeof message_snapshot_data == "object") {
+ if (typeof message_snapshot_data === "object") {
attachment.content = new Buffer.from(message_snapshot_data).toString('base64');
attachment.is_base64 = true;
} else
@@ -163,7 +163,7 @@ Content-Type: audio/wav`;
'filename': 'voicemail.wav'
}
- if (typeof message_voicemail_data == "object") {
+ if (typeof message_voicemail_data === "object") {
attachment.content = new Buffer.from(message_voicemail_data).toString('base64');
attachment.is_base64 = true;
} else
@@ -196,7 +196,7 @@ Content-Type: audio/wav`;
wtvnews.initializeUsenet(service_config.upstream_address, service_config.upstream_port, service_config.upstream_tls || null);
}
from_addr = userdisplayname + " <" + from_addr + ">";
- if (signature && signature != "" && !no_signature) {
+ if (signature && signature !== "" && !no_signature) {
if (signature.indexOf('') >= 0) {
attachments.push({
"mime": 'text/html',
@@ -299,13 +299,13 @@ wtv-expire-all: wtv-mail:/sendmail`;
headers = `200 OK
Content-type: text/html`;
mail_draft_data = session_data.getSessionData((newsgroup) ? "usenet_draft_attachments" : "mail_draft_attachments") || {};
- if (request_headers.query.snapping == "false") {
+ if (request_headers.query.snapping === "false") {
headers += "\nwtv-expire-all: cache:snapshot.jpg";
if (mail_draft_data.message_snapshot_data) mail_draft_data.message_snapshot_data = null;
session_data.setSessionData((newsgroup) ? "usenet_draft_attachments" : "mail_draft_attachments", mail_draft_data);
}
- if (request_headers.query.gabbing == "false") {
+ if (request_headers.query.gabbing === "false") {
headers += "\nwtv-expire-all: cache:voicemail.wav";
if (mail_draft_data.message_voicemail_data) mail_draft_data.message_voicemail_data = null;
session_data.setSessionData((newsgroup) ? "usenet_draft_attachments" : "mail_draft_attachments", mail_draft_data);
@@ -617,7 +617,7 @@ link=${message_colors.link}
vlink=${message_colors.vlink}
vspace=0
hspace=0>`;
- if (session_data.getSessionData("subscriber_signature") && session_data.getSessionData("subscriber_signature") != "" && !no_signature) {
+ if (session_data.getSessionData("subscriber_signature") && session_data.getSessionData("subscriber_signature") !== "" && !no_signature) {
data += wtvshared.sanitizeSignature(session_data.getSessionData("subscriber_signature"));
}
if (msg_url) {
@@ -642,7 +642,7 @@ Included Page: ${wtvshared.htmlEntitize(msg_url_title).repl
`;
- if (!session_data.getSessionData("subscriber_signature") || session_data.getSessionData("subscriber_signature") == "") {
+ if (!session_data.getSessionData("subscriber_signature") || session_data.getSessionData("subscriber_signature") === "") {
data += ` `;
} else if (no_signature) {
data += `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/verify-address.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/verify-address.js
index 5093f533..2cbc900b 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/verify-address.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-mail/verify-address.js
@@ -15,7 +15,7 @@ const ok = '1';
if (request_headers.query.address) {
const address_split = request_headers.query.address.split("@");
const domain = address_split[1];
- if (domain != "escargot.chat" && domain != "escargot.live") data = fail
+ if (domain !== "escargot.chat" && domain !== "escargot.live") data = fail
else data = ok;
} else {
data = fail;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/get-attachment.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/get-attachment.js
index febabeb2..0fb18b4c 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/get-attachment.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/get-attachment.js
@@ -4,7 +4,7 @@ request_is_async = true;
let errpage = null;
const group = request_headers.query.group;
const attachment_id = parseInt(request_headers.query.attachment_id);
-if ((!attachment_id && attachment_id != 0) || !group || !request_headers.query.article) {
+if ((!attachment_id && attachment_id !== 0) || !group || !request_headers.query.article) {
errpage = wtvshared.doErrorPage(400, "Attachment ID required.");
sendToClient(socket, errpage[0], errpage[1]);
} else {
@@ -32,13 +32,13 @@ if ((!attachment_id && attachment_id != 0) || !group || !request_headers.query.a
wtvnews.selectGroup(group).then((response) => {
wtvnews.getArticle(article).then((response) => {
wtvnews.quitUsenet();
- if (response.code == 220) {
+ if (response.code === 220) {
const message_data = wtvnews.parseAttachments(response);
if (message_data.attachments) {
if (attachment_id < message_data.attachments.length) {
const attachment = message_data.attachments[attachment_id];
const encoding = attachment.content_encoding.toLowerCase()
- if (encoding == 'base64') {
+ if (encoding === 'base64') {
data = Buffer.from(attachment.data, encoding);
headers = "200 OK\n"
headers += "Content-Type: " + attachment.content_type + "\n";
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/lobby.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/lobby.js
index 5ffabb27..c2e779d3 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/lobby.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/lobby.js
@@ -117,12 +117,12 @@ function printGroup(group) {
}
// evens
-Object.keys(featuredGroups).forEach((k) => { if (k % 2 == 0) { data += printGroup(featuredGroups[k]); } });
+Object.keys(featuredGroups).forEach((k) => { if (k % 2 === 0) { data += printGroup(featuredGroups[k]); } });
if (featuredGroups.length > 1) data += ` `;
// odds
-Object.keys(featuredGroups).forEach((k) => { if (k % 2 != 0) data += printGroup(featuredGroups[k]); });
+Object.keys(featuredGroups).forEach((k) => { if (k % 2 !== 0) data += printGroup(featuredGroups[k]); });
data += `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js
index 72cedf36..d6a70dc3 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-news/news.js
@@ -28,9 +28,9 @@ async function throwError(e) {
function isToday (chkdate) {
const today = new Date()
- return chkdate.getDate() == today.getDate() &&
- chkdate.getMonth() == today.getMonth() &&
- chkdate.getFullYear() == today.getFullYear()
+ return chkdate.getDate() === today.getDate() &&
+ chkdate.getMonth() === today.getMonth() &&
+ chkdate.getFullYear() === today.getFullYear()
}
async function WebTVListGroup(group) {
@@ -47,7 +47,7 @@ async function WebTVListGroup(group) {
limit_per_page = (page_end - (limit_per_page / (page + 1))) + limit_per_page;
}
wtvnews.listGroup(group, page, limit_per_page).then((response) => {
- if (response.code == 211) {
+ if (response.code === 211) {
const NGCount = response.group.number;
const NGArticles = response.group.articleNumbers;
page_start = (limit_per_page * page) + 1;
@@ -193,11 +193,11 @@ Group: ${request_headers.query.group}
`
- if (NGCount == 0) {
+ if (NGCount === 0) {
data += `This group has no postings`;
} else {
data += NGCount + " posting";
- if (NGCount != 1)
+ if (NGCount !== 1)
data += "s"
}
data += `
@@ -210,7 +210,7 @@ Group: ${request_headers.query.group}
-${(page > 0) ? ` ` : ` `}
+${(page > 0) ? ` ` : ` `}
@@ -218,7 +218,7 @@ ${(page > 0) ? `
-${(page_end < NGCount) ? ` ` : ` `}
+${(page_end < NGCount) ? ` ` : ` `}
@@ -337,7 +337,7 @@ wtv-expire-all: wtv-news:/news?group=${group}&article=`;
if (attachments) {
if (Object.keys(attachments).length > 0) {
Object.keys(attachments).forEach((k) => {
- if (attachments[k].filename == "wtv_signature.html" && attachments[k].content_type.match(/text\/html/)) {
+ if (attachments[k].filename === "wtv_signature.html" && attachments[k].content_type.match(/text\/html/)) {
signature = attachments[k].data;
signature_index = k;
return false;
@@ -350,7 +350,7 @@ wtv-expire-all: wtv-news:/news?group=${group}&article=`;
if (message_body.indexOf("
From:
`;
- if (message.from_name != message.from_addr) {
+ if (message.from_name !== message.from_addr) {
data += `${wtvshared.htmlEntitize(message.from_addr)} `;
} else {
data += `${wtvshared.htmlEntitize(response.article.headers.FROM)}`;
@@ -630,7 +630,7 @@ From:
if (attachments) {
if (attachments[0]) {
- if (attachments[0].filename == "message.html") {
+ if (attachments[0].filename === "message.html") {
body_data += wtvshared.sanitizeSignature(attachments[0].data);
delete attachments[0];
}
@@ -789,14 +789,14 @@ vspace=0>
-${(response.length == 0) ? "No " : ""}Discussion groups found
+${(response.length === 0) ? "No " : ""}Discussion groups found
`;
- if (response.length == 0) {
+ if (response.length === 0) {
data += `There are no discussion groups that match your request. Do you want to look for something else?`;
} else {
response.forEach((group) => {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js
index 9a91af0f..e9d9e374 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-passport/messengerlogin.js
@@ -14,7 +14,7 @@ if (messenger_email && messenger_password) {
const password = session_data.decryptPassword(messenger_password);
const challenge = request_headers.request.split('?')[1];
- if (request_headers.request.split('?')[1].slice(0, 3) != "ct=") {
+ if (request_headers.request.split('?')[1].slice(0, 3) !== "ct=") {
console.log(" *** Logging into Messenger via MSNP3")
data = crypto.createHash('md5').update(request_headers.request.split('?')[1] + password).digest("hex");
} else {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAccountInfo.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAccountInfo.js
index cf19a784..b2373f1d 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAccountInfo.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAccountInfo.js
@@ -16,7 +16,7 @@ if (!request_headers.query.registering) {
else if (!wtvr.checkUsernameSanity(request_headers.query.subscriber_username)) errpage = wtvshared.doErrorPage(400, "The username you have chosen contains invalid characters. Please choose a username with only letters , numbers , _ or - . Also, please be sure your username begins with a letter.");
else if (!wtvr.checkUsernameAvailable(request_headers.query.subscriber_username)) errpage = wtvshared.doErrorPage(400, "The username you have selected is not available. Please select another username.");
else if (!request_headers.query.subscriber_contact) errpage = wtvshared.doErrorPage(400, "Please enter your contact information.");
- else if (request_headers.query.subscriber_contact_method == "") errpage = wtvshared.doErrorPage(400, "Please select the type of contact information you provided.");
+ else if (request_headers.query.subscriber_contact_method === "") errpage = wtvshared.doErrorPage(400, "Please select the type of contact information you provided.");
if (errpage) {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAgreement.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAgreement.js
index d7bd7a02..ee79f810 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAgreement.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-register/ValidateAgreement.js
@@ -40,11 +40,11 @@ AutoCaps selected value="${request_headers.query.subscriber_contact || ""}">
CONTACT INFO TYPE:
Type
-E-Mail
-Discord
-Twitter
-Telegram
-Instagram
+E-Mail
+Discord
+Twitter
+Telegram
+Instagram
`;
const form_data = `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/accounts.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/accounts.js
index e9bd3933..93271091 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/accounts.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/accounts.js
@@ -1,7 +1,7 @@
const minisrv_service_file = true;
session_data.loadSessionData();
-if (session_data.user_id != 0) {
+if (session_data.user_id !== 0) {
const errpage = wtvshared.doErrorPage(400, "You are not authorized to edit the primary account.");
headers = errpage[0];
data = errpage[1];
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-name.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-name.js
index fdc86424..ebf1aa65 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-name.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-name.js
@@ -2,7 +2,7 @@ const minisrv_service_file = true;
let errpage;
-if (session_data.user_id != 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
+if (session_data.user_id !== 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
else if (session_data.getNumberOfUserAccounts() > minisrv_config.config.user_accounts.max_users_per_account) errpage = wtvshared.doErrorPage(400, "You are not authorized to add more than " + minisrv_config.config.user_accounts.max_users_per_account + ` account${minisrv_config.config.user_accounts.max_users_per_account > 1 ? 's' : ''}.`);
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-password.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-password.js
index a490f14a..7ca03d65 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-password.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user-password.js
@@ -3,7 +3,7 @@ let errpage = null;
const wtvr = new WTVRegister(minisrv_config, SessionStore);
-if (session_data.user_id != 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
+if (session_data.user_id !== 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
else if (!request_headers.query.user_name) errpage = wtvshared.doErrorPage(400, "Please enter a username.");
else if (request_headers.query.user_name.length < minisrv_config.config.user_accounts.min_username_length) errpage = wtvshared.doErrorPage(400, "Please choose a username with " + minisrv_config.config.user_accounts.min_username_length + " or more characters.");
else if (request_headers.query.user_name.length > minisrv_config.config.user_accounts.max_username_length) errpage = wtvshared.doErrorPage(400, "Please choose a username with " + minisrv_config.config.user_accounts.max_username_length + " or less characters.");
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user.js
index 956fc8b1..62ca9ffa 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/add-user.js
@@ -4,7 +4,7 @@ let errpage;
if (Object.keys(session_data.listPrimaryAccountUsers()).length >= minisrv_config.config.user_accounts.max_users_per_account) {
errpage = wtvshared.doErrorPage(400, "You are not authorized to add more than " + minisrv_config.config.user_accounts.max_users_per_account + ` account${minisrv_config.config.user_accounts.max_users_per_account > 1 ? 's' : ''}.`);
}
-else if (session_data.user_id != 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
+else if (session_data.user_id !== 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
if (errpage) {
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/choose-bg-songs.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/choose-bg-songs.js
index b5e64dc6..1a7b1d1f 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/choose-bg-songs.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/choose-bg-songs.js
@@ -88,7 +88,7 @@ Object.keys(categories).forEach(function (k) {
const catID = categories[k].id;
const songsInCat = wtvbgm.getCategorySongList(catID);
if (songsInCat.length > 0) {
- if (catsListed == divide) {
+ if (catsListed === divide) {
data += `
`;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-password.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-password.js
index 2b9c44a9..d13acd23 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-password.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-password.js
@@ -3,18 +3,18 @@ let userSession = null;
session_data.loadSessionData();
-let user_id = (request_headers.query.user_id) ? request_headers.query.user_id : session_data.user_id;
+let user_id = (request_headers.query.user_id) ? parseInt(request_headers.query.user_id) : session_data.user_id;
// security
-if (session_data.user_id != 0 && session_data.user_id != user_id) {
+if (session_data.user_id !== 0 && session_data.user_id !== parseInt(request_headers.query.user_id)) {
user_id = null; // force unset
const errpage = wtvshared.doErrorPage(400, "You are not authorized to change the selected user's password.");
headers = errpage[0];
data = errpage[1];
}
-if (user_id != null) {
- if (session_data.user_id == request_headers.query.user_id) userSession = session_data;
+if (user_id !== null) {
+ if (session_data.user_id === user_id) userSession = session_data;
else {
userSession = new WTVClientSessionData(minisrv_config, socket.ssid);
userSession.user_id = user_id;
@@ -34,7 +34,7 @@ Content-Type: text/html`;
-Change ${(user_id == session_data.user_id) ? 'your' : 'user'} password
+Change ${(user_id === session_data.user_id) ? 'your' : 'user'} password
@@ -73,7 +73,7 @@ Change ${(user_id == session_data.user_id) ? 'your' : 'user'} password
-Change ${(user_id == session_data.user_id) ? 'your' : 'user'} password
+Change ${(user_id === session_data.user_id) ? 'your' : 'user'} password
@@ -161,5 +161,4 @@ value=Done name="Done" usestyle width=103>
`;
}
-}
-if (userSession) userSession = null;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-begin.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-begin.js
index 42884b35..98fddd99 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-begin.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-begin.js
@@ -3,27 +3,27 @@ session_data.loadSessionData();
let userSession, user_id;
if (request_headers.query.user_id) {
- user_id = request_headers.query.user_id;
+ user_id = parseInt(request_headers.query.user_id);
} else {
user_id = session_data.user_id;
}
// security
-if (session_data.user_id != 0 && session_data.user_id != request_headers.query.user_id) {
+if (session_data.user_id !== 0 && session_data.user_id !== parseInt(request_headers.query.user_id)) {
user_id = null; // force unset
const errpage = wtvshared.doErrorPage(400, "You are not authorized to edit the selected user.");
headers = errpage[0];
data = errpage[1];
}
-if (user_id != null) {
+if (user_id !== null) {
headers = `200 OK
Connection: Keep-Alive
Content-Type: text/html
wtv-expire-all: wtv-setup:/edit-user
wtv-noback-all: wtv-setup:/edit-user`
- if (session_data.user_id == request_headers.query.user_id) userSession = session_data;
+ if (session_data.user_id === user_id) userSession = session_data;
else {
userSession = new WTVClientSessionData(minisrv_config, socket.ssid);
userSession.user_id = user_id;
@@ -39,7 +39,7 @@ wtv-noback-all: wtv-setup:/edit-user`
-Changing ${(user_id == 0) ? 'subscriber' : 'user'} information
+Changing ${(user_id === 0) ? 'subscriber' : 'user'} information
@@ -79,7 +79,7 @@ noscroll>
-${(user_id == 0) ? 'Subscriber' : 'User'} information
+${(user_id === 0) ? 'Subscriber' : 'User'} information
@@ -161,5 +161,4 @@ value=Done name="Done" usestyle width=103>
`;
}
-}
-if (userSession) userSession = null;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-name.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-name.js
index 52ab18bd..ae55762e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-name.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/edit-user-name.js
@@ -2,18 +2,18 @@ const minisrv_service_file = true;
let userSession = null;
session_data.loadSessionData();
-let user_id = (request_headers.query.user_id) ? request_headers.query.user_id : session_data.user_id;
+let user_id = (request_headers.query.user_id) ? parseInt(request_headers.query.user_id) : session_data.user_id;
// security
-if (session_data.user_id != 0 && session_data.user_id != request_headers.query.user_id) {
+if (session_data.user_id !== 0 && session_data.user_id !== parseInt(request_headers.query.user_id)) {
user_id = null; // force unset
const errpage = wtvshared.doErrorPage(400, "You are not authorized to change the selected user's password.");
headers = errpage[0];
data = errpage[1];
}
-if (user_id != null) {
- if (session_data.user_id == request_headers.query.user_id) userSession = session_data;
+if (user_id !== null) {
+ if (session_data.user_id === request_headers.query.user_id) userSession = session_data;
else {
userSession = new WTVClientSessionData(minisrv_config, socket.ssid);
userSession.user_id = user_id;
@@ -146,5 +146,4 @@ value=Done name="Done" usestyle width=103>
`;
}
-}
-if (userSession) userSession = null;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/keyboard.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/keyboard.js
index 14873152..8308ef8c 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/keyboard.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/keyboard.js
@@ -96,7 +96,7 @@ appear on your screen.
`;
-if (settings_obj['setup-keyboard'] == "standard") {
+if (settings_obj['setup-keyboard'] === "standard") {
data += ' ';
} else {
data += ' ';
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/mail-signature.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/mail-signature.js
index 9d5c1a95..8fd234e2 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/mail-signature.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/mail-signature.js
@@ -12,7 +12,7 @@ Content-Type: text/html`
let signature = session_data.getSessionData("subscriber_signature");
if (request_headers.query.mail_signature) {
- if (signature != request_headers.query.mail_signature) {
+ if (signature !== request_headers.query.mail_signature) {
session_data.setSessionData("subscriber_signature", (request_headers.query.mail_signature) ? request_headers.query.mail_signature : "");
session_data.saveSessionData();
signature = request_headers.query.mail_signature;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger-enable.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger-enable.js
index b79a9147..5e7373c3 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger-enable.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger-enable.js
@@ -1,7 +1,7 @@
const minisrv_service_file = true;
let justenabled, enablestatus;
-if (!session_data.getSessionData("messenger_enabled") == 1) {
+if (!session_data.getSessionData("messenger_enabled") === 1) {
session_data.setSessionData("messenger_enabled", 1);
session_data.saveSessionData;
justenabled = "true";
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger.js
index e83953a8..34aac313 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/messenger.js
@@ -47,7 +47,7 @@ function ShowMessengerPanel()
@@ -69,7 +69,7 @@ Messenger
Messenger is currently `;
-if (session_data.getSessionData("messenger_enabled") == 1) {
+if (session_data.getSessionData("messenger_enabled") === 1) {
data += "on"
} else {
data += "off"
@@ -81,7 +81,7 @@ if (session_data.getSessionData("messenger_enabled") == 1) {
Turn messenger `;
-if (!session_data.getSessionData("messenger_enabled") == 1) {
+if (!session_data.getSessionData("messenger_enabled") === 1) {
data += "on"
} else {
data += "off"
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/remove-users.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/remove-users.js
index 3ef3fe6e..e3a56b18 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/remove-users.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/remove-users.js
@@ -1,10 +1,10 @@
const minisrv_service_file = true;
let errpage;
-if (Object.keys(session_data.listPrimaryAccountUsers()).length == 1) {
+if (Object.keys(session_data.listPrimaryAccountUsers()).length === 1) {
errpage = wtvshared.doErrorPage(400, "There are no more users to remove.");
}
-else if (session_data.user_id != 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
+else if (session_data.user_id !== 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
if (errpage) {
headers = errpage[0];
data = errpage[1];
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/screen.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/screen.js
index c9f3896f..890617df 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/screen.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/screen.js
@@ -71,22 +71,23 @@ Television
-Center
-Center WebTV on your screen `;
+Picture
+Adjust brightness, contrast, and sharpness
+`;
// old classic apparently can do Screen Border
-if (session_data.get("wtv-client-rom-type") == "bf0app") {
+if (session_data.get("wtv-client-rom-type") === "bf0app") {
data += `
Border
-Change the color of the screen border `;
-}
+Change the color of the screen border
-data += `
-Picture
-Adjust brightness, contrast, and sharpness
+Center
+Center WebTV on your screen `;
+}
+data += `
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js
index c1f19950..3d869494 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/set-bg.js
@@ -96,7 +96,7 @@ Choose the songs that you'd like to include.
let songsListed = 0;
const divide = Math.round(musicList.length / 2, 0);
Object.keys(musicList).forEach(function (k) {
- if (songsListed == divide) {
+ if (songsListed === divide) {
data += `
`;
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/setup.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/setup.js
index e7255c31..3b0bcb6e 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/setup.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/setup.js
@@ -105,11 +105,11 @@ for (let i = 0; i < settings.length; i += 2) {
data += `
-${(settings[i][0] != "") ? ` ${settings[i][1]} ` : ` `}
+ ${(settings[i][0] !== "") ? ` ${settings[i][1]} ` : ` `}
`
if (i + 1 < settings.length) {
- data += (settings[i + 1][0] != "") ? ` ${settings[i + 1][1]} ` : ` `
+ data += (settings[i + 1][0] !== "") ? ` ${settings[i + 1][1]} ` : ` `
} else {
// require even number of settings
data += " "
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/transfer-account.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/transfer-account.js
index b1f8b7d4..98f1e158 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/transfer-account.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/transfer-account.js
@@ -1,7 +1,7 @@
const minisrv_service_file = true;
// security
-if (session_data.user_id != 0 && session_data.user_id != request_headers.query.user_id) {
+if (session_data.user_id !== 0 && session_data.user_id !== parseInt(request_headers.query.user_id)) {
const errpage = wtvshared.doErrorPage(400, "You are not authorized to transfer this account. Please log in as the primary user.");
headers = errpage[0];
data = errpage[1];
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user-done.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user-done.js
index eb6bcda4..730e01c0 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user-done.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user-done.js
@@ -2,7 +2,7 @@ const minisrv_service_file = true;
let userSession = null;
let errpage = null;
-if (session_data.user_id != 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
+if (session_data.user_id !== 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
// seperate if statements as to not overwrite the first error if multiple occur
@@ -71,6 +71,4 @@ wtv-expire: wtv-setup:/accounts
Location: wtv-setup:/accounts`;
}
}
-}
-
-if (userSession) userSession = null;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user.js
index f2ae465a..46f88213 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-add-user.js
@@ -1,7 +1,7 @@
const minisrv_service_file = true;
let errpage = null;
-if (session_data.user_id != 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
+if (session_data.user_id !== 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to add users to this account.");
// seperate if statements as to not overwrite the first error if multiple occur
@@ -129,7 +129,7 @@ display_name=${request_headers.query.display_name}&
user_name=${request_headers.query.user_name}&
user_password=${request_headers.query.user_password}&
user_password2=${request_headers.query.user_password2}">`;
- if ((request_headers.query.user_password) == "") {
+ if ((request_headers.query.user_password) === "") {
data += `No password`;
} else {
data += `Has password`;
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-bg-song-category.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-bg-song-category.js
index 029af94e..c8c8ca22 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-bg-song-category.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-bg-song-category.js
@@ -8,13 +8,13 @@ if (request_headers.query && session_data) {
if (request_headers.request_url.indexOf('?') >= 0) {
const category = (request_headers.query.category) ? request_headers.query.category : null;
- if (category == null) music_obj.enableCategories = [];
+ if (category === null) music_obj.enableCategories = [];
else {
const cat = wtvbgm.categories[parseInt(category) - 1];
if (cat) {
const toRemove = [];
Object.keys(music_obj.enableSongs).forEach(function (k) {
- if (wtvbgm.getSongCategory(parseInt(music_obj.enableSongs[k])) == parseInt(category)) toRemove.push(k);
+ if (wtvbgm.getSongCategory(parseInt(music_obj.enableSongs[k])) === parseInt(category)) toRemove.push(k);
});
toRemove.forEach(function (v) {
music_obj.enableSongs.splice(v, 1, "");
@@ -28,10 +28,10 @@ if (request_headers.query && session_data) {
const qraw = _qraw.split("&");
for (let i = 0; i < qraw.length; i++) {
const qraw_split = qraw[i].split("=");
- if (qraw_split.length == 2) {
+ if (qraw_split.length === 2) {
const k = qraw_split[0];
- if (k == "enableCategory") music_obj['enableCategories'].push(decodeURIComponent(qraw[i].split("=")[1].replace(/\+/g, "%20")));
- if (k == "enableSong") music_obj['enableSongs'].push(decodeURIComponent(qraw[i].split("=")[1].replace(/\+/g, "%20")));
+ if (k === "enableCategory") music_obj['enableCategories'].push(decodeURIComponent(qraw[i].split("=")[1].replace(/\+/g, "%20")));
+ if (k === "enableSong") music_obj['enableSongs'].push(decodeURIComponent(qraw[i].split("=")[1].replace(/\+/g, "%20")));
}
}
}
@@ -39,7 +39,7 @@ if (request_headers.query && session_data) {
music_obj.enableCategories = [...new Set(music_obj.enableCategories.filter(value => Object.keys(value).length !== 0))];
music_obj.enableSongs = [...new Set(music_obj.enableSongs.filter(value => Object.keys(value).length !== 0))];
music_obj = Object.assign({}, music_obj)
- if ((Object.keys(music_obj.enableCategories).length != Object.keys(old_music_obj.enableCategories).length) || (Object.keys(music_obj.enableSongs).length != Object.keys(old_music_obj.enableSongs).length)) {
+ if ((Object.keys(music_obj.enableCategories).length !== Object.keys(old_music_obj.enableCategories).length) || (Object.keys(music_obj.enableSongs).length !== Object.keys(old_music_obj.enableSongs).length)) {
// something changed
session_data.setSessionData("wtv-bgmusic", music_obj);
session_data.saveSessionData();
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-name.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-name.js
index 9a8fe410..23356edc 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-name.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-name.js
@@ -2,19 +2,19 @@ const minisrv_service_file = true;
let userSession;
session_data.loadSessionData();
-let user_id = (request_headers.query.user_id) ? request_headers.query.user_id : session_data.user_id;
+let user_id = (request_headers.query.user_id) ? parseInt(request_headers.query.user_id) : session_data.user_id;
// security
-if (session_data.user_id != 0 && session_data.user_id != request_headers.query.user_id) {
+if (session_data.user_id !== 0 && session_data.user_id !== parseInt(request_headers.query.user_id)) {
user_id = null; // force unset
const errpage = wtvshared.doErrorPage(400, "You are not authorized to change the selected user's password.");
headers = errpage[0];
data = errpage[1];
}
-if (user_id != null) {
+if (user_id !== null) {
- if (session_data.user_id == request_headers.query.user_id) userSession = session_data;
+ if (session_data.user_id === parseInt(request_headers.query.user_id)) userSession = session_data;
else {
userSession = new WTVClientSessionData(minisrv_config, socket.ssid);
userSession.user_id = user_id;
@@ -35,5 +35,4 @@ wtv-expire: wtv-setup:/edit-user-begin?user_id=${user_id}
wtv-expire: wtv-setup:/edit-user-name?user_id=${user_id}
Location: wtv-setup:/edit-user-begin?user_id=${user_id}`;
}
-}
-if (userSession) userSession = null;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-password.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-password.js
index 491383f0..4c5712fc 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-password.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-change-password.js
@@ -5,14 +5,14 @@ session_data.loadSessionData();
let user_id = null;
if (request_headers.query.user_id) {
- user_id = request_headers.query.user_id;
+ user_id = parseInt(request_headers.query.user_id);
} else {
errpage = wtvshared.doErrorPage(400, "User was not specified.");
headers = errpage[0];
data = errpage[1];
}
-if (session_data.user_id != 0 && session_data.user_id != request_headers.query.user_id) {
+if (session_data.user_id !== 0 && session_data.user_id !== parseInt(request_headers.query.user_id)) {
user_id = null; // force unset
errpage = wtvshared.doErrorPage(400, "You are not authorized to edit the selected user.");
headers = errpage[0];
@@ -24,10 +24,10 @@ if (user_id && !errpage) {
Connection: Keep-Alive
Content-Type: text/html`
userSession = null;
- if (session_data.user_id == request_headers.query.user_id) userSession = session_data;
+ if (session_data.user_id === parseInt(request_headers.query.user_id)) userSession = session_data;
else {
userSession = new WTVClientSessionData(minisrv_config, socket.ssid);
- userSession.user_id = user_id;``
+ userSession.user_id = user_id;
}
if (!userSession.loadSessionData()) {
@@ -36,7 +36,7 @@ Content-Type: text/html`
data = errpage[1];
}
else {
- if (request_headers.query.password.length == 0 && request_headers.query.password_verify.length == 0) {
+ if (request_headers.query.password.length === 0 && request_headers.query.password_verify.length === 0) {
userSession.disableUserPassword();
headers = `300 OK
Content-type: text/html
@@ -76,5 +76,3 @@ if (errpage) {
headers = errpage[0];
data = errpage[1];
}
-
-if (userSession) userSession = null;
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-mail-signature.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-mail-signature.js
index 1559d5fc..f73c300a 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-mail-signature.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-mail-signature.js
@@ -2,7 +2,7 @@ const minisrv_service_file = true;
if (request_headers.query && session_data) {
const signature = session_data.getSessionData("subscriber_signature");
- if (request_headers.query.mail_signature != signature) {
+ if (request_headers.query.mail_signature !== signature) {
session_data.setSessionData("subscriber_signature", (request_headers.query.mail_signature) ? request_headers.query.mail_signature : "");
session_data.saveSessionData();
}
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-remove-users.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-remove-users.js
index 3e505c9a..e415bfef 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-remove-users.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-remove-users.js
@@ -1,10 +1,10 @@
const minisrv_service_file = true;
let errpage;
-if (Object.keys(session_data.listPrimaryAccountUsers()).length == 1) {
+if (Object.keys(session_data.listPrimaryAccountUsers()).length === 1) {
errpage = wtvshared.doErrorPage(400, "There are no more users to remove.");
}
-else if (session_data.user_id != 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to remove users from this account.");
+else if (session_data.user_id !== 0) errpage = wtvshared.doErrorPage(400, "You are not authorized to remove users from this account.");
const usersToRemove = [];
Object.keys(request_headers.query).forEach(function (k) {
@@ -21,7 +21,7 @@ if (errpage) {
} else {
if (!request_headers.query.confirm_remove) {
let message = '';
- if (usersToRemove.length == 1) {
+ if (usersToRemove.length === 1) {
const userSession = new WTVClientSessionData(minisrv_config, socket.ssid);
userSession.switchUserID(usersToRemove[0]);
const userName = userSession.getSessionData("subscriber_username");
@@ -61,7 +61,7 @@ Location: ${confirmAlert}`
})
const num_accounts = session_data.getNumberOfUserAccounts();
let gourl = "wtv-setup:/remove-users?";
- if (num_accounts == 1) gourl = "wtv-setup:/accounts?";
+ if (num_accounts === 1) gourl = "wtv-setup:/accounts?";
headers = `300 OK
Connection: Keep-Alive
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-transfer-account.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-transfer-account.js
index 70c5feb0..cd83de9a 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-transfer-account.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-setup/validate-transfer-account.js
@@ -3,7 +3,7 @@ const minisrv_service_file = true;
const wtvr = new WTVRegister(minisrv_config);
// security
-if (session_data.user_id != 0 && session_data.user_id != request_headers.query.user_id) {
+if (session_data.user_id !== 0 && session_data.user_id !== parseInt(request_headers.query.user_id)) {
const errpage = wtvshared.doErrorPage(400, "You are not authorized to transfer this account. Please log in as the primary user.");
headers = errpage[0];
data = errpage[1];
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/info.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/info.js
index 2daaff9f..ca49dfd7 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/info.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/info.js
@@ -2,7 +2,7 @@ const minisrv_service_file = true;
let client_caps = null;
-if (socket.ssid != null) {
+if (socket.ssid !== null) {
if (session_data.capabilities) {
client_caps = session_data.capabilities.get();
}
@@ -90,37 +90,37 @@ switch (chipVersionStr >> 0x18) {
// determine box video type
let video;
-if ((sysConfigHex & 8) == 0) video = "NTSC";
+if ((sysConfigHex & 8) === 0) video = "NTSC";
else video = "PAL";
// determine box storage type
let storage;
-if ((sysConfigHex & 4) == 0) storage = "disk";
+if ((sysConfigHex & 4) === 0) storage = "disk";
else storage = "flash";
// determine box CPU endianness
let endianness;
-if ((sysConfigHex & 0x80000) == 0) endianness = "little";
+if ((sysConfigHex & 0x80000) === 0) endianness = "little";
else endianness = "big";
// determine box CPU type
let cpu;
-if ((sysConfigHex & 0x100000) == 0) cpu = 5230;
+if ((sysConfigHex & 0x100000) === 0) cpu = 5230;
else cpu = 4640;
// determine box CPU clock multiplier
let cpuMult;
-if ((sysConfigHex & 0x20000) == 0) cpuMult = 3;
+if ((sysConfigHex & 0x20000) === 0) cpuMult = 3;
else cpuMult = 2;
// determine smartcard 0 support
let sc0;
-if ((sysConfigHex & 0x400000) == 0) sc0 = "supported";
+if ((sysConfigHex & 0x400000) === 0) sc0 = "supported";
else sc0 = "not supported";
//determine smartcard 1 support
let sc1;
-if ((sysConfigHex & 0x200000) == 0) sc1 = "supported";
+if ((sysConfigHex & 0x200000) === 0) sc1 = "supported";
else sc1 = "not supported";
// ========================= FCS SYSCONFIG DECODE START =========================
@@ -130,47 +130,47 @@ else sc1 = "not supported";
// determine box CPU output bufs
let outputBufs;
-if ((sysConfigHex & 0x2000) == 0) outputBufs = 100;
+if ((sysConfigHex & 0x2000) === 0) outputBufs = 100;
else outputBufs = 50;
// determine box SGRAM speed
function getSGSpeed() {
const SGRAMand = sysConfigHex & 0xc00000;
- if (SGRAMand == 0x400000) return 66;
+ if (SGRAMand === 0x400000) return 66;
else if (0x400000 < SGRAMand)
- if (SGRAMand == 0x800000) return 77;
- else if (SGRAMand == 0xc00000) return 83; // potentially incorrect but looks like it should return 83MHz on known existing hardware
- else if (SGRAMand == 0) return 100;
+ if (SGRAMand === 0x800000) return 77;
+ else if (SGRAMand === 0xc00000) return 83; // potentially incorrect but looks like it should return 83MHz on known existing hardware
+ else if (SGRAMand === 0) return 100;
}
// determine box audio chip type
let audio;
-if ((sysConfigHex & 0xc0000) == 0xc0000) audio = "AKM4310/4309";
+if ((sysConfigHex & 0xc0000) === 0xc0000) audio = "AKM4310/4309";
else audio = "Unknown";
// determine box audio clock source
let audioClk;
-if ((sysConfigHex & 0x20000) == 0) audioClk = "SPOT";
+if ((sysConfigHex & 0x20000) === 0) audioClk = "SPOT";
else audioClk = "External";
// determine box video chip
function getVideoChip() {
const videoChipAnd = sysConfigHex & 0x600;
- if (videoChipAnd == 0x200) return "Bt851";
+ if (videoChipAnd === 0x200) return "Bt851";
else if (videoChipAnd < 0x201 && videoChipAnd !== 0) return "Unknown";
- else if (videoChipAnd == 0x400) return "Bt852";
+ else if (videoChipAnd === 0x400) return "Bt852";
else return "Philips7187/Bt866";
}
// determine box video type
let videoB;
-if ((sysConfigHex & 0x800) == 0) videoB = "PAL";
+if ((sysConfigHex & 0x800) === 0) videoB = "PAL";
else videoB = "NTSC";
// determine box video clock source
let videoClk;
-if ((sysConfigHex & 0x10000) == 0) videoClk = "External";
+if ((sysConfigHex & 0x10000) === 0) videoClk = "External";
else videoClk = "SPOT";
// determine box board type
@@ -193,17 +193,17 @@ else bank0Type = "Flash";
// determine bank 0 mode
let bank0Mode;
-if ((sysConfigHex & 0x40000000) == 0) bank0Mode = "Normal";
+if ((sysConfigHex & 0x40000000) === 0) bank0Mode = "Normal";
else bank0Mode = "PageMode";
// determine bank 1 type
let bank1Type;
-if ((sysConfigHex & 0x8000000) == 0) bank1Type = "Flash";
+if ((sysConfigHex & 0x8000000) === 0) bank1Type = "Flash";
else bank1Type = "Mask";
// determine bank 1 mode
let bank1Mode;
-if ((sysConfigHex & 0x40000000) == 0) bank1Mode = "Normal";
+if ((sysConfigHex & 0x40000000) === 0) bank1Mode = "Normal";
else bank1Mode = "PageMode";
data = `
@@ -326,7 +326,7 @@ data = `
`
// TODO: finish FCS decode
- if (romType == "bf0app" && sysConfigHex !== "0xNaN") {
+ if (romType === "bf0app" && sysConfigHex !== "0xNaN") {
data += `CPU Clk Mult = 2x Bus Clk, CPU output bufs @ ${outputBufs}%
ROM Bank 0: ${bank0Type}, ${bank0Mode}, 120ns/60ns
ROM Bank 1: ${bank1Type}, ${bank1Mode}, 150ns/75ns
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/tricks.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/tricks.js
index 1756c7cc..21b86ec2 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/tricks.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-tricks/tricks.js
@@ -46,11 +46,11 @@ for (let i = 0; i < tricks.length; i += 2) {
data += `
-${(tricks[i][0] != "") ? ` ${tricks[i][1]} ` : ` `}
+ ${(tricks[i][0] !== "") ? ` ${tricks[i][1]} ` : ` `}
`
if (i + 1 < tricks.length) {
- data += (tricks[i + 1][0] != "") ? ` ${tricks[i + 1][1]} ` : ` `
+ data += (tricks[i + 1][0] !== "") ? ` ${tricks[i + 1][1]} ` : ` `
} else {
// require even number of tricks
data += " "
diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtvchat/catchall.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtvchat/catchall.js
index 6201aac8..e497d2de 100644
--- a/zefie_wtvp_minisrv/includes/ServiceVault/wtvchat/catchall.js
+++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtvchat/catchall.js
@@ -5,7 +5,7 @@ delete urldata[0];
urldata = urldata.join(":").slice(1);
console.log(urldata);
-while (urldata.slice(0, 1) == "/") urldata = urldata.slice(1);
+while (urldata.slice(0, 1) === "/") urldata = urldata.slice(1);
let server = urldata.split('/')[0];
let port = 6667;
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVAdmin.js b/zefie_wtvp_minisrv/includes/classes/WTVAdmin.js
index 3369ec17..65f50ca4 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVAdmin.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVAdmin.js
@@ -51,7 +51,7 @@ class WTVAdmin {
* @returns {number} The result of the ban operation
*/
banSSID(ssid, admin_ssid = null) {
- if (ssid == admin_ssid) {
+ if (ssid === admin_ssid) {
return this.REASON_NOSELF;
} else {
const fake_config = this.wtvshared.getUserConfig();
@@ -60,7 +60,7 @@ class WTVAdmin {
let entry_exists = false;
const self = this;
Object.keys(fake_config.config.ssid_block_list).forEach(function (k) {
- if (fake_config.config.ssid_block_list[k] == ssid) {
+ if (fake_config.config.ssid_block_list[k] === ssid) {
entry_exists = true;
return self.REASON_EXISTS;
}
@@ -85,7 +85,7 @@ class WTVAdmin {
if (!fake_config.config.ssid_block_list) fake_config.config.ssid_block_list = [];
if (typeof ssid === 'string') {
Object.keys(fake_config.config.ssid_block_list).forEach(function (k) {
- if (fake_config.config.ssid_block_list[k].toLowerCase() == ssid.toLowerCase()) {
+ if (fake_config.config.ssid_block_list[k].toLowerCase() === ssid.toLowerCase()) {
fake_config.config.ssid_block_list.splice(k, 1);
config_changed = true
}
@@ -93,7 +93,7 @@ class WTVAdmin {
} else {
Object.keys(fake_config.config.ssid_block_list).forEach(function (k) {
Object.keys(ssid).forEach(function (j) {
- if (fake_config.config.ssid_block_list[k].toLowerCase() == ssid[j].toLowerCase()) {
+ if (fake_config.config.ssid_block_list[k].toLowerCase() === ssid[j].toLowerCase()) {
fake_config.config.ssid_block_list.splice(k, 1);
config_changed = true
}
@@ -139,14 +139,14 @@ class WTVAdmin {
checkPassword(password) {
if (this.pcservices) {
if (this.minisrv_config.config.pc_admin.password) {
- return (password == this.minisrv_config.config.pc_admin.password);
+ return (password === this.minisrv_config.config.pc_admin.password);
} else {
// no password set
return true;
}
} else {
if (this.minisrv_config.services[this.service_name].password) {
- return (password == this.minisrv_config.services[this.service_name].password);
+ return (password === this.minisrv_config.services[this.service_name].password);
} else {
// no password set
return true;
@@ -184,13 +184,13 @@ class WTVAdmin {
if (this.minisrv_config.services[this.service_name].authorized_ssids) {
const self = this;
Object.keys(self.minisrv_config.services[this.service_name].authorized_ssids).forEach(function (k) {
- if (typeof self.minisrv_config.services[self.service_name].authorized_ssids[k] == "string") {
+ if (typeof self.minisrv_config.services[self.service_name].authorized_ssids[k] === "string") {
const ssid = self.minisrv_config.services[self.service_name].authorized_ssids[k]
- if (ssid == self.wtvclient.ssid) allowed_ssid = true;
+ if (ssid === self.wtvclient.ssid) allowed_ssid = true;
allowed_ip = true; // no ip block defined
} else {
const ssid = k;
- if (ssid == self.wtvclient.ssid) {
+ if (ssid === self.wtvclient.ssid) {
allowed_ssid = true;
Object.keys(self.minisrv_config.services[self.service_name].authorized_ssids[k]).forEach(function (j) {
if (self.wtvshared.isInSubnet(self.clientAddress, self.minisrv_config.services[self.service_name].authorized_ssids[k][j])) {
@@ -247,7 +247,7 @@ class WTVAdmin {
const temp_session_data_file = self.fs.readFileSync(search_dir + self.path.sep + file, 'Utf8');
const temp_session_data = JSON.parse(temp_session_data_file);
- if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) {
+ if (temp_session_data.subscriber_username.toLowerCase() === username.toLowerCase()) {
account_data = [temp_session_data, (search_dir + self.path.sep + file).replace(this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + this.path.sep + "accounts"), "").split(this.path.sep)[1]];
}
} catch (e) {
@@ -317,7 +317,7 @@ class WTVAdmin {
let isBanned = false;
if (this.minisrv_config.config.ssid_block_list) {
Object.keys(this.minisrv_config.config.ssid_block_list).forEach(function (k) {
- if (self.minisrv_config.config.ssid_block_list[k] == ssid) {
+ if (self.minisrv_config.config.ssid_block_list[k] === ssid) {
isBanned = true;
}
});
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js b/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js
index 202b6808..d7a7efb0 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVAuthor.js
@@ -102,7 +102,7 @@ class WTVAuthor {
this.debug("createPage", "pagenum", pagenum)
this.debug("createPage", "pagelen", pagelen)
}
- if (pages.length == 0) {
+ if (pages.length === 0) {
pagenum = 0
pagefile = pagenum + this.pageFileExt;
} else {
@@ -130,7 +130,7 @@ class WTVAuthor {
// Encode page data into JSON
let returnval = pages.length
this.fs.writeFileSync(pagefileout, JSON.stringify(pagedata));
- if (returnval != 0) {
+ if (returnval !== 0) {
const npages = this.fs.readdirSync(pagestorepath)
returnval = npages.length - 1;
}
@@ -203,7 +203,7 @@ class WTVAuthor {
case "snapshot":
case "scrapbook":
- if (state == "publishing") {
+ if (state === "publishing") {
block = this.generatePublishImageBlock(number, page);
} else {
templatePath = this.wtvshared.getServiceDep('wtv-author/blocks/snapshot_block.njk', true);
@@ -212,7 +212,7 @@ class WTVAuthor {
break;
case "clipart":
- if (state == "publishing") {
+ if (state === "publishing") {
block = this.generatePublishImageBlock(number, page);
} else {
templatePath = this.wtvshared.getServiceDep('wtv-author/blocks/clipart_block.njk', true);
@@ -296,35 +296,35 @@ class WTVAuthor {
const pagedata = this.loadPage(pagenum);
let title;
// Should probably have a better way to know if the page has no title
- if (pagedata.title == "(Untitled)" && state == "editing")
+ if (pagedata.title === "(Untitled)" && state === "editing")
title = "Choose this to add a title to your document "
else
title = pagedata.title
// Set the page style with too many paramaters
this.setStyle(pagedata.style, title, pagedata.description, state, pagenum);
let html = this.header
- if (page == 1) {
- if (pagedata.showtitle == true){
+ if (page === 1) {
+ if (pagedata.showtitle === true){
html += this.titheader
}
}
html += this.tabstart
// This generates blocks on separate pages in the most neat and optimized way possible (i think, i hate past jar)
- if (page != 1) {
+ if (page !== 1) {
for (let i = pagedata.pagebreaks[page - 2]; i < (pagedata.pagebreaks[page - 1] || pagedata.blocks.length); i++) {
html += this.generateBlock(i, pagenum, state)
}
- } else if (pagedata.pagebreaks.length != 0){
+ } else if (pagedata.pagebreaks.length !== 0){
for (let i = 0; i < pagedata.pagebreaks[0]; i++) {
html += this.generateBlock(i, pagenum, state)
- if (this.afterblock1 && i == 0) {
+ if (this.afterblock1 && i === 0) {
html += this.afterblock1
}
}
} else {
for (let i = 0; i < pagedata.blocks.length; i++) {
html += this.generateBlock(i, pagenum, state)
- if (this.afterblock1 && i == 0) {
+ if (this.afterblock1 && i === 0) {
html += this.afterblock1
}
}
@@ -345,7 +345,7 @@ class WTVAuthor {
const pages = this.fs.readdirSync(pagestorepath)
const page = pages[pagenum]
const result = this.fs.writeFileSync(pagepath + page, JSON.stringify(pageout));
- if (pagedata.published == true && callPublish) {
+ if (pagedata.published === true && callPublish) {
this.publishPage(pagenum, pagedata.inlist, false)
}
if (!result) return false;
@@ -402,7 +402,7 @@ class WTVAuthor {
const blocks = pagedata.blocks;
blocks.splice(position, 1);
this.editPage(pagedata, pagenum);
- if (block.type == "break")
+ if (block.type === "break")
this.generateBreakList(pagenum)
return true;
}
@@ -411,7 +411,7 @@ class WTVAuthor {
if (this.minisrv_config.services['wtv-author'].public_domain) {
return this.minisrv_config.services['wtv-author'].public_domain;
} else {
- if (this.minisrv_config.services['wtv-author'].publish_mode == "service") {
+ if (this.minisrv_config.services['wtv-author'].publish_mode === "service") {
const target_service = this.minisrv_config.services[this.minisrv_config.services['wtv-author'].publish_dest];
if (target_service) {
return target_service.host + ":" + target_service.port;
@@ -432,7 +432,7 @@ class WTVAuthor {
getPublishDir() {
let destDir = false;
- if (this.minisrv_config.services['wtv-author'].publish_mode == "service") {
+ if (this.minisrv_config.services['wtv-author'].publish_mode === "service") {
const target_service = this.minisrv_config.services[this.minisrv_config.services['wtv-author'].publish_dest];
if (target_service) {
if (!target_service.pc_services) {
@@ -448,7 +448,7 @@ class WTVAuthor {
destDir = this.minisrv_config.config.ServiceVaults[0] + this.path.sep + target_service.servicevault_dir + this.path.sep;
}
}
- } else if (this.minisrv_config.services['wtv-author'].publish_mode == "directory") {
+ } else if (this.minisrv_config.services['wtv-author'].publish_mode === "directory") {
destDir = this.minisrv_config.services['wtv-author'].publish_dest;
} else {
console.error("Invalid service configuration: invalid publish_mode.");
@@ -461,7 +461,7 @@ class WTVAuthor {
unpublishPage(pagenum) {
const pagedata = this.loadPage(pagenum)
const destDir = this.getPublishDir();
- if (pagedata.published != true) {
+ if (pagedata.published !== true) {
return "This page is not published."
}
const publishname = pagedata.publishname;
@@ -489,7 +489,7 @@ class WTVAuthor {
const destDir = this.getPublishDir();
let publishname, fileout;
- if (pagedata.published != true) {
+ if (pagedata.published !== true) {
publishname = pagedata.title.slice(0, 50).replaceAll(" ", "").replace(/[^A-Za-z0-9]/g, "-");
pagedata.publishname = publishname;
this.editPage(pagedata, pagenum);
@@ -505,7 +505,7 @@ class WTVAuthor {
this.fs.mkdirSync(destDir + this.wtvclient.session_store.subscriber_username + '/' + publishname + "/media/", { recursive: true })
for (let i = 1; i < pagedata.pagebreaks.length + 2; i++) {
const pagehtml = this.generatePage("publishing", pagenum, i)
- if (i == 1)
+ if (i === 1)
fileout = "index.html"
else
fileout = "page" + i + ".html"
@@ -613,8 +613,8 @@ class WTVAuthor {
pagedata.blocks[oldposition].caption = caption
pagedata.blocks[oldposition].size = size
pagedata.blocks[oldposition].style = style
-
- if (oldposition != position)
+
+ if (oldposition !== position)
this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
this.editPage(pagedata, pagenum);
@@ -646,22 +646,22 @@ class WTVAuthor {
const blocks = pagedata.blocks
- if (photo != null) {
+ if (photo !== null) {
const base64photo = new Buffer.from(photo).toString('base64')
blocks[oldposition].photo = base64photo
}
- if (type != null) {
+ if (type !== null) {
blocks[oldposition].type = type
}
- if (title != null)
+ if (title !== null)
blocks[oldposition].title = title
- if (caption != null)
+ if (caption !== null)
blocks[oldposition].caption = caption
- if (oldposition != position) {
+ if (oldposition !== position) {
this.wtvshared.moveObjectKey(blocks, oldposition,position);
}
@@ -696,10 +696,10 @@ class WTVAuthor {
pagedata.blocks[oldposition].size = size
pagedata.blocks[oldposition].dividerBefore = dividerBefore
pagedata.blocks[oldposition].dividerAfter = dividerAfter
-
- if (oldposition != position)
- this.wtvshared.moveObjectKey(pagedata.blocks, oldposition,position);
-
+
+ if (oldposition !== position)
+ this.wtvshared.moveObjectKey(pagedata.blocks, oldposition, position);
+
this.editPage(pagedata, pagenum);
return true;
}
@@ -727,10 +727,10 @@ class WTVAuthor {
pagedata.blocks[oldposition].title = title
pagedata.blocks[oldposition].items = items
-
- if (oldposition != position)
- this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
-
+
+ if (oldposition !== position)
+ this.wtvshared.moveObjectKey(pagedata.blocks, oldposition, position);
+
this.editPage(pagedata, pagenum);
return true;
}
@@ -745,7 +745,7 @@ class WTVAuthor {
const url = linkItems[i]
const name = listItems[i]
- if (url == "http://") {
+ if (url === "http://") {
continue loop;
} else {
const subblock = {
@@ -778,8 +778,8 @@ class WTVAuthor {
for (let i = 0; i < linkItems.length; i++) {
const url = linkItems[i]
const name = listItems[i]
-
- if (url == "http://") {
+
+ if (url === "http://") {
continue loop;
} else {
const subblock = {
@@ -792,10 +792,10 @@ class WTVAuthor {
pagedata.blocks[oldposition].title = title
pagedata.blocks[oldposition].items = items
-
- if (oldposition != position)
- this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
-
+
+ if (oldposition !== position)
+ this.wtvshared.moveObjectKey(pagedata.blocks, oldposition, position);
+
this.editPage(pagedata, pagenum);
return true;
}
@@ -818,10 +818,10 @@ class WTVAuthor {
editBreakBlock(pagenum, position, oldposition) {
const pagedata = this.loadPage(pagenum);
if (!pagedata) return false;
-
- if (oldposition != position)
- this.wtvshared.moveObjectKey(pagedata.blocks,oldposition,position);
-
+
+ if (oldposition !== position)
+ this.wtvshared.moveObjectKey(pagedata.blocks, oldposition, position);
+
this.editPage(pagedata, pagenum);
this.generateBreakList(pagenum);
return true;
@@ -832,7 +832,7 @@ class WTVAuthor {
const breaks = [];
for (let i = 0; i < pagedata.blocks.length; i++) {
const type = pagedata.blocks[i].type
- if (type == "break")
+ if (type === "break")
breaks.push(i)
}
pagedata.pagebreaks = breaks;
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVBGMusic.js b/zefie_wtvp_minisrv/includes/classes/WTVBGMusic.js
index 0d4d3201..cd1396ba 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVBGMusic.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVBGMusic.js
@@ -1259,9 +1259,9 @@ class WTVBGMusic {
// check if we need to set defaults
let setDefaults = force_default;
if (!music_obj.enableCategories) setDefaults = true;
- else if (music_obj.enableCategories.length == 0) setDefaults = true;
+ else if (music_obj.enableCategories.length === 0) setDefaults = true;
if (!music_obj.enableSongs) setDefaults = true;
- else if (music_obj.enableSongs.length == 0) setDefaults = true;
+ else if (music_obj.enableSongs.length === 0) setDefaults = true;
if (setDefaults === true) {
// set up defaults
@@ -1355,10 +1355,10 @@ class WTVBGMusic {
musiclist[k].id = k;
if (String(category).length === 1) {
// 3 digit song id
- if (parseInt(k.slice(0, 1)) == parseInt(category) && String(k).length === 3) songList.push(musiclist[k]);
+ if (parseInt(k.slice(0, 1)) === parseInt(category) && String(k).length === 3) songList.push(musiclist[k]);
} else if (String(category).length === 2) {
// 4 digit song id
- if (parseInt(k.slice(0, 2)) == parseInt(category) && String(k).length === 4) songList.push(musiclist[k]);
+ if (parseInt(k.slice(0, 2)) === parseInt(category) && String(k).length === 4) songList.push(musiclist[k]);
}
});
return songList.filter(value => Object.keys(value).length !== 0);
@@ -1385,7 +1385,7 @@ class WTVBGMusic {
const music_obj = this.getMusicObj();
let enabled = false;
music_obj.enableCategories.forEach(function (v) {
- if (parseInt(v) == parseInt(category)) {
+ if (parseInt(v) === parseInt(category)) {
enabled = true;
}
});
@@ -1396,7 +1396,7 @@ class WTVBGMusic {
const music_obj = this.getMusicObj();
let enabled = false;
music_obj.enableSongs.forEach(function (v) {
- if (parseInt(v) == parseInt(song)) {
+ if (parseInt(v) === parseInt(song)) {
if (checkCat) {
const songCategory = this.getSongCategory(song);
if (this.isCategoryEnabled(songCategory)) {
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVClientCapabilities.js b/zefie_wtvp_minisrv/includes/classes/WTVClientCapabilities.js
index 5db1ad1e..9b9626e5 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVClientCapabilities.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVClientCapabilities.js
@@ -89,7 +89,7 @@ class WTVClientCapabilities {
const capabilities = [];
// might want to pass without a flag to get the table
- if (wtv_capability_flags != null) {
+ if (wtv_capability_flags !== null) {
// define function to convert hex string to binary string (0s & 1s)
const hex2bin = function (hex) {
@@ -118,7 +118,7 @@ class WTVClientCapabilities {
// process bitfield and set capabilities
Object.keys(bitfield).forEach(function (k) {
// Convert binary to boolean, 0 to false, 1 to true
- const bitfield_result = (bitfield[k] == "1")
+ const bitfield_result = (bitfield[k] === "1")
// set flags based on position of bit
try {
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js b/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js
index e94ed14c..7d2a0f13 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVClientSessionData.js
@@ -148,7 +148,7 @@ class WTVClientSessionData {
if (addresses) {
for (let i = 0; i < addresses.length; i++) {
console.log(addr.toLowerCase(), addresses[i].address.toLowerCase())
- if (addr.toLowerCase() == addresses[i].address.toLowerCase()) {
+ if (addr.toLowerCase() === addresses[i].address.toLowerCase()) {
return true;
}
}
@@ -157,7 +157,7 @@ class WTVClientSessionData {
}
findFreeUserSlot() {
- if (this.user_id != 0) return false; // subscriber only command
+ if (this.user_id !== 0) return false; // subscriber only command
const master_directory = this.getUserStoreDirectory(true);
if (this.fs.existsSync(master_directory)) {
for (let i = 0; i < this.minisrv_config.config.user_accounts.max_users_per_account; i++) {
@@ -171,17 +171,17 @@ class WTVClientSessionData {
}
getDisplayName() {
- return (this.user_id == 0) ? this.getSessionData("subscriber_name") : this.getSessionData("display_name");
+ return (this.user_id === 0) ? this.getSessionData("subscriber_name") : this.getSessionData("display_name");
}
getNumberOfUserAccounts() {
if (!this.isRegistered()) return false;
- if (this.user_id != 0) return false; // subscriber only command
+ if (this.user_id !== 0) return false; // subscriber only command
return Object.keys(this.listPrimaryAccountUsers()).length;
}
listPrimaryAccountUsers() {
- if (this.user_id != 0) return false; // subscriber only command
+ if (this.user_id !== 0) return false; // subscriber only command
const master_directory = this.getUserStoreDirectory(true);
const account_data = [];
@@ -191,7 +191,7 @@ class WTVClientSessionData {
if (f.startsWith("user")) {
const user_file = this.path.resolve(master_directory + this.path.sep + f + this.path.sep + f + ".json");
if (self.fs.existsSync(user_file)) {
- if (f == "user0") {
+ if (f === "user0") {
account_data['subscriber'] = JSON.parse(this.fs.readFileSync(user_file));
account_data['subscriber'].user_id = 0;
}
@@ -283,14 +283,14 @@ class WTVClientSessionData {
const pending_file = this.getUserStoreDirectory(true) + this.path.sep + "pending_transfer.json";
const file = this.fs.readFileSync(pending_file)
const ssidobj = JSON.parse(file);
- if (ssidobj.type != "target") return false; // Only allow completion from target
+ if (ssidobj.type !== "target") return false; // Only allow completion from target
const source_ssid = ssidobj.ssid
const old_account = this.getAccountStoreDirectory() + this.path.sep + source_ssid
const new_account = this.getUserStoreDirectory(true);
this.fs.cpSync(old_account, new_account, {
filter: (source, _destination) => {
- return source != "pending_transfer.json";
- },
+ return source !== "pending_transfer.json";
+ },
recursive: true
});
this.fs.rmSync(old_account, { recursive: true })
@@ -304,7 +304,7 @@ class WTVClientSessionData {
const ssidobj = JSON.parse(this.fs.readFileSync(pending_file));
console.log(ssidobj)
if (dtype) {
- (ssidobj.type == dtype) ? ssidobj.ssid : false;
+ (ssidobj.type === dtype) ? ssidobj.ssid : false;
}
else {
return ssidobj;
@@ -543,7 +543,7 @@ class WTVClientSessionData {
let cookie_data;
if (!this.checkCookies()) this.resetCookies();
if (!domain) return false;
- else if (typeof (domain) == 'object') {
+ else if (typeof (domain) === 'object') {
// accept array as first argument
if (domain.domain && domain.path && domain.expires && domain.data) cookie_data = domain;
else return false;
@@ -564,7 +564,7 @@ class WTVClientSessionData {
// see if we have a cookie for this domain/path
Object.keys(this.session_store.cookies).forEach(function (k) {
if (cookie_index >= 0) return;
- if (domain == self.session_store.cookies[k].domain && path == self.session_store.cookies[k].path) cookie_index = k;
+ if (domain === self.session_store.cookies[k].domain && path === self.session_store.cookies[k].path) cookie_index = k;
});
// otherwise add a new one
if (cookie_index === -1) cookie_index = this.countCookies();
@@ -586,8 +586,8 @@ class WTVClientSessionData {
let result = false;
Object.keys(this.session_store['cookies']).forEach(function (k) {
if (result !== false) return;
- if (self.session_store['cookies'][k].domain == domain &&
- self.session_store['cookies'][k].path == path) {
+ if (self.session_store['cookies'][k].domain === domain &&
+ self.session_store['cookies'][k].path === path) {
const current_epoch_utc = Date.parse((new Date()).toUTCString());
const cookie_expires_epoch_utc = Date.parse(new Date(Date.parse(self.session_store['cookies'][k].expires)).toUTCString());
@@ -621,7 +621,7 @@ class WTVClientSessionData {
return true;
}
if (!domain) return false;
- else if (typeof (domain) == 'object') {
+ else if (typeof (domain) === 'object') {
// accept array as first argument
if (domain.domain && domain.path) {
path = domain.path;
@@ -633,7 +633,7 @@ class WTVClientSessionData {
const self = this;
Object.keys(this.session_store['cookies']).forEach(function (k) {
- if (self.session_store['cookies'][k].domain == domain && self.session_store['cookies'][k].path == path) {
+ if (self.session_store['cookies'][k].domain === domain && self.session_store['cookies'][k].path === path) {
delete self.session_store['cookies'][k];
self.storeSessionData();
result = true;
@@ -649,7 +649,7 @@ class WTVClientSessionData {
*/
checkCookies() {
if (!this.session_store.cookies) return false;
- else if (this.session_store.cookies == []) return false;
+ else if (this.session_store.cookies.length === 0) return false;
return true;
}
@@ -677,7 +677,7 @@ class WTVClientSessionData {
}
} catch (e) {
// Don't log error 'file not found', it just means the client isn't registered yet
- if (e.code != "ENOENT") console.error(" # Error loading session data for", this.wtvshared.filterSSID(this.ssid), e);
+ if (e.code !== "ENOENT") console.error(" # Error loading session data for", this.wtvshared.filterSSID(this.ssid), e);
// also wipe any existing session_store
this.session_store = {};
return false;
@@ -723,7 +723,7 @@ class WTVClientSessionData {
validateUserPassword(passwd) {
if (!this.getUserPasswordEnabled()) return true; // no password is set so always validate
- return (this.encodePassword(passwd) == this.getSessionData("subscriber_password"));
+ return (this.encodePassword(passwd) === this.getSessionData("subscriber_password"));
}
isUserLoggedIn() {
@@ -761,7 +761,7 @@ class WTVClientSessionData {
if (!this.fs.existsSync(storeDir)) this.mkdirRecursive(storeDir);
if (sessionToStore.password_valid) delete sessionToStore.password_valid; // do not save validity state of password login, resets when session expires
- if (json_save_data != json_load_data) this.fs.writeFileSync(storeDir + "user" + this.user_id + ".json", JSON.stringify(sessionToStore), "Utf8");
+ if (json_save_data !== json_load_data) this.fs.writeFileSync(storeDir + "user" + this.user_id + ".json", JSON.stringify(sessionToStore), "Utf8");
return true;
} catch (e) {
console.error(" # Error saving session data for", this.wtvshared.filterSSID(this.ssid), e);
@@ -904,11 +904,9 @@ class WTVClientSessionData {
switch (this.get("wtv-client-rom-type")) {
case "US-DTV-disk-0MB-16MB-softmodem-CPU5230":
case "US-DTV-disk-0MB-32MB-softmodem-CPU5230":
- return "UltimateTV Satellite receiver";
-
case "US-WEBSTAR-disk-0MB-8MB-softmodem-CPU5230":
case "US-WEBSTAR-disk-0MB-16MB-softmodem-CPU5230":
- return "WebTV Satellite receiver";
+ return "satellite receiver";
case "US-LC2-flashdisk-0MB-16MB-softmodem-CPU5230":
case "US-LC2-disk-0MB-8MB":
@@ -922,10 +920,10 @@ class WTVClientSessionData {
case "JP-LC2-disk-0MB-8MB-CPU5230":
case "JP-LC2-disk-0MB-16MB-CPU5230":
case "JP-LC2-flash-2MB-8MB-CPU5230":
- return "WebTV Plus receiver";
+ return "Plus receiver";
default:
- return "WebTV Internet receiver";
+ return "Internet terminal";
}
}
@@ -954,7 +952,7 @@ class WTVClientSessionData {
ssid_access_list_ip_override = true;
}
} else {
- if (self.clientAddress == self.minisrv_config.config.ssid_ip_allow_list[self.ssid][k]) {
+ if (self.clientAddress === self.minisrv_config.config.ssid_ip_allow_list[self.ssid][k]) {
// remoteAddr directly matches IP
ssid_access_list_ip_override = true;
}
@@ -972,7 +970,7 @@ class WTVClientSessionData {
// process whitelist first
if (self.ssid && self.minisrv_config.config.ssid_allow_list) {
- const ssid_is_in_whitelist = self.minisrv_config.config.ssid_allow_list.findIndex(element => element == self.ssid);
+ const ssid_is_in_whitelist = self.minisrv_config.config.ssid_allow_list.findIndex(element => element === self.ssid);
if (ssid_is_in_whitelist === -1) {
// no whitelist match, but lets see if the remoteAddress is allowed
checkSSIDIPWhitelist(self.ssid, false);
@@ -981,7 +979,7 @@ class WTVClientSessionData {
// now check blacklist
if (self.ssid && self.minisrv_config.config.ssid_block_list) {
- const ssid_is_in_blacklist = self.minisrv_config.config.ssid_block_list.findIndex(element => element == self.ssid);
+ const ssid_is_in_blacklist = self.minisrv_config.config.ssid_block_list.findIndex(element => element === self.ssid);
if (ssid_is_in_blacklist !== -1) {
// blacklist match, but lets see if the remoteAddress is allowed
checkSSIDIPWhitelist(self.ssid, true);
@@ -1000,7 +998,7 @@ class WTVClientSessionData {
isAuthorized(url, whitelist = 'lockdown', ignore_lockdown = false) {
// not in lockdown so just return true
- if (whitelist == 'lockdown' && !this.lockdown && !ignore_lockdown) return true;
+ if (whitelist === 'lockdown' && !this.lockdown && !ignore_lockdown) return true;
// in lockdown, check whitelisted urls
const self = this;
@@ -1057,25 +1055,25 @@ class WTVClientSessionData {
const romtype = this.get("wtv-client-rom-type");
const brandId = this.ssid.charAt(8)
- if (brandId == 0)
- if (url && romtype == "US-DTV-disk-0MB-32MB-softmodem-CPU5230")
+ if (brandId === 0)
+ if (url && romtype === "US-DTV-disk-0MB-32MB-softmodem-CPU5230")
return "Sony/DirecTV";
else
return "Sony";
- else if (brandId == 1)
+ else if (brandId === 1)
if (url && isPlus === true)
return "Philips-Plus";
else
return "Philips";
- else if (brandId == 4)
+ else if (brandId === 4)
return "Mitsubishi";
- else if (brandId == 5)
+ else if (brandId === 5)
return "Philips-Mont";
- else if (brandId == 7)
+ else if (brandId === 7)
return "Samsung";
- else if (brandId == 9)
+ else if (brandId === 9)
if (url)
- if (romtype == "US-DTV-disk-0MB-32MB-softmodem-CPU5230")
+ if (romtype === "US-DTV-disk-0MB-32MB-softmodem-CPU5230")
return "Thomson/DirecTV";
else
return "Thomson";
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVDisk.js b/zefie_wtvp_minisrv/includes/classes/WTVDisk.js
index 9137e887..d2094604 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVDisk.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVDisk.js
@@ -159,9 +159,9 @@ class WTVDownloadList {
this.download_list += `group: ${group}-UPDATE\n`;
this.download_list += `location: ${source}\n`;
this.download_list += `file-permission: ${file_permission}\n`;
- if (checksum != null) this.download_list += `wtv-checksum: ${checksum}\n`;
- if (uncompressed_size != null) this.download_list += `wtv-uncompressed-filesize: ${uncompressed_size}\n`;
- this.download_list += `service-source-location: /webtv/content/${source.slice(source.indexOf('-') + 1, source.indexOf(':/'))}d/${source.slice(source.indexOf(':/') + 2)}\n`;
+ if (checksum !== null) this.download_list += `wtv-checksum: ${checksum}\n`;
+ if (uncompressed_size !== null) this.download_list += `wtv-uncompressed-filesize: ${uncompressed_size}\n`;
+ this.download_list += `service-source-location: /webtv/content/${source.slice(source.indexOf('-') + 1, source.indexOf(':/'))}d/${source.slice(source.indexOf(':/') + 2)}\n`;
this.download_list += `client-dest-location: ${path}\n\n`;
}
@@ -180,10 +180,10 @@ class WTVDownloadList {
}
getGroupDataFromClientPost(post_data) {
- if (typeof post_data == 'string') post_data = post_data.split("\n\n");
+ if (typeof post_data === 'string') post_data = post_data.split("\n\n");
const group_data = [];
post_data.forEach(function (v) {
- if (v.slice(0, 4) == "file") {
+ if (v.slice(0, 4) === "file") {
const block_split = v.split("\n");
const group_data_entry = {};
group_data_entry.path = block_split[0];
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVFavorites.js b/zefie_wtvp_minisrv/includes/classes/WTVFavorites.js
index ed9887f1..b6678789 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVFavorites.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVFavorites.js
@@ -87,7 +87,7 @@ class WTVFavorites {
const self = this;
if (folder_templates[folder]) {
Object.keys(folder_templates[folder]).forEach(function (k) {
- self.createFavorite(folder_templates[folder][k].title, folder_templates[folder][k].url, folder, (folder_templates[folder][k].image_type == "image/wtv-bitmap") ? atob(folder_templates[folder][k].image) : folder_templates[folder][k].image, folder_templates[folder][k].image_type);
+ self.createFavorite(folder_templates[folder][k].title, folder_templates[folder][k].url, folder, (folder_templates[folder][k].image_type === "image/wtv-bitmap") ? atob(folder_templates[folder][k].image) : folder_templates[folder][k].image, folder_templates[folder][k].image_type);
})
}
}
@@ -95,12 +95,12 @@ class WTVFavorites {
createDefaultFolders() {
const brandId = this.ssid.charAt(8);
this.createTemplateFolder("Recommended");
- if (brandId == 7)
+ if (brandId === 7)
this.createTemplateFolder("Personal (Samsung)");
else
this.createTemplateFolder("Personal");
-
- if (brandId == 0)
+
+ if (brandId === 0)
this.createTemplateFolder("Sony");
}
@@ -145,7 +145,7 @@ class WTVFavorites {
const favoriteid = this.createFavoriteID();
const favoritefile = favoriteid + this.favFileExt;
const favoritefileout = folderpath + favoritefile;
- if (imagetype != "url")
+ if (imagetype !== "url")
image = btoa(image);
title = decodeURIComponent(title).replaceAll("+", " ");
@@ -307,7 +307,7 @@ class WTVFavorites {
const keydata = JSON.parse(this.fs.readFileSync(favoritefileout));
const keys = Object.keys(keydata);
for (let i = 0; i < keys.length; i++) {
- if (keydata[keys[i]].id == favoriteid) {
+ if (keydata[keys[i]].id === favoriteid) {
return { key: keys[i], folder: keydata[keys[i]].folder };
}
}
@@ -419,7 +419,7 @@ class WTVFavorites {
}
break;
}
- if (oldkey != "none") {
+ if (oldkey !== "none") {
keydata[oldkey].folder = null;
keydata[oldkey].id = null;
}
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVFlashrom.js b/zefie_wtvp_minisrv/includes/classes/WTVFlashrom.js
index 93e68bdf..d1c37906 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVFlashrom.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVFlashrom.js
@@ -66,7 +66,7 @@ class WTVFlashrom {
flashrom_info.magic = part_header.toString('hex', 0, 4);
flashrom_info.valid_flashrom = false;
- if (flashrom_info.magic == flashrom_magic) flashrom_info.valid_flashrom = true;
+ if (flashrom_info.magic === flashrom_magic) flashrom_info.valid_flashrom = true;
if (!flashrom_info.valid_flashrom) console.error(" * Warning! FlashROM File Magic (" + flashrom_info.magic + ") did not match expected magic (" + flashrom_magic + ")...");
//if (this.minisrv_config.config.debug_flags.debug && !this.no_debug) console.log(" # FlashROM File Magic (" + flashrom_info.magic + "), expected magic (" + flashrom_magic + "), OK = " + flashrom_info.valid_flashrom + "...");
@@ -88,7 +88,7 @@ class WTVFlashrom {
flashrom_info.part_number = data.readUInt16BE(28);
if (this.minisrv_config.config.debug_flags.debug && !this.minisrv_config.config.debug_flags.quiet && !this.no_debug) console.log(" # Flashrom Curr Part Number :", flashrom_info.part_number);
- flashrom_info.is_last_part = ((flashrom_info.byte_progress + flashrom_info.part_total_size) == flashrom_info.total_parts_size) ? true : false;
+ flashrom_info.is_last_part = ((flashrom_info.byte_progress + flashrom_info.part_total_size) === flashrom_info.total_parts_size) ? true : false;
if (flashrom_info.is_last_part) {
if (this.minisrv_config.config.debug_flags.debug && !this.minisrv_config.config.debug_flags.quiet && !this.no_debug) console.log(" # Flashrom Curr Part is Last:", flashrom_info.is_last_part);
@@ -117,7 +117,7 @@ class WTVFlashrom {
const flashrom_info = this.getFlashromInfo(data, request_path)
if (flashrom_info.is_bootrom) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe?
else headers += "Content-Type: binary/x-wtv-flashblock";
- if (flashrom_info.next_rompath != null && this.bf0app_update) headers += "\nwtv-visit: " + flashrom_info.next_rompath;
+ if (flashrom_info.next_rompath !== null && this.bf0app_update) headers += "\nwtv-visit: " + flashrom_info.next_rompath;
headers += "\nminisrv-no-mail-count: true";
callback(data, headers);
}
@@ -132,7 +132,7 @@ class WTVFlashrom {
let headers, data, flashrom_file_path = null;
const self = this;
Object.keys(self.service_vaults).forEach(function (g) {
- if (flashrom_file_path != null) return;
+ if (flashrom_file_path !== null) return;
flashrom_file_path = self.service_vaults[g] + "/" + self.service_name + "/" + request_path;
if (!self.fs.existsSync(flashrom_file_path)) flashrom_file_path = null;
});
@@ -160,11 +160,11 @@ class WTVFlashrom {
res.on('end', function () {
if (self.minisrv_config.config.debug_flags.debug) console.log(` * minisrv FlashROM Server HTTP Status: ${res.statusCode} ${res.statusMessage}`)
- if (res.statusCode == 200) {
+ if (res.statusCode === 200) {
data = Buffer.from(data_hex, 'hex');
- } else if (res.statusCode == 206) {
+ } else if (res.statusCode === 206) {
data = self.getFlashromInfo(Buffer.from(data_hex, 'hex'), request_path);
- } else if (res.statusCode == 404) {
+ } else if (res.statusCode === 404) {
const errpage = self.wtvshared.doErrorPage(404, "The service could not find the requested ROM on the minisrv FlashROM server.")
headers = errpage[0];
data = errpage[1];
@@ -173,7 +173,7 @@ class WTVFlashrom {
headers = errpage[0];
data = errpage[1];
}
- if (!headers && res.statusCode != 206) {
+ if (!headers && res.statusCode !== 206) {
self.sendToClient(data, request_path, callback);
} else {
callback(data, headers);
@@ -182,7 +182,7 @@ class WTVFlashrom {
});
req.end();
} else {
- this.doLocalFlashROM(flashrom_file_path, request_path, callback, ((length != 0) ? true : false));
+ this.doLocalFlashROM(flashrom_file_path, request_path, callback, ((length !== 0) ? true : false));
}
}
}
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVGuide.js b/zefie_wtvp_minisrv/includes/classes/WTVGuide.js
index 3c737625..9083f8e7 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVGuide.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVGuide.js
@@ -70,7 +70,7 @@ class WTVGuide {
start = start + search.length;
const original_start = start;
// handle
- if (definition.charAt(start) != ">") {
+ if (definition.charAt(start) !== ">") {
start++; // +1 to skip =
end = definition.indexOf(">", start);
if (end === -1) break; // malformed tag, exit loop
@@ -99,10 +99,7 @@ class WTVGuide {
// replaces with the friendly name of the type of unit the user has
while (definition.indexOf("") >= 0) {
const romtype = this.session_data.get("wtv-client-rom-type");
- let boxname = "";
- if (romtype == "US-WEBSTAR-disk-0MB-16MB-softmodem-CPU5230" || romtype == "US-DTV-disk-0MB-32MB-softmodem-CPU5230") boxname = "satellite receiver"
- else if (this.session_data.capabilities.get("client-has-tv-experience")) boxname = "WebTV Plus receiver";
- else boxname = "WebTV Internet terminal";
+ const boxname = this.wtvshared.getBoxName(romtype);
definition = definition.replace(/\/g, boxname);
}
// replaces with either "WebTV" or "WebTV Plus" depending on user box type
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVIRC.js b/zefie_wtvp_minisrv/includes/classes/WTVIRC.js
deleted file mode 100644
index 6665b2de..00000000
--- a/zefie_wtvp_minisrv/includes/classes/WTVIRC.js
+++ /dev/null
@@ -1,4719 +0,0 @@
-const net = require('net');
-const dns = require('dns');
-const tls = require('tls');
-const fs = require('fs');
-const path = require('path');
-const { get } = require('http');
-const WTVShared = require('./WTVShared.js').WTVShared;
-
-class WTVIRC {
- /*
- * @constructor
- * @class WTVIRC
- * zefIRCd - A node.js IRC server implementation
- * Tested with WebTV, KvIRC and mIRC.
- * Supports unencrypted and encrypted (SSL) connections on the same port.
- * It supports basic commands like NICK, USER, JOIN, PART, PRIVMSG, NOTICE, TOPIC, AWAY, MODE, KICK, and PING.
- * Basic IRCOp functionality is included.
- * hybridircd compatible server link protocol (tested with Anope IRC Services, and partially with hybridircd itself).
- * Channel modes are supported, including invite-only, topic protection, password protection, and user modes (op/halfop/voice), and more.
- * SSL only channel mode +Z is supported. As is usermode +Z (no DMs from non-SSL users)
- *
- * TODO: Test for crashes with arbitrary data, or malformed commands (especially SSL handshake, or server interface).
- *
- * @param {Object} minisrv_config - The configuration object for minisrv.
- * @param {string} [host='localhost'] - The host to bind the IRC server to.
- * @param {number} [port=6667] - The port to bind the IRC server to.
- * @param {boolean} [debug=false] - Whether to enable debug mode for logging.
- */
- constructor(minisrv_config, host = 'localhost', port = 6667, debug = false) {
- this.minisrv_config = minisrv_config;
- this.wtvshared = new WTVShared(minisrv_config);
- this.version = '0.2.7';
- // Try to get git commit from environment variable or file, fallback to null if not available
- this.git_commit = this.getGitRevision();
- if (this.git_commit) {
- this.version += `-${this.git_commit}`;
- }
- this.host = host;
- this.port = port;
- this.debug = debug;
- this.server = null;
- this.clients = [];
- this.channelData = new Map();
- this.usernames = new Map(); // nickname -> username
- this.usertimestamps = new Map(); // nickname -> timestamp since last message
- this.usermodes = new Map(); // nickname -> Array of modes (e.g. ['w', 'i'])
- this.usersignontimestamps = new Map(); // nickname -> timestamp since user signed on
- this.nicknames = new Map(); // socket -> nickname
- this.awaymsgs = new Map(); // nickname -> away message
- this.servers = new Map(); // socket -> server information
- this.serverusers = new Map(); // server -> Set of users connected to this server
- this.reservednicks = [];
- this.klines = [];
- this.accounts = new Map(); // nickname -> account name
- this.hostnames = new Map(); // nickname -> hostname
- this.realhosts = new Map(); // nickname -> real IP address
- this.uniqueids = new Map(); // nickname -> unique ID mapping
- this.userinfo = new Map(); // nickname -> user info (e.g. real name)
- this.logdata = [];
- this.max_log_lines = 50;
- this.default_channel_modes = ['n','t'];
- this.default_user_modes = ['x'];
- this.server_start_time = this.getDate();
- this.allowed_common_characters = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','_','-'];
- this.allowed_chan_characters = [...this.allowed_common_characters, '.'];
- this.allowed_nick_characters = [...this.allowed_common_characters, '[',']','{','}','\\','|','^','-','~'];
- this.irc_config = minisrv_config.config.irc || {};
- this.channelprefixes = this.irc_config.channel_prefixes || ['#'];
- this.servername = this.irc_config.server_hostname || 'irc.local';
- this.network = this.irc_config.network || 'minisrv';
- this.oper_username = this.irc_config.oper_username || 'minisrv';
- this.oper_password = this.irc_config.oper_password || 'changeme573_PLEASE_CHANGE_THIS_PASSWORD';
- this.oper_enabled = this.irc_config.oper_enabled || false; // Default to off for security
- this.irc_motd = this.irc_config.motd || [
- 'Welcome to the zefIRCd IRC server, powered by minisrv.',
- 'This server is powered by Node.js, and the minisrv project.',
- '',
- 'For more information, visit:',
- 'https://github.com/zefie/zefie_wtvp_minisrv'
- ];
- this.nicklen = this.irc_config.nick_len || 31;
- this.maxbans = this.irc_config.max_bans || 100;
- this.maxlimit = this.irc_config.max_limit || 50;
- this.maxexcept = this.irc_config.max_except || 100;
- this.maxinvite = this.irc_config.max_invite || 100;
- this.maxkeylen = this.irc_config.max_keylen || 24;
- this.channellimit = this.irc_config.channel_limit || 10;
- this.channellen = this.irc_config.channel_len || 32;
- this.topiclen = this.irc_config.topic_len || 255;
- this.kicklen = this.irc_config.kick_len || 255;
- this.awaylen = this.irc_config.away_len || 200;
- this.enable_tls = this.irc_config.enable_ssl || false;
- this.maxtargets = this.irc_config.max_targets || 4;
- this.socket_timeout = 75; // Default socket timeout to 75 seconds, most clients will send PINGs every 60 seconds, so this should be enough to catch lost connections
- this.server_hello = this.irc_config.server_hello || `zefIRCd v${this.version} IRC server powered by minisrv`;
- this.serverId = this.irc_config.server_id || '00A'; // Default server ID, can be overridden in config
- this.allow_public_vhosts = this.irc_config.allow_public_vhosts || false; // Default to false for security
- this.kick_insecure_users_on_secure = this.irc_config.kick_insecure_users_on_secure || true; // If true, users without SSL connections will be kicked from a channel when +Z is applied
- this.hide_version = this.irc_config.hide_version || false; // If true, the server will not send its version in the MOTD
- this.clientpeak = 0;
- this.globalpeak = 0;
- this.socketpeak = 0;
- this.modeparamlimit = 5; // Technically we have no limit, but this is a good default for most IRC clients
- this.max_message_len = 512; // RFC2812 standard maximum message length (including \r\n)
- this.reject_overlength_messages = this.irc_config.reject_overlength_messages || true; // If true, messages longer than max_message_len will be rejected, if false, they will be truncated to max_message_len
- this.totalConnections = 0;
- this.supported_channel_modes = "Ibe,k,l,CNOQRSTVZcimnprt";
- this.supported_user_modes = "BRZciorswxz";
- this.supported_prefixes = ["ohv", "@%+"];
- this.supported_client_caps = ['chghost', 'away-notify', 'echo-message', 'invite-notify', 'multi-prefix', 'userhost-in-names', 'account-notify', 'extended-join'];
- this.supported_server_caps = ['TBURST', 'EOB', 'IE', 'EX'];
- this.enable_webtv_command_hacks = this.irc_config.enable_webtv_command_hacks || true;
- this.supported_webtv_command_hacks = ["MODE", "KICK"]; // You could technically add any command currently supported by the IRCd here, such as OPER, KILL, KLINE, etc.
-
- // Rate limiting configuration
- this.rate_limit_enabled = this.irc_config.rate_limit_enabled || true;
- this.max_messages_per_second = this.irc_config.max_messages_per_second || 5;
- this.message_counts = new Map(); // socket -> {count, resetTime}
-
- // Brute force protection
- this.failed_auth_attempts = new Map(); // IP -> {count, lockoutUntil}
- this.max_auth_attempts = this.irc_config.max_auth_attempts || 3;
- this.auth_lockout_duration = this.irc_config.auth_lockout_duration || 300; // 5 minutes
-
- // Connection limits
- this.connections_per_ip = new Map(); // IP -> count
- this.max_connections_per_ip = this.irc_config.max_connections_per_ip || 3;
-
- // Security logging
- this.security_log_enabled = this.irc_config.security_log_enabled || true;
- this.security_events = [];
- this.session_store_path = this.wtvshared.getAbsolutePath(this.minisrv_config.config.SessionStore + path.sep + 'minisrv_internal_irc');
- this.klines_path = this.session_store_path + path.sep + 'klines.json';
- this.caps = [
- `AWAYLEN=${this.awaylen} CASEMAPPING=rfc1459 BOT=B CHANMODES=${this.supported_channel_modes} CHANNELLEN=${this.channellen} CHANTYPES=${this.channelprefixes.join('')} PREFIX=(${this.supported_prefixes[0]})${this.supported_prefixes[1]} USERMODES=${this.supported_user_modes} MAXLIST=b:${this.maxbans},e:${this.maxexcept},i:${this.maxinvite},k:${this.maxkeylen},l:${this.maxlimit}`,
- `CHARSET=ascii MODES=${this.modeparamlimit} EXCEPTS=e INVEX=I NETWORK=${this.network} CHANLIMIT=${this.channelprefixes.join('')}:${this.channellimit} NICKLEN=${this.nicklen} TOPICLEN=${this.topiclen} KICKLEN=${this.kicklen}`
- ];
- }
-
- start() {
- this.loadKLinesFromFile();
-
- if (this.enable_tls) {
- this.supported_client_caps.push('tls');
- }
- if (this.irc_config.channels) {
- for (const channel of this.irc_config.channels) {
- this.createChannel(channel.name);
- if (channel.modes && Array.isArray(channel.modes)) {
- const channelData = this.channelData.get(channel.name);
- if (channelData) {
- channelData.modes = [...channel.modes];
- }
- }
- if (channel.topic) {
- const channelData = this.channelData.get(channel.name);
- if (channelData) {
- channelData.topic = channel.topic;
- }
- }
- }
- }
- this.server_start_time = this.getDate();
- this.server = net.createServer(async socket => {
-
- // Detect SSL handshake and wrap socket if needed
- socket.once('data', async firstChunk => {
- this.totalConnections++;
-
- // Check connection limits per IP
- const clientIP = socket.remoteAddress;
- const currentConnections = this.connections_per_ip.get(clientIP) || 0;
- if (currentConnections >= this.max_connections_per_ip) {
- this.debugLog('warn', `Connection limit exceeded for IP ${clientIP}`);
- socket.write(`:${this.servername} ERROR :Too many connections from your IP\r\n`);
- socket.end();
- return;
- }
- this.connections_per_ip.set(clientIP, currentConnections + 1);
-
- socket.removeAllListeners('data');
- socket.pause();
- socket.on('error', (err) => {
- this.debugLog('error', `Socket error: ${err.message}`);
- this.terminateSession(socket, true);
- });
- socket.on('timeout', () => {
- this.debugLog('warn', `Socket timeout for ${socket.remoteAddress}`);
- this.terminateSession(socket, true);
- });
- // Check if the first byte indicates SSL/TLS handshake (0x16 for TLS Handshake)
- if (Buffer.isBuffer(firstChunk) ? firstChunk[0] === 0x16 : firstChunk.charCodeAt(0) === 0x16) {
- if (!this.enable_tls) {
- // If SSL is not enabled, close the socket
- await this.safeWriteToSocket(socket, `:${this.servername} 421 * :TLS is not enabled on this server\r\n`);
- this.terminateSession(socket, true);
- return;
- }
-
- // SSL detected, upgrade socket to TLS
- const keyBuffer = fs.readFileSync(this.wtvshared.parseConfigVars(this.irc_config.ssl_cert.key));
- const certBuffer = fs.readFileSync(this.wtvshared.parseConfigVars(this.irc_config.ssl_cert.cert));
- const secureSocket = new tls.TLSSocket(socket, {
- isServer: true,
- ALPNProtocols: ['irc'],
- secureContext: tls.createSecureContext({
- key: keyBuffer,
- cert: certBuffer,
- }),
- });
- socket.push(firstChunk);
-
- secureSocket.on('error', (err) => {
- this.debugLog('error', `Secure socket error: ${err.message}`);
- this.terminateSession(secureSocket, true);
- });
-
- secureSocket.on('close', () => {
- this.terminateSession(secureSocket, false);
- });
-
- // Only start processing after handshake is complete
- secureSocket.on('secure', async () => {
- this.debugLog('info', 'Secure connection (SSL) established with '+ socket.remoteAddress);
- socket.removeAllListeners();
- await this.initializeSocket(secureSocket, true);
-
- });
- secureSocket.resume();
- return;
- } else {
- // Not SSL, re-emit the data event for normal processing
- await this.initializeSocket(socket);
- socket.emit('data', firstChunk.toString('ascii'));
- socket.resume();
- this.clientpeak = Math.max(this.clientpeak, this.clients.length);
- return;
- }
- });
- });
- this.server.listen(this.port, this.host, () => {
- this.debugLog('info', `zefIRCd ${this.version} server started on port ${this.host}:${this.port}`);
- });
- }
-
- async safeWriteToSocket(socket, data) {
- if (!socket || !data) {
- this.debugLog('error', 'writeToSocket called with invalid parameters:', socket, data);
- return;
- }
- if (typeof data !== 'string') {
- data = data.toString('ascii');
- }
- if (data.length > this.max_message_len) {
- data = data.slice(0, this.max_message_len - 2) + '\r\n';
- this.debugLog('warn', `Data length exceeds max_message_len (${this.max_message_len}), truncating: ${data.length} > ${this.max_message_len}`);
- }
-
- // Add timeout to prevent infinite loop
- let waitCount = 0;
- const maxWaitIterations = 1000; // 10 seconds max wait
- while (socket.writable === false && waitCount < maxWaitIterations) {
- await new Promise(resolve => setTimeout(resolve, 10));
- waitCount++;
- }
-
- if (socket.writable === false) {
- this.debugLog('error', 'Socket not writable after timeout, aborting write');
- return;
- }
- socket.write(data);
- }
-
- checkRateLimit(socket) {
- if (!this.rate_limit_enabled || socket.isserver || this.isIRCOp(socket.nickname)) {
- return true; // No rate limiting for servers or IRCOps
- }
-
- const now = Date.now();
- const socketId = socket.remoteAddress + ':' + socket.remotePort;
-
- if (!this.message_counts.has(socketId)) {
- this.message_counts.set(socketId, { count: 1, resetTime: now + 1000 });
- return true;
- }
-
- const rateLimitData = this.message_counts.get(socketId);
-
- if (now > rateLimitData.resetTime) {
- // Reset the counter
- rateLimitData.count = 1;
- rateLimitData.resetTime = now + 1000;
- return true;
- }
-
- if (rateLimitData.count >= this.max_messages_per_second) {
- return false; // Rate limit exceeded
- }
-
- rateLimitData.count++;
- return true;
- }
-
- checkAuthAttempts(socket) {
- const ip = socket.realhost || socket.remoteAddress;
- const now = Date.now();
-
- if (!this.failed_auth_attempts.has(ip)) {
- return true;
- }
-
- const authData = this.failed_auth_attempts.get(ip);
- if (authData.lockoutUntil && now < authData.lockoutUntil) {
- return false; // Still locked out
- }
-
- return true;
- }
-
- recordAuthFailure(socket) {
- const ip = socket.realhost || socket.remoteAddress;
- const now = Date.now();
-
- if (!this.failed_auth_attempts.has(ip)) {
- this.failed_auth_attempts.set(ip, { count: 1, lockoutUntil: null });
- return;
- }
-
- const authData = this.failed_auth_attempts.get(ip);
- authData.count++;
-
- if (authData.count >= this.max_auth_attempts) {
- authData.lockoutUntil = now + (this.auth_lockout_duration * 1000);
- this.debugLog('warn', `IP ${ip} locked out for ${this.auth_lockout_duration} seconds due to failed auth attempts`);
- }
- }
-
- clearAuthFailures(socket) {
- const ip = socket.realhost || socket.remoteAddress;
- this.failed_auth_attempts.delete(ip);
- }
-
- sanitizeInput(input, type = 'general') {
- if (typeof input !== 'string') {
- return '';
- }
-
- // Remove control characters except \r\n
- input = input.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
-
- switch (type) {
- case 'nickname':
- // IRC nicknames: A-Z a-z 0-9 [ ] \ ` _ ^ { | }
- return input.replace(/[^A-Za-z0-9\[\]\\`_^{|}]/g, '').slice(0, this.nicklen);
-
- case 'channel':
- // Channel names: start with #, no spaces, commas, or control chars
- if (!input.startsWith('#')) return '';
- return input.replace(/[^A-Za-z0-9#\-_.]/g, '').slice(0, this.channellen);
-
- case 'message':
- // Messages: no control chars, reasonable length
- return input.slice(0, 512);
-
- case 'username':
- // Usernames: alphanumeric and some special chars
- return input.replace(/[^A-Za-z0-9\-_.]/g, '').slice(0, 32);
-
- default:
- return input.slice(0, 512);
- }
- }
-
- validateCommand(command, params) {
- if (!command || typeof command !== 'string') {
- return false;
- }
-
- // Command must be uppercase letters only
- if (!/^[A-Z]+$/.test(command)) {
- return false;
- }
-
- // Reasonable command length
- if (command.length > 20) {
- return false;
- }
-
- // Parameters validation
- if (params && Array.isArray(params)) {
- for (const param of params) {
- if (typeof param !== 'string' || param.length > 512) {
- return false;
- }
- }
- }
-
- return true;
- }
-
- logSecurityEvent(event, socket, details = {}) {
- if (!this.security_log_enabled) return;
-
- const securityEvent = {
- timestamp: new Date().toISOString(),
- event: event,
- ip: socket ? (socket.realhost || socket.remoteAddress) : 'unknown',
- nickname: socket ? socket.nickname : 'unknown',
- details: details
- };
-
- this.security_events.push(securityEvent);
-
- // Keep only last 1000 security events in memory
- if (this.security_events.length > 1000) {
- this.security_events.shift();
- }
-
- // Log to console/file if needed
- this.debugLog('security', `Security Event: ${event} from ${securityEvent.ip} (${securityEvent.nickname})`);
-
- // Write to security log file if configured
- if (this.irc_config.security_log_file) {
- const fs = require('fs');
- fs.appendFileSync(this.irc_config.security_log_file, JSON.stringify(securityEvent) + '\n');
- }
- }
-
-
- async initializeSocket(socket, secure = false, oldSocket = null) {
- if (this.debug) {
- // debug output for socket data
- const originalWrite = socket.write.bind(socket);
- socket.write = function (...args) {
- var log_args = args.map(arg => {
- if (typeof arg === 'string') {
- return arg.replace(/\r\n/g, '').replace(/\n/g, '');
- }
- return arg;
- });
- console.log('<', ...log_args);
- return originalWrite(...args);
- };
- }
- if (oldSocket) {
- socket.registered = oldSocket.registered;
- socket.nickname = oldSocket.nickname;
- socket.username = oldSocket.username;
- socket.isserver = oldSocket.isserver;
- socket.is_srv_authorized = oldSocket.is_srv_authorized;
- socket.signedoff = oldSocket.signedoff;
- socket.hostname_resolved = oldSocket.hostname_resolved;
- socket.realhost = oldSocket.realhost;
- socket.client_version = oldSocket.client_version;
- socket.client_caps = oldSocket.client_caps || [];
- socket.host = oldSocket.host;
- socket.timestamp = oldSocket.timestamp;
- socket.uniqueId = oldSocket.uniqueId;
- } else {
- socket.registered = false;
- socket.nickname = '';
- socket.username = '';
- socket.isserver = false;
- socket.is_srv_authorized = false;
- socket.signedoff = false;
- socket.hostname_resolved = false;
- socket.realhost = socket.remoteAddress;
- socket.client_version = '';
- socket.client_caps = [];
- socket.host = this.filterHostname(socket, socket.remoteAddress);
- socket.timestamp = this.getDate();
- socket.uniqueId = `${this.serverId}${this.generateUniqueId(socket)}`;
- }
-
- socket.secure = secure;
- socket.upgrading_to_tls = false;
- socket.error_count = 0;
- socket.lastseen = this.getDate();
- await this.doInitialHandshake(socket);
-
- socket.on('data', async data => {
- socket.lastseen = this.getDate();
- await this.processSocketData(socket, data);
- });
-
- socket.on('end', () => {
- this.terminateSession(socket, false);
- });
-
- socket.on('error', () => {
- this.terminateSession(socket, true);
- });
-
- socket.on('close', () => {
- this.terminateSession(socket, false);
- });
-
- // Start a loop to check for idle clients and send PING if needed
- socket._idleInterval = setInterval(async () => {
- if (socket.signedoff) {
- clearInterval(socket._idleInterval);
- return;
- }
- const now = this.getDate();
- if ((now - socket.lastseen) > this.socket_timeout + 10) {
- // Over 10 seconds has passed since we sent our PING, assume lost
- this.debugLog('warn', `Socket ${socket.remoteAddress} has been idle for too long, terminating session`);
- if (socket.nickname) {
- await this.broadcastUser(socket.nickname, `:${socket.nickname}!${socket.username}@${socket.host} QUIT :Ping timeout (${now - socket.lastseen} seconds)\r\n`, socket);
- await this.broadcastToAllServers(`:${socket.uniqueId} QUIT :Ping timeout (${now - socket.lastseen} seconds)\r\n`, serverSocket);
- }
- socket.signedoff = true;
- this.terminateSession(socket, true);
- return;
- } else if ((now - socket.lastseen) > this.socket_timeout) {
- // Client has been idle for too long, send PING
- if (socket.isserver) {
- await this.safeWriteToSocket(socket, `:${this.serverId} PING ${this.serverId} ${this.servername}\r\n`);
- } else {
- await this.safeWriteToSocket(socket, `PING :${this.servername}\r\n`);
- }
- return;
- }
- }, 10000); // check every 5 seconds
-
- this.clients.push(socket);
- this.clientpeak = Math.max(this.clientpeak, this.clients.length);
- }
-
- async processServerData(socket, line) {
- // Handle server-specific commands
- const parts = line.split(' ');
- if (parts[0] == `:${socket.uniqueId}`) {
- parts.shift(); // Remove the unique ID prefix
- }
- if (parts.length < 1) return; // Invalid command
- const command = parts[0].toUpperCase();
- switch (command) {
- case 'PASS':
- // Handle PASS command from server
- if (parts.length < 2) {
- this.debugLog('warn', 'Invalid PASS command from server');
- return;
- }
- const password = parts[1];
- const servers = this.irc_config.servers || {};
- let matchedServer = null;
- Object.entries(servers).forEach(async ([key, serverObj]) => {
- if (serverObj.password && serverObj.password === password) {
- matchedServer = serverObj;
- this.debugLog('info', `Server ${serverObj.name || key} matched with provided password`);
- await this.safeWriteToSocket(socket, `PASS ${serverObj.password}\r\n`);
- socket.is_srv_authorized = true;
- var totalSockets = this.clients.length + this.servers.size;
- this.socketpeak = Math.max(this.socketpeak, totalSockets);
- return;
- }
- });
- if (!matchedServer) {
- this.debugLog('warn', 'Invalid server password provided');
- await this.safeWriteToSocket(socket, `:${this.servername} :ERROR :Invalid server password\r\n`);
- socket.error_count++;
- setTimeout((socket) => {
- if (socket) {
- socket.error_count--;
- }
- }, 60000);
- if (socket.error_count >= 5) {
- await this.safeWriteToSocket(socket, `:${this.servername} :ERROR :Too many errors, disconnecting\r\n`);
- this.terminateSession(socket, true);
- }
- return;
- }
- socket.serverinfo = matchedServer
- return;
- case 'CAPAB':
- if (!this.checkRegistered(socket, true)) {
- break;
- }
- // Handle CAPAB command from server
- if (parts.length < 2) {
- this.debugLog('warn', 'Invalid CAPAB command from server');
- break;
- }
- var capabilities = parts.slice(1).join(' ').slice(1); // Remove leading ':'
- capabilities = capabilities.split(' ');
- this.debugLog('info', `Received CAPAB from server: ${capabilities.join(' ')}`);
- var output_reply = [];
- for (const cap of capabilities) {
- if (this.supported_server_caps.includes(cap)) {
- output_reply.push(cap);
- } else {
- this.debugLog('warn', `Unsupported server capability: ${cap}`);
- }
- }
- await this.safeWriteToSocket(socket, `CAPAB :${output_reply.join(' ')}\r\n`);
- break;
- case 'SERVER':
- if (!this.checkRegistered(socket, true)) {
- break;
- }
- // Handle SERVER command from server
- if (parts.length < 6) {
- this.debugLog('warn', 'Invalid SERVER command from server');
- break;
- }
- var serverName = parts[1];
- var serverNumber = parts[2];
- var serverId = parts[3];
- var serverExtra = parts[4]
- var serverInfo = parts.slice(5).join(' ');
- socket.isserver = true;
- this.clients = this.clients.filter(c => c !== socket);
- this.clientpeak = this.clientpeak - 1;
- socket.registered = true;
- socket.servername = serverName;
- socket.uniqueId = serverId;
- socket.serverIdent = line;
- this.servers.set(socket, serverName)
- await this.safeWriteToSocket(socket, `SERVER ${this.servername} 1 ${this.serverId} + :${this.server_hello}\r\n`);
- for (const [sock, nickname] of this.nicknames.entries()) {
- if (!sock || !nickname) continue;
- const uniqueId = sock.uniqueId;
- const signonTime = Math.floor(this.usersignontimestamps.get(nickname) || this.getDate());
- const userModes = this.getUserModes(nickname);
- const username = this.usernames.get(nickname) || '';
- await this.safeWriteToSocket(socket, `:${this.serverId} UID ${nickname} 1 ${signonTime} +${userModes} ${username} ${sock.host} ${sock.realhost} ${sock.remoteAddress} ${uniqueId} * :${sock.userinfo}\r\n`);
- }
- for (const [channel, channelObj] of this.channelData.entries()) {
- const modes = channelObj.modes;
- for (const user of channelObj.users) {
- let userPrefix = '';
- if (channelObj.ops.has(user)) {
- userPrefix = '@';
- } else if (channelObj.halfops.has(user)) {
- userPrefix = '%';
- } else if (channelObj.voices.has(user)) {
- userPrefix = '+';
- }
- const userUniqueId = this.uniqueids.get(user);
- if (userUniqueId) {
- await this.safeWriteToSocket(socket, `:${this.serverId} SJOIN ${this.getDate()} ${channel} +${modes.join('')} :${userPrefix}${userUniqueId}\r\n`);
- }
- }
- }
-
- await this.broadcastToAllServers(socket.serverIdent, socket);
- // Send EOB to the server
- await this.safeWriteToSocket(socket, `:${this.serverId} EOB \r\n`);
- break;
- case 'SVINFO':
- if (!this.checkRegistered(socket, true)) {
- break;
- }
- // Handle SVINFO command from server
- if (parts.length < 4) {
- this.debugLog('warn', 'Invalid SVINFO command from server');
- return;
- }
- const serverInfoMessage = `:${this.serverId} SVINFO 6 6 0 ${this.getDate()}\r\n`;
- await this.safeWriteToSocket(socket, serverInfoMessage);
- break
- case 'PING':
- // Respond to PING with PONG
- var pong = parts.slice(1).join(' ');
- if (pong.startsWith(':')) {
- pong = pong.slice(1); // Remove leading ':'
- }
- await this.safeWriteToSocket(socket, `:${this.serverId} PONG ${pong}\r\n`);
- break;
- case 'PONG':
- // Ignore PONG from server
- break;
- case 'RESV':
- if (!this.checkRegistered(socket)) {
- break;
- }
- // Handle RESV command from server
- if (parts.length < 2) {
- this.debugLog('warn', 'Invalid RESV command from server');
- break;
- }
- const targetMask = parts[1];
- const expiry = parseInt(parts[2]) || 0;
- const reservedNick = parts[3];
- var reason = parts.slice(4).join(' ') || '';
- if (!this.reservednicks.includes(reservedNick)) {
- this.reservednicks.push(reservedNick);
- }
- if (expiry > 0) {
- setTimeout(() => {
- const index = this.reservednicks.indexOf(reservedNick);
- if (index !== -1) {
- this.reservednicks.splice(index, 1);
- this.debugLog('info', `Reservation for ${reservedNick} expired`);
- }
- }, expiry * 1000);
- }
- await this.broadcastToAllServers(`:${socket.servername} RESV ${targetMask} ${expiry} ${reservedNick} :${reason}\r\n`, socket);
- break;
- case 'UID':
- if (!this.checkRegistered(socket)) {
- break;
- }
- // Handle UID command from server
- if (parts.length < 10) {
- this.debugLog('warn', 'Invalid UID command from server');
- break;
- }
- var nickname = parts[1];
- const server_Id = parts[2];
- const timestamp = parseInt(parts[3]) || 0;
- const userModes = parts[4].replace("/\+/g","").split('');
- var username = parts[5];
- var hostname = parts[6];
- const ipaddress = parts[7];
- const ipaddress2 = parts[8];
- const userUniqueId = parts[9];
- var userinfo = parts.slice(10).join(' ').slice(1); // Remove leading ':'
- this.addRemoteServerUser(socket, nickname);
- this.addUserUniqueId(nickname, userUniqueId);
- this.globalpeak = Math.max(this.globalpeak, this.countGlobalUsers());
- this.usersignontimestamps.set(nickname, timestamp);
- this.usernames.set(nickname, username);
- this.hostnames.set(nickname, hostname);
- this.realhosts.set(nickname, ipaddress2);
- this.userinfo.set(nickname, userinfo);
- for (const mode of userModes) {
- this.setUserMode(nickname, mode, true);
- }
- await this.broadcastToAllServers(`:${socket.servername} UID ${nickname} ${server_Id} ${timestamp} +${userModes.join('')} ${username} ${hostname} ${ipaddress} ${ipaddress2} ${userUniqueId} * :${userinfo}\r\n`, socket);
- break;
- case 'SVSHOST':
- if (!this.checkRegistered(socket)) {
- break;
- }
- // Handle SVSHOST command from server
- if (parts.length < 4) {
- this.debugLog('warn', 'Invalid SVSHOST command from server');
- break;
- }
- var uniqueId = parts[1];
- var hostname = parts[3];
- var targetSocket = this.findSocketByUniqueId(uniqueId);
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for unique ID ${uniqueId}`);
- break;
- }
- this.hostnames.set(this.findUserByUniqueId(uniqueId), hostname);
- targetSocket.host = hostname;
- if (targetSocket.client_caps && targetSocket.client_caps.includes('CHGHOST')) {
- await this.safeWriteToSocket(targetSocket, `:${targetSocket.nickname}!${targetSocket.username}@${targetSocket.host} CHGHOST ${targetSocket.username} ${targetSocket.host}\r\n`);
- }
- await this.safeWriteToSocket(targetSocket, `:${this.servername} 396 ${targetSocket.nickname} ${targetSocket.host} :is now your visible host\r\n`);
- await this.broadcastToAllServers(`:${socket.servername} SVSHOST ${uniqueId} ${hostname}\r\n`, socket);
- break;
- case 'SVSACCOUNT':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (parts.length < 4) {
- this.debugLog('warn', 'Invalid SVSACCOUNT command from server');
- break;
- }
- var uniqueId = parts[1];
- var accountName = parts[3];
- var nickname = this.findUserByUniqueId(uniqueId);
- if (!nickname) {
- this.debugLog('warn', `No user found for unique ID ${uniqueId}`);
- break;
- }
- if (accountName === '*') {
- // Remove account association
- this.accounts.delete(nickname);
- } else {
- this.accounts.set(nickname, accountName);
- }
- var targetSocket = this.findSocketByUniqueId(uniqueId);
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for unique ID ${uniqueId}`);
- break;
- }
- if (targetSocket.client_caps && targetSocket.client_caps.includes('account-notify')) {
- await this.safeWriteToSocket(targetSocket, `:${targetSocket.nickname}!${targetSocket.username}@${targetSocket.host} ACCOUNT ${accountName}\r\n`);
- }
- break;
- case 'SVSNICK':
- if (!this.checkRegistered(socket)) {
- break;
- }
- // Handle SVSNICK command from server
- if (parts.length < 5) {
- this.debugLog('warn', 'Invalid SVSNICK command from server');
- break;
- }
- var oldNick = this.findUserByUniqueId(parts[1]);
- var newNick = parts[3];
- var targetSocket = this.findSocketByUniqueId(parts[1]);
- await this.broadcastUser(oldNick, `:${oldNick}!${this.usernames.get(oldNick)}@${targetSocket.host} NICK :${newNick}\r\n`);
- this.processNickChange(targetSocket, newNick);
- await this.broadcastToAllServers(line, socket);
- break;
- case 'SJOIN':
- if (!this.checkRegistered(socket)) {
- break;
- }
- var channel = parts[2];
- var modes = parts[3];
- var uniqueId = parts[4];
- if (uniqueId.startsWith(':')) {
- uniqueId = uniqueId.slice(1); // Remove leading ':'
- }
- if (!uniqueId) {
- await this.broadcastToAllServers(`:${socket.servername} SJOIN ${this.getDate()} ${channel} +${modes} :\r\n`, socket);
- break;
- }
- while (['@', '%', '+'].includes(uniqueId[0])) {
- uniqueId = uniqueId.slice(1);
- }
- var userSocket = this.findSocketByUniqueId(uniqueId);
- var nickname = this.findUserByUniqueId(uniqueId);
- var username = this.usernames.get(nickname) || nickname;
- var hostname = this.hostnames.get(nickname)
- if (!this.channelData.has(channel)) {
- this.createChannel(channel);
- }
- if (!this.channelData.get(channel).users.has(nickname)) {
- this.channelData.get(channel).users.add(nickname);
- }
- if (nickname && username && hostname) {
- await this.broadcastChannel(channel, `:${nickname}!${username}@${hostname} JOIN ${channel}\r\n`, userSocket);
- }
- await this.broadcastToAllServers(`:${socket.servername} SJOIN ${this.getDate()} ${channel} +${modes} :${uniqueId}\r\n`, socket);
- break;
- case 'SQUIT':
- await this.broadcastToAllServers(`:${socket.servername} SQUIT ${parts[1]} :${parts.slice(2).join(' ').slice(1)}\r\n`, socket);
- this.servers.delete(socket);
- break;
- case (command.match(/^\d{3}$/) || {}).input:
- if (!this.checkRegistered(socket)) {
- break;
- }
- // Numeric reply from server
- // Numeric replies are usually in the format: :
- var senderID = parts[1]
- var targetSocket = this.findSocketByUniqueId(senderID);
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for unique ID ${senderID}`);
- break;
- }
- var responded = false;
- switch (command) {
- case '307':
- // WHOIS AWAY reply
- if (parts.length < 3) {
- this.debugLog('warn', 'Invalid WHOIS AWAY reply from server');
- break;
- }
- var whoisNick = parts[2];
- var awayMessage = parts.slice(3).join(' ');
- if (awayMessage.startsWith(':')) {
- awayMessage = awayMessage.slice(1);
- }
- await this.safeWriteToSocket(targetSocket, `:${socket.servername} 307 ${whoisNick} ${whoisNick} :${awayMessage}\r\n`);
- responded = true;
- break;
- case '311':
- // WHOIS reply
- var whoisNick = parts[2];
- var whoisUser = parts[3];
- var whoisHost = parts[4];
- var whoisServer = parts[5];
- var whoisRealname = parts.slice(6).join(' ');
- if (whoisRealname.startsWith(':')) {
- whoisRealname = whoisRealname.slice(1);
- }
- await this.safeWriteToSocket(targetSocket, `:${socket.servername} 311 ${whoisNick} ${whoisNick} ${whoisUser} ${whoisHost} ${whoisServer} :${whoisRealname}\r\n`);
- responded = true;
- break;
- case '312':
- // WHOIS SERVER reply
- var serverID = parts[1];
- var whoisNick = parts[2];
- var serverName = parts[2];
- var serverInfo = parts.slice(3).join(' ');
- if (serverInfo.startsWith(':')) {
- serverInfo = serverInfo.slice(1);
- }
- await this.safeWriteToSocket(targetSocket, `:${socket.servername} 312 ${whoisNick} ${serverName} :${serverInfo}\r\n`);
- responded = true;
- break;
- case '313':
- // WHOIS operator reply
- if (parts.length < 3) {
- this.debugLog('warn', 'Invalid WHOIS operator reply from server');
- break;
- }
- var whoisNick = parts[2];
- var message = parts.slice(3).join(' ');
- if (message.startsWith(':')) {
- message = message.slice(1);
- }
- await this.safeWriteToSocket(targetSocket, `:${socket.servername} 313 ${whoisNick} ${whoisNick} :${message}\r\n`);
- responded = true;
- break;
- case '317':
- // WHOIS idle reply
- if (parts.length < 4) {
- this.debugLog('warn', 'Invalid WHOIS idle reply from server');
- break;
- }
- var whoisNick = parts[2];
- var idleTime = parts[3];
- var signonTime = parts[4];
- await this.safeWriteToSocket(targetSocket, `:${socket.servername} 317 ${whoisNick} ${whoisNick} ${idleTime} ${signonTime} :seconds idle, signon time\r\n`);
- responded = true;
- break;
- case '318':
- // WHOIS end of reply
- if (parts.length < 2) {
- this.debugLog('warn', 'Invalid WHOIS end of reply from server');
- break;
- }
- var whoisNick = parts[1];
- await this.safeWriteToSocket(targetSocket, `:${socket.servername} 318 ${whoisNick} :End of WHOIS list\r\n`);
- responded = true;
- break;
- }
- if (responded) {
- break;
- }
- if (parts.length < 4) {
- this.debugLog('warn', 'Invalid numeric reply from server');
- break;
- }
- const numericCode = parts[0];
- const targetID = parts[1];
- var numericMessage = parts.slice(3).join(' ');
- if (numericMessage.startsWith(':')) {
- numericMessage = numericMessage.slice(1); // Remove leading ':'
- }
-
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for target unique ID ${targetID}`);
- break;
- }
- await this.safeWriteToSocket(targetSocket, `:${socket.serverinfo.name} ${numericCode} ${targetID} :${numericMessage}\r\n`);
- break;
- default:
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (command.startsWith(':')) {
- // part out the line to "sourceUniqueId command targetUniqueId :message"
- var sourceUniqueId = parts[0].slice(1); // Remove the leading ':'
- var nickname = this.findUserByUniqueId(sourceUniqueId);
- if (!nickname) {
- this.debugLog('warn', `No nickname found for unique ID ${sourceUniqueId}`);
- break;
- }
- var srvCommand = parts[1];
- let whoisNick;
- switch (srvCommand) {
- case 'QUIT':
- var user_name = this.usernames.get(nickname) || nickname;
- var message = parts.slice(2).join(' ').slice(1); // Remove leading ':'
- // Remove user from the server's user list
- const serverUsers = this.serverusers.get(socket);
- if (serverUsers && typeof serverUsers.delete === 'function') {
- const nickToRemove = this.findUserByUniqueId(sourceUniqueId);
- serverUsers.delete(nickToRemove);
- this.cleanupUserSession(nickToRemove);
- }
- await this.broadcastToAllServers(`:${nickname}!${user_name}@${this.servername} QUIT :${message}\r\n`, socket);
- break;
- case 'JOIN':
- var channel = this.findChannel(parts[3]);
- if (!channel || !this.channelData.has(channel)) {
- channel = parts[3];
- this.createChannel(channel);
- }
- var userSocket = this.findSocketByUniqueId(sourceUniqueId);
- if (!userSocket) {
- this.debugLog('warn', `No socket found for source unique ID ${sourceUniqueId}`);
- break;
- }
- var username = this.usernames.get(nickname) || nickname;
- if (!this.channelData.get(channel).users.has(nickname)) {
- this.channelData.get(channel).users.add(nickname);
- }
- await this.broadcastChannelJoin(channel, userSocket);
- await this.broadcastToAllServers(`:${sourceUniqueId} JOIN ${channel}\r\n`, socket);
- break;
- case 'PART':
- var channel = this.findChannel(parts[2]);
- if (!channel) {
- this.debugLog('warn', `No channel found for PART command: ${parts[2]}`);
- break;
- }
- if (this.channelData.get(channel).ops.has(nickname)) {
- this.channelData.get(channel).ops.delete(nickname);
- }
- if (this.channelData.get(channel).halfops.has(nickname)) {
- this.channelData.get(channel).halfops.delete(nickname);
- }
- if (this.channelData.get(channel).voices.has(nickname)) {
- this.channelData.get(channel).voices.delete(nickname);
- }
-
- var username = this.usernames.get(nickname) || nickname;
- var hostname = this.hostnames.get(nickname);
- await this.broadcastChannel(channel, `:${nickname}!${username}@${hostname} PART ${channel} :${parts.slice(4).join(' ')}\r\n`, userSocket);
- if (this.channelData.has(channel) && this.channelData.get(channel).users.size === 0) {
- this.deleteChannel(channel);
- }
- await this.broadcastToAllServers(`:${sourceUniqueId} PART ${channel} :${parts.slice(4).join(' ')}\r\n`, socket);
- break;
- case 'GLOBOPS':
- var message = parts.slice(3).join(' ');
- await this.broadcastToAllServers(`:${sourceUniqueId} GLOBOPS :${message}`, socket);
- break;
- case 'TBURST':
- // Handle TBURST command from server
- if (parts.length < 6) {
- this.debugLog('warn', `Invalid TBURST command from server: ${line}`);
- break;
- }
- var channel = parts[3];
- var topic = parts.slice(6).join(' ');
- if (topic.startsWith(':')) {
- topic = topic.slice(1);
- }
- if (!this.channelData.has(channel)) {
- this.createChannel(channel);
- }
- this.channelData.get(channel).topic = topic;
- await this.broadcastChannel(channel, `:${nickname} TOPIC ${channel} :${topic}\r\n`);
- await this.broadcastToAllServers(`:${sourceUniqueId} TBURST ${channel} :${topic}\r\n`, socket);
- break;
- case 'KILL':
- // Handle KILL command from server
- if (parts.length < 3) {
- this.debugLog('warn', `Invalid KILL command from server: ${line}`);
- break;
- }
- var targetUniqueId = parts[2];
- var targetSocket = this.findSocketByUniqueId(targetUniqueId);
- var targetNickname = this.findUserByUniqueId(targetUniqueId);
- var sourceUsername = this.usernames.get(nickname) || nickname;
- var reason = parts.slice(3).join(' ');
- await this.safeWriteToSocket(targetSocket, `:${nickname}!${sourceUsername}@${socket.serverinfo.name} KILL ${targetNickname} :${reason}\r\n`);
- await this.broadcastUser(targetNickname, `:${nickname}!${sourceUsername}@${socket.serverinfo.name} KILL ${targetNickname} :${reason}\r\n`, targetSocket);
- await this.broadcastToAllServers(`:${sourceUniqueId} KILL ${targetUniqueId} :${reason}\r\n`, socket);
- await this.broadcastConnection(socket, `Killed: ${reason}`);
- this.terminateSession(targetSocket, true);
- break;
- case 'MODE':
- var targetUniqueId = parts[2];
- if (this.channelprefixes.some(prefix => targetUniqueId.startsWith(prefix))) {
- var targetChannel = this.findChannel(targetUniqueId)
- if (!targetChannel) {
- this.debugLog('warn', `No channel found for MODE command: ${line}`);
- break;
- }
- // It's a channel, broadcast to all users in the channel
- if (this.channelData.has(targetChannel)) {
- var modes = parts[3];
- await this.processChannelModes(nickname, targetChannel, modes, parts.slice(4), socket);
- }
- break;
- }
- var targetSocket = this.findSocketByUniqueId(targetUniqueId);
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for target unique ID ${targetUniqueId}`);
- break;
- }
- await this.safeWriteToSocket(targetSocket, `:${targetSocket.nickname} MODE ${targetSocket.nickname} ${parts.slice(2).join(' ')}\r\n`);
- if (this.clientIsWebTV(targetSocket) && this.enable_webtv_command_hacks) {
- await this.sendWebTVNoticeTo(targetSocket, `The network has set your user mode: ${parts.slice(3).join(' ')}`);
- }
- await this.broadcastToAllServers(`:${sourceUniqueId} MODE ${targetUniqueId} ${parts.slice(3).join(' ')}\r\n`, socket);
- break;
- case 'NICK':
- if (parts.length < 3) {
- this.debugLog('warn', 'Invalid NICK command from server');
- break;
- }
- var targetSocket = this.findSocketByUniqueId(sourceUniqueId);
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for source unique ID ${sourceUniqueId}`);
- break;
- }
- var oldNick = targetSocket.nickname;
- var newNick = parts[2];
-
- if (this.nicknames.has(newNick)) {
- await this.safeWriteToSocket(targetSocket, `:${this.servername} 433 ${oldNick} ${newNick} :Nickname is already in use\r\n`);
- break;
- }
- this.processNickChange(targetSocket, newNick);
- await this.broadcastUser(oldNick, `:${targetSocket.nickname}!${targetSocket.username}@${targetSocket.host} NICK :${newNick}\r\n`, targetSocket);
- await this.broadcastToAllServers(`:${sourceUniqueId} NICK ${newNick}\r\n`, socket);
- break;
- case 'TOPIC':
- if (parts.length < 3) {
- this.debugLog('warn', 'Invalid TOPIC command from server');
- break;
- }
- var channel = this.findChannel(parts[2]);
- if (!channel || !this.channelData.has(channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${nickname} ${channel} :No such channel\r\n`);
- break;
- }
- var topic = parts.slice(3).join(' ');
- if (topic.startsWith(':')) {
- topic = topic.slice(1); // Remove leading ':'
- }
- this.channelData.get(channel).topic = topic;
- var username = this.usernames.get(nickname) || nickname;
- var hostname = this.hostnames.get(nickname) || '';
- await this.broadcastChannel(channel, `:${nickname}!${username}@${hostname} TOPIC ${channel} :${topic}\r\n`, targetSocket);
- await this.broadcastToAllServers(`:${sourceUniqueId} TOPIC ${channel} :${topic}\r\n`, socket);
- break;
- case 'PRIVMSG':
- case 'NOTICE':
- var targetUniqueId = parts[2];
- var message = parts.slice(3).join(' ');
- if (message.startsWith(':')) {
- message = message.slice(1); // Remove leading ':'
- }
- var sourceSocket = this.findSocketByUniqueId(sourceUniqueId);
- if (!sourceSocket) {
- this.debugLog('warn', `No socket found for source unique ID ${sourceUniqueId}`);
- break;
- }
- var sourceUsername = this.usernames.get(nickname) || nickname;
- const host = this.hostnames.get(nickname) || socketSource.host;
- if (this.channelprefixes.some(prefix => targetUniqueId.startsWith(prefix))) {
- // It's a channel, broadcast to all users in the channel except the source
- if (this.channelData.has(targetUniqueId)) {
- const users = this.channelData.get(targetUniqueId).users;
- for (const user of users) {
- const userSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
- if (userSocket && userSocket.uniqueId !== sourceUniqueId) {
- const host = this.hostnames.get(user) || socketSource.host;
- await this.sendThrottled(userSocket, [`:${nickname}!${sourceUsername}@${host} ${srvCommand} ${targetUniqueId} :${message}\r\n`], 30);
- await this.broadcastToAllServers(`:${sourceUniqueId} ${srvCommand} ${targetUniqueId} :${message}\r\n`, socket);
- }
- }
- }
- break;
- }
- var targetSocket = this.findSocketByUniqueId(targetUniqueId);
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for target unique ID ${targetUniqueId}`);
- break;
- }
- var targetNickname = this.getUsernameFromUniqueId(targetUniqueId);
- if (message.startsWith(':')) {
- message = message.slice(1); // Remove leading ':'
- }
- if (this.clientIsWebTV(targetSocket)) {
- srvCommand = 'PRIVMSG';
- }
- await this.sendThrottled(targetSocket, [`:${nickname}!${sourceUsername}@${host} ${srvCommand} ${targetNickname} :${message}\r\n`], 30);
- await this.broadcastToAllServers(`:${sourceUniqueId} ${srvCommand} ${targetUniqueId} :${message}\r\n`, socket);
- break;
- case "WHOIS":
- if (parts.length < 3) {
- this.debugLog('warn', 'Invalid WHOIS command from server');
- break;
- }
- var targetUniqueId = parts[2];
- var targetSocket = this.findSocketByUniqueId(targetUniqueId);
- if (!targetSocket) {
- this.debugLog('warn', `No socket found for target unique ID ${targetUniqueId}`);
- break;
- }
- var targetUniqueId = parts[2];
- whoisNick = this.findUserByUniqueId(targetUniqueId);
- if (!whoisNick) {
- whoisNick = parts[3].slice(1); // Remove leading ':'
- }
- const whoisSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s).toLowerCase() === whoisNick.toLowerCase());
- if (whoisSocket) {
- whoisNick = whoisSocket.nickname;
- const whois_username = this.usernames.get(whoisNick);
- var userinfo = this.userinfo.get(whoisNick) || whoisSocket.userinfo || '';
- output_lines = [];
- output_lines.push(`:${this.serverId} 311 ${targetUniqueId} ${whoisNick} ${whois_username} ${whoisSocket.host} * :${userinfo}\r\n`);
- if (this.awaymsgs.has(whoisNick)) {
- output_lines.push(`:${this.serverId} 301 ${targetUniqueId} ${whoisNick} :${this.awaymsgs.get(whoisNick)}\r\n`);
- }
- const userChannels = [];
- for (const [ch, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(whoisNick)) {
- let prefix = '';
- var chanops = this.channelData.get(ch).ops;
- var chanhalfops = this.channelData.get(ch).halfops;
- var chanvoices = this.channelData.get(ch).voices;
- const modes = this.channelData.get(ch).modes;
- if ((modes.includes('p') || modes.includes('s')) && (!this.channelData.has(ch) || !this.channelData.get(ch).users.has(socket.nickname))) {
- continue; // Skip listing this channel if it's private/secret and user is not in it
- }
- if (chanops.has(whoisNick)) {
- prefix = '@';
- } else if (chanhalfops.has(whoisNick)) {
- prefix = '%';
- } else if (chanvoices.has(whoisNick)) {
- prefix = '+';
- }
- userChannels.push(prefix + ch);
- }
- }
- output_lines.push(`:${this.serverId} 312 ${targetUniqueId} ${whoisNick} ${this.servername} :zefIRCd v${this.version}\r\n`);
- if (this.isIRCOp(whoisNick)) {
- output_lines.push(`:${this.serverId} 313 ${targetUniqueId} ${whoisNick} :is an IRC operator\r\n`);
- }
- if (usermodes && this.getUserModes(whoisNick).includes('s')) {
- output_lines.push(`:${this.serverId} 671 ${targetUniqueId} ${whoisNick} :is using a secure connection\r\n`);
- }
- if (usermodes && this.getUserModes(whoisNick).includes('r')) {
- output_lines.push(`:${this.serverId} 307 ${targetUniqueId} ${whoisNick} :is a registered nick\r\n`);
- }
- var now = this.getDate();
- var userTimestamp = whoisSocket.lastspoke || now;
- var idleTime = now - userTimestamp;
- output_lines.push(`:${this.serverId} 317 ${targetUniqueId} ${whoisNick} ${idleTime} ${this.usersignontimestamps.get(whoisNick) || 0} :seconds idle, signon time\r\n`);
- if (userChannels.length > 0) {
- output_lines.push(`:${this.serverId} 319 ${targetUniqueId} ${whoisNick} :${userChannels.join(' ')}\r\n`);
- }
- output_lines.push(`:${this.serverId} 318 ${targetUniqueId} ${whoisNick} :End of /WHOIS list\r\n`);
- await this.sendThrottled(socket, output_lines);
- }
- break;
- case "SVSJOIN":
- if (parts.length < 3) {
- this.debugLog('warn', 'Invalid SVSJOIN command from server');
- break;
- }
- var targetUniqueId = parts[2];
- var channelName = this.findChannel(parts[3]);
- var targetSocket = this.findSocketByUniqueId(targetUniqueId);
- var username = this.usernames.get(targetSocket.nickname) || socket.nickname;
- var hostname = this.hostnames.get(targetSocket.nickname) || '';
- if (!channelName ||!this.channelData.has(channelName)) {
- channelName = parts[3];
- this.createChannel(channelName);
- }
- if (!this.channelData.get(channelName).users.has(targetSocket.nickname)) {
- this.channelData.get(channelName).users.add(targetSocket.nickname);
- }
- await this.broadcastChannelJoin(channelName, targetSocket);
- //this.broadcastToAllServers(`:${sourceUniqueId} SVSJOIN ${channelName} ${targetUniqueId}\r\n`, socket);
- var chan_modes = this.channelData.get(channelName).modes;
- let modeString = '';
- let modeParams = [];
- for (const m of chan_modes) {
- if (m === 'k' && this.channelData.get(channelName).key) {
- modeString += 'k';
- modeParams.push(this.channelData.get(channelName).key);
- } else if (m === 'l' && this.channelData.get(channelName).limit) {
- modeString += 'l';
- modeParams.push(this.channelData.get(channelName).limit);
- } else if (typeof m === 'string' && m.length === 1 && m !== 'k' && m !== 'l') {
- modeString += m;
- }
- }
- if (modeString.length > 0) {
- await this.safeWriteToSocket(targetSocket, `:${this.servername} 324 ${nickname} ${channelName} +${modeString}${modeParams.length ? ' ' + modeParams.join(' ') : ''}\r\n`);
- }
- await this.broadcastToAllServers(`:${this.serverId} SJOIN ${this.getDate()} ${channelName} +${modeString}${modeParams.length ? ' ' + modeParams.join(' ') : ''} ${targetUniqueId}\r\n`);
- break;
- case "SVSMODE":
- if (parts.length < 4) {
- this.debugLog('warn', 'Invalid SVSMODE command from server');
- break;
- }
- var targetUniqueId = parts[2];
- var targetSocket = this.findSocketByUniqueId(targetUniqueId);
- var targetNickname = targetSocket.nickname;
- var modes = parts[4].split('');
- let adding = true;
- for (const char of modes.join('')) {
- if (char === '+') {
- adding = true;
- } else if (char === '-') {
- adding = false;
- } else {
- if (adding) {
- this.setUserMode(targetNickname, char, true);
- } else {
- this.setUserMode(targetNickname, char, false);
- }
- }
- }
- var username = this.usernames.get(nickname);
- var hostname = this.hostnames.get(nickname);
- await this.safeWriteToSocket(targetSocket, `:${nickname}!${username}@${hostname} MODE ${targetSocket.nickname} ${modes.join('')}\r\n`);
- await this.broadcastToAllServers(`:${sourceUniqueId} SVSMODE ${targetUniqueId} ${modes.join('')}\r\n`, socket);
- break;
- default:
- if (!this.checkRegistered(socket)) {
- break;
- }
- this.debugLog('warn', `Unhandled server command from ${sourceUniqueId} to ${targetUniqueId}: ${srvCommand} ${message}`);
- }
- }
- }
- }
-
- async processSocketData(socket, data) {
- var output_lines = []; // Declare once at function scope
-
- if (socket.signedoff) {
- return;
- }
- if (socket.upgrading_to_tls) {
- socket.removeAllListeners()
- socket.pause();
- socket.on('error', (err) => {
- this.debugLog('error', 'Error during TLS upgrade: ' + err.message);
- this.terminateSession(socket, true);
- });
-
- if (Buffer.isBuffer(data) ? data[0] === 0x16 : data.charCodeAt(0) === 0x16) {
- if (!this.enable_tls) {
- // If SSL is not enabled, close the socket
- await this.safeWriteToSocket(socket, `:${this.servername} 421 * :TLS is not enabled on this server\r\n`);
- this.terminateSession(socket, true);
- return;
- }
-
- // SSL detected, upgrade socket to TLS
- const keyBuffer = fs.readFileSync(this.wtvshared.parseConfigVars(this.irc_config.ssl_cert.key));
- const certBuffer = fs.readFileSync(this.wtvshared.parseConfigVars(this.irc_config.ssl_cert.cert));
- // Remove from this.clients if present
-
- this.clients = this.clients.filter(c => c !== socket);
- const secureSocket = new tls.TLSSocket(socket, {
- isServer: true,
- ALPNProtocols: ['irc'],
- secureContext: tls.createSecureContext({
- key: keyBuffer,
- cert: certBuffer,
- }),
- });
- socket.push(data);
-
- secureSocket.on('error', (err) => {
- this.terminateSession(secureSocket, true);
- });
-
- secureSocket.on('close', () => {
- this.terminateSession(secureSocket, false);
- });
-
- // Only start processing after handshake is complete
- secureSocket.on('secure', async () => {
- this.debugLog('info', 'Secure connection (STARTTLS) established with '+ socket.remoteAddress);
- socket.removeAllListeners('error');
- await this.initializeSocket(secureSocket, true, socket);
- // Remove the original socket from clients
- this.clients = this.clients.filter(c => c !== socket);
- this.clientpeak = Math.max(this.clientpeak, this.clients.length);
- });
- secureSocket.resume();
- } else {
- socket.resume();
- await this.safeWriteToSocket(socket, `:${this.servername} 421 * :Invalid TLS handshake\r\n`);
- this.terminateSession(socket, true);
- }
- socket.upgrading_to_tls = false;
- return;
- }
- // Ensure data is a string
- if (typeof data !== 'string') {
- if (Buffer.isBuffer(data)) {
- data = data.toString('ascii');
- } else if (data && typeof data.toString === 'function') {
- data = data.toString();
- } else {
- return; // Invalid data, ignore
- }
- }
- const lines = data.split(/\r\n|\n/).filter(Boolean);
- for (let line of lines) {
- if (this.debug) {
- console.log(`> ${line}`);
- }
-
- // Rate limiting check for non-server connections
- if (!socket.isserver && !this.checkRateLimit(socket)) {
- this.debugLog('warn', `Rate limit exceeded for ${socket.remoteAddress}, disconnecting`);
- this.logSecurityEvent('RATE_LIMIT_EXCEEDED', socket, { limit: this.max_messages_per_second });
- await this.safeWriteToSocket(socket, `:${this.servername} ERROR :Rate limit exceeded\r\n`);
- this.terminateSession(socket, true);
- return;
- }
-
- if (socket.isserver) {
- await this.processServerData(socket, line);
- continue;
- }
- // Check for server prefix (e.g., :00B) and extract command
- let prefix = null;
- if (line.startsWith(':')) {
- const spaceIdx = line.indexOf(' ');
-
- if (spaceIdx > 0) {
- prefix = line.slice(1, spaceIdx);
- if (!socket.uniqueId) {
- socket.uniqueId = prefix;
- } else if (socket.uniqueId !== prefix) {
- if (!socket.isserver) {
- socket.uniqueId = prefix;
- } else {
- this.debugLog('warn', `Socket uniqueId mismatch: ${socket.uniqueId} !== ${prefix}`);
- this.debugLog('warn', line);
- continue;
- }
- }
- }
- this.processServerData(socket, line);
- continue;
- }
-
- // initial commands before we assign socket.isserver = true
- const serverCommands = ['PASS', 'CAPAB', 'SERVER', 'SVINFO'];
- const firstWord = line.trim().split(' ')[0].toUpperCase();
- if (!prefix && serverCommands.includes(firstWord)) {
- this.processServerData(socket, line);
- continue;
- }
-
-
- const [command, ...params] = line.trim().split(' ');
-
- // Validate command and parameters
- if (!this.validateCommand(command.toUpperCase(), params)) {
- this.logSecurityEvent('INVALID_COMMAND', socket, { command, params });
- await this.safeWriteToSocket(socket, `:${this.servername} 421 ${socket.nickname || '*'} ${command} :Unknown command\r\n`);
- continue;
- }
-
- switch (command.toUpperCase()) {
- case 'OPER':
- if (!socket.secure) {
- await this.safeWriteToSocket(socket, `:${this.servername} 464 ${socket.nickname} :SSL required for OPER\r\n`);
- }
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.checkAuthAttempts(socket)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 491 ${socket.nickname} :Too many failed attempts. Try again later.\r\n`);
- this.logSecurityEvent('OPER_LOCKOUT', socket, { attempts: this.failed_auth_attempts.get(socket.realhost || socket.remoteAddress) });
- break;
- }
- if (!this.oper_enabled) {
- await this.safeWriteToSocket(socket, `:${this.servername} 491 ${socket.nickname} :This server does not support IRC operators\r\n`);
- break;
- }
- if (params.length < 2) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} OPER :Not enough parameters\r\n`);
- break;
- }
- const [operName, operPassword] = params;
- if (operName !== this.oper_username) {
- await this.safeWriteToSocket(socket, `:${this.servername} 491 ${socket.nickname} :No permission\r\n`);
- this.debugLog('warn', `Invalid oper name attempt: ${operName} from ${socket.nickname} (${socket.username}@${socket.realhost})`);
- this.logSecurityEvent('OPER_FAILED_USERNAME', socket, { provided_username: operName });
- this.recordAuthFailure(socket);
- break;
- }
- // Use timing-safe comparison to prevent timing attacks
- const providedPassword = Buffer.from(operPassword, 'utf8');
- const actualPassword = Buffer.from(this.oper_password, 'utf8');
- const passwordMatch = providedPassword.length === actualPassword.length &&
- require('crypto').timingSafeEqual(providedPassword, actualPassword);
-
- if (!passwordMatch) {
- await this.safeWriteToSocket(socket, `:${this.servername} 464 ${socket.nickname} :Password incorrect\r\n`);
- this.debugLog('warn', `Invalid oper password attempt from ${socket.nickname} (${socket.username}@${socket.realhost}) (using oper name ${operName})`);
- this.logSecurityEvent('OPER_FAILED_PASSWORD', socket, { username: operName });
- this.recordAuthFailure(socket);
- break;
- }
- this.clearAuthFailures(socket);
- this.logSecurityEvent('OPER_SUCCESS', socket, { username: operName });
- this.setUserMode(socket.nickname, 'o', true);
- await this.safeWriteToSocket(socket, `:${this.servername} 381 ${socket.nickname} :You are now an IRC operator\r\n`);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +o\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +o\r\n`);
- this.debugLog('info', `IRC operator ${socket.nickname} (${socket.username}@${socket.realhost}) has logged in with oper name ${operName}`);
- break;
- case 'UPTIME':
- if (!this.checkRegistered(socket)) {
- break;
- }
- const uptime = this.getDate() - this.server_start_time;
- const days = Math.floor(uptime / 86400);
- const hours = Math.floor((uptime % 86400) / 3600);
- const minutes = Math.floor((uptime % 3600) / 60);
- const seconds = uptime % 60;
- await this.safeWriteToSocket(socket, `:${this.servername} 242 ${socket.nickname} :Server uptime is ${days} days, ${hours} hours, ${minutes} minutes, ${seconds} seconds\r\n`);
- break;
- case 'SECURITY':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- break;
- }
-
- // Show security statistics
- let output_lines = [];
- output_lines.push(`:${this.servername} NOTICE ${socket.nickname} :=== Security Report ===\r\n`);
- output_lines.push(`:${this.servername} NOTICE ${socket.nickname} :Active connections per IP: ${this.connections_per_ip.size}\r\n`);
- output_lines.push(`:${this.servername} NOTICE ${socket.nickname} :Failed auth attempts tracked: ${this.failed_auth_attempts.size}\r\n`);
- output_lines.push(`:${this.servername} NOTICE ${socket.nickname} :Security events logged: ${this.security_events.length}\r\n`);
- output_lines.push(`:${this.servername} NOTICE ${socket.nickname} :Rate limit violations: ${this.security_events.filter(e => e.event === 'RATE_LIMIT_EXCEEDED').length}\r\n`);
- output_lines.push(`:${this.servername} NOTICE ${socket.nickname} :=== End Report ===\r\n`);
-
- await this.sendThrottled(socket, output_lines);
- break;
- case 'KICK':
- if (!this.checkRegistered(socket)) {
- break;
- }
- var channel = this.findChannel(params[0]);
- var targetNick = this.findUser(params[1]);
- if (!channel || !targetNick) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${params[1]} :No such nick/channel\r\n`);
- break;
- }
- // Check if the user is a channel operator
- if (this.channelData.get(channel).ops instanceof Set && this.channelData.get(channel).ops.has(socket.nickname)) {
- // Allow kick
- } else if (this.channelData.get(channel).halfops instanceof Set && this.channelData.get(channel).halfops.has(socket.nickname)) {
- // Only allow kick if the target is NOT a channel operator
- if (this.channelData.get(channel).ops instanceof Set && this.channelData.get(channel).ops.has(targetNick)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${socket.nickname} ${channel} :You cannot kick a channel operator\r\n`);
- break;
- }
- // Allow kick
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${socket.nickname} ${channel} :You're not channel operator\r\n`);
- break;
- }
- if (params.length < 2) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} KICK :Not enough parameters\r\n`);
- break;
- }
- socket.lastspoke = this.getDate();
-
-
- if (!this.channelData.has(channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${channel} :No such channel\r\n`);
- break;
- }
- if (!this.channelData.get(channel).users.has(targetNick)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 441 ${socket.nickname} ${targetNick} :They aren't on that channel\r\n`);
- break;
- }
- // Check if channel mode +Q (no kicks) is set
- var chan_modes = this.channelData.get(channel).modes;
- if (chan_modes.includes('Q')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${socket.nickname} ${channel} :Cannot kick users, channel is +Q (no kicks allowed)\r\n`);
- break;
- }
- this.channelData.get(channel).users.delete(targetNick);
- var targetSocket = Array.from(this.clients).find(s => this.nicknames.get(s) === targetNick);
- if (params.length > 2) {
- let reason = params.slice(2).join(' ');
- if (reason.startsWith(':')) {
- reason = reason.slice(1);
- }
- await this.safeWriteToSocket(targetSocket, `:${socket.nickname}!${socket.username}@${socket.host} KICK ${channel} ${targetNick} :${reason}\r\n`);
- await this.broadcastChannel(channel, `:${socket.nickname}!${socket.username}@${socket.host} KICK ${channel} ${targetNick} :${reason}\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} KICK ${channel} ${targetSocket.uniqueId} :${reason}\r\n`);
- break;
- } else {
- await this.safeWriteToSocket(targetSocket, `:${socket.nickname}!${socket.username}@${socket.host} KICK ${channel} ${targetNick}\r\n`);
- await this.broadcastChannel(channel, `:${socket.nickname}!${socket.username}@${socket.host} KICK ${channel} ${targetNick}\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} KICK ${channel} ${targetSocket.uniqueId}\r\n`);
- }
- break;
- case 'TOPIC':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} TOPIC :Not enough parameters\r\n`);
- break;
- }
- var channel = this.findChannel(params[0]);
- if (!channel) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${params[0]} :No such channel\r\n`);
- break;
- }
- var chan_modes = this.channelData.get(channel).modes;
- if (chan_modes.includes('t')) {
- if (this.channelData.get(channel).ops instanceof Set && this.channelData.get(channel).ops.has(socket.nickname)) {
- // Allow topic
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${socket.nickname} ${channel} :You're not channel operator\r\n`);
- break;
- }
- }
- socket.lastspoke = this.getDate();
- if (!this.channelData.has(channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${channel} :No such channel\r\n`);
- break;
- }
- if (params.length > 1) {
- var topic = params.slice(1).join(' ');
- if (topic.startsWith(':')) {
- topic = topic.slice(1);
- }
- this.channelData.get(channel).topic = topic;
- await this.safeWriteToSocket(socket, `:${this.servername} 332 ${socket.nickname} ${channel} :${topic}\r\n`);
- await this.broadcastChannel(channel, `:${socket.nickname}!${socket.username}@${socket.host} TOPIC ${channel} :${topic}\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} TOPIC ${channel} :${topic}\r\n`);
- } else {
- const topic = this.channelData.get(channel).topic;
- await this.safeWriteToSocket(socket, `:${this.servername} 331 ${socket.nickname} ${channel} :${topic}\r\n`);
- }
- break;
- case 'AWAY':
- if (!this.checkRegistered(socket)) {
- break;
- }
- socket.lastspoke = this.getDate();
- if (params.length > 0) {
- if (params.length > this.awaylen) {
- await this.safeWriteToSocket(socket, `:${this.servername} 417 ${socket.nickname} ${channel} :Away message is too long\r\n`);
- break;
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 306 ${socket.nickname} :You are now marked as away\r\n`);
- let awayMsg = params.join(' ');
- if (awayMsg.startsWith(':')) {
- awayMsg = awayMsg.slice(1);
- }
- this.awaymsgs.set(socket.nickname, awayMsg);
- await this.broadcastUserIfCap(socket, `:${socket.nickname}!${socket.username}@${socket.host} AWAY :${awayMsg}\r\n`, socket, 'away-notify');
- await this.broadcastToAllServers(`:${socket.uniqueId} AWAY :${awayMsg}\r\n`);
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} 305 ${socket.nickname} :You are no longer marked as away\r\n`);
- this.awaymsgs.delete(socket.nickname);
- await this.broadcastUserIfCap(socket, `:${socket.nickname}!${socket.username}@${socket.host} AWAY\r\n`, socket, 'away-notify');
- await this.broadcastToAllServers(`:${socket.uniqueId} AWAY\r\n`);
- }
- break;
- case 'CAP':
- // Attempt to map any client caps with our supported caps
- if (params[0] && params[0].toUpperCase() === 'LS') {
- const capsString = this.supported_client_caps.map(cap => cap.toLowerCase()).join(' ');
- await this.safeWriteToSocket(socket, `:${this.servername} CAP ${socket.uniqueId} LS :${capsString}\r\n`);
- }
- if (params[0] && params[0].toUpperCase() === 'REQ') {
- socket.client_caps = params.slice(1).map(cap => {
- if (cap.startsWith(':')) {
- return cap.slice(1).toLowerCase();
- }
- return cap.toLowerCase();
- });
- var supportedCaps = this.supported_client_caps.filter(cap => socket.client_caps.includes(cap.toLowerCase()));
- if (params.length > 1) {
- // params[1] is the first cap, may be prefixed with ':'
- // Remove ':' from first cap if present
- let reqCaps = params.slice(1).map(cap => cap.startsWith(':') ? cap.slice(1).toLowerCase() : cap.toLowerCase());
- // Only include supported caps, in the order requested
- supportedCaps = reqCaps.filter(cap => this.supported_client_caps.includes(cap));
- }
- await this.safeWriteToSocket(socket, `:${this.servername} CAP ${socket.uniqueId} ACK :${supportedCaps.join(' ').toLowerCase()}\r\n`);
- this.debugLog('info', `Client with uniqueId ${socket.uniqueId} requested capabilities: ${supportedCaps.join(', ')}`);
- }
- break;
- case 'MODE':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} MODE :Not enough parameters\r\n`);
- break;
- }
- var isChannel = true;
- channel = this.findChannel(params[0]);
- if (!channel) {
- isChannel = false;
- channel = this.findUser(params[0]);
- }
- if (!channel) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${params[0]} :No such nick/channel\r\n`);
- break;
- }
- if (!this.channelData.has(channel)) {
- isChannel = false;
- }
- // Check if 'channel' is actually a user (nickname) instead of a channel name
- let isUser = false;
- for (const prefix of this.channelprefixes) {
- if (channel.startsWith(prefix)) {
- isUser = false;
- break;
- } else {
- isUser = true;
- }
- }
- if (!isChannel && !isUser) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${channel} :No such channel or user\r\n`);
- break;
- }
- const mode = params[1];
- if (isUser) {
- // User mode handling
- if (!this.isIRCOp(socket.nickname) && channel !== socket.nickname) {
- await this.safeWriteToSocket(socket, `:${this.servername} 502 ${socket.nickname} :Cannot set modes on other users\r\n`);
- } else {
-
- var usermodes = this.getUserModes(channel);
- if (!mode) {
- // List user modes
- if (usermodes.length === 0) {
- await this.safeWriteToSocket(socket, `:${this.servername} 324 ${socket.nickname} ${channel} :No modes set\r\n`);
- } else {
- const modes = usermodes.map(m => (m.startsWith('+') ? m : '+' + m)).join(' ');
- await this.safeWriteToSocket(socket, `:${this.servername} 324 ${socket.nickname} ${channel} :${modes}\r\n`);
- }
- } else if (mode.startsWith('+x')) {
- if (usermodes.includes('x')) {
- break;
- }
- this.setUserMode(socket.nickname, 'x', true);
- socket.host = this.filterHostname(socket, socket.realhost);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +x\r\n`);
- if (socket.client_caps && socket.client_caps.includes('CHGHOST')) {
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} CHGHOST ${socket.username} ${socket.host}\r\n`);
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 396 ${socket.nickname} ${socket.host} :is now your visible host\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +x\r\n`);
- } else if (mode.startsWith('-x')) {
- if (!usermodes.includes('x')) {
- break;
- }
- this.setUserMode(socket.nickname, 'x', false);
- socket.host = socket.realhost
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -x\r\n`);
- if (socket.client_caps && socket.client_caps.includes('CHGHOST')) {
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} CHGHOST ${socket.username} ${socket.host}\r\n`);
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 396 ${socket.nickname} ${socket.host} :is now your visible host\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -x\r\n`);
- } else if (mode.startsWith('+w')) {
- if (usermodes.includes('w')) {
- break;
- }
- this.setUserMode(socket.nickname, 'w', true);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +w\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +w\r\n`);
- } else if (mode.startsWith('-w')) {
- if (!usermodes.includes('w')) {
- break;
- }
- this.setUserMode(socket.nickname, 'w', false);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -w\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -w\r\n`);
- } else if (mode.startsWith('+c')) {
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `User ${socket.nickname} attempted to set +c mode without being an IRC operator`);
- break;
- }
- if (usermodes.includes('c')) {
- break;
- }
- this.setUserMode(socket.nickname, 'c', true);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +c\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +c\r\n`);
- } else if (mode.startsWith('-c')) {
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `User ${socket.nickname} attempted to unset +c mode without being an IRC operator`);
- break;
- }
- if (!usermodes.includes('c')) {
- break;
- }
- this.setUserMode(socket.nickname, 'c', false);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -c\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -c\r\n`);
- } else if (mode.startsWith('+i')) {
- if (usermodes.includes('i')) {
- break;
- }
- this.setUserMode(socket.nickname, 'i', true);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +i\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +i\r\n`);
- } else if (mode.startsWith('-i')) {
- if (!usermodes.includes('i')) {
- break;
- }
- this.setUserMode(socket.nickname, 'i', false);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -i\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -i\r\n`);
- } else if (mode.startsWith('+s')) {
- if (usermodes.includes('s')) {
- break;
- }
- this.setUserMode(socket.nickname, 's', true);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +s\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +s\r\n`);
- } else if (mode.startsWith('-s')) {
- if (!usermodes.includes('s')) {
- break;
- }
- this.setUserMode(socket.nickname, 's', false);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -s\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -s\r\n`);
- } else if (mode.startsWith('+B')) {
- if (usermodes.includes('B')) {
- break;
- }
- this.setUserMode(socket.nickname, 'B', true);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +B\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +B\r\n`);
- } else if (mode.startsWith('-B')) {
- if (!usermodes.includes('B')) {
- break;
- }
- this.setUserMode(socket.nickname, 'B', false);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -B\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -B\r\n`);
- } else if (mode.startsWith('+R')) {
- if (usermodes.includes('R')) {
- break;
- }
- this.setUserMode(socket.nickname, 'R', true);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +R\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +R\r\n`);
- } else if (mode.startsWith('-R')) {
- if (!usermodes.includes('R')) {
- break;
- }
- this.setUserMode(socket.nickname, 'R', false);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -R\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -R\r\n`);
- } else if (mode.startsWith('+z') || mode.startsWith('-z')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 472 ${socket.nickname} ${mode.slice(1)} :is set by the server and cannot be changed\r\n`);
- } else if (mode.startsWith('+r') || mode.startsWith('-r')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 472 ${socket.nickname} ${mode.slice(1)} :is set by the server and cannot be changed\r\n`);
- } else if (mode.startsWith('+Z')) {
- if (!socket.secure) {
- await this.safeWriteToSocket(socket, `:${this.servername} 472 ${socket.nickname} ${mode.slice(1)} :You must be secure to set this mode\r\n`);
- break;
- }
- if (usermodes.includes('Z')) {
- break;
- }
- this.setUserMode(socket.nickname, 'Z', true);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} +Z\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} +Z\r\n`);
- } else if (mode.startsWith('-Z')) {
- if (!socket.secure) {
- await this.safeWriteToSocket(socket, `:${this.servername} 472 ${socket.nickname} ${mode.slice(1)} :You must be secure to set this mode\r\n`);
- break;
- }
- if (!usermodes.includes('Z')) {
- break;
- }
- this.setUserMode(socket.nickname, 'Z', false);
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${socket.nickname} -Z\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} MODE ${socket.uniqueId} -Z\r\n`);
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} 472 ${socket.nickname} ${mode.slice(1)} :is unknown mode char to me\r\n`);
- }
- }
- break;
- }
- if (!mode) {
- // List channel modes
- if (!this.checkRegistered(socket)) {
- break;
- }
- let validPrefix = this.channelprefixes.some(prefix => channel.startsWith(prefix));
- if (!validPrefix) {
- await this.safeWriteToSocket(socket, `:${this.servername} 476 ${socket.nickname} ${channel} :Bad channel mask\r\n`);
- break;
- }
- if (!this.channelData.has(channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${channel} :No such channel\r\n`);
- break;
- }
- var chan_modes = this.channelData.get(channel).modes;
-
- chan_modes = chan_modes.map(mode => {
- if (typeof mode === 'string' && !mode.startsWith('+')) {
- return '+' + mode;
- }
- return mode;
- });
- if (chan_modes.length > 0) {
- var params2 = [];
- // Batch all modes into a single 324 reply
- var modeString =
- chan_modes.map(m => {
- // For modes with parameters (like k or l)
- if (typeof m === 'string' && (m === '+k' || m === '+l')) {
- if (m === '+l') {
- params2.push(this.channelData.get(channel).limit);
- } else if (m === '+k') {
- params2.push(this.channelData.get(channel).key);
- }
- return m.replace(/^\+/, '');
- }
- return m.replace(/^\+/, ''); // Remove leading '+' for other modes
- })
- .join('');
- params2.forEach(param => {
- if (param) {
- modeString += ` ${param}`;
- }
- });
- await this.safeWriteToSocket(socket, `:${this.servername} 324 ${socket.nickname} ${channel} +${modeString}\r\n`);
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} 324 ${socket.nickname} ${channel}\r\n`);
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 329 ${socket.nickname} ${channel} ${this.channelData.get(channel).timestamp || M}\r\n`);
- break;
- } else {
- // Process channel mode changes
- await this.processChannelModes(socket.nickname, channel, mode, params.slice(2), socket);
- break;
- }
- case 'NICK':
- var old_nickname = socket.nickname;
- var new_nickname = params[0];
- if (new_nickname && new_nickname.startsWith(':')) {
- new_nickname = new_nickname.slice(1);
- }
- if (!new_nickname || new_nickname.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 431 * :No nickname\r\n`);
- break;
- }
-
- // Sanitize nickname input
- const sanitized_nickname = this.sanitizeInput(new_nickname, 'nickname');
- if (sanitized_nickname !== new_nickname || sanitized_nickname.length === 0) {
- await this.safeWriteToSocket(socket, `:${this.servername} 432 * ${new_nickname} :Erroneus nickname (invalid characters)\r\n`);
- this.logSecurityEvent('INVALID_NICKNAME', socket, { provided: new_nickname, sanitized: sanitized_nickname });
- break;
- }
- new_nickname = sanitized_nickname;
-
- if (new_nickname.length > this.nicklen) {
- await this.safeWriteToSocket(socket, `:${this.servername} 432 * ${new_nickname} :Erroneus nickname (too long)\r\n`);
- break;
- }
- if (this.findUser(new_nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 433 * ${new_nickname} :Nickname is already in use\r\n`);
- break;
- }
- for (const prefix of this.channelprefixes) {
- if (new_nickname.startsWith(prefix)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 432 * ${new_nickname} :Erroneus nickname (you are not a channel)\r\n`);
- return;
- }
- }
- for (let i = 0; i < new_nickname.length; i++) {
- if (!this.allowed_nick_characters.includes(new_nickname[i])) {
- await this.safeWriteToSocket(socket, `:${this.servername} 432 * ${new_nickname} :Erroneus nickname (invalid character)\r\n`);
- return;
- }
- }
- if (this.reservednicks && Array.isArray(this.reservednicks)) {
- if (this.reservednicks.some(nick => nick.toLowerCase() === new_nickname.toLowerCase())) {
- await this.safeWriteToSocket(socket, `:${this.servername} 432 * ${new_nickname} :This nickname is reserved\r\n`);
- break;
- }
- }
- // Prevent nick change if user is in any channel with +N mode
- let inNoNickChangeChannel = false;
- for (const [ch, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(socket.nickname)) {
- const chanModes = this.channelData.get(ch).modes;
- if (chanModes.includes('N')) {
- inNoNickChangeChannel = true;
- break;
- }
- }
- }
- if (inNoNickChangeChannel) {
- await this.safeWriteToSocket(socket, `:${this.servername} 447 * :You cannot change your nickname while in a +N (no nick change) channel\r\n`);
- break;
- }
-
- if (!socket.nickname) {
- // If no nickname is set, set it now
- socket.nickname = new_nickname;
- this.nicknames.set(socket, socket.nickname);
- } else if (socket.nickname != new_nickname) {
- this.processNickChange(socket, new_nickname);
- if (socket.registered) {
- await this.safeWriteToSocket(socket, `:${old_nickname}!${socket.username}@${socket.host} NICK :${new_nickname}\r\n`);
- await this.broadcastUser(socket.nickname, `:${old_nickname}!${socket.username}@${socket.host} NICK :${new_nickname}\r\n`, socket);
- await this.broadcastToAllServers(`:${socket.uniqueId} NICK ${new_nickname} :${this.getDate()}\r\n`);
- }
- }
- if (!socket.registered && socket.nickname && socket.username) {
- var totalSockets = this.clients.length + this.servers.size;
- var totalSockets = this.clients.length + this.servers.size;
- this.socketpeak = Math.max(this.socketpeak, totalSockets);
- this.usernames.set(socket.nickname, socket.username);
- socket.lastspoke = this.getDate();
- this.usersignontimestamps.set(socket.nickname, socket.timestamp);
- this.doLogin(socket.nickname, socket);
- }
- break;
- case 'USER':
- if (params.length < 4) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} USER :Not enough parameters\r\n`);
- this.addSocketError(socket);
- break;
- }
- socket.username = params[0];
- socket.userinfo = params.slice(3).join(' ').replace(/^:/, '');
- if (!socket.registered && socket.nickname && socket.username) {
- var totalSockets = this.clients.length + this.servers.size;
- this.socketpeak = Math.max(this.socketpeak, totalSockets);
- this.usernames.set(socket.nickname, socket.username);
- socket.lastspoke = this.getDate();
- this.usersignontimestamps.set(socket.nickname, socket.timestamp);
- this.doLogin(socket.nickname, socket);
- }
- break;
- case 'JOIN':
- var key = null;
- if (!this.checkRegistered(socket)) {
- break;
- }
- channel = params[0];
- if (params.length == 2) {
- key = params[1];
- }
- if (channel.includes(',')) {
- var channels = channel.split(',');
- } else {
- var channels = [channel];
- }
- for (var ch of channels) {
- // Simulate a JOIN command for each channel
- for (let i = 0; i < ch.length; i++) {
- if (i == 0 && !this.channelprefixes.includes(ch[0])) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${ch} :No such channel\r\n`);
- return;
- }
- if (this.channelprefixes.includes(ch[1])) {
- ch = ch.slice(1); // Remove double prefix
- }
- for (let j = 0; j < ch.slice(1).length; j++) {
- if (!this.allowed_chan_characters.includes(ch.slice(1)[j])) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${ch} :No such channel\r\n`);
- return;
- }
- }
- }
- if (this.getUserChannelCount(socket.nickname) >= this.channellimit) {
- await this.safeWriteToSocket(socket, `:${this.servername} 405 ${socket.nickname} ${ch} :Too many channels\r\n`);
- continue; // Skip joining this channel
- }
- var validChannel = false;
- this.channelprefixes.forEach(prefix => {
- if (ch.startsWith(prefix)) {
- validChannel = true;
- }
- });
- if (!validChannel) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${ch} :No such channel\r\n`);
- continue; // Skip this channel
- }
- if (ch.length < 2 || ch.length > this.channellen) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${ch} :No such channel\r\n`);
- continue; // Skip this channel
- }
- let foundChannel = null;
- for (const existingChannel of this.channelData.keys()) {
- if (existingChannel.toLowerCase() === ch.toLowerCase()) {
- foundChannel = existingChannel;
- break;
- }
- }
- if (foundChannel) {
- ch = foundChannel;
- } else {
- this.createChannel(ch, socket.nickname);
- }
-
- var joinLine = '';
- if (key) {
- joinLine = `JOIN ${ch} ${key}`;
- } else {
- joinLine = `JOIN ${ch}`;
- }
- const [command, ...params] = joinLine.trim().split(' ');
-
- const chmodes = this.channelData.get(ch).modes;
- if (this.isBanned(ch, socket)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 474 ${socket.nickname} ${ch} :Cannot join channel (+b)\r\n`);
- continue; // Skip joining this channel
- }
- // Check if the user is in too many channels
- if (chmodes.includes('k')) {
- const channelKey = this.channelData.get(ch).key;
- // The key must be provided as the second parameter in the JOIN command
- // params[1] is the key for the first channel, params[2] for the second, etc.
- // For simplicity, assume only one channel per JOIN or the key is always params[1]
- const providedKey = params[1];
- if (!providedKey || providedKey !== channelKey) {
- var code = (this.clientIsWebTV(socket) ? 474 : 475);
- await this.safeWriteToSocket(socket, `:${this.servername} ${code} ${socket.nickname} ${ch} :Cannot join channel (+k)\r\n`);
- continue; // Skip joining this channel
- }
- }
- if (chmodes.includes('l')) {
- // Channel has a user limit (+l)
- const limit = this.channelData.get(ch).limit;
- if (limit !== null && this.channelData.get(ch).users.size >= limit) {
- await this.safeWriteToSocket(socket, `:${this.servername} 471 ${socket.nickname} ${ch} :Cannot join channel (+l)\r\n`);
- continue; // Skip joining this channel
- }
- }
- if (chmodes.includes('i')) {
- // Channel is invite-only (+i)
- const invited = this.channelData.get(ch).inviteexceptions;
- let isInvited = false;
- for (const inviteMask of invited) {
- isInvited = this.checkMask(inviteMask, socket);
- if (isInvited) {
- break; // Stop checking if we found a match
- }
- }
- if (!this.channelData.get(ch).invites.has(socket.nickname) && !isInvited) {
- await this.safeWriteToSocket(socket, `:${this.servername} 473 ${socket.nickname} ${ch} :Cannot join channel (+i)\r\n`);
- continue; // Skip joining this channel
- }
- if (!this.channelData.get(ch).invites.has(socket.nickname)) {
- this.channelData.get(ch).invites.delete(socket.nickname);
- }
- }
- if (chmodes.includes('O')) {
- if (!this.isIRCOp(socket.nickname)) {
- var code = (this.clientIsWebTV(socket) ? 474 : 404);
- await this.safeWriteToSocket(socket, `:${this.servername} ${code} ${socket.nickname} ${ch} :Cannot join channel (+O)\r\n`);
- continue; // Skip joining this channel
- }
- }
- if (chmodes.includes('S')) {
- // Channel is restricted to users with a secure connection (+S)
- if (!socket.secure) {
- var code = (this.clientIsWebTV(socket) ? 474 : 468);
- await this.safeWriteToSocket(socket, `:${this.servername} ${code} ${socket.nickname} ${ch} :Cannot join channel (+S)\r\n`);
- continue; // Skip joining this channel
- }
- }
- if (chmodes.includes('R')) {
- // Channel is registered users only (+R)
- if (!this.getUserModes(socket.nickname).includes('r')) {
- var code = (this.clientIsWebTV(socket) ? 474 : 447);
- await this.safeWriteToSocket(socket, `:${this.servername} ${code} ${socket.nickname} ${ch} :Cannot join channel (+R)\r\n`);
- continue; // Skip joining this channel
- }
- }
-
- // If we reach here, the user can join the channel
- // Reuse the JOIN logic for each channel
- // Only run the code after $PLACEHOLDER$ for each channel
- // (excluding the code before $PLACEHOLDER$ to avoid duplicate checks)
- // You can refactor this logic into a helper if needed
- socket.lastspoke = this.getDate();
- if (!this.channelData.has(ch)) {
- this.createChannel(ch, socket.nickname);
- }
- var channelObj = this.channelData.get(ch);
- channelObj.users.add(socket.nickname);
- await this.broadcastChannelJoin(ch, socket);
-
- let modes = channelObj.modes;
- let prefix = '';
- if (channelObj.ops.has(socket.nickname)) {
- if (socket.client_caps.includes('multi-prefix')) {
- prefix += '@';
- } else {
- prefix = '@';
- }
- }
- if (channelObj.halfops.has(socket.nickname)) {
- if (socket.client_caps.includes('multi-prefix')) {
- prefix += '%';
- } else {
- if (!prefix) {
- prefix = '%';
- }
- }
- }
- if (channelObj.voices.has(socket.nickname)) {
- if (socket.client_caps.includes('multi-prefix')) {
- prefix += '+';
- } else {
- if (!prefix) {
- prefix = '+';
- }
- }
- }
- await this.broadcastToAllServers(`:${this.serverId} SJOIN ${this.getDate()} ${ch} +${modes.join('')} :${prefix}${socket.uniqueId}\r\n`);
- if (channelObj.topic) {
- const topic = channelObj.topic;
- if (topic) {
- await this.safeWriteToSocket(socket, `:${this.servername} 332 ${socket.nickname} ${ch} :${topic}\r\n`);
- }
- }
- var users = this.getUsersInChannel(ch);
- output_lines = [];
- var prefixRegex = new RegExp(`^[${this.supported_prefixes[1]}]`);
- if (users.length > 0) {
- users.sort((a, b) => {
- // Remove any prefixes for comparison
- const cleanA = a.replace(prefixRegex, '');
- const cleanB = b.replace(prefixRegex, '');
- // Get privilege for each user
- var channelObj = this.channelData.get(ch);
- function getPriv(user) {
- if (channelObj.ops.has(user)) return 1;
- if (channelObj.halfops.has(user)) return 2;
- if (channelObj.voices.has(user)) return 3;
- return 4;
- }
- const privA = getPriv(cleanA);
- const privB = getPriv(cleanB);
- if (privA !== privB) return privA - privB;
- // If same privilege, sort alphabetically (case-insensitive)
- return cleanA.localeCompare(cleanB, undefined, { sensitivity: 'base' });
- });
- if (socket.client_caps.includes('userhost-in-names')) {
- const userHosts = users.map(user => {
- var nick = this.findUser(user.replace(prefixRegex, ''));
- var username = this.usernames.get(nick) || 'unknown';
- var host = this.hostnames.get(nick) || 'unknown';
- return `${user}!${username}@${host}`;
- });
- output_lines.push(`:${this.servername} 353 ${socket.nickname} = ${ch} :${userHosts.join(' ')}\r\n`);
- } else {
- output_lines.push(`:${this.servername} 353 ${socket.nickname} = ${ch} :${users.join(' ')}\r\n`);
- }
- }
- output_lines.push(`:${this.servername} 366 ${socket.nickname} ${ch} :End of /NAMES list\r\n`);
- await this.sendThrottled(socket, output_lines, 0);
- if (this.isReservedChannel(ch)) {
- if (this.checkIfReservedChannelOp(socket, ch)) {
- this.channelData.get(ch).ops.add(socket.nickname);
- await this.broadcastChannel(ch, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${ch} +o ${socket.nickname}\r\n`);
- }
- }
- var awaymsg = this.awaymsgs.get(socket.nickname);
- if (awaymsg) {
- await this.broadcastUserIfCap(socket, `:${socket.nickname}!${socket.username}@${socket.host} AWAY :${awaymsg}\r\n`, socket, 'away-notify');
- }
- if (
- this.irc_config &&
- Array.isArray(this.irc_config.channels)
- ) {
- const channel_data = this.irc_config.channels.find(cfg => cfg.name === ch);
- if (channel_data && channel_data.intro) {
- // Send intro messages (array of lines) to the joining user only
- for (const line of channel_data.intro) {
- await this.safeWriteToSocket(socket, `:${ch}!system@${this.servername} PRIVMSG ${ch} :${line}\r\n`);
- }
- }
- }
- if (this.clientIsWebTV(socket) && this.enable_webtv_command_hacks) {
- output_lines = [];
- var channelObj = this.channelData.get(ch);
- output_lines.push("You have joined " + ch);
- output_lines.push("Current channel modes: +" + channelObj.modes.join(''));
- let isOp = channelObj.ops.has(socket.nickname);
- let isHalfOp = channelObj.halfops.has(socket.nickname);
- let isVoice = channelObj.voices.has(socket.nickname);
- if (isOp) {
- output_lines.push("You are a channel operator (@) in " + ch);
- } else if (isHalfOp) {
- output_lines.push("You are a channel half-operator (%) in " + ch);
- } else if (isVoice) {
- output_lines.push("You are voiced (+) in " + ch);
- }
- this.sendWebTVSpoofedActionTo(socket, ch, output_lines);
- }
- }
- break;
- case 'NAMES':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} NAMES :Not enough parameters\r\n`);
- break;
- }
- channel = this.findChannel(params[0]);
- if (!channel || !this.channelData.has(channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${channel} :No such channel\r\n`);
- break;
- }
- var users = this.getUsersInChannel(channel);
- output_lines = [];
- if (users.length > 0) {
- if (socket.client_caps.includes('userhost-in-names')) {
- const userHosts = users.map(user => {
- var prefixRegex = new RegExp(`^[${this.supported_prefixes[1]}]`);
- var nick = this.findUser(user.replace(prefixRegex, ''));
- var username = this.usernames.get(nick) || 'unknown';
- var host = this.hostnames.get(nick) || 'unknown';
- return `${user}!${username}@${host}`;
- });
- output_lines.push(`:${this.servername} 353 ${socket.nickname} = ${ch} :${userHosts.join(' ')}\r\n`);
- } else {
- output_lines.push(`:${this.servername} 353 ${socket.nickname} = ${ch} :${users.join(' ')}\r\n`);
- }
- }
- output_lines.push(`:${this.servername} 366 ${socket.nickname} ${channel} :End of /NAMES list\r\n`);
- await this.sendThrottled(socket, output_lines);
- break;
- case 'PART':
- if (!this.checkRegistered(socket)) {
- break;
- }
- channel = this.findChannel(params[0]);
- if (!this.channelData.has(channel) || !this.channelData.get(channel).users.has(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 442 ${socket.nickname} ${channel} :You're not on that channel\r\n`);
- break;
- }
- if (this.channelData.get(channel).ops.has(socket.nickname)) {
- this.channelData.get(channel).ops.delete(socket.nickname);
- }
- if (this.channelData.get(channel).halfops.has(socket.nickname)) {
- this.channelData.get(channel).halfops.delete(socket.nickname);
- }
- if (this.channelData.get(channel).voices.has(socket.nickname)) {
- this.channelData.get(channel).voices.delete(socket.nickname);
- }
- socket.lastspoke = this.getDate();
- if (params.length == 2) {
- let reason = params.join(' ');
- if (reason.startsWith(':')) {
- reason = reason.slice(1);
- }
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} PART ${channel} :${reason}\r\n`);
- await this.broadcastChannel(channel, `:${socket.nickname}!${socket.username}@${socket.host} PART ${channel} :${reason}\r\n`, socket);
- } else {
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} PART ${channel}\r\n`);
- await this.broadcastChannel(channel, `:${socket.nickname}!${socket.username}@${socket.host} PART ${channel}\r\n`, socket);
- }
- if (this.channelData.has(channel)) {
- this.channelData.get(channel).users.delete(socket.nickname);
- if (this.channelData.get(channel).users.size === 0) {
- this.deleteChannel(channel);
- }
- }
- await this.broadcastToAllServers(`:${socket.uniqueId} PART ${channel}\r\n`);
- break;
- case 'INVITE':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (params.length < 2) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} INVITE :Not enough parameters\r\n`);
- break;
- }
- const invitee = this.findUser(params[0]);
- channel = this.findChannel(params[1]);
- if (!invitee || !channel) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${params[0]} :No such nick/channel\r\n`);
- break;
- }
- if (!this.channelData.has(channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${channel} :No such channel\r\n`);
- break;
- }
- if (!this.channelData.get(channel).ops.has(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${socket.socket.nickname} ${channel} :You're not channel operator\r\n`);
- break;
- }
- if (!this.nicknames.has(socket)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${invitee} :No such nick/channel\r\n`);
- break;
- }
- const inviteeSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === invitee);
- if (!inviteeSocket) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${invitee} :No such nick/channel\r\n`);
- break;
- }
- if (!this.channelData.has(channel) || !this.channelData.get(channel).users.has(invitee)) {
- if (this.channelData.get(channel).modes.includes('V')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${socket.nickname} ${channel} :Cannot invite users, channel is +V (no invites allowed)\r\n`);
- break;
- }
- const invited = this.channelData.get(channel).invites;
- invited.add(invitee);
- await this.safeWriteToSocket(socket, `:${this.servername} 341 ${socket.nickname} ${invitee} ${channel} :Invited to channel\r\n`);
- await this.broadcastUserIfCapAndChanOp(socket, `:${socket.nickname}!${socket.username}@${socket.host} INVITE ${invitee} ${channel}`, socket, 'invite-notify', channel);
- await this.safeWriteToSocket(inviteeSocket, `:${this.servername} 341 ${socket.nickname} ${invitee} ${channel} :You have been invited to join ${channel}\r\n`);
- break;
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} 443 ${socket.nickname} ${invitee} ${channel} :${invitee} is already on that channel\r\n`);
- break;
- }
- case 'LIST':
- if (!this.checkRegistered(socket)) {
- break;
- } let channelsToList;
- if (params.length > 0 && params[0]) {
- channelsToList = params[0].split(',').filter(ch => ch.length > 0);
- } else {
- channelsToList = Array.from(this.channelData.keys());
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 321 ${socket.nickname} :Channel :Users :Topic\r\n`);
- for (const channel of channelsToList) {
- if (!this.channelprefixes.some(prefix => channel.startsWith(prefix))) {
- continue; // Skip invalid channel names
- }
- var modes = this.channelData.get(channel).modes;
- if (modes.includes('p')) {
- if (!this.channelData.has(channel) || !this.channelData.get(channel).users.has(socket.nickname)) {
- continue; // Skip if user is not in the channel
- }
- }
- if (modes.includes('s')) {
- if (!this.channelData.has(channel) || !this.channelData.get(channel).users.has(socket.nickname)) {
- continue; // Skip if user is not in the channel
- }
- }
- const users = this.getUsersInChannel(channel);
- const topic = this.channelData.get(channel).topic;
- await this.safeWriteToSocket(socket, `:${this.servername} 322 ${socket.nickname} ${channel} ${users.length} :${topic}\r\n`);
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 323 ${socket.nickname} :End of /LIST\r\n`);
- break;
- case 'WHO':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!params[0]) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} WHO :Not enough parameters\r\n`);
- break;
- }
- const target = this.findChannel(params[0]);
- if (!target) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${params[0]} :No such nick/channel\r\n`);
- break;
- }
-
- var isChannel = false;
- for (const prefix of this.channelprefixes) {
- if (target.startsWith(prefix)) {
- isChannel = true;
- break;
- }
- }
- if (isChannel) {
- // WHO for channel
- const modes = this.channelData.get(target).modes
- if ((modes.includes('p') || modes.includes('s')) && (!this.channelData.has(target) || !this.channelData.get(target).users.has(socket.nickname))) {
- await this.safeWriteToSocket(socket, `:${this.servername} 315 ${socket.nickname} ${target} :End of /WHO list\r\n`);
- break;
- }
- if (this.channelData.has(target)) {
- const users = this.channelData.get(target).users;
- for (const user of users) {
- let cleanUser = user;
- if (!user) {
- continue; // Skip empty users
- }
- if (['@', '%', '+'].includes(cleanUser[0])) {
- cleanUser = cleanUser.slice(1);
- }
- var hostname = this.hostnames.get(cleanUser);
- var username = this.usernames.get(cleanUser) || cleanUser;
- var whoisSocket = Array.from(this.nicknames.keys()).find(
- s => this.nicknames.get(s).toLowerCase() === cleanUser.toLowerCase()
- );
- if (!whoisSocket) {
- // try to get server socket
- whoisSocket = this.getRemoteServerUserSocket(cleanUser);
- }
- var userSecure = false;
- if (whoisSocket) {
- userSecure = whoisSocket.secure;
- }
- let prefix = '';
- var channelObj = this.channelData.get(target);
- if (channelObj.ops.has(cleanUser)) {
- prefix = '@';
- } else if (channelObj.halfops.has(cleanUser)) {
- prefix = '%';
- } else if (channelObj.voices.has(cleanUser)) {
- prefix = '+';
- }
- var userinfo = this.userinfo.get(cleanUser) || cleanUser;
- var flags = `${(this.awaymsgs.has(cleanUser)) ? 'G' : 'H'}${(this.isIRCOp(cleanUser)) ? '*' : ''}${(userSecure) ? 'z' : ''}`
- var secondsIdle = (this.getDate() - whoisSocket.lastspoke);
- await this.safeWriteToSocket(socket, `:${this.servername} 352 ${socket.nickname} ${target} ${username} ${hostname} ${this.servername} ${cleanUser} ${flags} 0 ${secondsIdle} 0 :${userinfo}\r\n`);
- }
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 315 ${socket.nickname} ${target} :End of /WHO list\r\n`);
- } else {
- // WHO for nickname
- output_lines = [];
- if (target.includes('*') || target.includes('?')) {
- // Wildcard mask search for nicknames
- const maskRegex = new RegExp('^' + target.replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
- let found = false;
- for (const [sock, nick] of this.nicknames.entries()) {
- if (maskRegex.test(nick)) {
- if (this.getUserModes(nick).includes('s')) {
- continue;
- }
- found = true;
- output_lines.push(`:${this.servername} 352 ${socket.nickname} * ${nick} ${sock.host} ${this.servername} ${nick} ${(this.awaymsgs.has(nick)) ? 'G' : 'H'}${(sock.secure) ? 'z' : ''} :0 ${sock.userinfo}\r\n`);
- }
- }
- if (!found) {
- output_lines.push(`:${this.servername} 401 ${socket.nickname} ${target} :No such nick/channel\r\n`);
- }
- output_lines.push(`:${this.servername} 315 ${socket.nickname} ${target} :End of /WHO list\r\n`);
- await this.sendThrottled(socket, output_lines);
- break;
- } else {
- var whoisSocket = Array.from(this.nicknames.keys()).find(
- s => this.nicknames.get(s).toLowerCase() === target.toLowerCase()
- );
- if (whoisSocket) {
- if (this.getUserModes(whoisSocket.nickname).includes('s')) {
- // Skip invisible users
- output_lines.push(`:${this.servername} 315 ${socket.nickname} ${target} :End of /WHO list\r\n`);
- break;
- }
- output_lines.push(`:${this.servername} 352 ${socket.nickname} * ${whoisSocket.nickname} ${whoisSocket.host} ${this.servername} ${whoisSocket.nickname} ${(this.awaymsgs.has(target)) ? 'G' : 'H'}${(whoisSocket.secure) ? 'z' : ''} :0 ${whoisSocket.userinfo}\r\n`);
- } else {
- output_lines.push(`:${this.servername} 401 ${socket.nickname} ${target} :No such nick/channel\r\n`);
- }
- output_lines.push(`:${this.servername} 315 ${socket.nickname} ${target} :End of /WHO list\r\n`);
- await this.sendThrottled(socket, output_lines);
- break;
- }
- }
- break;
- case 'PRIVMSG':
- if (!this.checkRegistered(socket)) {
- break;
- }
- socket.lastspoke = this.getDate();
- if (params[0]) {
- const target = params[0];
- let targets = target.includes(',') ? target.split(',') : [target];
- if (targets.length > this.maxtargets) {
- await this.safeWriteToSocket(socket, `:${this.servername} 407 ${socket.nickname} :Too many targets. Maximum allowed is ${this.maxtargets}\r\n`);
- return;
- }
- for (var t of targets) {
- if (t === this.servername) {
- var msg = line.slice(line.indexOf(':', 1) + 1);
- if (msg.startsWith("\x01VERSION")) {
- await this.safeWriteToSocket(socket, `:${this.servername} NOTICE ${socket.nickname} :${this.servername} zefIRCd ${this.version} - zefIRCd IRC server - a part of the zefie minisrv project\r\n`);
- break;
- }
- if (msg.startsWith("\x01PING")) {
- await this.safeWriteToSocket(socket, `:${this.servername} NOTICE ${socket.nickname} :\x01PING ${this.getDate()}\r\n`);
- break;
- }
- if (msg.startsWith("\x01TIME")) {
- const dateObj = new Date();
- const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
- const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
- const pad = n => n.toString().padStart(2, '0');
- const formattedDate = `${dayNames[dateObj.getDay()]} ${monthNames[dateObj.getMonth()]} ${pad(dateObj.getDate())} ${pad(dateObj.getHours())}:${pad(dateObj.getMinutes())}:${pad(dateObj.getSeconds())} ${dateObj.getFullYear()}`;
- await this.safeWriteToSocket(socket, `:${this.servername} NOTICE ${socket.nickname} :\x01TIME ${formattedDate}\x01\r\n`);
- break;
- }
- }
- let isChan = false;
- for (const prefix of this.channelprefixes) {
- if (t.startsWith(prefix)) {
- isChan = true;
- t = this.findChannel(t);
- break;
- }
- }
- if (!t) {
- t = this.findUser(t);
- isChan = false;
- }
- if (!t) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${t} :No such nick/channel\r\n`);
- continue;
- }
- var channelObj = this.channelData.get(t);
- var msg = line.slice(line.indexOf(':', 1) + 1);
- if (isChan) {
- // Channel message
- if (channelObj.modes.includes('m')) {
- // Channel is moderated (+m)
-
- if (!channelObj.voices.has(socket.nickname && !channelObj.ops.has(socket.nickname) && !channelObj.halfops.has(socket.nickname))) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+m)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('n')) {
- // Channel is no-external-messages (+n)
- if (!channelObj.users.has(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+n)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('c')) {
- // Block all IRC control codes (ASCII 0x00-0x1F except \r and \n)
- if (/[\x00-\x09\x0B\x0C\x0E-\x1F]/.test(msg)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+c)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('C')) {
- // channel blocks CTCP, detect if the message contains CTCPS
- if (msg.includes('\x01')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+C)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('O')) {
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+O)\r\n`);
- }
- }
- }
- if (isChan) {
- if (!this.channelData.has(t)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${t} :No such channel\r\n`);
- continue;
- }
- if (this.clientIsWebTV(socket) && msg.startsWith('/') && this.enable_webtv_command_hacks) {
- var wtvcmd = msg.slice(1).split(' ');
- if (wtvcmd[0].length > 0) {
- if (this.supported_webtv_command_hacks.includes(wtvcmd[0].toUpperCase())) {
- var wtvstr = `${wtvcmd[0].toUpperCase()} ${wtvcmd.splice(1).join(' ')}\r\n`;
- this.processSocketData(socket, wtvstr);
- }
- }
- continue;
- }
- await this.broadcastChannel(t, `:${socket.nickname}!${socket.username}@${socket.host} PRIVMSG ${t} :${msg}\r\n`, socket);
- await this.broadcastToAllServers(`:${socket.uniqueId} PRIVMSG ${t} :${msg}\r\n`);
- } else {
- if (this.awaymsgs.has(t)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 301 ${socket.nickname} ${t} :${this.awaymsgs.get(t)}\r\n`);
- }
- var targetSock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s).toLowerCase() === t.toLowerCase());
- if (!targetSock) {
- // check remote servers
- targetSock = this.getRemoteServerUserSocket(t);
- if (targetSock) {
- const sender_id = this.getUniqueId(socket.nickname);
- const unique_id = this.getUniqueId(t);
- targetSock.write(`:${sender_id} PRIVMSG ${unique_id} :${msg}\r\n`);
- break;
- }
- }
- if (!targetSock) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${t} :No such nick/channel\r\n`);
- continue;
- }
- var targetUserModes = this.getUserModes(t);
- var usermodes = this.getUserModes(socket.nickname);
- if (targetUserModes.includes('R')) {
- if (!usermodes.includes('r')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 447 ${socket.nickname} ${t} :Cannot send to user (+R)\r\n`);
- continue;
- }
- }
- if (targetUserModes.includes('Z') && !socket.secure) {
- await this.safeWriteToSocket(socket, `:${this.servername} 484 ${socket.nickname} ${t} :Cannot send to user (+Z)\r\n`);
- continue;
- }
- if (!usermodes || usermodes === true) {
- usermodes = [];
- }
- if (usermodes.includes('Z') && !targetUserModes.includes('Z')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 484 ${socket.nickname} ${t} :Cannot send to non-+Z user while you are +Z\r\n`);
- continue;
- }
- targetSock.write(`:${socket.nickname}!${socket.username}@${socket.host} PRIVMSG ${targetSock.nickname} :${msg}\r\n`);
- if (socket.client_caps.includes('echo-message')) {
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} PRIVMSG ${targetSock.nickname} :${msg}\r\n`);
- }
- }
- }
- return;
- }
- break;
- case 'NOTICE':
- if (!this.checkRegistered(socket, false, true) && params[0] !== this.servername) {
- break;
- }
- socket.lastspoke = this.getDate();
- if (params[0]) {
- const target = params[0];
- let targets = target.includes(',') ? target.split(',') : [target];
- if (targets.length > this.maxtargets) {
- await this.safeWriteToSocket(socket, `:${this.servername} 407 ${socket.nickname} :Too many targets. Maximum allowed is ${this.maxtargets}\r\n`);
- return;
- }
- for (const t of targets) {
- let isChan = false;
- if (t === this.servername) {
- // client responding to a system message
- var msg = line.slice(line.indexOf(':', 1) + 1);
- if (msg.startsWith('\x01VERSION')) {
- socket.client_version = msg.replace('\x01VERSION ', '').replace('\x01', '');
- break;
- }
- }
- for (const prefix of this.channelprefixes) {
- if (t.startsWith(prefix)) {
- isChan = true;
- t = this.findChannel(t);
- break;
- }
- }
- if (!t) {
- t = this.findUser(t);
- isChan = false;
- }
- if (!t) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${t} :No such nick/channel\r\n`);
- continue;
- }
- var channelObj = this.channelData.get(t);
- var msg = line.slice(line.indexOf(':', 1) + 1);
- if (isChan) {
- if (!this.channelData.has(t)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 403 ${socket.nickname} ${t} :No such channel\r\n`);
- continue;
- }
- // Channel notice
- if (channelObj.modes.includes('n')) {
- // Channel is no-external-messages (+n)
- if (!this.channelData.get(t).users.has(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+n)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('c')) {
- // channel blocks color, detect if the message contains color codes
- if (/[\x00-\x09\x0B\x0C\x0E-\x1F]/.test(msg)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+c)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('C')) {
- // channel blocks CTCP, detect if the message contains CTCPS
- if (msg.includes('\x01')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+C)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('T')) {
- if (
- !channelObj.ops.has(socket.nickname) &&
- !channelObj.halfops.has(socket.nickname) &&
- !channelObj.voices.has(socket.nickname)
- ) {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${socket.nickname} ${t} :Cannot send to channel (+T)\r\n`);
- continue;
- }
- }
- if (channelObj.modes.includes('O')) {
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 404 ${socket.nickname} ${t} :Cannot send to channel (+O)\r\n`);
- }
- }
- await this.broadcastChannel(t, `:${socket.nickname}!${socket.username}@${socket.host} NOTICE ${t} :${msg}\r\n`, socket);
- await this.broadcastToAllServers(`:${socket.uniqueId} NOTICE ${t} :${msg}\r\n`);
- } else {
- // Assume it's a nick, check if it exists
- var targetSock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s).toLowerCase() === t.toLowerCase());
- if (!targetSock) {
- // check remote servers
- targetSock = this.getRemoteServerUserSocket(t);
- if (targetSock) {
- const sender_id = this.getUniqueId(socket.nickname);
- const unique_id = this.getUniqueId(t);
- targetSock.write(`:${sender_id} PRIVMSG ${unique_id} :${msg}\r\n`);
- break;
- }
- }
- if (!targetSock) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${t} :No such nick/channel\r\n`);
- continue;
- }
- var targetUserModes = this.getUserModes(t);
- var usermodes = this.getUserModes(socket.nickname);
- if (targetUserModes.includes('R')) {
- if (!usermodes.includes('r')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 447 ${socket.nickname} ${t} :Cannot send to user (+R)\r\n`);
- continue;
- }
- }
- if (targetUserModes.includes('Z') && !socket.secure) {
- await this.safeWriteToSocket(socket, `:${this.servername} 484 ${socket.nickname} ${t} :Cannot send to user (+Z)\r\n`);
- continue;
- }
- if (!usermodes || usermodes === true) {
- usermodes = [];
- }
- if (usermodes.includes('Z') && !targetUserModes.includes('Z')) {
- await this.safeWriteToSocket(socket, `:${this.servername} 484 ${socket.nickname} ${t} :Cannot send to non-+Z user while you are +Z\r\n`);
- continue;
- }
- var cmd = 'NOTICE';
- if (this.clientIsWebTV(targetSock)) {
- cmd = 'PRIVMSG'; // WebTV clients do not support NOTICE, use PRIVMSG instead
- }
- targetSock.write(`:${socket.nickname}!${socket.username}@${socket.host} ${cmd} ${targetSock.nickname} :${msg}\r\n`);
- if (socket.client_caps.includes('echo-message')) {
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} PRIVMSG ${targetSock.nickname} :${msg}\r\n`);
- }
- }
- }
- return;
- }
- break;
- case 'SYSTEM':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `SYSTEM command attempted by non-IRCOp: ${socket.nickname}`);
- break;
- }
- var type = params[0] ? params[0].toUpperCase() : '';
- output_lines = [];
- switch (type) {
- case "HELP":
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :Available commands:\r\n`);
- output_lines.push(`:${this.servername} 200 ${socket.nickname} : HELP - Show this help message\r\n`);
- output_lines.push(`:${this.servername} 200 ${socket.nickname} : LOG - Show server log data\r\n`);
- output_lines.push(`:${this.servername} 200 ${socket.nickname} : KLINES - Show KLINE data\r\n`);
- output_lines.push(`:${this.servername} 200 ${socket.nickname} : CHANNELS - Show channel data\r\n`);
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :End of help data\r\n`);
- break;
- case "LOG":
- this.logdata.forEach((logEntry) => {
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :${logEntry}\r\n`);
- });
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :End of log data\r\n`);
- break;
- case "KLINES":
- if (this.klines.length === 0) {
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :No KLINES found\r\n`);
- break;
- }
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :KLINE data:\r\n`);
- for (const kline of this.klines) {
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :Mask: ${kline.mask}, Expiry: ${kline.expiry}, Reason: ${kline.reason}\r\n`);
- }
- output_lines.push(`:${this.servername} 200 ${socket.nickname} :End of KLINE data\r\n`);
- break;
- case 'CHANNELS':
- for (const [channelName, channelObj] of this.channelData.entries()) {
- output_lines.push(`:${this.servername} 200 :Channel: ${channelName}\r\n`);
- for (const [key, value] of Object.entries(channelObj)) {
- let valStr;
- if (value instanceof Set) {
- valStr = Array.from(value).join(', ');
- } else if (typeof value === 'object' && value !== null) {
- valStr = JSON.stringify(value);
- } else {
- valStr = String(value);
- }
- output_lines.push(`:${this.servername} 200 : ${key}: ${valStr}\r\n`);
- }
- }
- break;
- default:
- output_lines.push(`:${this.servername} 500 ${socket.nickname} :Unknown debug command\r\n`);
- break;
- }
- await this.sendThrottled(socket, output_lines);
- break;
- case 'PING':
- await this.safeWriteToSocket(socket, `PONG ${params.join(' ')}\r\n`);
- break;
- case 'KLINE':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `KLINE command attempted by non-IRCOp: ${socket.nickname}`);
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} KLINE :Not enough parameters\r\n`);
- break;
- }
- var targetMask = params[0];
- var expiry = this.getDate() + 3600;
- var reasonParam = 1;
- if (!isNaN(parseInt(targetMask))) {
- expiry = this.getDate() + parseInt(targetMask);
- targetMask = params[1];
- reasonParam = 2;
- }
- if (this.klines.findIndex(k => k.mask === targetMask) !== -1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 200 ${socket.nickname} ${targetMask} :KLINE already exists for this mask\r\n`);
- break;
- }
- var reason = params.slice(reasonParam).join(' ') || '';
- var kline = {
- "mask": targetMask,
- "expiry": expiry,
- "reason": reason
- }
- this.klines.push(kline);
- this.saveKLinesToFile();
- if (reason) {
- await this.safeWriteToSocket(socket, `:${this.servername} 381 ${socket.nickname} :KLINE added for ${targetMask} (duration ${expiry - this.getDate()} seconds) [${reason}]\r\n`);
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} 381 ${socket.nickname} :KLINE added for ${targetMask} (duration ${expiry - this.getDate()} seconds)\r\n`);
- }
- await this.scanUsersForKLines();
- break;
- case 'UNKLINE':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `UNKLINE command attempted by non-IRCOp: ${socket.nickname}`);
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} UNKLINE :Not enough parameters\r\n`);
- break;
- }
- var targetMask = params[0];
- if (this.klines.findIndex(k => k.mask === targetMask) == -1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 200 ${socket.nickname} ${targetMask} :No such KLINE\r\n`);
- break;
- }
- const klineIndex = this.klines.findIndex(k => k.mask === targetMask);
- if (klineIndex !== -1) {
- this.klines.splice(klineIndex, 1);
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 381 ${socket.nickname} :KLINE removed for ${targetMask}\r\n`);
- break;
- case 'WHOIS':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} WHOIS :Not enough parameters\r\n`);
- break;
- }
- var whoisNick = params[0];
- var nickCheck = this.findUser(whoisNick);
- if (nickCheck) {
- whoisNick = nickCheck;
- var whoisSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s)=== whoisNick);
- const whois_username = this.usernames.get(whoisNick);
- var userinfo = this.userinfo.get(whoisNick) || whoisSocket.userinfo || 'unknown';
- await this.safeWriteToSocket(socket, `:${this.servername} 311 ${socket.nickname} ${whoisNick} ${whois_username} ${whoisSocket.host} * :${userinfo}\r\n`);
- if (this.awaymsgs.has(whoisNick)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 301 ${socket.nickname} ${whoisNick} :${this.awaymsgs.get(whoisNick)}\r\n`);
- }
- const userChannels = [];
-
- output_lines = [];
- for (const [ch, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(whoisNick)) {
- let prefix = '';
- var chanops = channelObj.ops;
- var chanhalfops = channelObj.halfops;
- var chanvoices = channelObj.voices;
- var modes = channelObj.modes;
-
- if ((modes.includes('p') || modes.includes('s')) && (!this.channelData.has(ch) || !this.channelData.get(ch).users.has(socket.nickname))) {
- continue; // Skip listing this channel if it's private/secret and user is not in it
- }
- if (chanops.has(whoisNick)) {
- if (socket.client_caps.includes('multi-prefix')) {
- prefix += '@';
- } else {
- prefix = '@';
- }
- }
- if (chanhalfops.has(whoisNick)) {
- if (socket.client_caps.includes('multi-prefix')) {
- prefix += '%';
- } else {
- if (!prefix) {
- prefix = '%';
- }
- }
- }
- if (chanvoices.has(whoisNick)) {
- if (socket.client_caps.includes('multi-prefix')) {
- prefix += '+';
- } else {
- if (!prefix) {
- prefix = '+';
- }
- }
- }
- userChannels.push(prefix + ch);
- }
- }
- output_lines.push(`:${this.servername} 312 ${socket.nickname} ${whoisNick} ${this.servername} :zefIRCd-${this.version}\r\n`);
- if (this.isIRCOp(whoisNick)) {
- output_lines.push(`:${this.servername} 313 ${socket.nickname} ${whoisNick} :is an IRC operator\r\n`);
- }
- usermodes = this.getUserModes(whoisNick);
- if (usermodes && usermodes.includes('s')) {
- output_lines.push(`:${this.servername} 671 ${socket.nickname} ${whoisNick} :is using a secure connection\r\n`);
- }
- if (usermodes && usermodes.includes('r')) {
- output_lines.push(`:${this.servername} 307 ${socket.nickname} ${whoisNick} :is a registered nick\r\n`);
- }
- if (usermodes && usermodes.includes('B')) {
- output_lines.push(`:${this.servername} 335 ${socket.nickname} ${whoisNick} :is a bot\r\n`);
- }
- const now = this.getDate();
- const userTimestamp = whoisSocket.lastspoke || now;
- const idleTime = now - userTimestamp;
- output_lines.push(`:${this.servername} 317 ${socket.nickname} ${whoisNick} ${idleTime} ${this.usersignontimestamps.get(whoisNick) || 0} :seconds idle, signon time\r\n`);
- if (userChannels.length > 0) {
- output_lines.push(`:${this.servername} 319 ${socket.nickname} ${whoisNick} :${userChannels.join(' ')}\r\n`);
- }
- output_lines.push(`:${this.servername} 318 ${socket.nickname} ${whoisNick} :End of /WHOIS list\r\n`);
- await this.sendThrottled(socket, output_lines);
- } else {
- // Check if whoisNick is a remote server user
- let foundRemote = false;
- for (const [srvSocket, users] of this.serverusers.entries()) {
- if (users && typeof users.has === 'function'
- ? Array.from(users).some(u => typeof u === 'string' && u.toLowerCase() === whoisNick.toLowerCase())
- : Array.isArray(users) && users.some(u => typeof u === 'string' && u.toLowerCase() === whoisNick.toLowerCase())
- ) {
- // Found remote user
- const sender_id = this.getUniqueId(socket.nickname);
- const unique_id = this.getUniqueId(whoisNick);
- await this.safeWriteToSocket(srvSocket, `:${sender_id} WHOIS :${unique_id}\r\n`);
- foundRemote = true;
- break;
- }
- }
- if (!foundRemote) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${whoisNick} :No such nick/channel\r\n`);
- }
- }
- break;
- case 'KILL':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `KILL command attempted by non-IRCOp: ${socket.nickname}`);
- break;
- }
- if (params.length < 2) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} KILL :Not enough parameters\r\n`);
- break;
- }
- const target_nick = this.findUser(params[0]);
- if (!target_nick) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${params[0]} :No such nick/channel\r\n`);
- break;
- }
-
- const killReason = params.slice(1).join(' ');
- let cleanKillReason = killReason;
- if (cleanKillReason.startsWith(':')) {
- cleanKillReason = cleanKillReason.slice(1);
- }
- targetSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === target_nick);
- if (!targetSocket) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${socket.nickname} ${target_nick} :No such nick/channel\r\n`);
- break;
- }
-
- // Broadcast the KILL message to all users
- await this.broadcastUser(target_nick, `:${socket.nickname}!${socket.username}@${socket.host} KILL ${target_nick} :${cleanKillReason}\r\n`);
- this.terminateSession(targetSocket, true);
- break;
- case 'QUIT':
- if (!this.checkRegistered(socket)) {
- break;
- }
- for (const [ch, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(socket.nickname)) {
- channelObj.ops.delete(socket.nickname);
- channelObj.halfops.delete(socket.nickname);
- channelObj.voices.delete(socket.nickname);
- }
- }
- if (params.length > 0) {
- let reason = params.join(' ');
- if (reason.startsWith(':')) {
- reason = reason.slice(1);
- }
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} QUIT :${reason}\r\n`);
- await this.broadcastUser(socket.nickname, `:${socket.nickname}!${socket.username}@${socket.host} QUIT :${reason}\r\n`, socket);
- await this.broadcastToAllServers(`:${socket.uniqueId} QUIT :${reason}\r\n`);
- await this.broadcastConnection(socket, `Quit: ${reason}`);
- socket.signedoff = true;
- } else {
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} QUIT\r\n`);
- await this.broadcastUser(socket.nickname, `:${socket.nickname}!${socket.username}@${socket.host} QUIT\r\n`, socket);
- await this.broadcastToAllServers(`:${socket.uniqueId} QUIT :Client disconnected\r\n`);
- await this.broadcastConnection(socket, 'Quit: Client disconnected');
- socket.signedoff = true;
- }
- this.terminateSession(socket, true);
- break;
- case 'MOTD':
- if (!this.checkRegistered(socket)) {
- break;
- }
- await this.doMOTD(socket.nickname, socket);
- break;
- case 'VERSION':
- if (!this.checkRegistered(socket)) {
- break;
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 351 ${socket.nickname} ${this.servername} zefIRCd ${this.version} :zefIRCd IRC server - a part of the zefie minisrv project\r\n`);
- break;
- case 'WALLOPS':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.isIRCOp(socket.nickname)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `WALLOPS command attempted by non-IRCOp: ${socket.nickname}`);
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} WALLOPS :Not enough parameters\r\n`);
- break;
- }
- let wallopsMessage = params.join(' ');
- if (wallopsMessage.startsWith(':')) {
- wallopsMessage = wallopsMessage.slice(1);
- }
- await this.broadcastWallops(`:${socket.nickname}!${socket.username}@${socket.host} WALLOPS :${wallopsMessage}\r\n`);
- case 'VHOST':
- if (!this.checkRegistered(socket)) {
- break;
- }
- if (!this.isIRCOp(socket.nickname) && !this.allow_public_vhosts) {
- await this.safeWriteToSocket(socket, `:${this.servername} 481 ${socket.nickname} :Permission denied - you are not an IRC operator\r\n`);
- this.debugLog('warn', `VHOST command attempted by non-IRCOp: ${socket.nickname}`);
- break;
- }
- if (params.length < 1) {
- await this.safeWriteToSocket(socket, `:${this.servername} 461 ${socket.nickname} VHOST :Not enough parameters\r\n`);
- break;
- }
- const newVHost = params[0];
- if (!newVHost || !/^[a-zA-Z0-9.-]+$/.test(newVHost)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 501 ${socket.nickname} :Invalid VHost format\r\n`);
- break;
- }
- // Prevent setting VHost to an IP address (IPv4 or IPv6)
- const ipv4Pattern = /^(?:\d{1,3}\.){3}\d{1,3}$/;
- const ipv6Pattern = /^([a-fA-F0-9:]+:+)+[a-fA-F0-9]+$/;
- if (ipv4Pattern.test(newVHost) || ipv6Pattern.test(newVHost)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 501 ${socket.nickname} :VHost cannot be an IP address\r\n`);
- break;
- }
- dns.lookup(newVHost, async (err, address) => {
- if (!err && address) {
- await this.safeWriteToSocket(socket, `:${this.servername} 501 ${socket.nickname} :VHost must not resolve to a real IP (resolved to: ${address})\r\n`);
- return;
- }
- // Set the new VHost for the socket
- socket.host = newVHost;
- if (socket.client_caps && socket.client_caps.includes('CHGHOST')) {
- await this.safeWriteToSocket(socket, `:${socket.nickname}!${socket.username}@${socket.host} CHGHOST ${socket.username} ${socket.host}\r\n`);
- }
- await this.safeWriteToSocket(socket, `:${this.servername} 396 ${socket.nickname} :Your VHost has been changed to ${socket.host}\r\n`);
- });
- break;
- case 'STARTTLS':
- socket.upgrading_to_tls = true;
- await this.safeWriteToSocket(socket, `:${this.servername} 670 ${socket.uniqueId} :STARTTLS successful, go ahead with TLS handshake\r\n`);
- break;
- default:
- // Ignore unknown commands
- break;
- }
- }
- }
-
- deleteChannel(channel) {
- // Cleans up the channel from all lists
- if (!this.isReservedChannel(channel)) {
- this.channelData.delete(channel);
- this.debugLog('info', `Channel ${channel} deleted`);
- }
- }
-
- cleanupUserSession(nickname) {
- this.usersignontimestamps.delete(nickname);
- this.usernames.delete(nickname);
- this.usermodes.delete(nickname);
- this.awaymsgs.delete(nickname);
- this.accounts.delete(nickname);
- this.userinfo.delete(nickname);
- this.deleteUserUniqueId(nickname);
- for (const [ch, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(nickname)) {
- channelObj.users.delete(nickname);
- }
- if (channelObj.ops.has(nickname)) {
- channelObj.ops.delete(nickname);
- }
- if (channelObj.halfops.has(nickname)) {
- channelObj.halfops.delete(nickname);
- }
- if (channelObj.voices.has(nickname)) {
- channelObj.voices.delete(nickname);
- }
- if (channelObj.invites.has(nickname)) {
- channelObj.invites.delete(nickname);
- }
- if (channelObj.users.size === 0) {
- this.deleteChannel(ch);
- }
- }
- }
-
-
- async terminateSession(socket, close = false) {
- // Cleans up the user session and removes them from all channels
- const nickname = this.nicknames.get(socket);
- if (nickname) {
- if (!socket.signedoff) {
- let serverSocket = null;
- for (const [srvSocket, users] of this.serverusers.entries()) {
- if (users && typeof users.has === 'function' && users.has(nickname)) {
- // Don't send QUIT to this server, as it owns the user
- serverSocket = srvSocket;
- continue;
- }
- }
- await this.broadcastUser(nickname, `:${nickname}!${socket.username}@${socket.host} QUIT :Client disconnected\r\n`, socket);
- await this.broadcastToAllServers(`:${socket.uniqueId} QUIT :Client disconnected\r\n`, serverSocket);
- socket.signedoff = true; // Just in case
- }
- this.cleanupUserSession(nickname);
- this.nicknames.delete(socket);
- }
- if (socket.isserver) {
- const srvUsers = this.serverusers.get(socket) || [];
- for (const nickname of srvUsers) {
- // Remove all user data for this server
- this.debugLog('debug', `Removing user ${nickname} from server ${socket.servername}`);
- if (users && typeof users.delete === 'function') {
- users.delete(nickname);
- }
- this.cleanupUserSession(nickname);
- }
- this.servers.delete(socket);
- this.serverusers.delete(socket);
- } else {
- this.clients = this.clients.filter(c => c !== socket);
- }
- if (socket._idleInterval) {
- clearInterval(socket._idleInterval);
- socket._idleInterval = null;
- }
-
- // Clean up rate limiting data
- const socketId = socket.remoteAddress + ':' + socket.remotePort;
- this.message_counts.delete(socketId);
-
- // Clean up connection count per IP
- const clientIP = socket.remoteAddress;
- if (this.connections_per_ip.has(clientIP)) {
- const currentCount = this.connections_per_ip.get(clientIP);
- if (currentCount <= 1) {
- this.connections_per_ip.delete(clientIP);
- } else {
- this.connections_per_ip.set(clientIP, currentCount - 1);
- }
- }
-
- if (close) {
- socket.end();
- }
- }
-
- async sendWebTVNotice(message) {
- // Send a WebTV Global Notice to all WebTV clients
- await this.broadcastToAllWebTVClients(`:${this.servername} NOTICE * :${message}\r\n`);
- }
-
- async sendWebTVNoticeTo(socket, message) {
- // Sends a WebTV Global Notice to the specified socket
- if (Array.isArray(message)) {
- message = message.map(line => `:${this.servername} NOTICE * :${line}\r\n`);
- await this.sendThrottled(socket, message);
- return;
- }
- await this.safeWriteToSocket(socket, `:${this.servername} NOTICE * :${message}\r\n`);
- }
-
- async sendWebTVSpoofedActionTo(socket, channel, message) {
- if (!Array.isArray(message)) {
- message = [message];
- }
- if (this.clientIsWebTV(socket)) {
- message.forEach(async (line) => {
- const msg = line.split(' ');
- const firstWord = msg[0];
- const action = msg.slice(1).join(' ');
- const message = [`:${firstWord}!system@webtv PRIVMSG ${channel} :\x01ACTION ${action}\x01\r\n`];
- await this.sendThrottled(socket, message);
- });
- return;
- }
- }
-
- getUserChannelCount(username) {
- // returns the number of channels a user is in
- let count = 0;
- for (const [channel, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(username)) {
- count++;
- }
- }
- return count;
- }
-
- getUsersInChannel(channel) {
- // Returns an array of users in a specific channel, with modes applied
- if (this.channelData.has(channel)) {
- const channelObj = this.channelData.get(channel);
- const ops = channelObj.ops || new Set();
- const halfops = channelObj.halfops || new Set();
- const voices = channelObj.voices || new Set();
- return Array.from(channelObj.users).map(user => {
- if (ops.has(user)) return '@' + user;
- if (halfops.has(user)) return '%' + user;
- if (voices.has(user)) return '+' + user;
- return user;
- });
- }
- }
-
- async broadcastUser(username, message, exceptSocket = null) {
- // Broadcast a message to all users in any channels that the specified user is in, except the one specified
- const alreadyNotified = [];
- for (const [channel, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(username)) {
- for (const user of channelObj.users) {
- const sock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
- if (alreadyNotified.includes(sock)) {
- continue;
- }
- if (sock && sock !== exceptSocket) {
- await this.safeWriteToSocket(sock, message);
- alreadyNotified.push(sock);
- }
- }
- }
- }
- }
-
- async broadcastChannel(channel, message, exceptSocket = null) {
- // Broadcast a message to all users in a specific channel, except the one specified
- const alreadyNotified = [];
- if (this.channelData.has(channel)) {
- const channelObj = this.channelData.get(channel);
- for (const user of channelObj.users) {
- // +Z (secureonly): Restricts private message (PRIVMSG) or notice (NOTICE) reception/sending to users with a secure connection (TLS).
- if (channelObj.modes.includes('Z') && (message.includes('PRIVMSG') || message.includes('NOTICE'))) {
- const user_modes = this.getUserModes(user);
- if (user_modes.includes('z')) {
- const sock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
- if (alreadyNotified.includes(sock)) {
- continue;
- }
- if (sock && sock !== exceptSocket) {
- await this.safeWriteToSocket(sock, message);
- alreadyNotified.push(sock);
- }
- }
- }
- else {
- const sock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
- if (alreadyNotified.includes(sock)) {
- continue;
- }
- if (sock && sock !== exceptSocket) {
- sock.write(message);
- alreadyNotified.push(sock);
- }
- }
- }
- }
- }
-
- async broadcastChannelWebTV(channel, message, exceptSocket = null) {
- // Broadcast a message to all WebTV users in a specific channel, except the one specified
- const alreadyNotified = [];
- if (this.channelData.has(channel)) {
- const channelObj = this.channelData.get(channel);
- for (const user of channelObj.users) {
- const socket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
- if (alreadyNotified.includes(socket)) {
- continue;
- }
- // Only send to WebTV clients
- if (socket && socket !== exceptSocket && this.clientIsWebTV(socket)) {
- this.sendWebTVSpoofedActionTo(socket, channel, message)
- alreadyNotified.push(socket);
- }
- }
- }
- }
-
- async broadcastChannelJoin(channel, sourceSocket, exceptSocket = null) {
- // Broadcast a channel join message to all users in the channel, except the one specified
- channel = this.findChannel(channel);
- if (!channel) {
- this.debugLog('warn', `Attempted to broadcast join to non-existent channel: ${channel}`);
- return;
- }
- if (this.channelData.has(channel)) {
- const channelObj = this.channelData.get(channel);
- for (const user of channelObj.users) {
- const sock = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
- if (sock && sock !== exceptSocket) {
- if (sock.client_caps && sock.client_caps.includes('extended-join')) {
- const account = this.accounts.get(sourceSocket.nickname) || '*';
- const userinfo = this.userinfo.get(sourceSocket.nickname) || '';
- await this.safeWriteToSocket(sock, `:${sourceSocket.nickname}!${sourceSocket.username}@${sourceSocket.host} JOIN ${channel} ${account} :${userinfo}\r\n`);
- } else {
- await this.safeWriteToSocket(sock,`:${sourceSocket.nickname}!${sourceSocket.username}@${sourceSocket.host} JOIN ${channel}\r\n`);
- }
- }
- }
- } else {
- this.debugLog('warn', `Attempted to broadcast join to non-existent channel: ${channel}`);
- }
- }
-
- async broadcastToAllServers(message, exceptSocket = null) {
- // Broadcast a message to all server sockets, except the one specified
- for (const [srvSocket, serverName] of this.servers.entries()) {
- if (srvSocket && srvSocket !== exceptSocket) {
- await this.safeWriteToSocket(srvSocket, message);
- }
- }
- }
-
- async broadcastWallops(message) {
- // Broadcast a message to all users with 'w' or 'o' user modes
- for (const [socket, nickname] of this.nicknames.entries()) {
- const usermodes = this.getUserModes(nickname);
- if (usermodes.includes('w') || usermodes.includes('o')) {
- await this.safeWriteToSocket(socket, message);
- }
- }
- }
-
- async broadcastToAllClients(message, exceptSocket = null) {
- // Broadcast a message to all connected clients, except the one specified
- for (const client of this.clients) {
- if (client !== exceptSocket) {
- await this.safeWriteToSocket(client, message);
- }
- }
- }
-
- async broadcastToAllWebTVClients(message, exceptSocket = null) {
- // Broadcast a message to all connected WebTV clients, except the one specified
- for (const client of this.clients) {
- if (client !== exceptSocket && this.clientIsWebTV(client)) {
- await this.safeWriteToSocket(client, message);
- }
- }
- }
-
- isIRCOp(nickname) {
- // Check if the user is an IRC operator
- if (!this.getUserModes(nickname)) return false;
- const modes = this.getUserModes(nickname);
- if (Array.isArray(modes)) {
- return modes.includes('o');
- }
- return false;
- }
-
- isSpyingOnConnections(nickname) {
- if (!this.getUserModes(nickname)) return false;
- const modes = this.getUserModes(nickname);
- if (Array.isArray(modes)) {
- return modes.includes('c');
- }
- return false;
- }
-
- createChannel(channel, creator) {
- // Create a new channel with the specified creator
- if (!this.channelData.has(channel)) {
- this.channelData.set(channel, {
- users: new Set(),
- ops: new Set([creator]),
- halfops: new Set(),
- voices: new Set(),
- topic: '',
- bans: new Set(),
- exemptions: new Set(),
- invites: new Set(),
- modes: [...this.default_channel_modes],
- mlock: [],
- limit: null,
- key: null,
- timestamp: this.getDate()
- });
- }
- }
-
- checkMask(mask, socket) {
- // Check if a mask matches a user's socket
- const host = socket.host;
- const realhost = socket.realhost;
- const realaddress = socket.remoteAddress;
- const nickname = this.nicknames.get(socket);
- let fullMask = `*!*@${host}`;
- let fullMask2 = `*!*@${realhost}`;
- let fullMask3 = `*!*@${realaddress}`;
- let userIdent;
- if (nickname) {
- userIdent = this.usernames.get(nickname) || nickname;
- fullMask = `${nickname}!${userIdent}@${host}`;
- fullMask2 = `${nickname}!${userIdent}@${realhost}`;
- fullMask3 = `${nickname}!${userIdent}@${realaddress}`;
- }
-
-
- // If mask does not contain '!', treat as nickname or username only
- if (!mask.includes('!')) {
- // Wildcard match for just the nickname or username
- // Try matching against both nickname and username
- const maskRegex = new RegExp('^' + mask.replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
- return maskRegex.test(nickname) || maskRegex.test(userIdent);
- }
-
- // If mask contains '!', match against full mask (nick!user@host)
- // Split mask into nick, user, host
- const [maskNick, rest] = mask.split('!', 2);
- const [maskUser, maskHost] = (rest || '').split('@', 2);
-
- // Split fullMask into nick, user, host
- const [fullNick, fullRest] = fullMask.split('!', 2);
- const [fullUser, fullHost] = (fullRest || '').split('@', 2);
-
- // Build regex for each part, defaulting to '*' if missing
- const nickRegex = new RegExp('^' + (maskNick || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
- const userRegex = new RegExp('^' + (maskUser || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
- const hostRegex = new RegExp('^' + (maskHost || '*').replace(/\*/g, '.*').replace(/\?/g, '.') + '$', 'i');
- let matches = nickRegex.test(fullNick) && userRegex.test(fullUser) && hostRegex.test(fullHost);
- if (!matches && fullMask2) {
- // Try matching against the real host if available
- const [fullNick2, fullRest2] = fullMask2.split('!', 2);
- const [fullUser2, fullHost2] = (fullRest2 || '').split('@', 2);
- matches = nickRegex.test(fullNick2) && userRegex.test(fullUser2) && hostRegex.test(fullHost2);
- }
- if (!matches && fullMask3) {
- // Try matching against the real IP if available
- const [fullNick3, fullRest3] = fullMask3.split('!', 2);
- const [fullUser3, fullHost3] = (fullRest3 || '').split('@', 2);
- matches = nickRegex.test(fullNick3) && userRegex.test(fullUser3) && hostRegex.test(fullHost3);
- }
- return matches;
- }
-
- filterHostname(socket, hostname) {
- // Masks the user's hostname or IP for privacy
- const username = this.nicknames.get(socket);
- let modes = null;
- if (username) {
- modes = this.getUserModes(username);
- }
- if (modes) {
- if (Array.isArray(modes) && modes.includes('x')) {
- // Masked hostname for +x users
- if (typeof hostname === 'string') {
- // Mask everything except the first and last octet for IPv4
- // Mask IP-like subdomains (e.g., 1-1-1-1.domain.com)
- const ipSubdomainMatch = hostname.match(/^(\d+)-(\d+)-(\d+)-(\d+)\./);
- if (ipSubdomainMatch) {
- return `${ipSubdomainMatch[1]}-x-x-${ipSubdomainMatch[4]}.${hostname.split('.').slice(1).join('.')}`;
- }
- const ipv4Match = hostname.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
- if (ipv4Match) {
- return `${ipv4Match[1]}.x.x.${ipv4Match[4]}`;
- }
- // For hostnames, mask all but the first and last label
- const parts = hostname.split('.');
- if (parts.length > 2) {
- return `${parts[0]}.x.${parts[parts.length - 1]}`;
- }
- // Otherwise, just return 'hidden.host'
- return 'hidden.host';
- }
- }
- }
- return hostname;
- }
-
- isBanned(channel, socket) {
- // Check if a user is banned from a channel
- const nickname = this.nicknames.get(socket);
- channel = this.findChannel(channel);
- if (!channel) {
- return false;
- }
- if (this.channelData.has(channel).bans) {
- const bans = this.channelData.get(channel).bans;
- // Check if the user's mask matches any ban mask
- let isUserBanned = false;
- for (const banMask of bans) {
- isUserBanned = this.checkMask(banMask, socket);
- if (isUserBanned) {
- if (this.channelexemptions.has(channel)) {
- const exemptions = this.channelexemptions.get(channel);
- for (const exemptMask of exemptions) {
- isUserBanned = !this.checkMask(exemptMask, socket);
- if (!isUserBanned) {
- break;
- }
- }
- }
- }
- }
- return isUserBanned;
- }
- return false;
- }
-
- findSocketByUniqueId(uniqueId) {
- // Find a socket related to a unique ID
- for (const [socket, nickname] of this.nicknames.entries()) {
- if (socket.uniqueId === uniqueId) {
- // client socket
- return socket;
- }
- }
- for (const [srvSocket, users] of this.serverusers.entries()) {
- const searchID = this.findUserByUniqueId(uniqueId);
- if (users.has(searchID)) {
- // server socket
- return srvSocket;
- }
- }
- return null;
- }
-
- findUserByUniqueId(uniqueId) {
- // Find a user by their unique ID
- let uniqueids = this.uniqueids || new Map();
- if (!uniqueids || uniqueids === true) {
- uniqueids = new Map();
- }
- for (const [nickname, id] of uniqueids.entries()) {
- if (id === uniqueId) {
- return nickname;
- }
- }
- for (const [socket, users] of this.serverusers.entries()) {
- for (const user of users) {
- if (this.getUniqueId(user) === uniqueId) {
- return user;
- }
- }
- }
- return null;
- }
-
- addUserUniqueId(nickname, uniqueId) {
- // Add or update the unique ID for a user
- if (!this.uniqueids || this.uniqueids === true) {
- this.uniqueids = new Map();
- }
- this.uniqueids.set(nickname, uniqueId);
- }
-
- deleteUserUniqueId(nickname) {
- // Remove the unique ID for a user
- if (this.uniqueids && this.uniqueids.has(nickname)) {
- this.uniqueids.delete(nickname);
- }
- }
-
- async doMOTD(nickname, socket = null) {
- // Sends the Message of the Day (MOTD) to the user
- const output_lines = [];
- output_lines.push(`:${this.servername} 375 ${nickname} :${this.servername} message of the day\r\n`);
- if (!this.irc_config.hide_version) {
- output_lines.push(`:${this.servername} 372 ${nickname} :This is zefIRCd v${this.version}, running on minisrv v${this.minisrv_config.version}\r\n`);
- }
- if (typeof this.irc_motd === 'string' && this.irc_motd.length > 0) {
- output_lines.push(`:${this.servername} 372 ${nickname} :${this.irc_motd}\r\n`);
- } else if (Array.isArray(this.irc_motd) && this.irc_motd.length > 0) {
- for (let line of this.irc_motd) {
- if (line === '') {
- line = '-';
- }
- output_lines.push(`:${this.servername} 372 ${nickname} :- ${line}\r\n`);
- }
- } else {
- output_lines.push(`:${this.servername} 372 ${nickname} :No message of the day is set\r\n`);
- }
- output_lines.push(`:${this.servername} 376 ${nickname} :End of /MOTD command\r\n`);
- if (socket) {
- await this.sendThrottled(socket, output_lines);
- } else {
- return output_lines;
- }
- }
-
- isReservedChannel(channel) {
- // Check if the channel is a reserved channel
- if (this.irc_config.channels && Array.isArray(this.irc_config.channels)) {
- return this.irc_config.channels.some(ch => ch.name === channel);
- }
- return false;
- }
-
- checkIfReservedChannelOp(socket, channel) {
- // Check if the channel is a reserved channel and if the user is an operator for that channel
- if (this.isReservedChannel(channel)) {
- const reservedChannel = this.irc_config.channels.find(ch => ch.name === channel);
- // reservedChannel.ops is an array of masks
- if (reservedChannel && reservedChannel.ops && Array.isArray(reservedChannel.ops)) {
- for (const mask of reservedChannel.ops) {
- if (this.checkMask(mask, socket)) {
- return true; // User is an operator for this reserved channel
- }
- }
- }
- }
- return false; // User is not an operator for this reserved channel
- }
-
- isRemoteServerUser(socket, username) {
- // Check if the user is a remote server user
- let serverUsers = this.serverusers.get(socket) || new Set();
- if (!serverUsers || serverUsers === true) {
- serverUsers = new Set();
- }
- for (const user of serverUsers) {
- if (typeof user === 'string' && user.toLowerCase() === username.toLowerCase()) {
- return true;
- }
- }
- return false;
- }
-
- addRemoteServerUser(socket, username) {
- // Add a remote server user to the serverusers map
- if (!this.serverusers.has(socket)) {
- this.serverusers.set(socket, new Set());
- }
- this.serverusers.get(socket).add(username);
- }
-
- getRemoteServerUserSocket(username) {
- // Find the socket of a remote server user by username
- for (const [socket, users] of this.serverusers.entries()) {
- for (const user of users) {
- if (typeof user === 'string' && user.toLowerCase() === username.toLowerCase()) {
- return socket;
- }
- }
- }
- return null;
- }
-
-
-
- getUsernameFromUniqueId(uniqueId) {
- // Find the username associated with a unique ID
- for (const [socket, nickname] of this.nicknames.entries()) {
- if (socket.uniqueId === uniqueId) {
- return nickname;
- }
- }
- for (const [nick, id] of this.uniqueids.entries()) {
- if (id === uniqueId) {
- return nick;
- }
- }
- return null;
- }
-
- getUniqueId(username) {
- // Find the unique ID for a given username
- const socket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s).toLowerCase() === username.toLowerCase());
- if (socket) {
- return socket.uniqueId;
- } else {
- for (const [nick, id] of this.uniqueids.entries()) {
- if (nick.toLowerCase() === username.toLowerCase()) {
- return id;
- }
- }
- }
- return null;
- }
-
- countGlobalUsers() {
- // Counts the total number of users across all clients and server users
- let globalUsers = this.clients.length;
- for (const users of this.serverusers.values()) {
- if (users && typeof users.size === 'number') {
- globalUsers += users.size;
- } else if (Array.isArray(users)) {
- globalUsers += users.length;
- }
- }
- return globalUsers;
- }
-
- processNickChange(socket, newNick) {
- // Handles nickname changes, assumes the newNick is already validated
- // Update all channel user lists to use channelData
- for (const [ch, channelObj] of this.channelData.entries()) {
- if (channelObj.users.has(socket.nickname)) {
- channelObj.users.delete(socket.nickname);
- channelObj.users.add(newNick);
- }
- }
- this.usernames.set(newNick, this.usernames.get(socket.nickname) || socket.nickname);
- this.usernames.delete(socket.nickname);
- this.nicknames.set(socket, newNick);
- this.nicknames.delete(socket.nickname);
- this.addUserUniqueId(newNick, socket.uniqueId);
- this.deleteUserUniqueId(socket.nickname);
- this.usermodes.set(newNick, this.getUserModes(socket.nickname) || []);
- this.usermodes.delete(socket.nickname);
- if (this.awaymsgs.has(socket.nickname)) {
- this.awaymsgs.set(newNick, this.awaymsgs.get(socket.nickname) || '');
- this.awaymsgs.delete(socket.nickname);
- }
- this.usersignontimestamps.set(newNick, this.usersignontimestamps.get(socket.nickname) || this.getDate());
- this.usersignontimestamps.delete(socket.nickname);
- socket.nickname = newNick;
- }
-
- generateUniqueId(socket) {
- // Generate a unique ID
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- let id = '';
- for (let i = 0; i < 6; i++) {
- id += chars.charAt(Math.floor(Math.random() * chars.length));
- }
- if (this.uniqueids.has(id)) {
- // If the ID already exists, generate a new one
- return this.generateUniqueId(socket);
- }
- return id;
- }
-
- async sendThrottled(socket, lines, delayMs = 1) {
- for (const line of lines) {
- await new Promise(res => setTimeout(res, delayMs));
- if (socket.writable) {
- await this.safeWriteToSocket(socket, line);
- }
- }
- }
-
- getDate() {
- // Returns the current timestamp in seconds
- return Math.floor(Date.now() / 1000)
- }
-
- findChannel(channel) {
- // Normalize the channel name to lowercase for case-insensitive comparison
- let foundChannel = null;
- for (const existingChannel of this.channelData.keys()) {
- if (existingChannel.toLowerCase() === channel.toLowerCase()) {
- foundChannel = existingChannel;
- break;
- }
- }
- return foundChannel;
- }
-
- findUser(username) {
- // Normalize the username to lowercase for case-insensitive comparison
- let foundUser = null;
- if (typeof username !== 'string') {
- return null;
- }
- for (const [socket, nick] of this.nicknames.entries()) {
- if (nick.toLowerCase() === username.toLowerCase()) {
- foundUser = nick;
- break;
- }
- }
- return foundUser;
- }
-
- clientIsWebTV(socket) {
- // Check if the client is a WebTV client based on the client version
- if (socket.client_version.includes('WebTV')) {
- return true;
- }
- return false;
- }
-
- async broadcastUserIfCap(socket, message, exceptSocket = null, client_cap) {
- if (socket.client_caps.includes(client_cap)) {
- await this.broadcastUser(socket.nickname, message, exceptSocket);
- }
- }
-
- async broadcastUserIfCapAndChanOp(socket, message, exceptSocket = null, client_cap, channel) {
- if (socket.client_caps.includes(client_cap)) {
- // Check if the user is an operator in the specified channel
- channel = this.findChannel(channel);
- if (!channel) {
- this.debugLog('warn', `Attempted to broadcast to channel ${channel} that does not exist.`);
- return;
- }
- const channelObj = this.channelData.get(channel);
- const isOp = channelObj.ops.has(socket.nickname) || false;
- const isHalfOp = channelObj.halfops.has(socket.nickname) || false;
- if (isOp || isHalfOp) {
- await this.broadcastUser(socket.nickname, message, exceptSocket);
- }
- }
- }
-
- async broadcastConnection(clientSocket, quitMsg = null) {
- // Broadcasts a connection message to all clients with mode +c
- for (const [index, socket] of this.clients.entries()) {
- if (socket !== clientSocket && this.isSpyingOnConnections(socket.nickname)) {
- if (quitMsg) {
- await this.sendWebTVNoticeTo(socket, `*** Notice --- Client exiting: ${clientSocket.nickname} (${clientSocket.username}@${clientSocket.host}) [${clientSocket.remoteAddress}] [${quitMsg}]`);
- this.debugLog('info', `Client exiting: ${clientSocket.nickname} (${clientSocket.username}@${clientSocket.host}) [${clientSocket.remoteAddress}] [${quitMsg}]`);
- } else {
- await this.sendWebTVNoticeTo(socket, `*** Notice --- Client connecting: ${clientSocket.nickname} (${clientSocket.username}@${clientSocket.host}) [${clientSocket.remoteAddress}] {users} [${clientSocket.userinfo}] <${clientSocket.uniqueId}>`);
- this.debugLog('info', `Client connecting: ${clientSocket.nickname} (${clientSocket.username}@${clientSocket.host}) [${clientSocket.remoteAddress}] {users} [${clientSocket.userinfo}] <${clientSocket.uniqueId}>`);
- }
- }
- }
- }
-
- getUserModes(nickname) {
- // Returns the user modes for a given nickname
- let foundSocket = null;
- for (const [socket, nick] of this.nicknames.entries()) {
- if (nick.toLowerCase() === nickname.toLowerCase()) {
- foundSocket = socket;
- nickname = socket.nickname; // Ensure we use the correct nickname
- break;
- }
- }
- if (!foundSocket) {
- // Also search this.serverusers for remote users (case-insensitive)
- for (const [srvSocket, users] of this.serverusers.entries()) {
- if (users && typeof users.forEach === 'function') {
- for (const user of users) {
- if (typeof user === 'string' && user.toLowerCase() === nickname.toLowerCase()) {
- foundSocket = srvSocket;
- nickname = user;
- break;
- }
- }
- } else if (Array.isArray(users)) {
- for (const user of users) {
- if (typeof user === 'string' && user.toLowerCase() === nickname.toLowerCase()) {
- foundSocket = srvSocket;
- nickname = user;
- break;
- }
- }
- }
- if (foundSocket) break;
- }
- }
- if (!foundSocket) {
- return null;
- }
- const modes = this.usermodes.get(nickname);
- if (!modes || modes === true) {
- this.usermodes.set(nickname, [...this.default_user_modes]);
- }
- return this.usermodes.get(nickname);
- }
-
- setUserMode(nickname, mode, adding) {
- // Sets a user mode for a given nickname
- const modes = this.getUserModes(nickname);
- if (adding) {
- if (!modes.includes(mode)) {
- modes.push(mode);
- }
- } else {
- const index = modes.indexOf(mode);
- if (index !== -1) {
- modes.splice(index, 1);
- }
- }
- }
-
- async getHostname(socket) {
- // Resolve the hostname for a socket, using reverse DNS lookup
- let hostname;
- if (socket && socket.remoteAddress) {
- try {
- hostname = socket.remoteAddress;
- hostname = await new Promise((resolve) => {
- dns.reverse(socket.remoteAddress, (err, hostnames) => {
- if (!err && hostnames && hostnames.length > 0) {
- socket.hostname_resolved = true;
- this.safeWriteToSocket(socket, `:${this.servername} NOTICE AUTH :*** Hostname found: ${hostnames[0]}\r\n`);
- resolve(hostnames[0]);
- } else {
- if (!err) {
- err = 'Domain name not found';
- }
- socket.hostname_resolved = true;
- this.safeWriteToSocket(socket, `:${this.servername} NOTICE AUTH :*** Could not resolve your hostname: ${err}; using your IP address (${socket.remoteAddress}) instead.\r\n`);
- resolve(socket.remoteAddress);
- }
- });
- });
- } catch (e) {
- this.debugLog('error', `Error resolving hostname for ${socket.remoteAddress}: ${e}`);
- socket.hostname_resolved = true;
- await this.safeWriteToSocket(socket, `:${this.servername} NOTICE AUTH :*** Could not resolve your hostname: ${e}; using your IP address (${socket.remoteAddress}) instead.\r\n`);
- }
- return hostname;
- }
- }
-
- async doInitialHandshake(socket) {
- // Perform the initial handshake with the client
- // We pause the socket to prevent sending data before the hostname is resolved
- await this.safeWriteToSocket(socket, `:${this.servername} NOTICE AUTH :*** Looking up your hostname\r\n`);
- socket.pause();
- socket.host = await this.getHostname(socket);
- socket.resume();
- socket.realhost = socket.host;
- }
-
- async scanSocketForKLine(socket) {
- for (const kline of this.klines) {
- if (this.checkMask(kline.mask, socket)) {
- if (kline.expiry && kline.expiry > this.getDate()) {
- if (kline.reason) {
- await this.safeWriteToSocket(socket, `:${this.servername} KILL ${socket.nickname} :K-lined: ${kline.reason}\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} KILL ${socket.uniqueId} :K-lined: ${kline.reason}\r\n`, socket);
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} KILL ${socket.nickname} :K-lined\r\n`);
- await this.broadcastToAllServers(`:${socket.uniqueId} KILL ${socket.uniqueId} :K-lined\r\n`, socket);
- }
- this.terminateSession(socket, true);
- return true;
- } else {
- const klineIndex = this.klines.findIndex(k => k.mask === kline.mask);
- if (klineIndex !== -1) {
- this.klines.splice(klineIndex, 1);
- }
- this.saveKLinesToFile();
- }
- }
- }
- return false;
- }
-
- async scanUsersForKLines() {
- for (const kline of this.klines) {
- for (const socket of this.nicknames.keys()) {
- if (this.checkMask(kline.mask, socket)) {
- if (kline.expiry && kline.expiry > this.getDate()) {
- if (kline.reason) {
- await this.safeWriteToSocket(socket, `:${this.servername} KILL ${socket.nickname} :K-lined: ${kline.reason}\r\n`);
- await this.broadcastUser(socket.nickname, `:${socket.nickname}!${socket.username}@${socket.host} KILL :K-lined: ${kline.reason}\r\n`);
- } else {
- await this.safeWriteToSocket(socket, `:${this.servername} KILL ${socket.nickname} :K-lined\r\n`);
- await this.broadcastUser(socket.nickname, `:${socket.nickname}!${socket.username}@${socket.host} KILL :K-lined\r\n`);
- }
- await this.broadcastToAllServers(`:${socket.uniqueId} KILL ${socket.uniqueId} :K-lined: ${kline.reason}\r\n`, socket);
- this.terminateSession(socket, true);
- } else {
- const klineIndex = this.klines.findIndex(k => k.mask === kline.mask);
- if (klineIndex !== -1) {
- this.klines.splice(klineIndex, 1);
- }
- this.saveKLinesToFile();
- }
- }
- }
- }
- }
-
- saveKLinesToFile() {
- // Ensure the session store directory exists
- if (!fs.existsSync(this.session_store_path)) {
- fs.mkdirSync(this.session_store_path, { recursive: true });
- }
- // Save the KLines to a file
- fs.writeFileSync(this.klines_path, JSON.stringify(this.klines, null, 2));
- }
-
- loadKLinesFromFile() {
- // Load KLines from a file if it exists
- if (fs.existsSync(this.klines_path)) {
- const data = fs.readFileSync(this.klines_path, 'utf8');
- this.klines = JSON.parse(data);
- }
- }
-
- getGitRevision() {
- try {
- const gitPath = __dirname + path.sep + ".." + path.sep + ".." + path.sep + ".." + path.sep + ".git" + path.sep
- const rev = fs.readFileSync(gitPath + "HEAD").toString().trim();
- if (rev.indexOf(':') === -1) {
- return rev.slice(0, 8);
- } else {
- return fs.readFileSync(gitPath + rev.slice(5)).toString().trim().slice(0, 8) + "-" + rev.split('/').pop();
- }
- } catch (e) {
- return null;
- }
- }
-
- isChannelOp(nickname, channel) {
- // Check if the user is a channel operator
- channel = this.findChannel(channel);
- if (!channel) {
- return false; // Channel not found
- }
- const channelOps = this.channelData.get(channel).ops;
- if (channelOps === true) {
- return false;
- }
- if (channelOps.has(nickname)) {
- return true; // User is a channel operator
- }
- // Check if the user is an IRC operator
- if (this.isIRCOp(nickname)) {
- return true; // IRC operator is considered a channel operator
- }
- }
-
- isChannelHalfOp(nickname, channel) {
- // Check if the user is a channel half-operator
- channel = this.findChannel(channel);
- if (!channel) {
- return false; // Channel not found
- }
- const channelHalfOps = this.channelData.get(channel).halfops;
- if (channelHalfOps === true) {
- return false;
- }
- if (channelHalfOps.has(nickname)) {
- return true; // User is a channel half-operator
- }
- // Check if the user is an IRC operator
- if (this.isIRCOp(nickname)) {
- return true; // IRC operator is considered a channel half-operator
- }
- }
-
-
- processChannelModeParams(channel, mode, target) {
- let result = false;
- if (!target) {
- this.debugLog('warn', `No target specified for mode ${mode} on channel ${channel}`);
- return false;
- }
- if (mode === '+o' || mode === '-o') {
- const channelOps = this.channelData.get(channel).ops;
- if (mode === '+o') {
- if (!channelOps.has(target)) {
- channelOps.add(target);
- return true;
- }
- } else if (mode === '-o') {
- if (channelOps.has(target)) {
- channelOps.delete(target);
- return true;
- }
- }
- } else if (mode === '+h' || mode === '-h') {
- const channelHalfOps = this.channelData.get(channel).halfops;
- if (mode === '+h') {
- if (!channelHalfOps.has(target)) {
- channelHalfOps.add(target);
- return true;
- }
- } else if (mode === '-h') {
- if (channelHalfOps.has(target)) {
- channelHalfOps.delete(target);
- return true;
- }
- }
- } else if (mode === '+v' || mode === '-v') {
- const channelVoices = this.channelData.get(channel).voices;
- if (mode === '+v') {
- if (!channelVoices.has(target)) {
- channelVoices.add(target);
- return true;
- }
- } else if (mode === '-v') {
- if (channelVoices.has(target)) {
- channelVoices.delete(target);
- return true;
- }
- }
- } else if (mode === '+b' || mode === '-b') {
- let channelBans = this.channelData.get(channel).bans;
- if (mode === '+b') {
- if (!channelBans.includes(target)) {
- channelBans.push(target);
- return true;
- }
- } else if (mode === '-b') {
- if (channelBans.includes(target)) {
- channelBans = channelBans.filter(ban => ban !== target);
- return true;
- }
- }
- } else if (mode === '+e' || mode === '-e') {
- let channelExemptions = this.channelData.get(channel).exemptions;
- if (mode === '+e') {
- if (!channelExemptions.includes(target)) {
- channelExemptions.push(target);
- return true;
- }
- } else if (mode === '-e') {
- if (channelExemptions.includes(target)) {
- channelExemptions = channelExemptions.filter(exception => exception !== target);
- return true;
- }
- }
- } else if (mode === '+I' || mode === '-I') {
- let channelInvites = this.channelData.get(channel).inviteexemptions;
- if (mode === '+I') {
- if (!channelInvites.includes(target)) {
- channelInvites.push(target);
- return true;
- }
- } else if (mode === '-I') {
- if (channelInvites.includes(target)) {
- channelInvites = channelInvites.filter(invite => invite !== target);
- return true;
- }
- }
- } else if (mode === '+l' || mode === '-l') {
- if (mode === '+l') {
- result = this.setChannelMode(channel, 'l', true);
- if (result === false && this.channelData.get(channel).limit === parseInt(target)) {
- return false; // Mode already set with the same limit
- }
- this.channelData.get(channel).limit = parseInt(target);
- return true;
- } else {
- result = this.setChannelMode(channel, 'l', false);
- if (result === false && this.channelData.get(channel).limit === null) {
- return false; // Mode already unset
- }
- this.channelData.get(channel).limit = null;
- return true;
- }
- } else if (mode === '+k' || mode === '-k') {
- if (mode === '+k') {
- result = this.setChannelMode(channel, 'k', true);
- if (result === false && this.channelData.get(channel).key === target) {
- return false; // Mode already set with the same key
- }
- this.channelData.get(channel).key = target;
- return true;
- } else {
- result = this.setChannelMode(channel, 'k', false);
- if (result === false && !this.channelData.get(channel).key) {
- return false; // Mode already unset
- }
- this.channelData.get(channel).key = null;
- return true;
- }
- }
- }
-
- async processChannelModes(nickname, channel, modes, params, socket) {
- // Split modes into array and process each character
- const modeChars = modes.split('');
- const validModes = [];
- const supportedChannelModes = (this.supported_channel_modes.split(',').join('') + this.supported_prefixes[0]).split('');
- let serverModeMsg = '';
- let target = null;
- if (socket.isserver) {
- const sourceUniqueId = this.uniqueids.get(nickname);
- serverModeMsg = `:${sourceUniqueId} MODE ${channel} `;
- } else {
- if (!this.checkRegistered(socket)) {
- return;
- }
- serverModeMsg = `:${socket.uniqueId} MODE ${channel} `;
- }
- const username = this.usernames.get(nickname);
- const hostname = this.hostnames.get(nickname);
-
- let modeMsg = `:${nickname}!${username}@${hostname} MODE ${channel} `;
- let WTVMsg = `${nickname} has set channel mode `;
- let addingFlag = false;
- let paramIndex = 0;
- const output_lines = [];
- if (!socket.isserver) {
- if (modeChars.includes('o')) {
- if (!this.isIRCOp(nickname) && !this.isChannelOp(nickname, channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${nickname} ${channel} :You're not a channel operator\r\n`);
- return;
- }
- }
- else if (modeChars.includes('O')) {
- if (!this.isIRCOp(nickname))
- {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${nickname} ${channel} :You're not an IRC operator\r\n`);
- return;
- }
- } else if (modes === 'b') {
- // Get the list of channel ban
- if (this.channelData.has(channel).bans) {
- const bans = this.channelData.has(channel).bans;
- for (const ban of bans) {
- output_lines.push(`:${this.servername} 367 ${nickname} ${channel} ${ban}\r\n`);
- }
- }
- output_lines.push(`:${this.servername} 368 ${nickname} ${channel} :End of channel ban list\r\n`);
- await this.sendThrottled(socket, output_lines);
- return;
- } else if (modes === 'e') {
- // Get the list of channel exemptions
- if (this.channelData.has(channel).exemptions) {
- const exemptions = this.channelData.has(channel).exemptions;
- for (const exemption of exemptions) {
- output_lines.push(`:${this.servername} 348 ${nickname} ${channel} ${exemption}\r\n`);
- }
- }
- output_lines.push(`:${this.servername} 349 ${nickname} ${channel} :End of channel exception list\r\n`);
- await this.sendThrottled(socket, output_lines);
- return;
- } else if (modes === 'I') {
- // Get the list of channel invites masks
- if (this.channelData.has(channel).invites) {
- const invites = this.channelData.has(channel).invites;
- for (const invite of invites) {
- output_lines.push(`:${this.servername} 336 ${nickname} ${channel} ${invite}\r\n`);
- }
- }
- output_lines.push(`:${this.servername} 337 ${nickname} ${channel} :End of channel invite list\r\n`);
- await this.sendThrottled(socket, output_lines);
- return;
- } else {
- if (!this.isIRCOp(nickname) && !this.isChannelOp(nickname, channel) && !this.isChannelHalfOp(nickname, channel)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 482 ${nickname} ${channel} :You're not a channel operator\r\n`);
- return;
- }
- }
- }
- for (let j = 0; j < modeChars.length; j++) {
- let param = null;
- let modeStr = '';
- const mc = modeChars[j];
- let result = false;
- if (mc === '+') {
- addingFlag = true;
- modeMsg += '+';
- WTVMsg += '+';
- serverModeMsg += '+';
- continue;
- } else if (mc === '-') {
- addingFlag = false;
- modeMsg += '-';
- WTVMsg += '-';
- serverModeMsg += '-';
- continue;
- }
- if (!supportedChannelModes.includes(mc)) {
- if (!socket.isserver) {
- await this.safeWriteToSocket(socket, `:${this.servername} 472 ${nickname} ${channel} :Unknown channel mode char: ${mc}\r\n`);
- }
- continue;
- }
- modeStr += mc;
- // Modes that require a parameter
- if ([...this.supported_prefixes[0], 'I', 'b', 'e', 'l', 'k'].includes(mc)) {
- const plusminus = (addingFlag) ? "+" : "-";
- param = params[paramIndex];
- if (socket.isserver) {
- target = this.findUserByUniqueId(param);
- } else {
- target = this.findUser(param);
- }
- if ((!target && !socket.isserver) || !this.channelData.get(channel).users.has(target)) {
- await this.safeWriteToSocket(socket, `:${this.servername} 401 ${nickname} ${param} :No such nick/channel\r\n`);
- return;
- }
- result = this.processChannelModeParams(channel, plusminus + mc, target, socket);
- paramIndex++;
- if (!result) {
- if (params.length > 0) {
- params.shift();
- }
- }
- } else {
- result = this.setChannelMode(channel, mc, addingFlag);
- if (addingFlag) {
- if (mc === 'S' && this.kick_insecure_users_on_secure) {
- // Kick users who do not have user mode +z
- const usersInChannel = this.channelData.get(channel).users;
- for (const user of usersInChannel) {
- const userSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === user);
- if (userSocket && !userSocket.secure) {
- await this.safeWriteToSocket(userSocket, `:${nickname}!${username}@${socket.host} KICK ${channel} ${userSocket.nickname} :Channel is now +S (SSL-only, +z usermode required)\r\n`);
- await this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} KICK ${channel} ${userSocket.nickname} :Channel is now +S (SSL-only, +z usermode required)\r\n`, userSocket);
- await this.broadcastToAllServers(`:${sourceUniqueId} KICK ${channel} ${userSocket.uniqueId} :Channel is now +S (SSL-only, +z usermode required)\r\n`);
- this.channelData.get(channel).users.delete(userSocket.nickname);
- }
- }
- }
- }
- }
- if (result) {
- WTVMsg += mc;
- validModes.push(mc);
- if (modeStr.length > 0) {
- modeMsg += modeStr;
- serverModeMsg += modeStr;
- }
- }
- }
- if (params.length > 0) {
- for (let i = 0; i < params.length; i++) {
- if (socket.isserver) {
- modeMsg += ' ' + this.findUserByUniqueId(params[i]);
- } else {
- modeMsg += ' ' + params[i];
- WTVMsg += ' ' + params[i];
- }
- serverModeMsg += ' ' + params[i];
- }
- }
- if (modeMsg.endsWith('-') || modeMsg.endsWith('+')) {
- return;
- }
- modeMsg += '\r\n';
- if (validModes.length > 0) {
- await this.broadcastChannel(channel, modeMsg);
- await this.broadcastChannelWebTV(channel, WTVMsg);
- await this.broadcastToAllServers(serverModeMsg, socket);
- }
- }
-
- async addSocketError(socket) {
- socket.error_count++;
- if (socket.error_count >= 5) {
- if (socket.writable) {
- await this.safeWriteToSocket(socket, `:${this.servername} :ERROR :Too many errors, disconnecting\r\n`);
- }
- this.terminateSession(socket, true);
- return;
- }
- setTimeout((socket) => {
- if (socket) {
- socket.error_count--;
- }
- }, 60000);
- }
-
- async checkRegistered(socket, allowUnregistered = false, silent = false) {
- let retval = false;
- if (socket.isserver) {
- if (!socket.is_srv_authorized && (!socket.registered && !allowUnregistered)) {
- if (socket.writable && !silent) {
- await this.safeWriteToSocket(socket, `:${this.servername} ERROR :Unauthorized\r\n`);
- }
- this.addSocketError(socket);
- } else {
- retval = true; // Server is authorized
- }
- }
- if (!socket.registered && (!socket.registered && !allowUnregistered)) {
- if (socket.writable && !silent) {
- await this.safeWriteToSocket(socket, `:${this.servername} 451 ${socket.uniqueId} :You have not registered\r\n`);
- }
- this.addSocketError(socket);
- } else {
- retval = true; // User is registered
- }
- return retval;
- }
-
- setChannelMode(channel, mode, adding) {
- // Updates the channel modes for a given channel
- const modes = this.channelData.get(channel).modes;
- if (!modes) {
- return false; // Channel not found
- }
- if (adding) {
- if (!modes.includes(mode)) {
- modes.push(mode);
- return true;
- }
- } else {
- const index = modes.indexOf(mode);
- if (index !== -1) {
- modes.splice(index, 1);
- return true;
- }
- }
- return false; // Mode not changed
- }
-
- debugLog(type = 'debug', ...message) {
- const parsedMessage = message.map(m =>
- typeof m === 'object' ? JSON.stringify(m) : String(m)
- ).join(' ');
-
- // Logs debug messages to the console if debugging is enabled
- switch (type) {
- case 'debug':
- this.logdata.push(`[DEBUG] ${parsedMessage}`);
- if (this.debug) {
- console.log(`[DEBUG] ${parsedMessage}`);
- }
- break;
- case 'warn':
- this.logdata.push(`[WARN] ${parsedMessage}`);
- if (this.debug) {
- console.warn(`[WARN] ${parsedMessage}`);
- }
- break;
- case 'error':
- this.logdata.push(`[ERROR] ${parsedMessage}`);
- if (this.debug) {
- console.error(`[ERROR] ${parsedMessage}`);
- }
- break;
- case 'info':
- this.logdata.push(`[INFO] ${parsedMessage}`);
- if (this.debug) {
- console.info(`[INFO] ${parsedMessage}`);
- }
- break;
- default:
- this.logdata.push(`[LOG] ${parsedMessage}`);
- if (this.debug) {
- console.log(`[LOG] ${parsedMessage}`);
- }
- }
- if (this.logdata.length > this.max_log_lines) {
- this.logdata.shift();
- }
- }
-
- async doLogin(nickname, socket) {
- if (await this.scanSocketForKLine(socket)) {
- return; // If the socket is K-lined, exit early
- }
- this.addUserUniqueId(nickname, socket.uniqueId);
- this.hostnames.set(nickname, socket.host);
- this.realhosts.set(nickname, socket.realhost);
- await this.safeWriteToSocket(socket, `:${this.servername} PRIVMSG ${socket.nickname} :\x01VERSION\x01\r\n`);
- let waited = 0;
- while (socket.client_version === '' && waited < 3000) {
- await new Promise(res => setTimeout(res, 100));
- waited += 100;
- }
- const output_lines = [];
- output_lines.push(`:${this.servername} NOTICE AUTH :Welcome to \x02${this.network}\x0F\r\n`);
- output_lines.push(`:${this.servername} 001 ${nickname} :Welcome to the IRC server, ${nickname}\r\n`);
- output_lines.push(`:${this.servername} 002 ${nickname} :Your host is ${this.servername}, running version zefIRCd v${this.version}\r\n`);
- output_lines.push(`:${this.servername} 003 ${nickname} :This server is ready to accept commands\r\n`);
- // Sort supported_channel_modes and supported_user_modes alphabetically with capitals first
- function sortModesAlphaCapsFirst(modes) {
- // Remove commas, split to chars, sort, then re-insert commas if needed
- // If input is comma-separated groups, sort each group
- return modes
- .split(',')
- .map(group => {
- return group
- .split('')
- .sort((a, b) => {
- // Capital letters first, then lowercase, then numbers/symbols
- if (a === b) return 0;
- const isACap = a >= 'A' && a <= 'Z';
- const isBCap = b >= 'A' && b <= 'Z';
- const isALower = a >= 'a' && a <= 'z';
- const isBLower = b >= 'a' && b <= 'z';
- if (isACap && !isBCap) return -1;
- if (!isACap && isBCap) return 1;
- if (isALower && !isBLower) return -1;
- if (!isALower && isBLower) return 1;
- return a.localeCompare(b);
- })
- .join('');
- })
- .join(',');
- }
- const channelModesParts = this.supported_channel_modes.split(',');
- let sortedModesWithParams;
- if (channelModesParts.length > 1) {
- let modesToSort = channelModesParts.slice(0, -1).join('').split('');
- modesToSort.push(...this.supported_prefixes[0].split(''));
- modesToSort = Array.from(new Set(modesToSort)); // remove duplicates
- modesToSort.sort();
- sortedModesWithParams = modesToSort.join('');
- }
- const channelModes = this.supported_channel_modes.split(',').join('') + this.supported_prefixes[0];
- const sortedChannelModes = sortModesAlphaCapsFirst(channelModes).replace(/,/g, '');
- const sortedUserModes = sortModesAlphaCapsFirst(this.supported_user_modes);
- output_lines.push(`:${this.servername} 004 ${nickname} ${this.servername} zefIRCd-${this.version} ${sortedUserModes} ${sortedChannelModes} ${sortedModesWithParams}\r\n`);
- for (const caps of this.caps) {
- output_lines.push(`:${this.servername} 005 ${caps}\r\n`);
- }
- socket.registered = true;
- output_lines.push(`:${this.servername} 042 ${nickname} ${socket.uniqueId} :your unique ID\r\n`);
-
- output_lines.push(...(await this.doMOTD(nickname)));
-
- const visibleClients = Array.from(this.nicknames.values()).filter(nick => {
- const modes = this.usermodes.get(nick) || [];
- return !modes.includes('i');
- });
- const invisibleClients = Array.from(this.nicknames.values()).filter(nick => {
- const modes = this.usermodes.get(nick) || [];
- return modes.includes('i');
- });
- const operClients = Array.from(this.nicknames.values()).filter(nick => {
- const modes = this.usermodes.get(nick) || [];
- return modes.includes('o');
- });
- const serverCount = this.servers.size + 1; // Include this server
- output_lines.push(`:${this.servername} 251 ${nickname} :There are ${visibleClients.length} visible users and ${invisibleClients.length} invisible users on this server\r\n`);
- if (operClients.length > 0) {
- output_lines.push(`:${this.servername} 252 ${nickname} ${operClients.length} :operator(s) online\r\n`);
- }
- if (this.channelData.size > 0) {
- output_lines.push(`:${this.servername} 253 ${nickname} ${this.channelData.size} :channels formed\r\n`);
- }
- output_lines.push(`:${this.servername} 255 ${nickname} :I have ${this.clients.length} clients and ${serverCount} servers\r\n`);
- output_lines.push(`:${this.servername} 265 ${nickname} :Current Local Users: ${this.clients.length} Max: ${this.clientpeak}\r\n`);
- const globalUsers = this.countGlobalUsers();
- this.globalpeak = Math.max(this.globalpeak, this.countGlobalUsers());
- const totalSockets = this.clients.length + this.servers.size;
- this.socketpeak = Math.max(this.socketpeak, totalSockets);
-
- output_lines.push(`:${this.servername} 266 ${nickname} :Current Global Users: ${globalUsers} Max: ${this.globalpeak}\r\n`);
- output_lines.push(`:${this.servername} 250 ${nickname} :Highest connection count: ${this.socketpeak} (${this.clientpeak} clients) (${this.totalConnections} connections received)\r\n`);
- let usermodes = this.usermodes.get(nickname);
- if (!usermodes || usermodes === true) {
- usermodes = [];
- }
- for (const mode of this.default_user_modes) {
- if (!usermodes.includes(mode)) {
- usermodes.push(mode);
- }
- }
- if (socket.secure) {
- usermodes.push('z');
- }
- this.usermodes.set(nickname, [...usermodes]);
- if (usermodes.includes('x')) {
- socket.host = this.filterHostname(socket, socket.realhost);
- if (socket.client_caps && socket.client_caps.includes('CHGHOST')) {
- output_lines.push(`:${socket.nickname}!${socket.username}@${socket.host} CHGHOST ${socket.username} ${socket.host}\r\n`);
- }
- output_lines.push(`:${this.servername} 396 ${socket.nickname} ${socket.host} :is now your visible host\r\n`);
- }
- output_lines.push(`:${this.servername} 221 ${nickname} :+${this.usermodes.get(nickname).join('')}\r\n`);
- await this.sendThrottled(socket, output_lines);
- for (const [srvSocket, serverName] of this.servers.entries()) {
- if (srvSocket) {
- // Compose UID message for this client
- const nickname = socket.nickname;
- const username = socket.username || this.usernames.get(socket.nickname) || socket.nickname;
- const uniqueId = socket.uniqueId;
- const signonTime = socket.timestamp || this.getDate();
- const userModes = (this.usermodes.get(nickname) || []).join('');
- const userinfo = socket.userinfo || '';
- await this.safeWriteToSocket(srvSocket, `:${this.serverId} UID ${nickname} 1 ${signonTime} +${userModes} ${username} ${socket.host} ${socket.realhost} ${socket.remoteAddress} ${uniqueId} * ${nickname} :${userinfo}\r\n`);
- }
- }
- await this.broadcastConnection(socket);
- }
-}
-
-module.exports = WTVIRC;
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVMail.js b/zefie_wtvp_minisrv/includes/classes/WTVMail.js
index 1e55bb8b..0ee95438 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVMail.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVMail.js
@@ -119,7 +119,7 @@ class WTVMail {
getMailboxByName(mailbox_name) {
let mailbox_id = false;
this.mailboxes.every(function (v, k) {
- if (v.toLowerCase() == mailbox_name.toLowerCase()) {
+ if (v.toLowerCase() === mailbox_name.toLowerCase()) {
mailbox_id = k;
return false;
}
@@ -238,7 +238,7 @@ class WTVMail {
subj = header[1];
break;
}
- } else if (line == '') end_of_headers = true;
+ } else if (line === '') end_of_headers = true;
else {
msg += line.replace(/\$\{(\w{1,})\}/g, function (x) {
let out = '';
@@ -327,7 +327,7 @@ class WTVMail {
if (v.name.slice((v.name.length - self.msgFileExt.length)) === self.msgFileExt) return v.name.slice(0, (v.name.length - 5));
});
- if (files.length == 0) return false; // no messages
+ if (files.length === 0) return false; // no messages
else {
// todo filter previous results when offset
const messagelist_out = new Array();
@@ -388,7 +388,7 @@ class WTVMail {
const temp_session_data_file = self.fs.readFileSync(search_dir + self.path.sep + file, 'Utf8');
const temp_session_data = JSON.parse(temp_session_data_file);
if (temp_session_data.subscriber_username) {
- if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) {
+ if (temp_session_data.subscriber_username.toLowerCase() === username.toLowerCase()) {
// Use the absolute path for replacement since search_dir is now absolute
const accounts_dir = self.wtvshared.getAbsolutePath(self.minisrv_config.config.SessionStore + self.path.sep + "accounts" + self.path.sep);
let path_after_replace = search_dir.replace(accounts_dir, '');
@@ -505,7 +505,7 @@ class WTVMail {
const mailbox_name = this.getMessageMailboxName(messageid);
if (!mailbox_name) return false;
- const mailboxid = this.mailboxes.findIndex((value) => value == mailbox_name);
+ const mailboxid = this.mailboxes.findIndex((value) => value === mailbox_name);
if (mailboxid !== false) return this.getMessage(mailboxid, messageid);
return null;
@@ -515,7 +515,7 @@ class WTVMail {
// returns true if successful, false if failed.
const currentMailbox = this.getMessageMailboxID(messageid);
// Same mailbox
- if (dest_mailbox_id == currentMailbox) return false;
+ if (dest_mailbox_id === currentMailbox) return false;
// Invalid destination mailbox ID
if (dest_mailbox_id > (this.mailboxes.length - 1) || dest_mailbox_id < 0) return false;
@@ -540,7 +540,7 @@ class WTVMail {
deleteMessage(messageid) {
const currentMailbox = this.getMessageMailboxName(messageid);
const trashMailbox = this.getMailboxByName(this.trashMailboxName);
- if (currentMailbox != trashMailbox) {
+ if (currentMailbox !== trashMailbox) {
// if not in the trash, move it to trash
return this.moveMailMessage(messageid, trashMailbox);
} else {
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVMime.js b/zefie_wtvp_minisrv/includes/classes/WTVMime.js
index da54b4d9..647e674f 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVMime.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVMime.js
@@ -35,7 +35,7 @@ class WTVMime {
if (ssid_session) {
// if gzip is enabled...
if (this.minisrv_config.config.enable_gzip_compression || this.minisrv_config.config.force_compression_type) {
- const is_bf0app = ssid_session.get("wtv-client-rom-type") == "bf0app";
+ const is_bf0app = ssid_session.get("wtv-client-rom-type") === "bf0app";
const isOldBuild = this.wtvshared.isOldBuild(ssid_session);
let is_softmodem = false;
if (ssid_session.get("wtv-client-rom-type")) is_softmodem = ssid_session.get("wtv-client-rom-type").match(/softmodem/);
@@ -52,23 +52,23 @@ class WTVMime {
// mostly for debugging
- if (this.minisrv_config.config.force_compression_type == "lzpf") compression_type = 1;
- if (this.minisrv_config.config.force_compression_type == "gzip") compression_type = 2;
+ if (this.minisrv_config.config.force_compression_type === "lzpf") compression_type = 1;
+ if (this.minisrv_config.config.force_compression_type === "gzip") compression_type = 2;
// do not compress if already encoded
if (headers_obj["Content-Encoding"]) return 0;
// should we bother to compress?
let content_type = "";
- if (typeof (headers_obj) == 'string') content_type = headers_obj;
+ if (typeof (headers_obj) === 'string') content_type = headers_obj;
else content_type = (typeof (headers_obj["wtv-modern-content-type"]) !== 'undefined') ? headers_obj["wtv-modern-content-type"] : headers_obj["Content-type"];
if (content_type) {
// both lzpf and gzip
- if (content_type.match(/^text\//) && content_type != "text/tellyscript") compress_data = true;
+ if (content_type.match(/^text\//) && content_type !== "text/tellyscript") compress_data = true;
else if (content_type.match(/^application\/(x-?)javascript$/)) compress_data = true;
- else if (content_type == "application/json") compress_data = true;
- if (compression_type == 2) {
+ else if (content_type === "application/json") compress_data = true;
+ if (compression_type === 2) {
// gzip only
if (content_type.match(/^audio\/(x-)?(s3m|mod|xm|midi|wav|wave|aif(f)?)$/)) compress_data = true; // s3m, mod, xm, midi & wav
if (content_type.match(/^application\/karaoke$/)) compress_data = true; // midi karaoke
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVNews.js b/zefie_wtvp_minisrv/includes/classes/WTVNews.js
index ac2f9878..e5603210 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVNews.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVNews.js
@@ -37,13 +37,13 @@ class WTVNews {
connectUsenet() {
return new Promise((resolve, reject) => {
this.client.connect().then((response) => {
- if (response.code == 200 || response.code == 201) {
- if (response.code == 201) this.posting_allowed = false;
+ if (response.code === 200 || response.code === 201) {
+ if (response.code === 201) this.posting_allowed = false;
if (this.username && this.password) {
this.client.authInfoUser(this.username).then((res) => {
- if (res.code == "381") {
+ if (res.code === 381) {
res.authInfoPass(this.password).then((res) => {
- if (res.code == 281) resolve(true);
+ if (res.code === 281) resolve(true);
else reject(res.description);
}).catch((e) => {
console.error(" * WTVNews Error:", "Command: connect", e);
@@ -124,7 +124,7 @@ class WTVNews {
selectGroup(group) {
return new Promise((resolve, reject) => {
this.client.group(group).then((response) => {
- if (response.code == 211) resolve(response);
+ if (response.code === 211) resolve(response);
else reject(`No such group ${group} `);
}).catch((e) => {
console.error(" * WTVNews Error:", "Command: selectGroup", e);
@@ -241,7 +241,7 @@ class WTVNews {
let response;
if (message.article.headers) {
Object.keys(message.article.headers).forEach((k) => {
- if (k.toLowerCase() == header.toLowerCase()) {
+ if (k.toLowerCase() === header.toLowerCase()) {
response = message.article.headers[k];
return false;
}
@@ -253,7 +253,7 @@ class WTVNews {
quitUsenet() {
return new Promise((resolve, reject) => {
this.client.quit().then((response) => {
- if (response.code == 205) resolve(true);
+ if (response.code === 205) resolve(true);
else {
console.error(" * WTVNews Error:", "Command: quit", response.code);
reject(`Unexpected response code ${response.code}`);
@@ -290,7 +290,7 @@ class WTVNews {
Promise.all(promises).then(() => {
this.client.post()
.then((response) => {
- if (response.code == 340) {
+ if (response.code === 340) {
const articleData = {};
articleData.headers = {
'Relay-Version': "version zefie_wtvp_minisrv " + this.minisrv_config.version + "; site " + this.minisrv_config.config.domain_name,
@@ -356,7 +356,7 @@ class WTVNews {
const messages = [];
const promises = [];
for (const article in NGArticles) {
- if (article == "getCaseInsensitiveKey" || isNaN(article)) continue;
+ if (article === "getCaseInsensitiveKey" || isNaN(article)) continue;
promises.push(new Promise((resolve, reject) => {
this.getHeader(NGArticles[article]).then((data) => {
if (data.article) messages.push(data.article)
@@ -419,7 +419,7 @@ class WTVNews {
section_match = line.match(/^Content-Transfer-Encoding: (.+)/i)
if (section_match) attachments[i].content_encoding = section_match[1];
} else {
- if (section_type != null) {
+ if (section_type !== null) {
if (section_type.match("text/plain")) message_body += line;
else {
if (attachments[i].data) attachments[i].data += line;
@@ -459,7 +459,7 @@ class WTVNews {
const messageId = messages[k].messageId;
const ref = messages[k].headers.REFERENCES;
if (ref) {
- const res = message_id_roots.find(e => e.messageId == ref);
+ const res = message_id_roots.find(e => e.messageId === ref);
if (res) {
// see if its attached to a root post
if (message_relations[res.messageId]) message_relations[res.messageId].push({ "messageId": messageId, "index": k });
@@ -473,11 +473,11 @@ class WTVNews {
if (message_relations[j].length > 0) {
Object.keys(message_relations[j]).forEach((h) => {
if (found) return;
- if (message_relations[j][h].messageId == ref) {
+ if (message_relations[j][h].messageId === ref) {
let searchref = messages[message_relations[j][h].index].headers.REFERENCES || null;
let mainref = j; // j is already the main reference messageId
while (searchref !== null) {
- const searchart = messages.find(e => e.messageId == searchref);
+ const searchart = messages.find(e => e.messageId === searchref);
if (searchart) {
mainref = searchart.messageId;
searchref = searchart.headers.REFERENCES || null;
@@ -495,7 +495,7 @@ class WTVNews {
// If not found in relations, add as root (but check for duplicates first)
if (!found) {
- const existingRoot = message_id_roots.find(e => e.messageId == messageId);
+ const existingRoot = message_id_roots.find(e => e.messageId === messageId);
if (!existingRoot) {
message_id_roots.push({ "messageId": messageId, "index": k });
}
@@ -504,7 +504,7 @@ class WTVNews {
}
else {
// Check for duplicates before adding as root
- const existingRoot = message_id_roots.find(e => e.messageId == messageId);
+ const existingRoot = message_id_roots.find(e => e.messageId === messageId);
if (!existingRoot) {
message_id_roots.push({ "messageId": messageId, "index": k });
}
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVNewsServer.js b/zefie_wtvp_minisrv/includes/classes/WTVNewsServer.js
index 103ac219..0e80378e 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVNewsServer.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVNewsServer.js
@@ -40,7 +40,7 @@ class WTVNewsServer {
...nntp_server.prototype,
_authenticate: function (session) {
// authenticate
- if (session.authinfo_user == self.username && session.authinfo_pass == self.password) {
+ if (session.authinfo_user === self.username && session.authinfo_pass === self.password) {
session.posting_allowed = true;
return Promise.resolve(true);
}
@@ -157,7 +157,7 @@ class WTVNewsServer {
getHeader(message, header) {
if (message.headers) {
- const search = Object.keys(message.headers).find(e => (e.toLowerCase() == header.toLowerCase()));
+ const search = Object.keys(message.headers).find(e => (e.toLowerCase() === header.toLowerCase()));
if (search) return message.headers[search];
}
return null;
@@ -199,7 +199,7 @@ class WTVNewsServer {
let response;
if (headers) {
Object.keys(headers).forEach((k) => {
- if (k.toLowerCase() == header.toLowerCase()) {
+ if (k.toLowerCase() === header.toLowerCase()) {
response = k;
return false;
}
@@ -315,10 +315,10 @@ class WTVNewsServer {
}
} else out = { ...meta }
- if (meta.min_index == 0) force_update = true;
+ if (meta.min_index === 0) force_update = true;
if (this.featuredGroups) {
Object.keys(this.featuredGroups).forEach((k) => {
- if (group == this.featuredGroups[k].name) {
+ if (group === this.featuredGroups[k].name) {
out.wildmat = 'y';
out.description = this.featuredGroups[k].description
return false;
@@ -329,9 +329,9 @@ class WTVNewsServer {
if (force_update || this.doesMetaNeedRefreshing(meta)) {
out.total = 0;
this.fs.readdirSync(g).forEach(file => {
- if (file == "meta.json") return;
+ if (file === "meta.json") return;
const articleNumber = parseInt(file.split('.')[0]);
- if (out.min_index == 0) out.min_index = articleNumber;
+ if (out.min_index === 0) out.min_index = articleNumber;
else if (articleNumber < out.min_index) out.min_index = articleNumber;
else if (articleNumber > out.max_index) out.max_index = articleNumber;
@@ -371,18 +371,18 @@ class WTVNewsServer {
try {
const articleNumbers = [];
this.fs.readdirSync(g).forEach(file => {
- if (file == "meta.json") return;
+ if (file === "meta.json") return;
const articleNumber = parseInt(file.split('.')[0]);
articleNumbers.push(articleNumber);
});
articleNumbers.sort((a, b) => a - b)
- const index = articleNumbers.findIndex((e) => e == current) - 1;
+ const index = articleNumbers.findIndex((e) => e === current) - 1;
if (index >= 0) res = articleNumbers[index];
} catch (e) {
return e;
}
if (res) {
- if (res == current) return null;
+ if (res === current) return null;
const message = this.getArticle(group, res);
if (message.messageId) {
res = { "articleNumber": res, "message_id": message.messageId };
@@ -397,12 +397,12 @@ class WTVNewsServer {
try {
const articleNumbers = [];
this.fs.readdirSync(g).forEach(file => {
- if (file == "meta.json") return;
+ if (file === "meta.json") return;
const articleNumber = parseInt(file.split('.')[0]);
articleNumbers.push(articleNumber);
});
articleNumbers.sort((a, b) => a - b)
- const index = articleNumbers.findIndex((e) => e == current) + 1;
+ const index = articleNumbers.findIndex((e) => e === current) + 1;
if (index < articleNumbers.length) res = articleNumbers[index];
} catch (e) {
return e;
@@ -444,11 +444,11 @@ class WTVNewsServer {
try {
meta = this.getMetadata(group);
this.fs.readdirSync(g).forEach(file => {
- if (file == "meta.json") return;
+ if (file === "meta.json") return;
const articleNumber = parseInt(file.split('.')[0]);
if (articleNumber < start) return;
if (articleNumber > end) return false;
- if (out.min_index == null) out.min_index = articleNumber;
+ if (out.min_index === null) out.min_index = articleNumber;
else if (articleNumber < out.min_index) out.min_index = articleNumber;
if (articleNumber > out.max_index) out.max_index = articleNumber;
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVRegister.js b/zefie_wtvp_minisrv/includes/classes/WTVRegister.js
index 582f6b1d..edea5fce 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVRegister.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVRegister.js
@@ -16,7 +16,7 @@ class WTVRegister {
}
getServiceOperator(first_letter_lower = false) {
- if (this.service_owner == "a minisrv user") {
+ if (this.service_owner === "a minisrv user") {
if (first_letter_lower) return "the operator of this service";
else return "The operator of this service";
} else {
@@ -45,7 +45,7 @@ class WTVRegister {
let available = true;
if (this.fs.existsSync(directory)) {
this.fs.readdirSync(directory).forEach(file => {
- if (file.toLowerCase() == ssid.toLowerCase()) {
+ if (file.toLowerCase() === ssid.toLowerCase()) {
available = false;
return false;
}
@@ -97,7 +97,7 @@ class WTVRegister {
const temp_session_data_file = self.fs.readFileSync(directory + self.path.sep + file, 'Utf8');
const temp_session_data = JSON.parse(temp_session_data_file);
if (temp_session_data.subscriber_username) {
- if (temp_session_data.subscriber_username.toLowerCase() == username.toLowerCase()) {
+ if (temp_session_data.subscriber_username.toLowerCase() === username.toLowerCase()) {
return_val = true;
}
}
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVShared.js b/zefie_wtvp_minisrv/includes/classes/WTVShared.js
index 710c7d42..f2c27c21 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVShared.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVShared.js
@@ -205,7 +205,7 @@ class WTVShared {
* @return {boolean} true if the SSID is valid, false if not
*/
checkSSID(ssid) {
- if (ssid.slice(-2) == this.getSSIDCRC(ssid))
+ if (ssid.slice(-2) === this.getSSIDCRC(ssid))
return true;
return false;
}
@@ -412,8 +412,8 @@ class WTVShared {
exclusiveFilter: (frame) => {
let allowed = true;
Object.keys(frame.attribs).forEach((k) => {
- if (k == "href" || k == "background" || k == "src") {
- allowed = false;
+ if (k === "href" || k === "background" || k === "src") {
+ allowed = false;
const value = frame.attribs[k];
if (frame.tag !== "a") {
@@ -1043,7 +1043,7 @@ class WTVShared {
new_obj = this.cloneObj(obj)
new_obj["wtv-client-serial-number"] = this.censorSSID(new_obj["wtv-client-serial-number"]);
}
- return (new_obj != false) ? new_obj : obj;
+ return (new_obj !== false) ? new_obj : obj;
}
}
return obj;
@@ -1127,14 +1127,14 @@ class WTVShared {
*/
getAbsolutePath(path = '', directory = '.') {
// Check if directory is already an absolute path
- if (directory.length > 0 && (directory[0] == "/" || (directory.length >= 3 && directory[1] === ':' && directory[2] === this.path.sep))) {
+ if (directory.length > 0 && (directory[0] === "/" || (directory.length >= 3 && directory[1] === ':' && directory[2] === this.path.sep))) {
return this.path.resolve(directory + this.path.sep + path);
}
try {
// start with our absolute path (of app.js)
const appdir = this.path.resolve(__dirname + this.path.sep + '..' + this.path.sep + '..')
- if (path == '' && directory == '.') {
+ if (path === '' && directory === '.') {
return appdir;
}
// If the directory is a valid directory, prepend it to the path
@@ -1252,7 +1252,7 @@ class WTVShared {
if (overrides.exceptions) {
Object.keys(overrides.exceptions).forEach((j) => {
- if (k != overrides.exceptions[j]) out += self.minisrv_config.services[k].toString(overrides) + "\n";
+ if (k !== overrides.exceptions[j]) out += self.minisrv_config.services[k].toString(overrides) + "\n";
});
} else {
out += self.minisrv_config.services[k].toString(overrides) + "\n";
diff --git a/zefie_wtvp_minisrv/includes/classes/WTVShenanigans.js b/zefie_wtvp_minisrv/includes/classes/WTVShenanigans.js
index d9a6cb65..b89bcd86 100644
--- a/zefie_wtvp_minisrv/includes/classes/WTVShenanigans.js
+++ b/zefie_wtvp_minisrv/includes/classes/WTVShenanigans.js
@@ -41,7 +41,7 @@ class WTVShenanigans {
// shenanigans are enabled, so check if the requested shenanigan is within the level enabled
Object.keys(shenanigans).forEach((k) => {
- if (shenanigans[k] == value) {
+ if (shenanigans[k] === value) {
if (level >= shenanigans[k]) {
retval = true;
return false;
diff --git a/zefie_wtvp_minisrv/includes/config.json b/zefie_wtvp_minisrv/includes/config.json
index d64fdc7f..1fea4389 100644
--- a/zefie_wtvp_minisrv/includes/config.json
+++ b/zefie_wtvp_minisrv/includes/config.json
@@ -61,56 +61,6 @@
"filestore_storage": 16, // Megabytes
"scrapbook_storage": 8 // Megabytes
},
- "irc": {
- "enabled": false,
- "port": 1667,
- "oper_username": "minisrv",
- "oper_password": "changeme573",
- "oper_enabled": false, // Don't enable with default credentials!
- "channel_limit": 10,
- "enable_ssl": true,
- "ssl_cert": {
- /* self-signed, can be replaced with another cert */
- "cert": "%ServiceDeps%/irc/selfsigned_cert.pem",
- "key": "%ServiceDeps%/irc/selfsigned_key.pem"
- },
- "channels": [
- {
- "name": "#general",
- "modes": ["n","t"],
- "topic": "General Chat Channel",
- "intro": [
- "Welcome to the general chat channel!"
- ],
- "ops": [
- "*!*@127.0.0.1"
- ]
- },
- {
- "name": "#WebTV",
- "modes": ["n", "t", "c", "C", "T"],
- "topic": "Welcome to the WebTV channel",
- "intro": [
- "Welcome to the WebTV channel!"
- ],
- "ops": [
- "*!*@127.0.0.1"
- ]
- },
- {
- "name": "#secure",
- "modes": ["n", "t", "S", "Z"],
- "topic": "SSL only chat",
- "intro": [
- "Welcome to zefie's secure hangout",
- "Here, all traffic is SSL encrypted."
- ],
- "ops": [
- "*!*@127.0.0.1"
- ]
- }
- ]
- },
"pc_admin": {
"enabled": false,
"ip_whitelist": [
diff --git a/zefie_wtvp_minisrv/irconly.js b/zefie_wtvp_minisrv/irconly.js
deleted file mode 100644
index 3d4a6a38..00000000
--- a/zefie_wtvp_minisrv/irconly.js
+++ /dev/null
@@ -1,12 +0,0 @@
-'use strict';
-const path = require('path');
-const classPath = path.resolve(__dirname + path.sep + "includes" + path.sep + "classes" + path.sep) + path.sep;
-require(classPath + "Prototypes.js");
-const WTVIRC = require(classPath + "WTVIRC.js");
-const { WTVShared, clientShowAlert } = require(classPath + "WTVShared.js");
-const wtvshared = new WTVShared(); // creates minisrv_config
-
-const minisrv_config = wtvshared.readMiniSrvConfig(true, false, true);
-minisrv_config.version = require('./package.json').version;
-const ircServer = new WTVIRC(minisrv_config, '0.0.0.0', minisrv_config.config.irc.port, true);
-ircServer.start();
\ No newline at end of file
diff --git a/zefie_wtvp_minisrv/packer.js b/zefie_wtvp_minisrv/packer.js
index ec4bf335..fdab7e8f 100644
--- a/zefie_wtvp_minisrv/packer.js
+++ b/zefie_wtvp_minisrv/packer.js
@@ -14,7 +14,7 @@ if (process.argv) {
if (process.argv[2]) {
let reverse = false;
let file = process.argv[2];
- if (file == "-d") {
+ if (file === "-d") {
file = process.argv[3];
reverse = true;
}
diff --git a/zefie_wtvp_minisrv/sync_nntp.js b/zefie_wtvp_minisrv/sync_nntp.js
index a1083f47..86bdd1b4 100644
--- a/zefie_wtvp_minisrv/sync_nntp.js
+++ b/zefie_wtvp_minisrv/sync_nntp.js
@@ -62,7 +62,7 @@ function deleteMissing(group, articles) {
fs.readdirSync(g).forEach(file => {
const articleNumber = parseInt(file.split('.')[0]);
file = g + path.sep + file;
- if (!articles.find(e => (e == articleNumber))) {
+ if (!articles.find(e => (e === articleNumber))) {
console.log(" * ", group, "article", articleNumber, "deleted from upstream, removing locally")
fs.rmSync(file);
}
@@ -96,7 +96,7 @@ wtvnews.connectUsenet().then((res) => {
wtvnews.getArticle(article, false).then((message) => {
res = wtvnewsserver.createArticle(group, article, message);
if (res) {
- if (res == "exists") {
+ if (res === "exists") {
console.log(" * ", group, "article", article, "already exists")
} else {
console.log(" * Created", group, "article", article, res)
diff --git a/zefie_wtvp_minisrv/test.js b/zefie_wtvp_minisrv/test.js
index 6a7813e2..76702015 100644
--- a/zefie_wtvp_minisrv/test.js
+++ b/zefie_wtvp_minisrv/test.js
@@ -32,13 +32,15 @@ function checkScopeErrors(file) {
const eslintConfig = {
"parserOptions": {
"ecmaVersion": 2022,
- "sourceType": "module"
+ "sourceType": isServiceFile ? "script" : "module"
},
"env": {
"node": true,
"es2022": true
},
"rules": {
+ "eqeqeq": ["warn", "always"],
+ "no-eq-null": "warn",
"no-redeclare": 2,
"no-undef": 2,
"no-use-before-define": ["error", {"variables": false, "functions": false, "classes": false}],
@@ -192,6 +194,31 @@ function checkScopeErrors(file) {
{
"selector": "CallExpression[callee.type='MemberExpression'][callee.object.type='MemberExpression'][callee.object.property.name='session_data'][callee.property.name='hasCap']",
"message": "session_data.hasCap() is deprecated. Use session_data.capabilities.get() instead."
+ },
+ // Type coercion warnings
+ {
+ "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.value=/^\\d+$/][left.typeof='number'][right.type='Identifier']",
+ "message": "Comparing string literal that looks like a number with a variable using strict equality. Consider parseInt() or ensure both operands are the same type."
+ },
+ {
+ "selector": "BinaryExpression[operator='==='][left.type='Identifier'][right.type='Literal'][right.value=/^\\d+$/][right.typeof='number']",
+ "message": "Comparing variable with string literal that looks like a number using strict equality. Consider parseInt() or ensure both operands are the same type."
+ },
+ {
+ "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.typeof='string'][right.type='Literal'][right.typeof='number']",
+ "message": "Comparing string literal with number literal using strict equality. This will always be false."
+ },
+ {
+ "selector": "BinaryExpression[operator='==='][left.type='Literal'][left.typeof='number'][right.type='Literal'][right.typeof='string']",
+ "message": "Comparing number literal with string literal using strict equality. This will always be false."
+ },
+ {
+ "selector": "BinaryExpression[operator='!=='][left.type='Literal'][left.typeof='string'][right.type='Literal'][right.typeof='number']",
+ "message": "Comparing string literal with number literal using strict inequality. This will always be true."
+ },
+ {
+ "selector": "BinaryExpression[operator='!=='][left.type='Literal'][left.typeof='number'][right.type='Literal'][right.typeof='string']",
+ "message": "Comparing number literal with string literal using strict inequality. This will always be true."
}
]
}
@@ -294,8 +321,10 @@ function checkScopeErrors(file) {
fs.writeFileSync(tempConfigPath, JSON.stringify(eslintConfig, null, 2));
// Use ESLint to check for scope-related errors with let/const
- const eslintCmd = `npx eslint --no-eslintrc --config "${tempConfigPath}" --format compact "${file}"`;
-
+ // Create a temporary .eslintignore file to exclude files or directories
+ const eslintIgnorePath = path.join(__dirname, '.eslintignore');
+ const eslintCmd = `npx eslint --no-eslintrc --config "${tempConfigPath}" --ignore-path "${eslintIgnorePath}" --format compact "${file}"`;
+
exec(eslintCmd, (error, stdout, stderr) => {
// Clean up temporary config file
try {