bridgedirecte
v0.3.1
Published
RESTful API bridge for EcoleDirecte via wrapdirecte
Maintainers
Readme
bridgeDirecte 🌸 Flower 1.1
RESTful API bridge for EcoleDirecte, powered by wrapdirecte and Cloudflare Workers.
Utilisation
Le bridge peut être utilisé de deux manières :
1. via npm (recommandé)
Vous pouvez utiliser bridgedirecte comme une bibliothèque dans votre propre Worker Cloudflare.
import { createBridge } from 'bridgedirecte'
// Exportation de l'instance configurée
export default createBridge({
allowedOrigins: ['https://votre-site.com'], // défaut ["*"]
appName: 'monApplication', // défaut: nom dans package.json
appVersion: '1.0.0', // défaut: version dans package.json
forceHttps: true, // refuse les requêtes non sécurisées, défaut true
})Si vous souhaitez simplement faire une nouvelle instance vierge :
git clone https://bridge.directe.qzz.io/new
npm i
npx wrangler deployVous pourrez modifier les paramètres de configuration dans le fichier worker.js.
2. par clonage du code source
git clone https://bridge.directe.qzz.io/sourcecodeSi vous clonez le code source directement, vous pouvez configurer l'instance via un fichier bridgedirecte.config.jsonc à la racine du projet :
{
"allowedOrigins": ["*"],
"appName": "bridgeDirecteCustom",
"appVersion": "1.0.0",
"forceHttps": true,
}Configuration
| Réglage | Description | Défaut |
| ---------------- | ------------------------------------- | -------------- |
| allowedOrigins | Liste des origines autorisées (CORS) | ["*"] |
| appName | Nom de l'application (User-Agent) | package.json |
| appVersion | Version de l'application (User-Agent) | package.json |
| forceHttps | Exiger HTTPS (sauf localhost) | true |
[!CAUTION] Si vous fournissez des réglages à
createBridge()ET qu'un fichierbridgedirecte.config.jsoncest présent, le bridge renverra une erreur "Bad config".
Authentification
Le bridge est stateless. Chaque requête (sauf /login et /login/2fa) nécessite :
| Header | Description | Exemple |
| --------------- | --------------------------------------- | -------------------- |
| Authorization | Token Bearer obtenu après /login | Bearer eyJhbGci... |
| Account-ID | ID numérique du compte élève à utiliser | 1234 |
Endpoints
🔐 Authentification
POST /login
Connexion avec identifiants EcoleDirecte.
Query (Optionnel) : ?direct=true pour bypasser le 2FA si vous avez un 2faProof.
Body :
{
"username": "mon.identifiant",
"password": "monMotDePasse",
"2faProof": "mon2faProof (requis si direct=true)",
"uuid": "optionnel-uuid"
}Réponse (succès) :
{
"success": true,
"status": "authenticated",
"token": "eyJhbGci...",
"faProof": "leProofAStocker",
"accounts": [{ "id": 123456, "firstName": "Jean", "lastName": "Dupont" }]
}Réponse (2FA requis) :
{
"success": true,
"status": "needs_2fa",
"challenge": {
"question": "Quel est le prénom de votre professeur principal ?",
"proposals": []
},
"partialToken": "eyJhbGci..."
}POST /login/2fa
Soumettre la réponse 2FA.
Headers requis : Authorization: Bearer <partial_token>
Body :
{
"answer": "reponse",
"username": "votre_username",
"password": "votre_password",
"uuid": "optionnel"
}Réponse :
{
"success": true,
"status": "authenticated",
"token": "eyJhbGci...",
"faProof": "leProofAStocker",
"accounts": [{ "id": 123456 }]
}📚 Notes
GET /grades
Headers : Authorization, Account-ID
Query : ?year=2025-2026 (défaut : année scolaire en cours)
Réponse :
{
"grades": [...],
"periods": [...],
"settings": {}
}📝 Devoirs
GET /homework
Headers : Authorization, Account-ID
Query : ?date=2026-04-08 (défaut : aujourd'hui)
Réponse : CleanHomework[]
PATCH /homework
Marquer un devoir comme fait ou non fait.
Headers : Authorization, Account-ID
Query : ?id=<homeworkId>
Body :
{ "done": true }Réponse :
{ "success": true, "id": 987654, "done": true }POST /homework/:id/comment
Ajouter un commentaire à un devoir.
Headers : Authorization, Account-ID
Body :
{ "content": "Mon commentaire" }Réponse :
{ "success": true, "commentId": 111 }📅 Emploi du temps
GET /timetable
Headers : Authorization, Account-ID
Query : ?from=2026-04-01&to=2026-04-07 (défaut : semaine courante)
Réponse : CleanCourse[]
GET /timetable/ical
Headers : Authorization, Account-ID
Réponse :
{ "success": true, "url": "https://api.ecoledirecte.com/ical/..." }🚫 Absences
GET /absences
Headers : Authorization, Account-ID
Réponse : CleanAbsence[]
📰 Timeline
GET /timeline
Timeline personnelle de l'élève.
Headers : Authorization, Account-ID
Réponse : CleanTimelineEvent[]
GET /timeline/school
Timeline commune (toute l'école).
Headers : Authorization, Account-ID
Réponse :
{
"events": [...],
"postits": [...]
}📄 Documents
GET /documents
Headers : Authorization, Account-ID
Réponse :
{
"factures": [...],
"notes": [...]
}☁️ Cloud
GET /cloud
Headers : Authorization, Account-ID
Query : ?depth=3 (défaut : 3)
Réponse : CleanCloudNode[]
POST /cloud/folder
Créer un dossier.
Headers : Authorization, Account-ID
Body :
{ "path": "parent/chemin", "name": "nouveauDossier" }POST /cloud/copy
Copier des fichiers/dossiers.
Body :
{ "destination": "dest/chemin", "nodes": [...] }POST /cloud/move
Déplacer des fichiers/dossiers.
Body :
{ "destination": "dest/chemin", "nodes": [...] }DELETE /cloud
Supprimer des fichiers/dossiers.
Body :
{ "nodes": [...] }POST /cloud/restore
Restaurer des fichiers/dossiers supprimés.
Body :
{ "nodes": [...] }POST /cloud/export
Exporter un fichier vers le cloud.
Body :
{
"fileId": "abc123",
"source": "CAHIER_DE_TEXTES"
}source : "CAHIER_DE_TEXTES" ou "MESSAGERIE"
✉️ Messagerie
GET /messages
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{
"received": [...],
"sent": [...],
"draft": [...],
"archived": [...],
"folders": [...]
}GET /messages/:id
Contenu complet d'un message.
Headers : Authorization, Account-ID
Query : ?year=2025-2026&glance=true (glance=true marque le message comme non lu lors de l'ouverture)
Réponse : CleanMessage avec champ content
GET /messages/folder/:folderId
Messages d'un dossier spécifique.
Headers : Authorization, Account-ID
Réponse : CleanMessage[]
GET /messages/contacts/:type
Récupérer les contacts.
Headers : Authorization, Account-ID
Paramètre : :type = professeurs | personnels | entreprises
Réponse : Contact[]
POST /messages
Envoyer un message.
Headers : Authorization, Account-ID
Body :
{
"subject": "Objet du message",
"content": "Contenu du message",
"recipients": [{ "id": 123, "type": "P" }],
"year": "2025-2026"
}Réponse :
{ "success": true, "messageId": 456789 }PUT /messages/:id/read
Marquer un message comme lu.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }PUT /messages/:id/unread
Marquer un message comme non lu.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }PUT /messages/:id/archive
Archiver un message.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }PUT /messages/:id/unarchive
Désarchiver un message.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }PATCH /messages/:id/move
Déplacer un message vers un autre dossier.
Headers : Authorization, Account-ID
Body :
{ "folder": 12345 }Réponse :
{ "success": true }POST /messages/folder
Créer un nouveau dossier.
Headers : Authorization, Account-ID
Body :
{ "name": "Nom du dossier" }Réponse :
{ "success": true, "id": 12345 }DELETE /messages/folder/:folderId
Supprimer un dossier.
Headers : Authorization, Account-ID
Réponse :
{ "success": true }⚙️ Paramètres
GET /settings
Headers : Authorization, Account-ID
Query : ?loginId=123 (optionnel)
PATCH /settings
Mettre à jour les paramètres du compte.
Headers : Authorization, Account-ID
Body :
{
"identifiant": "nouvelIdentifiant",
"nouveauMotDePasse": "nouveauMotDePasse",
"confirmationMotDePasse": "nouveauMotDePasse",
"email": "[email protected]",
"portable": "0612345678",
"questionSecrete": "Question secrète",
"reponse": "Réponse",
"uuid": "optionnel"
}PATCH /settings/param
Mettre à jour un paramètre individuel.
Headers : Authorization, Account-ID
Body :
{ "value": "nouvelle-valeur" }Format des erreurs
Toutes les erreurs suivent ce format :
{
"success": false,
"error": "Description de l'erreur",
"code": 400
}| Code | Signification | | ---- | -------------------------------- | | 400 | Requête invalide (body, params) | | 401 | Non authentifié / token invalide | | 404 | Route introuvable | | 500 | Erreur interne du serveur | | 503 | Module indisponible |
IP Spoofing
Le bridge injecte automatiquement un header X-Forwarded-For avec une IP française aléatoire sur chaque requête vers EcoleDirecte, en utilisant les préfixes des principaux opérateurs :
| Préfixe | Opérateur |
| ----------- | ------------- |
| 80.12.* | Orange |
| 82.224.* | Free |
| 176.128.* | SFR |
| 90.1.* | Orange Mobile |
Licence
AGPL 3.0 — Voir LICENSE pour les détails.
