diff --git a/README.md b/README.md index 8769fd1ac80ab471dc80b7f6c995f3a98fd0bf93..ccd8eb9e7b42b6d2772ca1f104c78a8ddb2342f0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,33 @@ # Projet tutoré Developpement mobile +## Membres + +- Brian Bardet +- Julien Cayla +- Guillaume Courtes +- Elise Moreau + +## Contexte + +L'usage de plus en plus croissant des téléphones mobiles nécessite le développement +d'applications toujours plus riches, ergonomiques et fluides. Toutefois, il existe encore plusieurs +environnements très différents dont les principaux sont Android et IOS. C'est pourquoi, il peut +être intéressant d'étudier différents langages et plateformes permettant de répondre au besoin +de n'écrire qu'un seul code source, et ainsi éviter de faire du code natif. + +## Objectif du projet + +L'objectif de ce projet est d'étudier les différentes possibilités pour répondre à ce besoin, en +effectuant un travail de veille dans ce domaine, puis de tester minimum trois solutions retenues. Ainsi, il sera possible d'évaluer l'intérêt mais +aussi les limites des solutions retenues, chaque solution ayant ses avantages et ses incovénients. + + +## Structure du dépôt + +- API : + - node + +- 3 applications mobiles : + - Flutter + - Ionic + - React Native diff --git a/api/README.md b/api/README.md index a49348a7fa37f2229b71559cfa8caafdfc14f97e..a5dda1b79bf30c3891d03785fa79b802eb7acf9b 100644 --- a/api/README.md +++ b/api/README.md @@ -18,6 +18,7 @@ * Route : `/users/login,` * Méthode : `post` * Body : + ``` { "username": string, @@ -35,6 +36,7 @@ * Route : `/messages` * Méthode : `post` * Body : + ``` { "body": string, @@ -53,6 +55,7 @@ #### Création d’une room * Route : `/rooms,` * Méthode : `post` +* Body : ``` { "name": string, @@ -73,6 +76,7 @@ * Route : `/rooms/:id` * Paramètres de la room : id de la room * Méthode : put +* Body : ``` { "name": string, @@ -89,6 +93,8 @@ * Route : `/rooms/:id/users` * Paramètres de la route : id de la room * Méthode : `post` +* Body : + ``` { "ids": [string] diff --git a/api/models/Message.js b/api/models/Message.js index f9d8657f645a280261cc9d039c9bdef3c6b44d70..bd05e8df138eb571865b4832925f030f461881c3 100644 --- a/api/models/Message.js +++ b/api/models/Message.js @@ -3,8 +3,8 @@ const Schema = mongoose.Schema const message = new Schema( { body: String, - author: { type: Schema.Types.ObjectId, ref:'User'}, - room: { type: Schema.Types.ObjectId, ref:'Room'}, + author: { type: Schema.Types.ObjectId, ref:'users'}, + room: { type: Schema.Types.ObjectId, ref:'rooms'}, date: Date, } ); diff --git a/api/routes/messages_routes.js b/api/routes/messages_routes.js index faffffff4a15e5a642b9b9e126e93d9ac28cbdb3..23be6c24b36f27e3df1667e3d326ab6ce95805aa 100644 --- a/api/routes/messages_routes.js +++ b/api/routes/messages_routes.js @@ -1,5 +1,4 @@ import express from 'express'; -import mongoose from "mongoose"; const router = express.Router(); import Room from "../models/Room.js"; @@ -35,7 +34,7 @@ router.post('/', validator.body(messageSchema), async function(req, res, next){ const newMessage = new Message({ body: req.body.body, - author : author._id, + author: author, room: room._id, date: new Date() }); @@ -46,10 +45,6 @@ router.post('/', validator.body(messageSchema), async function(req, res, next){ return next(err); } - // websockets.forEach(function (otherWS) { - // otherWS.send(JSON.stringify(msg)) - // }); - res.json(newMessage); }) @@ -58,12 +53,12 @@ router.post('/', validator.body(messageSchema), async function(req, res, next){ router.get('/', async function (req, res, next) { let messages = null; try { - messages = await Message.find({}).sort({ date: -1 }).limit(50); + messages = await Message.find({}).populate('author').sort({ date: -1 }).limit(50); } catch(err) { return next(err); } res.status(200).json(messages); -}) +}); export default router; diff --git a/api/routes/rooms_routes.js b/api/routes/rooms_routes.js index 98dae16b67b14131125160cf0f55c584985c5cc1..3503d745da7f7f15cd37129e0d810a608f0cc563 100644 --- a/api/routes/rooms_routes.js +++ b/api/routes/rooms_routes.js @@ -1,5 +1,4 @@ import express from 'express'; -import mongoose from "mongoose"; const router = express.Router(); import Room from "../models/Room.js"; @@ -26,7 +25,7 @@ router.post('/', validator.body(roomSchema), async function(req, res, next){ if (!currentUser){ return res.status(401).json({ - 'error': 'User does\'nt exist.' + 'error': 'User doesn\'t exist.' }); } @@ -45,14 +44,15 @@ router.post('/', validator.body(roomSchema), async function(req, res, next){ res.json(newRoom); -}) + emit('new-room', newRoom, newRoom.users); +}); // Liste des room contenant l'utilisateur courant // Pas de room publique router.get('/', async function (req, res, next){ let room = null; try { - room = await Room.find({users: req.user.id}).populate('users'); + room = await Room.find({ users: req.user.id }).populate('users'); } catch(err) { return next(err); } @@ -64,29 +64,34 @@ router.get('/', async function (req, res, next){ } return res.json(room); -}) +}); // Récupère les messages d'une room router.get('/:id/messages', async function (req, res, next) { let room = null; try { + room = await Room.findOne({ _id: req.params.id, users: req.user.id }); room = await Room.findById(req.params.id); } catch (err){ return next(err); } - if (!room) return res.status(404).json({error: 'Room not found'}); + if (!room) return res.status(404).json({ error: 'Room not found' }); let messages = null; try { + messages = await Message.find({ room: room._id }) + .populate('author') + .sort({ date: -1 }) + .limit(50); messages = await Message.find({room: room._id}).sort({ date: -1 }).limit(50); } catch(err) { return next(err); } return res.json(messages); -}) +}); // Récupération de liste des utilisateurs d'une room dans laquelle est l'utilisateur courant router.get('/:id/users', async function(req, res, next){ @@ -104,7 +109,7 @@ router.get('/:id/users', async function(req, res, next){ } return res.json(room.users); -}) +}); //Suppression d'une room router.delete('/:id', async function(req, res, next){ @@ -116,7 +121,7 @@ router.delete('/:id', async function(req, res, next){ } res.status(204).end(); -}) +}); const roomSchemaPut = Joi.object({ name: Joi.string().required().trim().min(1), @@ -143,11 +148,11 @@ router.put('/:id', validator.body(roomSchemaPut), async function(req, res, next) if (!room) return res.status(404).json({error: 'Room not found'}); return res.json(room); -}) +}); const roomSchemaUsers = Joi.object({ ids: Joi.array().items(Joi.string()).required() -}) +}); //Ajouter un ou plusieurs utilisateurs dans une room router.post('/:id/add_users', validator.body(roomSchemaUsers), async function(req, res, next){ @@ -179,7 +184,7 @@ router.post('/:id/add_users', validator.body(roomSchemaUsers), async function(re room.save(); return res.json(room); -}) +}); //Supprimer des utilisateurs d'une room (excepté le créateur de celle ci) router.post('/:id/remove_users', validator.body(roomSchemaUsers), async function(req, res, next){ @@ -197,12 +202,12 @@ router.post('/:id/remove_users', validator.body(roomSchemaUsers), async function } let ids = req.body.ids; // On ne peut pas supprimer le créateur de la room de celle-ci - ids = ids.filter(id => id !== room.createdBy.toString()) + ids = ids.filter(id => id !== room.createdBy.toString()); room.users.pull(...ids); room.save(); return res.json(room); -}) +}); export default router; diff --git a/api/routes/users_routes.js b/api/routes/users_routes.js index 3922be6d351d9a8b88f0a6e1b02eb11a87bfbc62..0cfa1905be3e9e02c56bd65d60ab381f7e344f25 100644 --- a/api/routes/users_routes.js +++ b/api/routes/users_routes.js @@ -1,5 +1,4 @@ import express from 'express'; -import mongoose from "mongoose"; const router = express.Router(); import User from "../models/User.js"; import crypto from 'crypto'; @@ -15,8 +14,42 @@ const userSchema = Joi.object({ confirm: Joi.string().required().trim().min(1) }); +router.get('/me', async function(req, res, next){ + let user; + try { + user = await User.findById(req.user.id); + } catch(err) { + return next(err); + } + + if (!user){ + return res.status(401).json({ + error: 'not authenticated' + }); + } + + res.status(200).json(user); +}); + +const searchSchema = Joi.object({ + q: Joi.string().required().trim().min(1), +}); + +router.post('/search', validator.query(searchSchema), async function(req, res, next){ + let users; + + try { + users = await User.find(); + } catch(err) { + return next(err); + } + + res.status(200).json(users); +}); + + // Créer un nouvel utilisateur -router.post('/', validator.body(userSchema), async function(req, res){ +router.post('/', validator.body(userSchema), async function(req, res, next){ if (req.body.confirm !== req.body.password){ return res.status(400).json({ @@ -31,7 +64,7 @@ router.post('/', validator.body(userSchema), async function(req, res){ if(user){ return res.status(409).json({ error: 'Username already exists.' - }) + }); } } catch(err) { return next(err); @@ -50,7 +83,7 @@ router.post('/', validator.body(userSchema), async function(req, res){ } res.json(newUser); -}) +}); const userSchemaLogin = Joi.object({ username: Joi.string().required().trim().min(1), @@ -70,7 +103,7 @@ router.post('/login', validator.body(userSchemaLogin), async function(req, res, if (!user){ return res.status(401).json({ error: 'Fail to authenticate with given credentials.' - }) + }); } const password = crypto.createHash('md5').update(req.body.password).digest("hex"); @@ -91,7 +124,7 @@ router.post('/login', validator.body(userSchemaLogin), async function(req, res, } ); return res.json({token, user: {username: user.username, id: user._id}}); -}) +}); //Récupérer la liste des utilisateurs router.get('/', async function (req, res, next){ @@ -109,6 +142,6 @@ router.get('/', async function (req, res, next){ } return res.json(users); -}) +}); export default router;