Forráskód Böngészése

register&login avec vraie db

Benoît Hubert 8 éve
szülő
commit
39bb832074

+ 38 - 0
exemples/jquery/validation-de-formulaires-bootstrap/alert-box.js

@@ -0,0 +1,38 @@
+// alert-box.js
+
+$(document).ready(function() {
+
+  /**
+   * L'objet window est toujours accessible à JavaScript dans le navigateur.
+   * On peut lui assigner des propriétés assez librement (à condition de
+   * ne pas empiéter sur des propriétés prédéfinies de window).
+   * On va créer une "variable globale" MyApp comme propriété de window,
+   * pour que les scripts de l'application puissent partager des données
+   * via cet objet.
+   * Ci-dessous, la 1ère ligne indique de créer un objet vide si
+   * window.MyApp n'existe pas, et de l'assigner à window.MyApp.
+   */
+  window.MyApp = window.MyApp || {};
+  // On crée un objet jQuery contenant l'élément div#alert-box.
+  window.MyApp.alertBox = $( '#alert-box' );
+  
+  /**
+   * Fonction pour notifier via la boîte d'alertes
+   * Prend comme arguments:
+   *     - status:  'danger' ou 'success'
+   *     - message: le message à afficher
+   */
+  window.MyApp.alert = function( status, message ) {
+    MyApp.alertBox.removeClass( 'alert-danger alert-success' )
+    .addClass( 'show alert-' + status )
+    .html( message );
+    
+    // Après un délai de 5 sec. (2ème param. de setTimeout = millisec.)
+    // On va enlever la classe "show" ce qui va faire se "replier" (collapser)
+    // la boîte. Voir https://getbootstrap.com/docs/4.0/components/collapse/
+    setTimeout( function() {
+      MyApp.alertBox.removeClass( 'show' );
+    }, 5000 );
+  }
+});
+

+ 3 - 3
exemples/jquery/validation-de-formulaires-bootstrap/config.json

@@ -2,8 +2,8 @@
   "title": "Validation de formulaires Bootstrap",
   "category": "misc",
   "html": [ "example.html" ],
-  "js": [ "script.js" ],
-  "css": [],
+  "js": [ "script.js", "alert-box.js" ],
+  "css": [ "styles.css" ],
   "libsJs": [ "jquery-3.2.1.min.js" ],
-  "libsCss": [ "styles.css", "bootstrap.min.css" ]
+  "libsCss": [ "bootstrap.min.css" ]
 }

+ 44 - 39
exemples/jquery/validation-de-formulaires-bootstrap/example.html

@@ -1,54 +1,59 @@
-<ul id="onglets" class="tab-nav">
+<ul id="onglets" class="nav nav-tabs">
     <li>
-        <a data-tab-id="tab-login" id="onglet1" class="active" href="#">Login</a>
+        <a class="nav-link active" data-tab-id="tab-login" id="onglet1" class="active" href="#">Connexion</a>
     </li>
     <li class="tab-nav">
-        <a data-tab-id="tab-register" id="onglet2" href="#">Register</a>
+        <a class="nav-link" data-tab-id="tab-register" id="onglet2" href="#">Inscription</a>
     </li>
 
 </ul>
 
-<div id="alert-box" class="alert alert-danger hidden" role="alert">
+<div id="alert-box" class="alert alert-danger collapse" role="alert">
   
 </div>
 
 <div class="tab" id="tab-login">
-    <form id="form-login">
-      <div class="form-group">
-        <label for="login-email">Email address</label>
-        <input type="email" class="form-control" id="login-email" aria-describedby="emailHelp" placeholder="Enter email">
-        <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
-      </div>
-      <div class="form-group">
-        <label for="login-password">Password</label>
-        <input type="password" class="form-control" id="login-password" placeholder="Password">
-      </div>
-      <div class="form-check">
-        <label class="form-check-label">
-          <input type="checkbox" class="form-check-input">
-          Check me out
-        </label>
-      </div>
-      <button type="submit" class="btn btn-primary">Submit</button>
-    </form>
+  <div class="card">
+    <div class="card-body">
+      <form id="form-login">
+        <div class="form-group">
+          <label for="login-identifier">Identifiant ou e-mail</label>
+          <input type="text" class="form-control" id="login-identifier" aria-describedby="identifierHelp" placeholder="Entrez votre identifiant ou e-mail">
+          <small class="text-danger collapse"></small>
+        </div>
+        <div class="form-group">
+          <label for="login-password">Mot de passe</label>
+          <input type="password" class="form-control" id="login-password" placeholder="Mot de passe">
+        </div>
+        <button type="submit" class="btn btn-primary">Envoyer</button>
+      </form>
+    </div>
+  </div>
 </div>
-<div class="tab" id="tab-register" style="display:none">
-    <form id="form-register">
-      <div class="form-group">
-        <label for="register-username">Username</label>
-        <input type="text" class="form-control" id="register-username" aria-describedby="usernameHelp" placeholder="Enter username" />
-      </div>
-      <div class="form-group">
-        <label for="register-email">Email address</label>
-        <input type="email" class="form-control" id="register-email" aria-describedby="emailHelp" placeholder="Enter email">
-        <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
-      </div>
-      <div class="form-group">
-        <label for="register-password">Password</label>
-        <input type="password" class="form-control" id="register-password" placeholder="Password">
-      </div>
 
-      <button type="submit" class="btn btn-primary">Register</button>
-    </form>
+<div class="tab" id="tab-register" style="display:none">
+  <div class="card">
+    <div class="card-body">
+      <form id="form-register">
+        <div class="form-group">
+          <label for="register-username">Identifiant</label>
+          <input type="text" class="form-control" id="register-username" aria-describedby="usernameHelp" placeholder="Entrez un identifiant (lettres, chiffres, _)" />
+          <small class="text-danger collapse"></small>
+        </div>
+        <div class="form-group">
+          <label for="register-email">Adresse e-mail</label>
+          <input type="email" class="form-control" id="register-email" aria-describedby="emailHelp" placeholder="Entrez un e-mail">
+          <small class="text-danger collapse"></small>
+        </div>
+        <div class="form-group">
+          <label for="register-password">Mot de passe</label>
+          <input type="password" class="form-control" id="register-password" placeholder="Mot de passe (4 caractères min.)">
+          <small class="text-danger collapse"></small>
+        </div>
+  
+        <button type="submit" class="btn btn-primary">Envoyer</button>
+      </form>
+    </div>
+  </div>
 </div>
 

+ 156 - 76
exemples/jquery/validation-de-formulaires-bootstrap/script.js

@@ -1,107 +1,187 @@
-// Paramètres pour les envois par AJAX
-$.ajaxSetup({
-    headers: {
-        'content-type': 'application/json'
-    }
-});
+$(document).ready(function() {
+  
+  // Si vous vous demandez pourquoi on fait ça...
+  // https://stackoverflow.com/questions/16284724/what-does-var-app-app-do
+  window.MyApp = window.MyApp || {};
 
-// Gestion des erreurs
-$( document ).ajaxError(function(event, jqXHR,  ajaxSettings, thrownError) {
-    var data = JSON.parse(jqXHR.responseText);
-    console.log('parsed', data);
-    $('#alert-box')
-    .removeClass('hidden')
-    .removeClass('alert-success')
-    .addClass('alert-danger')
-    .html(data.message);
-});
+  function markInputAsValid( input ) {
+    // Utiliser les classes Bootstrap .is-valid et .is-invalid
+    input
+    .addClass('is-valid')
+    .removeClass('is-invalid');
+    // On va se servir de l'id pour le sélecteur suivant
+    // (balise small adjacente au champ input)
+    var inputId = input.attr( 'id' );
+    $( '#' + inputId + ' + small' )
+    .removeClass( 'show' );
+  }
 
-$('#register-username')
-.change(function(e) {
+  function markInputAsInvalid( input, message ) {
+    input
+    .addClass('is-invalid')
+    .removeClass('is-valid');
+    var inputId = input.attr( 'id' );
+    console.log( inputId, $( '#' + inputId + ' + small' ), message );
+    $( '#' + inputId + ' + small' )
+    .addClass( 'show' )
+    .html( message );
+  }
+
+  // Paramètres pour les envois par AJAX
+  $.ajaxSetup({
+      headers: {
+          'content-type': 'application/json'
+      }
+  });
+  
+  // Gestion des erreurs
+  $( document ).ajaxError(function(event, jqXHR,  ajaxSettings, thrownError) {
+    var data = JSON.parse(jqXHR.responseText);
+    window.MyApp.alert( 'danger', data.message );
+  });
+  
+  $('#register-username')
+  .change(function(e) {
     var inputUsername = $(this);
     var username = inputUsername.val();
     var re = /^[A-Za-z][A-Za-z0-9_]+$/;
     var isUsernameValid = username.match(re);
     if(! isUsernameValid) {
-        inputUsername
-        .addClass('is-invalid')
-        .removeClass('is-valid');
+      markInputAsInvalid( inputUsername,
+        "L'identifiant doit commencer par une lettre, et être suivi par " +
+        "au moins une lettre OU un chiffre OU un tiret bas _"
+      );
+      return;
+    }
+
+    // Envoi d'une requête AJAX vers une URL qui va nous renvoyer un
+    // objet JSON avec un booléen "success" qui va nous dire si le username
+    // est disponible (true) ou non (false)
+    $.get(
+      'http://localhost:3000/jquery/ajax/username-check?username=' + username,
+      function(response) {
+        console.log(response.success)
+        if(response.success) {
+          markInputAsValid( inputUsername );
+        }
+        else {
+          markInputAsInvalid( inputUsername, "Cet identifiant est déjà pris" );
+        }
+      }
+    );
+  });
+
+  $('#register-email')
+  .change(function(e) {
+    var inputEmail = $(this);
+    var email = inputEmail.val();
+    var re = /^[A-Za-z][A-Za-z0-9_\.]+@[A-Za-z][A-Za-z0-9_\.]+\.[a-z]{2,}$/;
+    var isEmailValid = email.match(re);
+    if(! isEmailValid) {
+        markInputAsInvalid( inputEmail );
         return;
     }
 
+    // Même chose que pour le username, cette fois avec l'email
     $.get(
-        'http://localhost:3000/jquery/ajax/username-check?username=' + username,
-        function(response) {
-            console.log(response.success)
-            if(response.success) {
-                inputUsername
-                .addClass('is-valid')
-                .removeClass('is-invalid');
-            }
-            else {
-                inputUsername
-                .addClass('is-invalid')
-                .removeClass('is-valid');
-                return;
-            }
+      'http://localhost:3000/jquery/ajax/email-check?email=' + email,
+      function(response) {
+        console.log(response.success)
+        if(response.success) {
+          markInputAsValid( inputEmail );
         }
+        else {
+          markInputAsInvalid( inputEmail, "Cet e-mail est déjà pris" );
+        }
+      }
     );
-});
+  });
+
+$('#register-password')
+  .change(function(e) {
+    var inputPassword = $(this);
+    var password = inputPassword.val();
+    if(password.length < 4) {
+        markInputAsInvalid( inputPassword, "Mot de passe trop court (4 caractères minimum" );
+        return;
+    }
+
+    markInputAsValid( inputPassword );
+  });
 
-// Soumission du formulaire d'inscription vers le serveur
-$('#form-register').submit(function(e) {
+  // Soumission du formulaire d'inscription vers le serveur
+  $('#form-register').submit(function(e) {
+    var inputs = $(this).find('input');
+    var emptyOrInvalid = [];
+    inputs.each( function( index, elem ) {
+      var input = $( this );
+      if( ! input.val() || ! input.hasClass( 'is-valid' ) ) {
+        emptyOrInvalid.push( input.siblings( 'label' ).html() );
+      }
+    } );
+    // Si au moins un champ est vide ou n'a pas is-valid
+    // on notifie et on interrompt par return
+    if( emptyOrInvalid.length ) {
+      var message = emptyOrInvalid.length + ' champs vides ou ' +
+        'invalides :<br>' + emptyOrInvalid.join(', ');
+      MyApp.alert( 'danger', message );
+      return false;
+    }
+    // Dans chaque itération input[i] est un élément DOM
     var username = $('#register-username').val();
     var email    = $('#register-email').val();
     var password = $('#register-password').val();
     var user = {
-        username: username,
-        email: email,
-        password: password
+      username: username,
+      email: email,
+      password: password
     };
     var userJSON = JSON.stringify(user);
     console.log(user);
     console.log(userJSON);
     e.preventDefault();
-    $(this).find('input').val('');
-    $.post('/jquery/ajax/register', userJSON, 'json');
-})
-
-
-$('#form-login').submit(function(e) {
-    var email    = $('#login-email').val();
-    var password = $('#login-password').val();
-    var user = {
-        email: email,
-        password: password
-    };
-    var userJSON = JSON.stringify(user);
-    e.preventDefault();
-    $(this).find('input').val('');
+    inputs.val('').removeClass('is-valid');
     $.post(
-      '/jquery/ajax/login',
+      '/jquery/ajax/register',
       userJSON,
       function(data) {
-        $('#alert-box')
-        .removeClass('alert-danger')
-        .addClass('alert-success')
-        .removeClass('hidden')
-        .html(data.message);
+        window.MyApp.alert( 'success', 'Bienvenue, ' + data.user.username );
       },
       'json'
     );
-})
-
-
-
-
-
-var onglets = $('#onglets li a');
+  })
+  
+  
+  $('#form-login').submit(function(e) {
+      var identifier = $('#login-identifier').val();
+      var password   = $('#login-password').val();
+      var user = {
+          identifier: identifier,
+          password: password
+      };
+      var userJSON = JSON.stringify(user);
+      e.preventDefault();
+      $(this).find('input').val('');
+      $.post(
+        '/jquery/ajax/login',
+        userJSON,
+        function(data) {
+          MyApp.alert('success', "Vous êtes identifié, " + data.user.username);
+        },
+        'json'
+      );
+  })
+  
+  var onglets = $('#onglets li a');
+  
+  onglets.click(function(e) {
+      var link = $(this);
+      onglets.removeClass('active');
+      link.addClass('active');
+      var idPanneau = link.data('tab-id');
+      $('.tab').hide();
+      $('#' + idPanneau).show();
+  });
 
-onglets.click(function(e) {
-    var link = $(this);
-    onglets.removeClass('active');
-    link.addClass('active');
-    var idPanneau = link.data('tab-id');
-    $('.tab').hide();
-    $('#' + idPanneau).show();
+  
 });

+ 7 - 0
exemples/jquery/validation-de-formulaires-bootstrap/styles.css

@@ -0,0 +1,7 @@
+/* styles.css */
+#alert-box {
+  margin-top: 15px;
+}
+#onglets {
+  margin-top: 20px;
+}

+ 4 - 0
js/ws-editor.js

@@ -82,6 +82,10 @@ $(document).ready(function() {
     editor.setTheme("ace/theme/eclipse");
     editor.$blockScrolling = Infinity;
     editorSession.setUseWrapMode(true);
+    editorSession.setOptions({
+        tabSize: 2,
+        useSoftTabs: true
+    });
     setDefaultEditorContent();
   }
 

+ 29 - 0
lib/passwd.js

@@ -0,0 +1,29 @@
+const Promise = require('bluebird');
+const bcrypt  = Promise.promisifyAll(require('bcrypt'));
+
+const SALT_WORK_FACTOR = 10;
+
+function throwIfFalsy(errorMsg) {
+  return value => {
+    if(! value) {
+      throw new Error(errorMsg);
+    }
+    return value;
+  };
+}
+
+function hashPasswordAsync(password) {
+  return bcrypt.genSaltAsync(SALT_WORK_FACTOR)
+  .then(salt => bcrypt.hashAsync(password, salt));
+}
+
+function matchPasswordAsync(user, password) {
+  return bcrypt.compare(password, user.password)
+  .then(throwIfFalsy('Wrong password'))
+  .then(() => (user));
+}
+
+module.exports = {
+  hash: hashPasswordAsync,
+  match: matchPasswordAsync
+};

+ 168 - 0
lib/queryBuilder.js

@@ -0,0 +1,168 @@
+const squel = require("squel");
+
+function selectAll(table, whereString) {
+  let query = squel.select()
+  .from(table)
+  .field('*');
+  if (whereString) {
+    query = query.where(whereString);
+  }
+  return query.toString();
+}
+
+function selectOne(table, id) {
+  return squel.select()
+  .from(table)
+  .field('*')
+  .where("id = ?", id)
+  .toString();
+}
+
+function selectWhere(table, where, operator) {
+  operator = operator || '=';
+  let query = squel.select()
+  .from(table)
+  .field('*');
+  for (var key in where) {
+    query = query.where(key + ' ' + operator + ' ?', where[key]);
+  }
+  return query.toString();
+}
+
+function deleteWithId(table, id, idKey) {
+  idKey = idKey !== undefined ? idKey : 'id';
+  return squel.delete()
+  .from(table)
+  .where(idKey + " = ?", id)
+  .toString();
+}
+
+function selectIn(table, ids) {
+  const where = ids.length === 0 ? '0' :
+    "id IN (" + ids.join(',') + ")";
+  return squel.select()
+  .from(table)
+  .field('*')
+  .where(where)
+  .toString();
+}
+
+function selectRelatees(table, relateeKey, relateeId) {
+  return squel.select()
+  .from(table)
+  .field('*')
+  .where(relateeKey + " = ?", relateeId)
+  .toString();
+}
+
+function selectRelateesIn(table, relateeKey, relateeIds) {
+  const where = relateeIds.length === 0 ? '0' :
+    relateeKey + " IN (" + relateeIds.join(',') + ")";
+  return squel.select()
+  .from(table)
+  .field('*')
+  .where(where)
+  .toString();
+}
+
+
+// function selectMany(table, ids) {
+//   const idsString = ids.join(',');
+//   return squel.select()
+//   .from(table)
+//   .field('*')
+//   .where("id IN ?", idsString)
+//   .toString();
+// }
+
+
+function getSelectOne(table) {
+  return id => {
+    return squel.select()
+    .from(table)
+    .field('*')
+    .where("id = ?", id)
+    .toString();
+  };
+}
+
+function getInsert(table) {
+  return attributes => {
+    attributes = Array.isArray(attributes) ? attributes : [attributes];
+    return insert(table, attributes);
+  };
+}
+
+function insert(table, rows) {
+  rows = Array.isArray(rows) ? rows : [rows];
+  rows.forEach(row => { delete row.id; });
+  return squel.insert({ replaceSingleQuotes: true, autoQuoteFieldNames: true })
+  .into(table)
+  .setFieldsRows(rows)
+  .toString();
+}
+
+function updateOne(table, id, attributes) {
+  delete attributes.id;
+  if(attributes.createdAt) {
+    delete attributes.createdAt;
+  }
+  return squel.update({ replaceSingleQuotes: true, autoQuoteFieldNames: true })
+    .table(table)
+    .setFields(attributes)
+    .where('id = ' + id)
+    .toString();
+}
+
+function updateWhere(table, where, attributes) {
+  delete attributes.id;
+  if(attributes.createdAt) {
+    delete attributes.createdAt;
+  }
+  let query = squel.update({ replaceSingleQuotes: true, autoQuoteFieldNames: true })
+  .table(table)
+  .setFields(attributes);
+  for (var key in where) {
+    query = query.where(key + ' = ?', where[key]);
+  }
+  return query.toString();
+}
+
+function updateIn(table, ids, attributes) {
+  delete attributes.id;
+  if(attributes.createdAt) {
+    delete attributes.createdAt;
+  }
+  const where = ids.length === 0 ? '0' :
+    "id IN (" + ids.join(',') + ")";
+  return squel.update({ replaceSingleQuotes: true, autoQuoteFieldNames: true })
+  .table(table)
+  .setFields(attributes)
+  .where(where)
+  .toString();
+}
+
+
+function getUpdateOne(table, id) {
+  return attributes => updateOne(table, id, attributes);
+}
+// describe('squel query', () => {
+  
+//  it('should build a select query', () => {
+//    const sql = 
+//     sql.should.equal('SELECT * FROM table');
+//  });
+
+//   it('should build an insert query', () => {
+//     const sql = create('users', { email: 'bh@localhost.local', order: 1, password: '###bloody#hash', createdAt: '2017-02-27' });
+//     lineLogger(sql);
+//   });
+
+// });
+
+module.exports = {
+  selectAll, selectOne, selectIn, selectWhere, selectRelatees, selectRelateesIn, getSelectOne,
+  insert, getInsert,
+  updateOne, updateWhere, getUpdateOne, updateIn,
+  deleteWithId
+};

+ 12 - 0
migrations/001-initial-schema.sql

@@ -0,0 +1,12 @@
+-- Up
+CREATE TABLE users (
+	id INTEGER PRIMARY KEY,
+	username VARCHAR(64) UNIQUE,
+  firstname VARCHAR(64),
+  lastname VARCHAR(64),
+	email VARCHAR(64) UNIQUE,
+  password VARCHAR(255)
+);
+
+-- Down
+DROP TABLE users;

+ 4 - 1
package.json

@@ -1,6 +1,7 @@
 {
   "name": "ipi-inline-editor",
   "dependencies": {
+    "bcrypt": "^1.0.3",
     "bluebird": "^3.5.1",
     "body-parser": "^1.18.2",
     "chokidar": "^1.7.0",
@@ -10,7 +11,9 @@
     "lodash": "^4.17.4",
     "mustache": "^2.3.0",
     "slug": "^0.9.1",
-    "sprintf-js": "^1.1.1"
+    "sprintf-js": "^1.1.1",
+    "sqlite": "^2.8.0",
+    "squel": "^5.12.0"
   },
   "devDependencies": {
     "chai": "^4.1.2",

+ 79 - 52
server.js

@@ -2,10 +2,11 @@
  * ATTENTION le fichier sandboxApp.js est assez complexe.
  * Il sert à initialiser l'appli permettant d'avoir l'éditeur HTML&JavaScript en ligne
  */
-var app = require('./sandboxApp');
-
-
-
+const app      = require('./sandboxApp');
+const db       = require('sqlite');
+const Promise  = require('bluebird');
+const qbuilder = require('./lib/queryBuilder');
+const passwd   = require('./lib/passwd');
 /*-------------------------------------------------------*
  | Déclaration de gestionnaires pour les exemples AJAX
  *-------------------------------------------------------*
@@ -58,20 +59,27 @@ function createNewUser(user) {
   // On vérifie que les données de l'utilisateur sont renseignées
   // Si non, on renvoie false
   if(! user || ! user.username || ! user.email || ! user.password) {
-    return false;
+    return Promise.reject(new Error('Missing fields'));
   }
 
+  const { username, email } = user;
+
   // L'étape de vérification a réussi, on insère l'utilisateur dans le tableau
   // On crée un faux "id" pour simuler une insertion SQL. En SQL les "id" sont
   // incrémentés à chaque insertion. On simule cela en incrémentant un compteur
   // "userId" à chaque insertion
-  userList.push({
-    id: userId++,
+  // userList.push();
+  // return true;
+
+  return passwd.hash(user.password)
+  .then(password => qbuilder.insert('users', {
     username: user.username,
     email:    user.email,
-    password: user.password
-  });
-  return true;
+    password
+  }))
+  .then(query => db.run(query))
+  .then(() => qbuilder.selectWhere('users', { email }))
+  .then(query => db.get(query));
 }
 
 
@@ -79,34 +87,30 @@ app.post('/jquery/ajax/login', function(req, res) {
 
   // Récupérer email et password
   var identifiants = req.body;
-  if(! identifiants.email || ! identifiants.password) {
+  var identifier = identifiants.identifier;
+  if(! identifiants.identifier || ! identifiants.password) {
     return res.status(400).json({
       message: 'paramètre requis manquant'
     });
   }
-
-  for(var i = 0 ; i < userList.length ; i++) {
-    var user = userList[i];
-
-    if(identifiants.email == user.email) {
-
-
-      if(identifiants.password == user.password) {
-        return res.json({
-          message: 'Vous avez été identifié',
-        });
-      }
-      else {
-        return res.status(401).json({
-          message: 'Mot de passe incorrect'
-        });
-      }
-
+  var query = qbuilder.selectAll('users', "email='" + identifier + "' OR username='" + identifier + "'");
+  console.log('requête SQL recherche user pour login', query);
+  db.get(query)
+  .then(existingUser => {
+    console.log('résultat requête', existingUser);
+    if(! existingUser) {
+      return res.status(404).json({
+        message: 'Utilisateur non trouvé'
+      });
     }
-
-  }
-  return res.status(404).json({
-    message: 'Utilisateur non trouvé'
+    passwd.match(existingUser, identifiants.password)
+    .then(() => res.json({ user: existingUser }))
+    .catch(err => {
+      console.error(err);
+      return res.status(401).json({
+        message: 'Mot de passe incorrect'
+      });
+    });
   });
 
 });
@@ -122,30 +126,53 @@ app.post('/jquery/ajax/register', function(req, res) {
   var user = req.body;
 
   // createNewUser() va nous renvoyer true ou false
-  var success = createNewUser(user);
-
-  if(success) {
-    // Envoyer un message sur la console du serveur
-    console.log('Utilisateur enregistré: ', user, '\nListe des utilisateurs', userList);
-    res.json({ user: user });
-  }
-  else {
-    res.status(400).json({ error: 'Champs manquants dans la requête' });
-  }
+  createNewUser(user)
+  .then(user => res.json({ user: user }))
+  .catch(err => {
+    if( err.code === 'SQLITE_CONSTRAINT' ) {
+      return res.status(409).json({
+        message: 'Un utilisateur existe déjà avec cet email ou cet identifiant'
+      });
+    }
+    else if( err.message === 'Missing fields' ) {
+      return res.status(400).json({ message: 'Champs manquants dans la requête' });
+    }
+    else {
+      return res.status(500).json({ message: 'Erreur serveur inconnue: ' + err.message }); 
+    }
+  });
 });
 
 app.get('/jquery/ajax/username-check', function(req, res) {
   var username = req.query.username;
-  for(u = 0 ; u < userList.length ; u++) {
-    if(username === userList[u].username) {
-      return res.json({ success: false });
-    }
-  }
-  res.json({ success: true });
+  var query = qbuilder.selectWhere('users', { username });
+  db.get(query)
+  .then(records => {
+    // Si aucun user n'existe avec cet username, records vaut undefined
+    // et on renvoie alors true
+    res.json({ success: records === undefined });
+  });
 });
 
+app.get('/jquery/ajax/email-check', function(req, res) {
+  var email = req.query.email;
+  var query = qbuilder.selectWhere('users', { email });
+  db.get(query)
+  .then(records => {
+    // Si aucun user n'existe avec cet email, records vaut undefined
+    // et on renvoie alors true
+    res.json({ success: records === undefined });
+  });
 
+});
 
-
-console.log('Le serveur écoute sur le port 3000. Laissez cette console ouverte ! Avec votre navigateur, allez sur http://localhost:3000');
-app.listen(3000);
+Promise.resolve()
+  // First, try connect to the database
+  .then(() => db.open('./example-database.sqlite', { Promise }))
+  .then(() => db.migrate({})) //  force: 'last' 
+  .catch(err => console.error(err.stack))
+  // Finally, launch Node.js app
+  .finally(() => {
+    app.listen(3000);
+    console.log('Le serveur écoute sur le port 3000. Laissez cette console ouverte ! Avec votre navigateur, allez sur http://localhost:3000');
+  });