631 lines
19 KiB
JavaScript
631 lines
19 KiB
JavaScript
require("dotenv").config();
|
|
const express = require("express");
|
|
const cors = require("cors");
|
|
const fs = require("node:fs");
|
|
const wol = require("wol");
|
|
const mariadb = require("mariadb");
|
|
const bodyParser = require("body-parser");
|
|
const escapeString = require("sql-escape-string");
|
|
|
|
const pool = mariadb.createPool({
|
|
host: process.env.DB_HOST,
|
|
user: process.env.DB_USER,
|
|
password: process.env.DB_PASS,
|
|
connectionLimit: 5,
|
|
});
|
|
|
|
// initializing app
|
|
const app = express();
|
|
|
|
// initializing cors middleware for all routes
|
|
const corsOptions = {
|
|
origin: "*",
|
|
credentials: true,
|
|
};
|
|
|
|
app.use(cors(corsOptions));
|
|
app.use(bodyParser.json());
|
|
|
|
//////////////////////////////////////////////
|
|
// Personal Data //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/personalData", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * FROM trigger_database.personalData;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/personalData", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.personalData SET firstName = ${escapeString(req.body.firstName)}, lastName = ${escapeString(req.body.lastName)}, email = ${escapeString(req.body.email)}, physicalAddress = ${escapeString(req.body.physicalAddress)};`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
//////////////////////////////////////////////
|
|
// Messages //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/messages", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * FROM trigger_database.messages;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.get("/trigger/api/displayedGreeting", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query =
|
|
"SELECT * FROM trigger_database.messages ORDER BY RAND() LIMIT 1;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/messages", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.messages (message) VALUES (${escapeString(req.body.message)});`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/messages", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.messages SET message = ${escapeString(req.body.message)} WHERE id = ${req.body.id};`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/messages", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.messages WHERE id = ${req.body.id};`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
//////////////////////////////////////////////
|
|
// Application Data //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/applications", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * FROM trigger_database.applications;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.get("/trigger/api/enabledApplications", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query =
|
|
"SELECT * FROM trigger_database.applications WHERE enabled = 1;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/applications", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.applications (name, url, icon, baseUrl, filterName, enabled, \`index\`) VALUES (${escapeString(req.body.name)}, ${escapeString(req.body.url)}, ${escapeString(req.body.icon)}, ${escapeString(req.body.baseUrl)}, ${escapeString(req.body.filterName)}, ${req.body.enabled}, ${req.body.index});`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/applications", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.applications SET name = ${escapeString(req.body.name)}, url = ${escapeString(req.body.url)}, icon = ${escapeString(req.body.icon)}, baseUrl = ${escapeString(req.body.baseUrl)}, filterName = ${escapeString(req.body.filterName)}, enabled = ${req.body.enabled} WHERE id = ${req.body.id};`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/applications", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.applications WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.get("/trigger/api/appCategories", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query =
|
|
"SELECT filterName FROM trigger_database.applications UNION SELECT filterName FROM trigger_database.bookmarkCategories;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/applicationOrder", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
req.body.map((link) => {
|
|
conn
|
|
.query(
|
|
"UPDATE trigger_database.applications SET `index` = ? where id IN (?)",
|
|
[link.index, link.id],
|
|
)
|
|
.then((rows) => {
|
|
res.status(200);
|
|
});
|
|
});
|
|
res.send({ status: "success" });
|
|
conn.end();
|
|
});
|
|
|
|
//////////////////////////////////////////////
|
|
// Bookmark Data //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/bookmarks", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * FROM trigger_database.bookmarks;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/bookmarks", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.bookmarks (name, url, category, \`index\`) VALUES (${escapeString(req.body.name)}, ${escapeString(req.body.url)}, ${escapeString(req.body.category)}, ${req.body.index});`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/bookmarks", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.bookmarks SET name = ${escapeString(req.body.name)}, url = ${escapeString(req.body.url)}, category = ${escapeString(req.body.category)} WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/bookmarks", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
if (req.body.length > 1) {
|
|
req.body.map((link) => {
|
|
conn
|
|
.query("DELETE FROM trigger_database.bookmarks where id IN (?)", [
|
|
link.id,
|
|
])
|
|
.then(() => {
|
|
res.status(200);
|
|
});
|
|
});
|
|
res.send({ status: "success" });
|
|
} else {
|
|
const query = `DELETE FROM trigger_database.bookmarks WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then(() => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
}
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/bookmarkOrder", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
req.body.map((link) => {
|
|
conn
|
|
.query(
|
|
"UPDATE trigger_database.bookmarks SET `index` = ? where id IN (?)",
|
|
[link.index, link.id],
|
|
)
|
|
.then(() => {
|
|
res.status(200);
|
|
});
|
|
});
|
|
res.send({ status: "success" });
|
|
conn.end();
|
|
});
|
|
|
|
app.get("/trigger/api/bookmarkCategories", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * from trigger_database.bookmarkCategories;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/bookmarkCategories", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.bookmarkCategories (categoryName, categoryIndex, filterName) VALUES (${escapeString(req.body.categoryName)},${req.body.categoryIndex || 0},${escapeString(req.body.filterName)})`;
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/bookmarkCategories", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.bookmarkCategories SET categoryName = ${escapeString(req.body.categoryName)}, filterName = ${escapeString(req.body.filterName)} WHERE id = ${req.body.id};`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/bookmarkCategories", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.bookmarkCategories WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/bookmarkCategoryOrder", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
req.body.map((category) => {
|
|
conn
|
|
.query(
|
|
"UPDATE trigger_database.bookmarkCategories SET categoryIndex = ? where id IN (?)",
|
|
[category.index, category.id],
|
|
)
|
|
.then((rows) => {
|
|
res.status(200);
|
|
});
|
|
});
|
|
res.send({ status: "success" });
|
|
conn.end();
|
|
});
|
|
//////////////////////////////////////////////
|
|
// Provider Data //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/providers", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * FROM trigger_database.providers;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/providers", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.providers (name, url, prefix) VALUES (${escapeString(req.body.name)}, ${req.body.url}, ${req.body.prefix})`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/providers", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.providers SET name = ${escapeString(req.body.name)}, url = ${escapeString(req.body.url)}, prefix = ${escapeString(req.body.prefix)} WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/providers", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.providers WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
//////////////////////////////////////////////
|
|
// Theming //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/themes", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * FROM trigger_database.themes;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/themes", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.themes (name, backgroundImage, backgroundColor, searchColor, primaryColor, accentColor, borderColor) VALUES (${escapeString(req.body.name)},${escapeString(req.body.backgroundImage)},${escapeString(req.body.backgroundColor)},${escapeString(req.body.searchColor)},${escapeString(req.body.primaryColor)},${escapeString(req.body.accentColor)},${escapeString(req.body.borderColor)})`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/themes", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.themes SET name = ${escapeString(req.body.name)}, backgroundImage = ${escapeString(req.body.backgroundImage)}, backgroundColor = ${escapeString(req.body.backgroundColor)}, searchColor = ${escapeString(req.body.searchColor)}, primaryColor = ${escapeString(req.body.primaryColor)}, accentColor = ${escapeString(req.body.accentColor)}, borderColor = ${escapeString(req.body.borderColor)}, randomEnabled = ${req.body.randomEnabled ? 1 : 0} WHERE id = ${req.body.id};`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/themes", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.themes WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.get("/trigger/api/themePlaylists", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * FROM trigger_database.themePlaylists;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/themePlaylists", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.themePlaylists (name, themeList) VALUES (${escapeString(req.body.name)},${escapeString(req.body.themeList)});`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/themePlaylists", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.themePlaylists SET name = ${escapeString(req.body.name)}, themeList = ${escapeString(req.body.themeList)} WHERE id = ${req.body.id};`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/themePlaylists", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.themePlaylists WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.get("/trigger/api/backgrounds", async (req, res) => {
|
|
fs.readdir("../TriggerFrontend/dist/backgrounds", (err, files) => {
|
|
res.status(200).send(files);
|
|
});
|
|
});
|
|
|
|
//////////////////////////////////////////////
|
|
// Wake on LAN Clients //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/wolClients", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = "SELECT * from trigger_database.wolClients;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/wolClients", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.wolClients (hostname, macAddress) VALUES (${escapeString(req.body.hostname)}, ${escapeString(req.body.macAddress)})`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.patch("/trigger/api/wolClients", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `UPDATE trigger_database.wolClients SET hostname = ${escapeString(req.body.hostname)}, macAddress = ${escapeString(req.body.macAddress)} WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/wolClients", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.wolClients WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/wakeClient", async (req, res) => {
|
|
wol.wake(req.body.macAddress, () => {
|
|
res.status(200).send({ status: "success" });
|
|
});
|
|
});
|
|
|
|
//////////////////////////////////////////////
|
|
// Search //
|
|
//////////////////////////////////////////////
|
|
|
|
app.get("/trigger/api/searchHistory", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query =
|
|
"SELECT * FROM trigger_database.searchHistory ORDER BY dateTimeStamp DESC;";
|
|
conn.query(query).then((rows) => {
|
|
res.status(200).send(rows);
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.post("/trigger/api/searchHistory", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `INSERT INTO trigger_database.searchHistory (prefix, provider, searchTerm) VALUES (${escapeString(req.body.prefix)}, ${escapeString(req.body.provider)}, ${escapeString(req.body.searchTerm)})`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
app.delete("/trigger/api/searchHistory", async (req, res) => {
|
|
const conn = await pool.getConnection();
|
|
const query = `DELETE FROM trigger_database.searchHistory WHERE id = ${req.body.id}`;
|
|
conn
|
|
.query(query)
|
|
.then((rows) => {
|
|
res.status(200).send({ status: "success" });
|
|
})
|
|
.catch((err) => {
|
|
res.status(500).send({ error: err });
|
|
});
|
|
conn.end();
|
|
});
|
|
|
|
// app is listening on port 5000
|
|
app.listen(5000, "0.0.0.0", () => {});
|