diff --git a/little_website/package.json b/little_website/package.json new file mode 100644 index 0000000..6500d25 --- /dev/null +++ b/little_website/package.json @@ -0,0 +1,19 @@ +{ + "name": "little_website_phone", + "version": "1.0.0", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "body-parser": "^2.2.0", + "cors": "^2.8.5", + "express": "^5.1.0", + "express-rate-limit": "^8.0.1" + } +} diff --git a/little_website/public/index.html b/little_website/public/index.html new file mode 100644 index 0000000..e0fe65f --- /dev/null +++ b/little_website/public/index.html @@ -0,0 +1,23 @@ + + + + + Hosted on my phone btw + + + + +

Hosted on a phone from 2016 btw

+
Loading battery status...
+

Leave an anonymous message

+
+
+ +
+ +

Recent Messages

+ + + + + diff --git a/little_website/public/script.js b/little_website/public/script.js new file mode 100644 index 0000000..5766f24 --- /dev/null +++ b/little_website/public/script.js @@ -0,0 +1,53 @@ +async function loadBattery() { + const res = await fetch('/api/battery'); + const data = await res.json(); + console.log(data); + const battery_json = JSON.parse(data.battery); + const health = battery_json.health; + const status = battery_json.status; + const percentage = battery_json.percentage; + const voltage = battery_json.voltage; + const current = battery_json.current; + const temperature = battery_json.temperature; + let power = parseInt(voltage) * parseInt(current) / 1000000000; + power = String(power).substring(0, 5); + document.getElementById("battery-status").innerText = `Battery infos 🔋\n\nstatus : ${status}\nLevel : ${percentage}%\nPower : ${power}W (${current}µA x ${voltage}mV)\nTemperature : ${temperature}°C\nHealth : ${health}`; +} + +async function loadMessages() { + const res = await fetch('/api/messages'); + const data = await res.json(); + const list = document.getElementById("messages"); + list.innerHTML = ""; + data.forEach(msg => { + const li = document.createElement("li"); + li.textContent = `[${new Date(msg.time).toLocaleTimeString()}] ${msg.message}`; + list.appendChild(li); + }); +} + +document.getElementById("msgForm").addEventListener("submit", async (e) => { + e.preventDefault(); + const message = document.getElementById("message").value.trim().substring(0, 1000); + const captcha = {}; + const captchaAnswer = {}; + const res = await fetch("/api/message", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ message, captchaAnswer, captcha }) + }); + + const result = await res.json(); + if (result.success) { + alert("Message sent!"); + document.getElementById("message").value = ""; + loadMessages(); + } else { + alert(result); + } + +}); + +loadMessages(); +loadBattery(); +setInterval(loadBattery, 30000); diff --git a/little_website/public/shrek.png b/little_website/public/shrek.png new file mode 100644 index 0000000..736cb48 Binary files /dev/null and b/little_website/public/shrek.png differ diff --git a/little_website/public/style.css b/little_website/public/style.css new file mode 100644 index 0000000..4205cf4 --- /dev/null +++ b/little_website/public/style.css @@ -0,0 +1,34 @@ +body { + font-family: sans-serif; + padding: 20px; + max-width: 600px; + margin: auto; + background-image: url("shrek.png"); + background-repeat: no-repeat; + background-position: bottom; +} + +#battery-status { + font-size: 1.2em; + margin-bottom: 10px; + color: green; +} + +textarea { + width: 100%; + margin-bottom: 10px; +} + +ul { + list-style: none; + padding-left: 0; +} + +li { + border-bottom: 1px solid #ccc; + padding: 5px 0; + word-wrap: break-word; + overflow-wrap: break-word; + white-space: normal; + max-width: 100%; +} diff --git a/little_website/server.js b/little_website/server.js new file mode 100644 index 0000000..116a1c8 --- /dev/null +++ b/little_website/server.js @@ -0,0 +1,57 @@ +const express = require("express"); +const fs = require("fs"); +const path = require("path"); +const { exec } = require("child_process"); +const bodyParser = require("body-parser"); +const rateLimit = require("express-rate-limit"); +const app = express(); +const PORT = 3000; + +const limiter = rateLimit({ + windowMs: 10000, + max: 5, + message: "Try harder to make my battery boom lol", +}) + +app.use(express.static("public")); +app.use(bodyParser.json()); +app.use(limiter) + +// app.use("/api/message", limiter); +// app.use("/api/messages", limiter); +// app.use("/api/battery", limiter); + +const MESSAGES_FILES = "messages.json"; + +let messages = []; +if (fs.existsSync(MESSAGES_FILES)) { + messages = JSON.parse(fs.readFileSync((MESSAGES_FILES))); +} + +app.get("/api/messages", (req, res) => { + res.json(messages.slice(-20).reverse()); +}) + +app.post("/api/message", (req, res) => { + let { message, captchaAnswer, captcha } = req.body; + if (!message || !captchaAnswer || !captcha) return res.status(400).send("Missing fields"); + + //maybe some captcha verif here + + if (messages.length > 20) messages.shift(); + message = message.substring(0, 1000); + messages.push({ message, time: new Date().toISOString() }); + fs.writeFileSync(MESSAGES_FILES, JSON.stringify(messages, null, 2)); + res.json({ success: true }); +}); + +app.get("/api/battery", (req, res) => { + exec("./test_cmd", (err, stdout) => { + if (err) return res.status(500).send("termux-battery-status error"); + res.json({ battery: stdout.trim() }); + }); +}); + +app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`)); + + diff --git a/little_website/test_cmd b/little_website/test_cmd new file mode 100755 index 0000000..6b2ad36 --- /dev/null +++ b/little_website/test_cmd @@ -0,0 +1 @@ +termux-battery-status diff --git a/n8n_hosting_android/README.md b/n8n_hosting_android/README.md new file mode 100644 index 0000000..7d4dda1 --- /dev/null +++ b/n8n_hosting_android/README.md @@ -0,0 +1,14 @@ +# Intro & Prerequisite +n8n is a cool automation tool like zappier to automate your workflows. +But n8n source code is available and you can host it on your hardware ! +And in this guide I'll show you how to host n8n on an old android phone (And you do not need root) ! + +I assume you have read +https://github.com/Crizomb/android_hosting_tutorials/tree/main +Or already have Termux and ssh set-up. + +# Difficulties +The recommended way of running n8n is via docker. +But docker doesn't run natively on tmux, even with proot I didn't manage to get it working. +If your bootloader is unlocked it can be maybe better to install a custom OS to get docker working, but this tutorial is made for devices that are noot rooted. +