Node-red file repository
MegaUpload personnel avec Node-RED
Objectif
Mettre en place un petit service de partage de fichiers :
- Upload protégé par login/mot de passe.
- Téléchargement public via une URL.
- Noms des fichiers pseudonymisés.
- Fichiers servis directement par Node-RED.
- Reverse proxy HTTPS assuré par Caddy.
Architecture :
Internet
|
v
Front-Router (Caddy)
|
v
Node-RED (main-host)
|
+--- Upload via flow Node-RED
|
+--- Fichiers statiques (/var/www/static-files)
Installation des modules
Installer :
node-red-contrib-http-multipart @alexandrainst/node-red-http-basic-auth
Le premier permet de recevoir des formulaires HTML multipart/form-data.
Le second ajoute une authentification HTTP Basic.
Répertoire de stockage
Créer un répertoire destiné à contenir les fichiers :
sudo mkdir -p /var/www/static-files sudo chown nodered:nodered /var/www/static-files
Adapter l'utilisateur si nécessaire.
Activation du serveur statique Node-RED
Modifier :
~/.node-red/settings.js
Décommenter et adapter :
httpStatic: [
{
path: "/var/www/static-files",
root: "/files/"
}
],
Redémarrer Node-RED :
systemctl --user restart nodered
Ou selon l'installation :
sudo systemctl restart nodered
Test :
echo hello > /var/www/static-files/test.txt
Puis ouvrir :
https://node-red.mon-domaine.fr/files/test.txt
Si le texte "hello" apparaît, le serveur statique fonctionne.
Page d'upload
URL :
https://node-red.mon-domaine.fr/megaupload/
HTML :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>MegaUpload</title>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
background: #f4f7fb;
}
.container {
max-width: 700px;
margin: 80px auto;
background: white;
padding: 40px;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
}
.upload-box {
text-align: center;
}
button {
background: #2563eb;
color: white;
border: 0;
padding: 12px 30px;
border-radius: 8px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1>📤 MegaUpload</h1>
<div class="upload-box">
pload/upload"
method="post"
enctype="multipart/form-data">
<input type="file"
name="fichier"
required>
<button type="submit">
Envoyer le fichier
</button>
</form>
</div>
</div>
</body>
</html>
Protection par mot de passe
Ajouter un noeud :
http basic auth
devant :
- GET /megaupload/
- POST /megaupload/upload
Ainsi :
[http in]
|
v
[http basic auth]
|
v
[template]
|
v
[http response]
Utilisateur unique
Configurer directement :
Utilisateur : upload Mot de passe : xxxx
Fichier d'utilisateurs
Format :
jean:motdepasse alice:motdepasse
Ou mieux, avec mots de passe bcrypt.
Exemple :
jean:$2y$10$... alice:$2y$10$...
Réception du fichier
Flow :
[httpInMultipart]
|
v
[http basic auth]
|
v
[function]
|
v
[exec]
|
v
[template]
|
v
[http response]
Configuration HTTP Multipart :
[
{
"name": "fichier",
"maxCount": 1
}
]
Pseudonymisation du nom de fichier
Function :
const f = msg.req.files.fichier[0];
// Extension
const pos = f.originalname.lastIndexOf(".");
const ext = (pos >= 0)
? f.originalname.substring(pos).toLowerCase()
: "";
// Identifiant unique
const id =
Date.now().toString(36) +
"-" +
Math.random().toString(36).substring(2, 10);
// Nom stocké
msg.safeName = id + ext;
// Nom affiché
msg.nomFichier =
f.originalname.replace(/[<>]/g, "");
// URL publique
msg.urlFichier =
"https://node-red.mon-domaine.fr/files/" +
encodeURIComponent(msg.safeName);
// Déplacement du fichier
msg.payload =
'-c \'mv "' + f.path +
'" "/var/www/static-files/' +
msg.safeName + '"\'';
return msg;
Exemple :
PhotoVacances.jpg
devient :
mrggesvw-hwdhacrc.jpg
Déplacement du fichier
Noeud Exec :
Command : bash Append : msg.payload
Le fichier temporaire créé par Multipart est déplacé :
/tmp/abc123
->
/var/www/static-files/mrggesvw-hwdhacrc.jpg
Page de succès
Template :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Fichier enregistré</title>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
background: #f4f7fb;
}
.container {
max-width: 800px;
margin: 80px auto;
background: white;
padding: 40px;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.linkbox {
padding: 15px;
background: #f8fafc;
border-radius: 8px;
}
button {
background: #2563eb;
color: white;
border: 0;
padding: 10px 20px;
border-radius: 8px;
}
</style>
<script>
function copyLink() {
const text =
document.getElementById("downloadLink").value;
navigator.clipboard.writeText(text);
document.getElementById("status").innerText =
"Lien copié ✓";
}
</script>
</head>
<body>
<div class="container">
<h1>✅ Fichier enregistré</h1>
<p>
Nom du fichier :
<b>{{nomFichier}}</b>
</p>
<div class="linkbox">
<input id="downloadLink"
type="text"
value="{{urlFichier}}"
readonly
style="width:100%">
</div>
<br>
<button onclick="copyLink()">
Copier le lien
</button>
<span id="status"></span>
</div>
</body>
</html>
Utilisation
Upload
L'utilisateur authentifié ouvre :
https://node-red.mon-domaine.fr/megaupload/
Sélectionne un fichier puis clique :
Envoyer le fichier
Téléchargement
Le destinataire reçoit un lien :
https://node-red.mon-domaine.fr/files/mrggesvw-hwdhacrc.jpg
Aucune authentification n'est nécessaire.
Améliorations possibles
- Limiter la taille maximale des fichiers.
- Limiter les extensions autorisées.
- Suppression automatique après X jours.
- Historique des uploads dans MariaDB.
- Génération de liens à durée de vie limitée.
- Statistiques de téléchargement.
- QR-Code du lien de téléchargement.
Résultat
On obtient un mini "WeTransfer" personnel :
- HTTPS via Caddy.
- Upload privé.
- Download public.
- Noms de fichiers non prévisibles.
- Aucun serveur web supplémentaire requis.
- Entièrement réalisé avec Node-RED.