Download server.js from BelikanM/server: direct link, hf CLI and curl.
- Browser
- Download file 6.86 kB
-
https://huggingface.co/spaces/BelikanM/server/resolve/main/server.js
- Command line
-
hf download hf://spaces/BelikanM/server/server.js
-
curl -L -o server.js https://huggingface.co/spaces/BelikanM/server/resolve/main/server.js
6.86 kB
| const express = require('express'); | |
| const nodemailer = require('nodemailer'); | |
| const crypto = require('crypto'); | |
| const cors = require('cors'); | |
| const https = require('https'); | |
| const cloudinary = require('cloudinary').v2; | |
| const sgMail = require('@sendgrid/mail'); | |
| require('dotenv').config({ path: process.cwd() + '/.env' }); | |
| const app = express(); | |
| app.use(express.json()); | |
| app.use(cors()); | |
| // Configuration Cloudinary | |
| cloudinary.config({ | |
| cloud_name: process.env.CLOUDINARY_CLOUD_NAME, | |
| api_key: process.env.CLOUDINARY_API_KEY, | |
| api_secret: process.env.CLOUDINARY_API_SECRET | |
| }); | |
| console.log('Cloudinary configured with cloud_name:', process.env.CLOUDINARY_CLOUD_NAME); | |
| // Configuration SendGrid | |
| sgMail.setApiKey(process.env.SENDGRID_API_KEY); | |
| console.log('SendGrid configured'); | |
| // Stockage temporaire des OTP | |
| const otpStore = new Map(); | |
| // Fonction pour charger les utilisateurs depuis Cloudinary | |
| async function loadUsers() { | |
| try { | |
| console.log('Loading users from Cloudinary...'); | |
| const result = await cloudinary.api.resources({ resource_type: 'raw', type: 'upload', prefix: 'users/', max_results: 500 }); | |
| console.log('Cloudinary resources fetched:', result.resources.length); | |
| const users = {}; | |
| for (const resource of result.resources) { | |
| const publicId = resource.public_id; | |
| console.log('Processing user:', publicId); | |
| const downloadResult = await cloudinary.api.resource(publicId, { resource_type: 'raw' }); | |
| const url = downloadResult.secure_url; | |
| const userData = await new Promise((resolve, reject) => { | |
| https.get(url, (res) => { | |
| let data = ''; | |
| res.on('data', (chunk) => data += chunk); | |
| res.on('end', () => { | |
| try { | |
| resolve(JSON.parse(data)); | |
| } catch (e) { | |
| reject(e); | |
| } | |
| }); | |
| }).on('error', reject); | |
| }); | |
| if (userData.email) { | |
| users[userData.email] = userData; | |
| } | |
| } | |
| console.log('Users loaded:', Object.keys(users).length); | |
| return users; | |
| } catch (error) { | |
| console.error('Erreur chargement utilisateurs:', error); | |
| return {}; | |
| } | |
| } | |
| // Fonction pour sauvegarder un utilisateur dans Cloudinary | |
| async function saveUser(email, userData) { | |
| try { | |
| const hash = crypto.createHash('md5').update(email).digest('hex'); | |
| const dataStr = JSON.stringify({ ...userData, email }); // Assurer que l'email est inclus | |
| const dataBase64 = Buffer.from(dataStr).toString('base64'); | |
| await cloudinary.uploader.upload(`data:text/plain;base64,${dataBase64}`, { | |
| public_id: `users/${hash}`, | |
| resource_type: 'raw' | |
| }); | |
| } catch (error) { | |
| console.error('Erreur sauvegarde utilisateur:', error); | |
| } | |
| } | |
| let users = {}; | |
| // Charger les utilisateurs au démarrage | |
| loadUsers().then(loadedUsers => { | |
| users = loadedUsers; | |
| }); | |
| // Route d'inscription | |
| app.post('/register', async (req, res) => { | |
| const { email } = req.body; | |
| if (!email) { | |
| return res.status(400).json({ error: 'Email requis' }); | |
| } | |
| if (users[email]) { | |
| console.log(`Tentative d'inscription pour email déjà enregistré: ${email}`); | |
| return res.status(400).json({ error: 'Utilisateur déjà enregistré' }); | |
| } | |
| const otp = crypto.randomInt(100000, 999999).toString(); | |
| otpStore.set(email, { otp, expires: Date.now() + 5 * 60 * 1000 }); | |
| try { | |
| const msg = { | |
| to: email, | |
| from: process.env.EMAIL_USER, | |
| subject: 'Code de vérification - Inscription', | |
| text: `Votre code de vérification est: ${otp}` | |
| }; | |
| await sgMail.send(msg); | |
| console.log('OTP email sent successfully for registration'); | |
| res.json({ message: 'Code envoyé à votre email' }); | |
| } catch (error) { | |
| console.error('Erreur envoi email:', error); | |
| res.status(500).json({ error: 'Erreur envoi email' }); | |
| } | |
| }); | |
| // Route de connexion | |
| app.post('/login', async (req, res) => { | |
| const { email } = req.body; | |
| if (!email) { | |
| return res.status(400).json({ error: 'Email requis' }); | |
| } | |
| if (!users[email]) { | |
| console.log(`Tentative de connexion pour email non enregistré: ${email}`); | |
| return res.status(400).json({ error: 'Utilisateur non trouvé' }); | |
| } | |
| const otp = crypto.randomInt(100000, 999999).toString(); | |
| otpStore.set(email, { otp, expires: Date.now() + 5 * 60 * 1000 }); | |
| try { | |
| const msg = { | |
| to: email, | |
| from: process.env.EMAIL_USER, | |
| subject: 'Code de vérification - Connexion', | |
| text: `Votre code de vérification est: ${otp}` | |
| }; | |
| await sgMail.send(msg); | |
| console.log('Login OTP email sent successfully'); | |
| res.json({ message: 'Code envoyé à votre email' }); | |
| } catch (error) { | |
| console.error('Erreur envoi email:', error); | |
| res.status(500).json({ error: 'Erreur envoi email' }); | |
| } | |
| }); | |
| // Route de vérification OTP | |
| app.post('/verify', async (req, res) => { | |
| const { email, otp } = req.body; | |
| if (!email || !otp) { | |
| return res.status(400).json({ error: 'Email et OTP requis' }); | |
| } | |
| const stored = otpStore.get(email); | |
| if (!stored || stored.otp !== otp || Date.now() > stored.expires) { | |
| console.log(`OTP invalide ou expiré pour ${email}`); | |
| return res.status(400).json({ error: 'OTP invalide ou expiré' }); | |
| } | |
| otpStore.delete(email); | |
| // Enregistrer l'utilisateur si c'est une inscription | |
| if (!users[email]) { | |
| users[email] = { email, registeredAt: new Date() }; | |
| console.log(`Nouveau utilisateur enregistré: ${email}`); | |
| await saveUser(email, users[email]); | |
| console.log(`Utilisateur ${email} sauvegardé dans Cloudinary`); | |
| } else { | |
| console.log(`Utilisateur existant connecté: ${email}`); | |
| } | |
| res.json({ message: 'Authentification réussie', token: 'dummy-token' }); | |
| }); | |
| // Route pour envoyer des notifications par email | |
| app.post('/send-notification', async (req, res) => { | |
| try { | |
| const { to, subject, html, action_type, entity_type, entity_id, user_info, timestamp } = req.body; | |
| if (!to || !subject || !html) { | |
| return res.status(400).json({ error: 'Destinataire, sujet et contenu HTML requis' }); | |
| } | |
| // Configuration de l'email | |
| const msg = { | |
| to: to, | |
| from: process.env.EMAIL_USER, | |
| subject: subject, | |
| html: html | |
| }; | |
| // Envoi de l'email | |
| const result = await sgMail.send(msg); | |
| console.log('Email de notification envoyé:', result[0].statusCode); | |
| res.json({ | |
| message: 'Notification envoyée avec succès', | |
| statusCode: result[0].statusCode, | |
| action_type, | |
| entity_type, | |
| entity_id, | |
| user_info, | |
| timestamp | |
| }); | |
| } catch (error) { | |
| console.error('Erreur envoi notification:', error); | |
| res.status(500).json({ error: 'Erreur envoi notification: ' + error.message }); | |
| } | |
| }); | |
| const PORT = process.env.PORT || 3000; | |
| app.listen(PORT, () => { | |
| console.log(`Serveur démarré sur le port ${PORT}`); | |
| }); |