« Node-red file repository » : différence entre les versions

De knowledge
Aller à la navigation Aller à la recherche
Page créée avec « = 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 : <pre> Internet | v Front-Router (Caddy) | v Node-RED (main-host) | +--- Upload via flow Node-RED | +-... »
 
mAucun résumé des modifications
 
Ligne 8 : Ligne 8 :
* Noms des fichiers pseudonymisés.
* Noms des fichiers pseudonymisés.
* Fichiers servis directement par Node-RED.
* Fichiers servis directement par Node-RED.
* Reverse proxy HTTPS assuré par Caddy.


Architecture :
Architecture :
Ligne 16 : Ligne 15 :
     |
     |
     v
     v
Front-Router (Caddy)
Reverse Proxy
     |
     |
     v
     v
Ligne 28 : Ligne 27 :
== Installation des modules ==
== Installation des modules ==


Installer :
Copilot m'avait proposer d'Installer "à ma main" :


<pre>
<pre>node-red-contrib-http-multipart
node-red-contrib-http-multipart
@alexandrainst/node-red-http-basic-auth</pre>
@alexandrainst/node-red-http-basic-auth
</pre>


Le premier permet de recevoir des formulaires HTML multipart/form-data.
Le premier permet de recevoir des formulaires HTML multipart/form-data.


Le second ajoute une authentification HTTP Basic.
Le second ajoute une authentification HTTP Basic.
Pour le coup l'interface graphique de node-red le permet tout aussi bien.
[[Fichier:Node-red-update-palette.png|sans_cadre]]
Dans le menu en haut a droite on a l'option "Gérer la palette". On a l'impression que c'est juste de la GUI mais non on passe par là pour ajouter des modules.
On clique sur "Gérer la palette" et on a une fenêtre de sélection.
[[Fichier:Nodered-add-node-red-contrib-http-multipart.png|sans_cadre|547x547px]]
On choisit l'onglet "Installer" et on recherche node-red-contrib-http-multipart.
Dans le screenshot ci-dessus le bouton "Installé" est grisé mais si le module n'était pas installé on aurait un bouton installer. Il suffit de cliquer dessus et c'est fait.


== Répertoire de stockage ==
== Répertoire de stockage ==
Ligne 44 : Ligne 55 :


<pre>
<pre>
sudo mkdir -p /var/www/static-files
sudo mkdir -p /var/www/static-files/
sudo chown nodered:nodered /var/www/static-files
sudo mkdir -p /var/www/static-files/assets
sudo chown nodered:nodered /var/www/static-files/assets
</pre>
</pre>


Ligne 63 : Ligne 75 :
httpStatic: [
httpStatic: [
     {
     {
         path: "/var/www/static-files",
         path: "/var/www/static-files/assets",
         root: "/files/"
         root: "/files/"
     }
     }
Ligne 70 : Ligne 82 :


Redémarrer Node-RED :
Redémarrer Node-RED :
<pre>
systemctl --user restart nodered
</pre>
Ou selon l'installation :


<pre>
<pre>
Ligne 174 : Ligne 180 :
</body>
</body>
</html>
</html>
</syntaxhighlight>
</syntaxhighlight>Que l'on rangera dans <code>/var/www/static-files/upload.html</code>


== Protection par mot de passe ==
== Protection par mot de passe ==
Ligne 214 : Ligne 220 :


=== Fichier d'utilisateurs ===
=== Fichier d'utilisateurs ===
Je penses que c'est la seule solution acceptable car les mots de passes ne sont pas "en clair"


Format :
Format :
Ligne 229 : Ligne 236 :
jean:$2y$10$...
jean:$2y$10$...
alice:$2y$10$...
alice:$2y$10$...
</pre>
</pre>J'ai donc crée la chaine de noeuds:
 
[[Fichier:Node-red-upload-page.png|sans_cadre|921x921px]]
 
C'est tres simple :
 
* Ou expose l'url /megaupload (noeud index)
* au authentifie l'utilisateur
* on lit le fichier /var/www/static-files/upload.html
* On le renvoie au client


== Réception du fichier ==
== Réception du fichier ==
Ligne 256 : Ligne 272 :
Configuration HTTP Multipart :
Configuration HTTP Multipart :


<pre>
<pre>[
[
   {
   {
     "name": "fichier",
     "name": "fichier",
     "maxCount": 1
     "maxCount": 1
   }
   }
]
]</pre>En effet, dans la page d'upload on ne propose qu'un seul fichier. SI on veut en envoyer plusieurs, soit on refait l'opération soit un fait un zip ou un tgz.
</pre>


== Pseudonymisation du nom de fichier ==
== Pseudonymisation du nom de fichier ==
Ligne 311 : Ligne 325 :
</pre>
</pre>


devient :
devient, par exemple :


<pre>
<pre>
Ligne 320 : Ligne 334 :


Noeud Exec :
Noeud Exec :
On lance l'exécution du msg.payload construit au dessus.


<pre>
<pre>
Ligne 419 : Ligne 435 :
</body>
</body>
</html>
</html>
</syntaxhighlight>
</syntaxhighlight>[[Fichier:Chaine de upload.png|sans_cadre|852x852px]]
 
Récapitulatifs des actions ci-dessus.


== Utilisation ==
== Utilisation ==
Ligne 461 : Ligne 479 :
On obtient un mini "WeTransfer" personnel :
On obtient un mini "WeTransfer" personnel :


* HTTPS via Caddy.
* HTTPS via le reverse proxy.
* Upload privé.
* Upload privé.
* Download public.
* Download public.

Dernière version du 11 juillet 2026 à 16:22

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.

Architecture :

Internet
    |
    v
Reverse Proxy
    |
    v
Node-RED (main-host)
    |
    +--- Upload via flow Node-RED
    |
    +--- Fichiers statiques (/var/www/static-files)

Installation des modules

Copilot m'avait proposer d'Installer "à ma main" :

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.

Pour le coup l'interface graphique de node-red le permet tout aussi bien.

Dans le menu en haut a droite on a l'option "Gérer la palette". On a l'impression que c'est juste de la GUI mais non on passe par là pour ajouter des modules.

On clique sur "Gérer la palette" et on a une fenêtre de sélection.

On choisit l'onglet "Installer" et on recherche node-red-contrib-http-multipart.

Dans le screenshot ci-dessus le bouton "Installé" est grisé mais si le module n'était pas installé on aurait un bouton installer. Il suffit de cliquer dessus et c'est fait.

Répertoire de stockage

Créer un répertoire destiné à contenir les fichiers :

sudo mkdir -p /var/www/static-files/
sudo mkdir -p /var/www/static-files/assets
sudo chown nodered:nodered /var/www/static-files/assets

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/assets",
        root: "/files/"
    }
],

Redémarrer Node-RED :

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>

Que l'on rangera dans /var/www/static-files/upload.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

Je penses que c'est la seule solution acceptable car les mots de passes ne sont pas "en clair"

Format :

jean:motdepasse
alice:motdepasse

Ou mieux, avec mots de passe bcrypt.

Exemple :

jean:$2y$10$...
alice:$2y$10$...

J'ai donc crée la chaine de noeuds:

C'est tres simple :

  • Ou expose l'url /megaupload (noeud index)
  • au authentifie l'utilisateur
  • on lit le fichier /var/www/static-files/upload.html
  • On le renvoie au client

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
  }
]

En effet, dans la page d'upload on ne propose qu'un seul fichier. SI on veut en envoyer plusieurs, soit on refait l'opération soit un fait un zip ou un tgz.

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, par exemple :

mrggesvw-hwdhacrc.jpg

Déplacement du fichier

Noeud Exec :

On lance l'exécution du msg.payload construit au dessus.

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>

Récapitulatifs des actions ci-dessus.

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 le reverse proxy.
  • Upload privé.
  • Download public.
  • Noms de fichiers non prévisibles.
  • Aucun serveur web supplémentaire requis.
  • Entièrement réalisé avec Node-RED.