diff --git a/src/libs/models/permissionRole.js b/src/libs/models/permissionRole.js
index 441b4345c927f1349be21ecaf13882e6bb6957c4..e415acc697f2db9af4be231efdb8e855cbd9ec53 100644
--- a/src/libs/models/permissionRole.js
+++ b/src/libs/models/permissionRole.js
@@ -22,8 +22,8 @@ var PermissionRole = db.define("PermissionRole",{
 },
 {timestamps: false});
 
-PermissionRole.hasOne(Role, {foreignKey: 'id'});
-PermissionRole.hasOne(Permission, {foreignKey: 'id'});
+PermissionRole.hasMany(Role, {foreignKey: 'id'});
+PermissionRole.hasMany(Permission, {foreignKey: 'id'});
 
 module.exports = PermissionRole;
 
diff --git a/src/libs/models/publication.js b/src/libs/models/publication.js
new file mode 100644
index 0000000000000000000000000000000000000000..03b3f0f4da986e10458688c5fe5635a43e441412
--- /dev/null
+++ b/src/libs/models/publication.js
@@ -0,0 +1,57 @@
+const Sequelize = require("sequelize");
+const db = require('../db/postgres.js');
+const libs = `${process.cwd()}/libs`;
+
+var Publication = db.define("Publication",{
+    id:{
+        type: Sequelize.INTEGER,
+        allowNull:false,
+        unique: true,
+        primaryKey: true
+    },
+    filter:{
+        type: Sequelize.ENUM("Artigo", "Tese", "Dissertação", "Relatório", "Periódico"),
+        allowNull:false,
+        validate: {
+            notNull: { msg: "O campo categoria é obrigatória e aceita apenas os valores 'Artigo', 'Tese', 'Dissertação', 'Relatório', 'Periódico."},
+        }
+    },
+    title:{
+        type: Sequelize.STRING,
+        allowNull:false,
+    },
+    authors:{
+        type: Sequelize.STRING,
+        allowNull:false
+    },
+    organization:{
+        type: Sequelize.STRING,
+        allowNull:false
+    },
+    year:{
+        type:Sequelize.STRING,
+        allowNull:false
+    },
+    text:{ 
+        type: Sequelize.ENUM("Baixar","Acessar"),
+        allowNull:false,
+        validate: {
+            notNull: { msg: "O campo origem é obrigatória e aceita apenas os valores 'Baixar', 'Acessar'."},
+        }
+    },
+    link:{
+        type: Sequelize.STRING
+    },
+    upload:{
+        type: Sequelize.STRING
+    },
+    is_draft:{
+        type:Sequelize.BOOLEAN,
+        allowNull:false,
+        defaultValue: true
+    }
+
+},
+{timestamps: false});
+
+module.exports = Publication;
\ No newline at end of file
diff --git a/src/libs/models/userPublication.js b/src/libs/models/userPublication.js
new file mode 100644
index 0000000000000000000000000000000000000000..43417ffe06d4bb8991d8134909c165d9d6e7e2a3
--- /dev/null
+++ b/src/libs/models/userPublication.js
@@ -0,0 +1,29 @@
+const Sequelize = require("sequelize");
+const db = require('../db/postgres.js');
+const libs = `${process.cwd()}/libs`;
+const User = require(`${libs}/models/user`);
+const Publication = require(`${libs}/models/publication`);
+
+var userPublication = db.define("userPublication",{
+    id:{
+        type: Sequelize.INTEGER,
+        allowNull:false,
+        unique: true,
+        primaryKey: true
+    },
+    user_id:{
+        type: Sequelize.STRING,
+        allowNull:false,
+    },
+    publication_id:{
+        type: Sequelize.INTEGER,
+        allowNull:false
+    }
+},
+{timestamps: false});
+
+userPublication.hasMany(User, {foreignKey: 'id'});
+userPublication.hasMany(Publication, {foreignKey: 'id'});
+
+module.exports = userPublication;
+
diff --git a/src/libs/routes_v1/publication.js b/src/libs/routes_v1/publication.js
new file mode 100644
index 0000000000000000000000000000000000000000..dc6d647103fc76307cf6da1998675d05bddd1d16
--- /dev/null
+++ b/src/libs/routes_v1/publication.js
@@ -0,0 +1,266 @@
+const express = require('express');
+
+const pubApp = express();
+
+const libs = `${process.cwd()}/libs`;
+
+const config = require(`${libs}/config`);
+
+const log = require(`${libs}/log`)(module);
+
+const VerificationToken = require(`${libs}/models/verificationToken`);
+
+const Publication = require(`${libs}/models/publication`);
+
+const UserPublication = require(`${libs}/models/userPublication`);
+
+const ResetToken = require(`${libs}/models/resetToken`);
+
+const response = require(`${libs}/middlewares/response`);
+
+const email = require(`${libs}/middlewares/email`);
+
+const passport = require('passport');
+
+const uuid = require('node-uuid');
+
+function emailSyntax(email) {
+  const regex = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+  return regex.test(email);
+}
+
+pubApp.get('/', passport.authenticate('bearer', { session: false }), async (req, res, next) => {
+  let up = await UserPublication.findAll({where:{user_id:req.user.id}}).catch(function(err){
+    if(err){
+        log.error(err);
+        return next(err);
+    }
+  });
+  console.log(up);
+  let publications = [];
+  for(let _id in up.publication_id){
+    let pb = await Publication.findByPk(_id).catch(function(err){
+        if(err){
+            log.error(err);
+            return next(err);
+        }
+      });
+    publications.push(pb);
+  }
+  next();
+}, response('user'));
+
+pubApp.get('/:id', (req, res, next) => {
+  UserPublication.findByPk(req.params.id).then((user) => {
+    if (!user) {
+      res.statusCode = 404;
+      res.json({ msg: "O usuário não está cadastrado" });
+    } else {
+      let u = user.toJSON();
+      delete u.hashed_password;
+      delete u.salt;
+      req.result = u;
+      next();
+    }
+  }).catch(function (err) {
+    log.error(err);
+    return next(err);
+  });
+}, response('publication'));
+
+pubApp.post('/', async (req, res, next) => {
+  if (typeof req.body.password === 'undefined' || !req.body.password) {
+    res.statusCode = 400;
+    return res.json({ errors: ["O campo senha é obrigatório"] });
+  } else {
+    let user = await User.create({
+      id: 0,
+      email: req.body.email,
+      password: req.body.password,
+      hashed_password: 0,
+      salt: 0,
+      name: req.body.name,
+      nickname: req.body.nickname,
+      cpf: req.body.cpf,
+      cep: req.body.cep,
+      complement: req.body.complement,
+      address: req.body.address,
+      phone: req.body.phone,
+      schooling: req.body.schooling,
+      course: req.body.course,
+      segment: req.body.segment,
+      role: req.body.role,
+      institution_name: req.body.institutionName,
+      state: req.body.state,
+      city: req.body.city,
+      receiveEmails: false || req.body.receiveEmails,
+      origin: req.body.origin,
+      citesegment: req.body.citesegment,
+      citerole: req.body.citerole,
+      admin: false,
+      role_id: 0
+    }).catch(function (err) {
+      log.error(err);
+      let errors = [];
+      for (let errName in err.errors) {
+        errors.push(err.errors[errName].message);
+      }
+      log.error(errors);
+      res.statusCode = 400;
+      return res.json({ err, errors });
+      // handle error;
+    });
+    let tokenValue = uuid.v4();
+    const verificationToken = VerificationToken.create({
+      user_id: user.id,
+      token: tokenValue,
+      verified: false
+    });
+    if (!verificationToken) {
+      res.statusCode = 404;
+      return res.json({ msg: "Couldn't create Verification Token" });
+    }
+    let url = config.default.lde.url + '/verify';
+    let text = `Olá, ${user.name}, seja bem vindo/a ao Laboratório de Dados Educacionais.\n\nClique neste link para confirmar sua conta: ${url}/${tokenValue}`;
+    // Send confirmation email
+    let mailOptions = {
+      to: `"${user.name} <${user.email}>"`,
+      subject: "Confirme seu cadastro - Laboratório de Dados Educacionais",
+      text
+    }
+    email(mailOptions, (err, info) => {
+      if (err) {
+        log.error(err);
+        res.json({ msg: 'Message not delivered, user created but not confirmed' });
+      }
+      if (info) {
+        log.info(`Message ${info.messageId} sent: ${info.response}`);
+        log.info(`Usuário ${user.email} foi criado`);
+      }
+      res.json({ msg: 'User created' });
+    });
+  }
+});
+
+pubApp.put('/:id', passport.authenticate('bearer', { session: false }), async (req, res, next) => {
+  let user = await User.findByPk(req.params.id).catch(function (err) {
+    if (err) {
+      log.error(err);
+      return next({ err });
+    }
+  })
+  if (!user) {
+    res.statusCode = 404;
+    return next({
+      err: {
+        message: 'Usuário não encontrado'
+      }
+    });
+  }
+
+  user.email = req.body.email || user.email;
+  user.name = req.body.name || user.name;
+  user.nickname = req.body.nickname || user.nickname || user.name;
+  user.cep = req.body.cep || user.cep;
+  user.complement = req.body.complement || user.complement;
+  user.address = req.body.address || user.address;
+  user.phone = req.body.phone || user.phone;
+  user.schooling = req.body.schooling || user.schooling;
+  user.course = req.body.course || user.course;
+  user.segment = req.body.segment || user.segment;
+  user.role = req.body.role || user.role;
+  user.institutionName = req.body.institutionName || user.institutionName;
+  user.state = req.body.state || user.state;
+  user.city = req.body.city || user.city;
+  user.receiveEmails = req.body.receiveEmails || user.receiveEmails;
+  user.citesegment = req.body.citesegment || user.citesegment;
+  user.citerole = req.body.citerole || user.citerole;
+
+
+
+  if ((req.body.password) && (req.body.newpassword)) {
+    if (req.body.password != req.body.newpassword) {
+      if (user.checkPassword(user, req.body.password)) {
+          await user.update({password:req.body.newpassword});
+        } 
+      else {
+        res.statusCode = 500;
+        return res.json({
+          error: {
+            message: 'A senha atual está incorreta'
+          }
+        });
+      }
+    } else {
+      res.statusCode = 500;
+      return res.json({
+        error: {
+          message: 'A nova senha é a mesma da senha atual'
+        }
+      });
+    }
+  }
+
+  user.save().catch(err => {
+    if (err) {
+      log.error(err);
+      return next({ message: 'Erro ao atualizar usuário' });
+    }})
+  let u = user.toJSON();
+  delete u.hashed_password;
+  delete u.salt;
+  delete u.password;
+  res.json({ user: u });
+
+});
+
+
+pubApp.get('/reset/password', async (req, res, next) => {
+  let emailAddress = req.query.email;
+  let user = await User.findOne({ where: { email: emailAddress } }).catch(function (err) {
+    log.error(err);
+    let errors = [];
+    for (let errName in err.errors) {
+      errors.push(err.errors[errName].message);
+    }
+    log.error(errors);
+    res.statusCode = 400;
+    return res.json({ err, errors });
+    // handle error;
+  });
+  if (!user) {
+    res.statusCode = 404;
+    res.json({ msg: "O usuário não está cadastrado" });
+  }
+  else {
+    let tokenValue = uuid.v4();
+    const rt = await ResetToken.create({
+      user_id: user.id,
+      token: tokenValue,
+      reset: false
+    });
+    if (!rt) {
+      res.statusCode = 404;
+      return res.json({ msg: "Couldn't create Reset Password Token" });
+    }
+    let url = config.default.lde.url + '/reset-password';
+    let text = `Olá, ${user.name}.\n\nRecebemos uma solicitação para redefinir sua senha do Laboratório de Dados Educacionais. Clique neste link para redefinir a sua senha: ${url}/${tokenValue}`;
+    let mailOptions = {
+      to: `"${user.name} <${user.email}>"`,
+      subject: "Redefinição de Senha - Laboratório de Dados Educacionais",
+      text
+    }
+    console.log(mailOptions);
+    email(mailOptions, (err, info) => {
+      if (err) {
+        console.log(err);
+        log.error(err);
+        res.json({ msg: 'Undelivered Reset Password Mail' });
+      }
+      log.info(`Message ${info.messageId} sent: ${info.response}`);
+      res.json({ msg: 'Reset Password Mail Successfully Delivered' });
+    });
+  }
+});
+
+module.exports = pubApp;
diff --git a/src/libs/routes_v1/user.js b/src/libs/routes_v1/user.js
index d02edd848e688079c201e30352edae7160405ea2..eedf07b50876dc4faafadfc936305aa7c4bba02a 100644
--- a/src/libs/routes_v1/user.js
+++ b/src/libs/routes_v1/user.js
@@ -148,7 +148,8 @@ userApp.post('/', async (req, res, next) => {
       origin: req.body.origin,
       citesegment: req.body.citesegment,
       citerole: req.body.citerole,
-      admin: false
+      admin: false,
+      role_id: 0
     }).catch(function (err) {
       log.error(err);
       let errors = [];