Skip to content
Snippets Groups Projects
Commit 174f34ec authored by tom.ryser's avatar tom.ryser :carousel_horse:
Browse files

server end

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 364 additions and 0 deletions
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/manga_v2-server.iml" filepath="$PROJECT_DIR$/.idea/manga_v2-server.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
node_modules
# Keep environment variables out of version control
.env
const jwt = require('jsonwebtoken');
const auth = (req, res, next) => {
const token = req.header('Authorization')?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'Accès refusé. Aucun token fourni.' });
}
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch (error) {
res.status(401).json({ error: 'Token invalide.' });
}
};
module.exports = auth;
\ No newline at end of file
This diff is collapsed.
{
"name": "mangaapp-backend",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "tsc",
"start": "node dist/server.js",
"dev": "ts-node-dev --respawn --transpile-only src/server.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@prisma/client": "^6.5.0",
"bcryptjs": "^3.0.2",
"dotenv": "^16.4.7",
"express": "^5.1.0",
"jsonwebtoken": "^9.0.2"
},
"devDependencies": {
"@types/bcryptjs": "^2.4.6",
"@types/express": "^5.0.1",
"@types/jsonwebtoken": "^9.0.9",
"@types/node": "^22.14.0",
"ts-node-dev": "^2.0.0",
"typescript": "^5.8.2"
}
}
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
module.exports = prisma;
\ No newline at end of file
File added
-- CreateTable
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CreateTable
CREATE TABLE "Comment" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"mangaId" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"content" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Comment_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "sqlite"
\ No newline at end of file
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
password String
createdAt DateTime @default(now())
comments Comment[]
}
model Comment {
id Int @id @default(autoincrement())
mangaId String
userId Int
user User @relation(fields: [userId], references: [id])
content String
createdAt DateTime @default(now())
}
const express = require('express');
const router = express.Router();
const prisma = require('../prisma/client');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
router.post('/register', async (req, res) => {
const { email, password } = req.body;
try {
const existingUser = await prisma.user.findUnique({
where: { email },
});
if (existingUser) {
console.log("Utilisateur existe déja"+existingUser);
return res.status(400).json({ error: 'Cet email est déjà utilisé.' });
}
const hashedPassword = await bcrypt.hash(password, 10);
const user = await prisma.user.create({
data: {
email,
password: hashedPassword,
},
});
const token = jwt.sign({ id: user.id, email: user.email }, process.env.JWT_SECRET, {
expiresIn: '1h',
});
console.log(token);
res.status(201).json({ token });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Erreur serveur.' });
}
});
router.post('/login', async (req, res) => {
//print req.body
console.log(req.body);
const { email, password } = req.body;
try {
const user = await prisma.user.findUnique({
where: { email },
});
if (!user) {
console.log('Utilisateur non trouvé');
return res.status(400).json({ error: 'Email ou mot de passe incorrect.' });
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
console.log('Mot de passe incorrect');
return res.status(400).json({ error: 'Email ou mot de passe incorrect.' });
}
const token = jwt.sign({ id: user.id, email: user.email }, process.env.JWT_SECRET, {
expiresIn: '1h',
});
console.log(token);
res.json({ token });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Erreur serveur.' });
}
});
module.exports = router;
\ No newline at end of file
const express = require('express');
const router = express.Router();
const prisma = require('../prisma/client');
const auth = require('../middleware/auth');
router.post('/', auth, async (req, res) => {
const { mangaId, content } = req.body;
try {
const comment = await prisma.comment.create({
data: {
mangaId,
userId: req.user.id,
content,
},
});
res.status(201).json({
id: comment.id.toString(),
mangaId: comment.mangaId,
userId: req.user.id.toString(),
content: comment.content,
createdAt: comment.createdAt.toISOString(),
});
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Erreur serveur.' });
}
});
router.get('/:mangaId', async (req, res) => {
try {
const comments = await prisma.comment.findMany({
where: { mangaId: req.params.mangaId },
include: { user: { select: { email: true } } },
});
res.json(
comments.map((comment) => ({
id: comment.id.toString(),
mangaId: comment.mangaId,
userId: comment.user.email,
content: comment.content,
createdAt: comment.createdAt.toISOString(),
}))
);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Erreur serveur.' });
}
});
module.exports = router;
\ No newline at end of file
const express = require('express');
const dotenv = require('dotenv');
const prisma = require('./prisma/client');
const authRoutes = require('./routes/auth');
const commentRoutes = require('./routes/comments');
dotenv.config();
const app = express();
app.use(express.json());
// Test de connexion à la base de données
async function testDatabaseConnection() {
try {
console.log('Tentative de connexion à la base de données...');
console.log('DATABASE_URL:', process.env.DATABASE_URL);
await prisma.$connect();
console.log('Connexion à la base de données réussie.');
} catch (error) {
console.error('Erreur lors de la connexion à la base de données:', error);
process.exit(1);
}
}
// Routes
app.get('/', (req, res) => {
res.send('Bienvenue sur l\'API Manga !');
});
app.use('/auth', authRoutes);
app.use('/comments', commentRoutes);
// Gestion des erreurs globales
app.use((err, req, res, next) => {
console.error('Erreur serveur:', err.stack);
res.status(500).json({ error: 'Erreur serveur.' });
});
// Gestion des erreurs non capturées
process.on('uncaughtException', (err) => {
console.error('Erreur non capturée:', err);
process.exit(1);
});
// Gestion des promesses rejetées non gérées
process.on('unhandledRejection', (reason, promise) => {
console.error('Rejet non géré à:', promise, 'raison:', reason);
process.exit(1);
});
// Gestion de la fermeture du serveur
process.on('SIGINT', async () => {
console.log('Reçu SIGINT. Fermeture du serveur...');
await prisma.$disconnect();
console.log('Connexion à la base de données fermée.');
process.exit(0);
});
process.on('SIGTERM', async () => {
console.log('Reçu SIGTERM. Fermeture du serveur...');
await prisma.$disconnect();
console.log('Connexion à la base de données fermée.');
process.exit(0);
});
const PORT = process.env.PORT || 3000;
testDatabaseConnection()
.then(() => {
const server = app.listen(PORT, () => {
console.log(`Serveur démarré sur le port ${PORT}`);
});
// Capturer les erreurs du serveur
server.on('error', (error) => {
console.error('Erreur du serveur:', error);
process.exit(1);
});
})
.catch((error) => {
console.error('Erreur lors du démarrage du serveur:', error);
process.exit(1);
});
\ No newline at end of file
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment