feat: application n8n Pilot complète (Expo managed workflow)
- Stack : Expo Router, Axios, Zustand, React Native Paper (thème sombre), date-fns - Sécurité : secrets dans Android Keystore via expo-secure-store, TLS obligatoire, headers X-N8N-API-KEY + X-App-Token injectés par intercepteur Axios - API : client.ts centralisé + workflows.ts + executions.ts (TypeScript strict) - Store : Zustand appStore avec chargement depuis secure store au démarrage - Hooks : usePolling (générique), useWorkflows, useExecutions - Composants : StatusBadge, WorkflowCard, ExecutionCard, SkeletonLoader - Screens : Dashboard, Workflows, Executions, Logs (détail exécution), Settings - Navigation Expo Router : 4 tabs + stack Logs + écran Setup initial - Docs : INSTALL.md, UPDATE.md, BACKUP.md, HAPROXY.md, SECURITY.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# Sauvegarde de n8n Pilot
|
||||
|
||||
## Ce qu'il faut sauvegarder
|
||||
|
||||
### 1. Credentials de signature EAS (`credentials.json`)
|
||||
|
||||
**Où** : généré par EAS lors du premier build dans `~/.eas/` ou téléchargeable depuis le dashboard Expo.
|
||||
|
||||
**Pourquoi** : sans le keystore de signature, il est **impossible** de mettre à jour l'APK sur un appareil
|
||||
qui a déjà la version signée avec ce keystore. Android refuse les mises à jour avec un keystore différent.
|
||||
|
||||
**Comment sauvegarder** :
|
||||
|
||||
```bash
|
||||
# Télécharger les credentials depuis EAS
|
||||
eas credentials
|
||||
|
||||
# Choisir : Android > Keystore > Download
|
||||
# Sauvegarder le fichier .jks et les mots de passe associés
|
||||
```
|
||||
|
||||
> **Criticalité : MAXIMALE** — perte du keystore = obligation de désinstaller l'app sur tous les appareils
|
||||
> avant de pouvoir installer une nouvelle version.
|
||||
|
||||
---
|
||||
|
||||
### 2. Fichier `.env` de développement
|
||||
|
||||
**Où** : racine du projet (jamais dans git)
|
||||
|
||||
**Pourquoi** : contient l'URL de l'instance, la clé API et le token HAProxy pour l'environnement de dev.
|
||||
Sans ce fichier, les développeurs doivent reconfigurer manuellement l'environnement.
|
||||
|
||||
**Comment sauvegarder** : gestionnaire de mots de passe (Bitwarden, 1Password, Vault) avec les champs :
|
||||
- `N8N_BASE_URL`
|
||||
- `N8N_API_KEY`
|
||||
- `N8N_APP_TOKEN`
|
||||
|
||||
---
|
||||
|
||||
### 3. Configuration EAS (`eas.json`)
|
||||
|
||||
**Où** : racine du projet, **committé dans git**
|
||||
|
||||
**Pourquoi** : définit les profils de build (development, preview, production).
|
||||
|
||||
**Statut** : déjà sauvegardé via git — aucune action supplémentaire requise.
|
||||
|
||||
---
|
||||
|
||||
### 4. Données utilisateur sur l'appareil
|
||||
|
||||
Les credentials (URL, clé API, token) sont chiffrés dans l'**Android Keystore** de l'appareil.
|
||||
Ils ne sont **pas** sauvegardés dans les sauvegardes Android standard (par conception de sécurité).
|
||||
|
||||
**Conséquence** : après réinitialisation usine ou changement d'appareil, l'utilisateur doit
|
||||
reconfigurer l'app depuis l'écran Paramètres.
|
||||
|
||||
---
|
||||
|
||||
## Fréquence recommandée
|
||||
|
||||
| Élément | Fréquence | Stockage |
|
||||
|---------|-----------|----------|
|
||||
| Keystore EAS | À chaque rotation + après génération | Coffre chiffré hors-ligne |
|
||||
| `.env` dev | À chaque rotation des tokens | Gestionnaire de mots de passe |
|
||||
| Code source | En continu via git push | Gitea self-hosted |
|
||||
|
||||
---
|
||||
|
||||
## Procédure de restauration
|
||||
|
||||
### Restaurer le keystore
|
||||
|
||||
```bash
|
||||
# Uploader le keystore sauvegardé vers EAS
|
||||
eas credentials
|
||||
# Choisir : Android > Keystore > Upload existing keystore
|
||||
```
|
||||
|
||||
### Restaurer l'environnement de développement
|
||||
|
||||
```bash
|
||||
git clone https://homegit.gyozamancave.fr/billisdead/n8n-mobile.git
|
||||
cd n8n-mobile
|
||||
cp .env.example .env
|
||||
# Remplir .env depuis le gestionnaire de mots de passe
|
||||
npm install --legacy-peer-deps
|
||||
```
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
# Configuration HAProxy pour n8n Pilot
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Android App → HTTPS → HAProxy (443) → HTTP → n8n (5678)
|
||||
↓
|
||||
Validation X-App-Token
|
||||
Rate limiting
|
||||
TLS termination
|
||||
```
|
||||
|
||||
HAProxy agit comme reverse proxy devant n8n. Il :
|
||||
1. Termine TLS (certificat Let's Encrypt ou autosigné)
|
||||
2. Valide le header `X-App-Token` (token secret partagé)
|
||||
3. Applique du rate limiting pour protéger l'API
|
||||
4. Forward les requêtes vers n8n en HTTP interne
|
||||
|
||||
---
|
||||
|
||||
## Configuration HAProxy complète
|
||||
|
||||
```haproxy
|
||||
#---------------------------------------------------------------------
|
||||
# global : paramètres du processus HAProxy
|
||||
#---------------------------------------------------------------------
|
||||
global
|
||||
log /dev/log local0
|
||||
log /dev/log local1 notice
|
||||
maxconn 2000
|
||||
daemon
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# defaults : valeurs par défaut pour tous les frontends/backends
|
||||
#---------------------------------------------------------------------
|
||||
defaults
|
||||
log global
|
||||
mode http
|
||||
option httplog
|
||||
option dontlognull
|
||||
timeout connect 5s
|
||||
timeout client 30s
|
||||
timeout server 30s
|
||||
# Timeout plus long pour les webhooks n8n qui peuvent prendre du temps
|
||||
timeout tunnel 3600s
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# frontend : point d'entrée HTTPS sur le port 443
|
||||
#---------------------------------------------------------------------
|
||||
frontend n8n_pilot_frontend
|
||||
bind *:443 ssl crt /etc/ssl/n8n/fullchain.pem alpn h2,http/1.1
|
||||
|
||||
# Sécurité TLS : désactiver les versions obsolètes
|
||||
ssl-min-ver TLSv1.2
|
||||
|
||||
# Headers de sécurité injectés sur toutes les réponses
|
||||
http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
|
||||
http-response set-header X-Content-Type-Options "nosniff"
|
||||
http-response set-header X-Frame-Options "DENY"
|
||||
|
||||
# ACL : vérification du X-App-Token
|
||||
# La valeur doit correspondre exactement au token configuré dans l'app
|
||||
acl valid_app_token req.hdr(X-App-Token) -m str "VOTRE_TOKEN_ICI"
|
||||
|
||||
# Refuser les requêtes sans token valide avec 403
|
||||
http-request deny deny_status 403 if !valid_app_token
|
||||
|
||||
# Rate limiting : max 60 requêtes par minute par IP
|
||||
# Protège contre les scripts de scan et les abus
|
||||
stick-table type ip size 100k expire 60s store http_req_rate(60s)
|
||||
http-request track-sc0 src
|
||||
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 60 }
|
||||
|
||||
# Redirection HTTP → HTTPS (optionnel si port 80 ouvert)
|
||||
# redirect scheme https if !{ ssl_fc }
|
||||
|
||||
default_backend n8n_backend
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# backend : instance n8n locale
|
||||
#---------------------------------------------------------------------
|
||||
backend n8n_backend
|
||||
balance roundrobin
|
||||
|
||||
# Supprimer le X-App-Token avant de forwarder à n8n (ne doit pas atteindre n8n)
|
||||
http-request del-header X-App-Token
|
||||
|
||||
# Health check : n8n répond sur /healthz
|
||||
option httpchk GET /healthz
|
||||
http-check expect status 200
|
||||
|
||||
server n8n_local 127.0.0.1:5678 check inter 10s fall 3 rise 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rotation du X-App-Token
|
||||
|
||||
Le token doit être tourné régulièrement (recommandé : tous les 90 jours minimum).
|
||||
|
||||
### Procédure de rotation sans downtime
|
||||
|
||||
1. **Générer un nouveau token** :
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
# Exemple : a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1
|
||||
```
|
||||
|
||||
2. **Phase de transition — accepter les deux tokens** :
|
||||
```haproxy
|
||||
# Accepter l'ancien ET le nouveau pendant la transition
|
||||
acl valid_app_token req.hdr(X-App-Token) -m str "ANCIEN_TOKEN"
|
||||
acl valid_app_token_new req.hdr(X-App-Token) -m str "NOUVEAU_TOKEN"
|
||||
http-request deny deny_status 403 if !valid_app_token !valid_app_token_new
|
||||
```
|
||||
|
||||
3. **Mettre à jour l'app** sur tous les appareils (Paramètres > Token HAProxy > Sauvegarder)
|
||||
|
||||
4. **Retirer l'ancien token** de HAProxy une fois tous les appareils mis à jour :
|
||||
```haproxy
|
||||
acl valid_app_token req.hdr(X-App-Token) -m str "NOUVEAU_TOKEN"
|
||||
http-request deny deny_status 403 if !valid_app_token
|
||||
```
|
||||
|
||||
5. **Recharger HAProxy** sans coupure :
|
||||
```bash
|
||||
haproxy -f /etc/haproxy/haproxy.cfg -c # Valider la config
|
||||
systemctl reload haproxy # Rechargement gracieux
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Erreur 403 Forbidden
|
||||
|
||||
**Cause** : `X-App-Token` absent ou incorrect.
|
||||
|
||||
**Diagnostic** :
|
||||
```bash
|
||||
# Tester manuellement avec curl
|
||||
curl -v -H "X-App-Token: VOTRE_TOKEN" https://n8n.votre-domaine.com/api/v1/workflows
|
||||
```
|
||||
|
||||
**Solutions** :
|
||||
- Vérifier que le token dans l'app (Paramètres) correspond exactement à la config HAProxy
|
||||
- Contrôler les espaces ou caractères invisibles dans le token
|
||||
- Vérifier les logs HAProxy : `journalctl -u haproxy -f`
|
||||
|
||||
---
|
||||
|
||||
### Erreur 429 Too Many Requests
|
||||
|
||||
**Cause** : rate limit dépassé (> 60 req/min).
|
||||
|
||||
**Solutions** :
|
||||
- Augmenter l'intervalle de polling dans l'app (Paramètres > Intervalle)
|
||||
- Ajuster la limite dans HAProxy si l'usage légitime est plus élevé
|
||||
- Vérifier qu'aucun processus tiers ne spam l'endpoint
|
||||
|
||||
---
|
||||
|
||||
### Timeout / connexion refusée
|
||||
|
||||
**Cause** : n8n inaccessible sur le port 5678, ou HAProxy mal configuré.
|
||||
|
||||
**Diagnostic** :
|
||||
```bash
|
||||
# Vérifier que n8n tourne
|
||||
curl http://127.0.0.1:5678/healthz
|
||||
|
||||
# Vérifier le statut HAProxy
|
||||
systemctl status haproxy
|
||||
haproxy -f /etc/haproxy/haproxy.cfg -c
|
||||
|
||||
# Logs HAProxy en temps réel
|
||||
journalctl -u haproxy -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Certificat TLS expiré
|
||||
|
||||
```bash
|
||||
# Renouveler avec Certbot
|
||||
certbot renew --quiet
|
||||
# Recharger HAProxy pour prendre en compte le nouveau certificat
|
||||
systemctl reload haproxy
|
||||
```
|
||||
|
||||
Automatiser le renouvellement :
|
||||
```bash
|
||||
# Ajouter dans crontab (root)
|
||||
0 3 * * 1 certbot renew --quiet && systemctl reload haproxy
|
||||
```
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
# Installation de n8n Pilot
|
||||
|
||||
## Prérequis
|
||||
|
||||
| Outil | Version minimale | Rôle |
|
||||
|-------|-----------------|------|
|
||||
| Node.js | 20 LTS | Runtime JS |
|
||||
| npm | 10+ | Gestionnaire de paquets |
|
||||
| EAS CLI | 3.0+ | Build cloud Expo |
|
||||
| Android | 8.0 (API 26) | Cible minimum |
|
||||
| Compte Expo | gratuit | Build EAS |
|
||||
|
||||
```bash
|
||||
# Vérifier les prérequis
|
||||
node --version # >= 20
|
||||
npm --version # >= 10
|
||||
eas --version # >= 3.0 (après install)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Cloner le dépôt
|
||||
|
||||
```bash
|
||||
git clone https://homegit.gyozamancave.fr/billisdead/n8n-mobile.git
|
||||
cd n8n-mobile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Installer les dépendances
|
||||
|
||||
```bash
|
||||
npm install --legacy-peer-deps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Configurer l'environnement de développement
|
||||
|
||||
Copiez le fichier exemple et remplissez vos valeurs **localement uniquement** :
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Éditez .env avec votre URL, clé API et token HAProxy
|
||||
```
|
||||
|
||||
> ⚠️ Le fichier `.env` est dans `.gitignore` — ne jamais le committer.
|
||||
> En production, les secrets transitent **uniquement** par `expo-secure-store`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Lancer en développement
|
||||
|
||||
```bash
|
||||
# Démarrer le serveur Metro
|
||||
npm start
|
||||
|
||||
# Sur appareil Android (USB ou WiFi) ou émulateur
|
||||
npm run android
|
||||
```
|
||||
|
||||
Pour le développement, l'app vous demandera de saisir l'URL et la clé API
|
||||
directement dans l'écran Paramètres — elles seront stockées dans le Keystore Android.
|
||||
|
||||
---
|
||||
|
||||
## 5. Installer EAS CLI
|
||||
|
||||
```bash
|
||||
npm install -g eas-cli
|
||||
eas login # Connectez-vous avec votre compte Expo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Configurer le projet EAS
|
||||
|
||||
```bash
|
||||
# Initialise l'ID de projet Expo (première fois uniquement)
|
||||
eas init
|
||||
|
||||
# Vérifie la configuration
|
||||
eas build:configure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Builder l'APK (profil preview)
|
||||
|
||||
```bash
|
||||
# Build Android APK — exécuté dans le cloud Expo
|
||||
eas build --platform android --profile preview
|
||||
```
|
||||
|
||||
Le build prend environ 10–15 minutes. EAS envoie un email avec le lien de téléchargement.
|
||||
|
||||
Pour un build local (nécessite Android Studio + JDK 17) :
|
||||
|
||||
```bash
|
||||
eas build --platform android --profile preview --local
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Sideloader l'APK sur Android
|
||||
|
||||
### Via ADB
|
||||
|
||||
```bash
|
||||
# Connecter l'appareil en USB avec le débogage USB activé
|
||||
adb devices
|
||||
|
||||
# Installer l'APK
|
||||
adb install chemin/vers/n8n-pilot.apk
|
||||
```
|
||||
|
||||
### Manuellement
|
||||
|
||||
1. Transférez l'APK sur l'appareil (câble, Google Drive, etc.)
|
||||
2. Ouvrez l'APK depuis le gestionnaire de fichiers
|
||||
3. Autorisez l'installation depuis des sources inconnues si demandé
|
||||
4. Suivez l'assistant d'installation
|
||||
|
||||
---
|
||||
|
||||
## 9. Premier lancement
|
||||
|
||||
Au premier démarrage, l'écran de configuration apparaît automatiquement :
|
||||
|
||||
1. Saisissez l'URL HTTPS de votre instance n8n
|
||||
2. Collez votre clé API n8n (Settings > API Keys dans n8n)
|
||||
3. Saisissez le token HAProxy si applicable
|
||||
4. Appuyez sur **Sauvegarder**
|
||||
|
||||
Les credentials sont chiffrés dans l'Android Keystore — ils ne quittent jamais l'appareil.
|
||||
@@ -0,0 +1,147 @@
|
||||
# Sécurité — n8n Pilot
|
||||
|
||||
## Modèle de menaces
|
||||
|
||||
### Acteurs et vecteurs
|
||||
|
||||
| Menace | Impact | Probabilité | Mitigation |
|
||||
|--------|--------|-------------|-----------|
|
||||
| Vol de l'appareil Android | Accès aux credentials n8n | Moyen | Android Keystore chiffré, biométrie optionnelle |
|
||||
| Interception réseau (MITM) | Exposition de la clé API | Faible (TLS) | TLS obligatoire, refus HTTP |
|
||||
| Fuite du token HAProxy | Accès non autorisé à n8n | Moyen | Rotation régulière, token hors bundle |
|
||||
| Compromission du build APK | Backdoor dans l'app | Faible | Keystore signé, builds EAS reproductibles |
|
||||
| Brute force API | Épuisement quotas n8n | Faible | Rate limiting HAProxy (429) |
|
||||
| Logs applicatifs exposés | Fuite de secrets | Faible | Jamais de log de secrets, même en dev |
|
||||
|
||||
---
|
||||
|
||||
## Principes appliqués
|
||||
|
||||
### Least Privilege (moindre privilège)
|
||||
|
||||
La clé API n8n doit être créée avec le **scope minimal** nécessaire :
|
||||
|
||||
```
|
||||
Recommandé :
|
||||
✓ workflows:list — lister les workflows
|
||||
✓ workflows:read — lire les détails
|
||||
✓ workflows:update — activer/désactiver (toggle)
|
||||
✓ executions:list — voir l'historique
|
||||
✓ executions:read — lire les logs
|
||||
✓ executions:delete — supprimer des exécutions
|
||||
✓ workflows:run — déclencher manuellement
|
||||
|
||||
Non recommandé :
|
||||
✗ credentials:* — inutile pour cette app
|
||||
✗ users:* — inutile pour cette app
|
||||
✗ admin:* — jamais
|
||||
```
|
||||
|
||||
**Comment créer la clé** dans n8n :
|
||||
1. Settings > n8n API
|
||||
2. Create API Key
|
||||
3. Nommer la clé "n8n-pilot-mobile"
|
||||
4. Définir les scopes minimaux ci-dessus
|
||||
5. Copier la clé — elle n'est affichée qu'une seule fois
|
||||
|
||||
---
|
||||
|
||||
### Defense in Depth (défense en profondeur)
|
||||
|
||||
L'accès à l'API n8n passe par **deux barrières indépendantes** :
|
||||
|
||||
```
|
||||
Requête → [TLS] → [X-App-Token HAProxy] → [X-N8N-API-KEY n8n] → Données
|
||||
```
|
||||
|
||||
Si un token est compromis :
|
||||
- Compromission du `X-App-Token` seul → HAProxy bloque, n8n jamais atteint
|
||||
- Compromission de la clé API seul → sans le `X-App-Token`, HAProxy bloque à 403
|
||||
- Les deux compromis → rotation immédiate des deux (procédures dans HAPROXY.md et BACKUP.md)
|
||||
|
||||
---
|
||||
|
||||
### Zero Trust (réseau local inclus)
|
||||
|
||||
n8n ne doit **pas** être accessible directement sur le réseau, même en local.
|
||||
Toutes les requêtes passent par HAProxy qui valide le token.
|
||||
|
||||
```
|
||||
# Bloquer l'accès direct au port n8n (iptables)
|
||||
iptables -A INPUT -p tcp --dport 5678 -s 127.0.0.1 -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 5678 -j DROP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Gestion des secrets — cycle de vie
|
||||
|
||||
### Stockage
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Appareil Android │
|
||||
│ ┌─────────────────────────────────────────────┐ │
|
||||
│ │ Android Keystore (expo-secure-store) │ │
|
||||
│ │ n8n_base_url → https://n8n.example.com │ │
|
||||
│ │ n8n_api_key → clé API (chiffrée) │ │
|
||||
│ │ n8n_app_token → token HAProxy (chiffré) │ │
|
||||
│ └─────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ État React (Zustand) — en mémoire uniquement : │
|
||||
│ config.baseUrl → copie non sensible │
|
||||
│ config.isConfigured → booléen │
|
||||
│ JAMAIS : apiKey, appToken en mémoire JS │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Transit
|
||||
|
||||
- Les secrets sont lus depuis le Keystore **à chaque requête** HTTP dans `client.ts`
|
||||
- Ils sont injectés dans les headers HTTP et **ne sont pas loggués**
|
||||
- Ils ne sont **jamais** :
|
||||
- Sérialisés dans AsyncStorage
|
||||
- Inclus dans des logs (même en dev)
|
||||
- Embarqués dans le bundle JS (`app.json`, `package.json`, code source)
|
||||
- Envoyés à des services tiers (analytics, crash reporters)
|
||||
|
||||
### Rotation
|
||||
|
||||
| Secret | Fréquence recommandée | Procédure |
|
||||
|--------|-----------------------|-----------|
|
||||
| Clé API n8n | Tous les 180 jours, ou en cas de compromission | Créer nouvelle clé dans n8n, mettre à jour dans l'app |
|
||||
| X-App-Token | Tous les 90 jours | Voir docs/HAPROXY.md |
|
||||
| Keystore EAS | Jamais (sauf compromission) | Voir docs/BACKUP.md |
|
||||
|
||||
---
|
||||
|
||||
## Checklist avant mise en production
|
||||
|
||||
### Application
|
||||
|
||||
- [ ] `app.json` : `userInterfaceStyle` = `"dark"` (pas d'info sensible en clair)
|
||||
- [ ] `.env` non commité dans git (`git status` ne montre pas `.env`)
|
||||
- [ ] Aucun `console.log` de valeurs sensibles dans le code
|
||||
- [ ] `__DEV__` gate sur tous les logs dans `errorHandler.ts`
|
||||
- [ ] Expo SDK à jour — vérifier les CVE : `npx expo-doctor`
|
||||
- [ ] Dépendances à jour : `npm audit`
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- [ ] HAProxy : TLS 1.2 minimum, TLS 1.0/1.1 désactivés
|
||||
- [ ] Certificat TLS valide et non expiré
|
||||
- [ ] n8n inaccessible directement sur le port 5678 depuis l'extérieur
|
||||
- [ ] Rate limiting HAProxy activé (429 configuré)
|
||||
- [ ] Logs HAProxy ne contiennent pas les valeurs des headers secrets
|
||||
|
||||
### n8n
|
||||
|
||||
- [ ] Clé API avec scope minimal (voir § Least Privilege ci-dessus)
|
||||
- [ ] n8n mis à jour vers la dernière version stable
|
||||
- [ ] Sauvegardes n8n actives (workflows, credentials n8n)
|
||||
|
||||
### Appareil
|
||||
|
||||
- [ ] Verrouillage d'écran activé (PIN, pattern ou biométrie)
|
||||
- [ ] Biométrie configurée dans l'app si disponible
|
||||
- [ ] Appareil Android 8+ (API 26+) pour garantir la robustesse du Keystore
|
||||
@@ -0,0 +1,78 @@
|
||||
# Mise à jour de n8n Pilot
|
||||
|
||||
## Processus de mise à jour
|
||||
|
||||
### 1. Récupérer les changements
|
||||
|
||||
```bash
|
||||
git pull origin main
|
||||
npm install --legacy-peer-deps
|
||||
```
|
||||
|
||||
### 2. Bumper la version
|
||||
|
||||
Éditez `app.json` et incrémentez `version` :
|
||||
|
||||
```json
|
||||
{
|
||||
"expo": {
|
||||
"version": "1.1.0",
|
||||
"android": {
|
||||
"versionCode": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Règle** : `versionCode` doit être strictement supérieur à la version précédente.
|
||||
> `version` suit [semver](https://semver.org/) : MAJEUR.MINEUR.CORRECTIF
|
||||
|
||||
### 3. Rebuilder l'APK
|
||||
|
||||
```bash
|
||||
eas build --platform android --profile preview
|
||||
```
|
||||
|
||||
### 4. Distribuer la mise à jour
|
||||
|
||||
#### Option A — Sideload manuel
|
||||
|
||||
Répétez la procédure de sideload (voir INSTALL.md § 8) avec le nouvel APK.
|
||||
L'Android Package Manager gère la mise à jour en place si le `versionCode` est supérieur.
|
||||
|
||||
#### Option B — OTA (Over The Air) via Expo Updates
|
||||
|
||||
Pour les mises à jour mineures (JS uniquement, pas de changements natifs) :
|
||||
|
||||
```bash
|
||||
eas update --branch production --message "Fix: correction du polling"
|
||||
```
|
||||
|
||||
L'app télécharge la mise à jour au prochain démarrage si elle est connectée.
|
||||
|
||||
> **Important** : les changements dans `app.json`, l'ajout de plugins natifs
|
||||
> ou la modification des permissions nécessitent un rebuild APK complet.
|
||||
|
||||
---
|
||||
|
||||
## Vérifications avant release
|
||||
|
||||
- [ ] Tests sur appareil physique (pas seulement émulateur)
|
||||
- [ ] Vérifier que la connexion à l8n fonctionne avec les nouvelles données
|
||||
- [ ] Valider le polling sur WiFi et données mobiles
|
||||
- [ ] Vérifier que les secrets restent dans le Keystore après mise à jour
|
||||
- [ ] Contrôler les logs Android (`adb logcat`) pour des erreurs inattendues
|
||||
|
||||
---
|
||||
|
||||
## Rollback
|
||||
|
||||
En cas de régression critique :
|
||||
|
||||
```bash
|
||||
# Revenir au commit précédent
|
||||
git revert HEAD
|
||||
|
||||
# Rebuilder et redéployer la version précédente
|
||||
eas build --platform android --profile preview
|
||||
```
|
||||
Reference in New Issue
Block a user