From c0719e4e478cd0e48dc25bc37e995845d3018a20 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Tue, 12 Nov 2024 13:52:01 +0100
Subject: [PATCH 01/13] chore: removed useless oackage consul

---
 app/api/index.js |  8 +-----
 consul.js        | 75 ------------------------------------------------
 package.json     |  1 -
 web.js           | 12 --------
 4 files changed, 1 insertion(+), 95 deletions(-)
 delete mode 100644 consul.js

diff --git a/app/api/index.js b/app/api/index.js
index 96dbbe4..414364a 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -18,10 +18,8 @@ const routers = new Router()
 
 routers.use(bodyParser())
 routers.get('/healthcheck', (ctx) => {
-    // ctx.body = 'inra.paca.gatekeeper is up!'
-    console.log('consul hit!!')
     ctx.res.statusCode = 200
-    ctx.res.end('OK!')
+    ctx.res.end('OK')
 })
 
 // user
@@ -96,8 +94,4 @@ routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.al
 routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update)
 routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole)
 
-// user-resource
-
-// role-field
-
 module.exports = routers
diff --git a/consul.js b/consul.js
deleted file mode 100644
index 9ec9b07..0000000
--- a/consul.js
+++ /dev/null
@@ -1,75 +0,0 @@
-const Consul = require("consul");
-
-class ConsulConfig {
-  constructor() {
-    //Initialize consumer
-    this.consul = new Consul({
-      host: this.ConsulIp,
-      port: this.ConsulPort,
-      promisify: true,
-    });
-
-    // Service registration and health check configuration
-    this.consul.agent.service.register(
-      {
-        name: this.ServiceName,
-        Address: this.ServiceIp,
-        port: this.ServicePort,
-        /* check: {
-                http: 'http://147.100.18.116:4000/healthcheck',
-                interval: '10s',
-                timeout: '6s', 
-            } */
-      },
-      function (err, result) {
-        if (err) {
-          console.error(err);
-          throw err;
-        }
-
-        console.log(
-          "in-sylva.gatekeeper" + "registered successfully!" + result
-        );
-      }
-    );
-  }
-
-  async getConfig(key) {
-    const result = await this.consul.kv.get(key);
-
-    if (!result) {
-      return Promise.reject(key + "does not exist");
-    }
-
-    return JSON.parse(result.Value);
-  }
-
-  //Read user configuration simple package
-  async getUserConfig(key) {
-    const result = await this.getConfig("develop/user");
-
-    if (!key) {
-      return result;
-    }
-
-    return result[key];
-  }
-
-  //Update user configuration simple package
-  async setUserConfig(key, val) {
-    const user = await this.getConfig("develop/user");
-
-    user[key] = val;
-
-    return this.consul.kv.set("develop/user", JSON.stringify(user));
-  }
-}
-
-ConsulConfig.prototype.ConsulIp = null;
-ConsulConfig.prototype.ConsulPort = null;
-ConsulConfig.prototype.ServiceIp = null;
-ConsulConfig.prototype.ServicePort = null;
-ConsulConfig.prototype.ServiceName = "in-sylva-source-manager";
-
-module.exports = ConsulConfig;
-
diff --git a/package.json b/package.json
index 6e9070b..8287ebe 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,6 @@
     "array.prototype.flatmap": "1.2.4",
     "bcrypt": "^5.1.0",
     "bluebird": "3.7.2",
-    "consul": "^0.37.0",
     "keycloak-admin": "1.14.8",
     "keycloak-connect": "12.0.3",
     "keycloak-koa-connect": "^1.0.5",
diff --git a/web.js b/web.js
index dfb191c..f714d79 100644
--- a/web.js
+++ b/web.js
@@ -11,17 +11,6 @@ logger.level = config.logger.level
 const server = http.createServer(app.callback())
 const serverListen = promisify(server.listen).bind(server)
 
-if (process.env.NODE_ENV === 'production') {
-
-    // const ConsulConfig = require('./consul');
-    // const consul = new ConsulConfig();
-    // consul.ConsulIp = process.env.CONSUL_IP
-    // consul.ConsulPort = process.env.CONSUL_PORT
-    // consul.ServiceIp = process.env.SERVICE_IP
-    // consul.ServicePort = process.env.PORT
-    // consul.ServiceName = process.env.SERVICE_NAME
-}
-
 serverListen(config.port)
     .then(() => {
         logger.info(`in-sylva.gatekeeper service is up and running on localhost:${config.port}`)
@@ -30,4 +19,3 @@ serverListen(config.port)
         logger.error(err)
         process.exit(1)
     })
-
-- 
GitLab


From d9926e0566e05be6a9bbf53c1701b6c17a663154 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Tue, 12 Nov 2024 17:09:48 +0100
Subject: [PATCH 02/13] chore: general clean-up

---
 app/api/index.js                      | 22 ++++----
 app/api/realm/delete.js               |  4 +-
 app/api/realm/get.js                  |  5 +-
 app/api/realm/post.js                 |  5 +-
 app/api/realm/put.js                  |  5 +-
 app/api/role-user/delete.js           |  3 +-
 app/api/role-user/get.js              |  3 +-
 app/api/role-user/post.js             |  2 -
 app/api/role-user/put.js              |  3 +-
 app/api/role-v2/index.js              |  2 -
 app/api/roles/delete.js               |  4 +-
 app/api/roles/get.js                  |  2 -
 app/api/roles/post.js                 |  4 +-
 app/api/roles/put.js                  |  4 +-
 app/api/user-requests/delete.js       |  4 +-
 app/api/user-requests/get.js          |  4 +-
 app/api/user-requests/post.js         |  4 +-
 app/api/user-search-history/delete.js |  4 +-
 app/api/user-search-history/get.js    |  4 +-
 app/api/user-search-history/post.js   |  7 ++-
 app/api/users/delete.js               |  2 -
 app/api/users/get.js                  |  1 -
 app/api/users/post.js                 |  3 ++
 app/api/users/put.js                  |  4 +-
 app/dal/groupService.js               | 72 +++++++-------------------
 app/dal/policyService.js              | 74 +++++----------------------
 app/dal/realmService.js               | 23 +++------
 app/dal/roleAllocationService.js      | 26 +++-------
 app/dal/roleService.js                | 38 ++++++--------
 app/dal/searchHistoryService.js       | 35 ++++---------
 app/dal/userRequestService.js         | 52 +++++--------------
 app/dal/userService.js                | 51 ++++++------------
 app/models/Group.js                   | 40 +--------------
 app/models/Policy.js                  | 42 +--------------
 app/models/Role.js                    | 18 -------
 app/models/StdField.js                |  7 ---
 app/models/User.js                    |  5 +-
 app/utils/format.js                   |  4 +-
 app/utils/hashPass.js                 | 20 --------
 app/utils/memory-store.js             | 29 -----------
 init-keycloak.js                      | 26 +++-------
 keycloak.js                           |  8 +--
 server.js                             | 19 ++-----
 43 files changed, 153 insertions(+), 541 deletions(-)
 delete mode 100644 app/api/role-v2/index.js
 delete mode 100644 app/utils/hashPass.js
 delete mode 100644 app/utils/memory-store.js

diff --git a/app/api/index.js b/app/api/index.js
index 414364a..acc378f 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -2,8 +2,7 @@
 
 const Router = require("koa-router")
 const bodyParser = require("koa-bodyparser")
-
-const { keycloak } = require('../../init-keycloak')
+/* const { keycloak } = require('../../init-keycloak') */
 
 // handlers
 const userHandler = require('./users')
@@ -13,7 +12,7 @@ const searchHistoryHandler = require('./user-search-history')
 const userRequestHandler = require('./user-requests')
 const groupHandler = require('./group')
 const policyHandler = require('./policy')
-const { groups } = require("../dal/groupService")
+
 const routers = new Router()
 
 routers.use(bodyParser())
@@ -22,7 +21,7 @@ routers.get('/healthcheck', (ctx) => {
     ctx.res.end('OK')
 })
 
-// user
+// Users
 routers.post('/user', userHandler.addNewUser)
 routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user)
 routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users)
@@ -34,17 +33,17 @@ routers.post('/user/assigned-by-role', userHandler.getAssignedUserByRole)
 routers.post('/user/send-mail', userHandler.sendMail)
 routers.post('/user/reset-password', userHandler.resetPassword)
 
-// System User
+// System admin user
 routers.post('/user/create-system-user', userHandler.createSystemUser)
 routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole)
 routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole)
 
-// search-history
+// Search history
 routers.post('/user/add-history', searchHistoryHandler.add)
 routers.post('/user/fetch-history', searchHistoryHandler.fetch)
 routers.delete('/user/delete-history', searchHistoryHandler.deleteH)
 
-// user requests
+// User requests
 routers.post('/user/create-request', userRequestHandler.createRequest)
 routers.delete('/user/delete-request', userRequestHandler.deleteRequest)
 routers.post('/user/process-request', userRequestHandler.processRequest)
@@ -52,7 +51,7 @@ routers.get('/user/list-requests', userRequestHandler.fetchRequests)
 routers.post('/user/list-requests-by-user', userRequestHandler.fetchRequestsByUser)
 routers.get('/user/list-pending-requests', userRequestHandler.fetchPendingRequests)
 
-// group
+// Groups
 routers.post('/user/groups', groupHandler.groups)
 routers.post('/user/group-policies', groupHandler.groupPolicies)
 routers.post('/user/group-users', groupHandler.groupUsers)
@@ -66,7 +65,7 @@ routers.delete('/user/delete-group', groupHandler.deleteGroup)
 routers.delete('/user/delete-group-policy', groupHandler.deleteGroupPolicy)
 routers.delete('/user/delete-group-user', groupHandler.deleteGroupUser)
 
-// policy
+// Policies
 routers.post('/policy/add', policyHandler.createPolicy)
 routers.delete('/policy/delete', policyHandler.deletePolicy)
 routers.put('/policy/update', policyHandler.updatePolicy)
@@ -81,14 +80,15 @@ routers.delete('/policyField/delete', policyHandler.deletePolicyField)
 routers.put('/policyField/update', policyHandler.updatePolicyField)
 routers.get('/policyField/list', policyHandler.policyFields)
 routers.post('/policySource/add', policyHandler.createPolicySource)
-// role
+
+// Roles
 routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole)
 routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles)
 routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role)
 routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole)
 routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update)
 
-// role-user
+// Role allocation to users
 routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole)
 routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles)
 routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update)
diff --git a/app/api/realm/delete.js b/app/api/realm/delete.js
index 791f45c..7549275 100644
--- a/app/api/realm/delete.js
+++ b/app/api/realm/delete.js
@@ -4,7 +4,6 @@ const realmService = require('../../dal/realmService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const DeleteRealm = {
     async deleteRealm(ctx) {
         try {
@@ -19,8 +18,7 @@ const DeleteRealm = {
     }
 }
 
-
 module.exports = {
     deleteRealm: DeleteRealm.deleteRealm,
     DeleteRealm
-}
\ No newline at end of file
+}
diff --git a/app/api/realm/get.js b/app/api/realm/get.js
index 743d94c..e360853 100644
--- a/app/api/realm/get.js
+++ b/app/api/realm/get.js
@@ -4,9 +4,7 @@ const realmService = require('../../dal/realmService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const GetRealm = {
-
     async find(ctx) {
         try {
             ctx.body = await realmService.realms()
@@ -33,9 +31,8 @@ const GetRealm = {
 
 }
 
-
 module.exports = {
     realms: GetRealm.find,
     realm: GetRealm.findOne,
     GetRealm
-}
\ No newline at end of file
+}
diff --git a/app/api/realm/post.js b/app/api/realm/post.js
index 0e04834..b27dd6e 100644
--- a/app/api/realm/post.js
+++ b/app/api/realm/post.js
@@ -4,9 +4,7 @@ const realmService = require("../../dal/realmService")
 const logger = require("../../utils/format")
 const util = require('util')
 
-
 const AddRealm = {
-
     async AddNewRealm(ctx) {
         try {
             ctx.body = await realmService.create(ctx.request.body)
@@ -20,8 +18,7 @@ const AddRealm = {
     }
 }
 
-
 module.exports = {
     addRealm: AddRealm.AddNewRealm,
     AddRealm
-}
\ No newline at end of file
+}
diff --git a/app/api/realm/put.js b/app/api/realm/put.js
index 3c8e3d9..8a4b28b 100644
--- a/app/api/realm/put.js
+++ b/app/api/realm/put.js
@@ -4,9 +4,7 @@ const realmService = require("../../dal/realmService");
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const UpdateRealm = {
-
     async update(ctx) {
         try {
             ctx.body = await realmService.update(ctx.request.body);
@@ -20,8 +18,7 @@ const UpdateRealm = {
     }
 }
 
-
 module.exports = {
     update: UpdateRealm.update,
     UpdateRealm
-}
\ No newline at end of file
+}
diff --git a/app/api/role-user/delete.js b/app/api/role-user/delete.js
index 7394e1b..618849b 100644
--- a/app/api/role-user/delete.js
+++ b/app/api/role-user/delete.js
@@ -6,7 +6,6 @@ const util = require('util')
 
 
 const DeleteAllocatedRole = {
-
     async deleteAllocatedRole(ctx) {
         try {
             ctx.body = await roleAllocationService.delete(ctx.request.body)
@@ -23,4 +22,4 @@ const DeleteAllocatedRole = {
 module.exports = {
     deleteAllocatedRole: DeleteAllocatedRole.deleteAllocatedRole,
     DeleteAllocatedRole
-}
\ No newline at end of file
+}
diff --git a/app/api/role-user/get.js b/app/api/role-user/get.js
index 29deb2f..cc3d513 100644
--- a/app/api/role-user/get.js
+++ b/app/api/role-user/get.js
@@ -5,7 +5,6 @@ const logger = require("../../utils/format")
 const util = require('util')
 
 const GetAllocatedRole = {
-
     async find(ctx) {
         try {
             const allocatedRoles = await roleAllocationService.allocatedRoles(ctx.request.body)
@@ -24,4 +23,4 @@ const GetAllocatedRole = {
 module.exports = {
     allocatedRoles: GetAllocatedRole.find,
     GetAllocatedRole
-}
\ No newline at end of file
+}
diff --git a/app/api/role-user/post.js b/app/api/role-user/post.js
index 798ed05..26313ab 100644
--- a/app/api/role-user/post.js
+++ b/app/api/role-user/post.js
@@ -4,9 +4,7 @@ const roleAllocationService = require("../../dal/roleAllocationService")
 const logger = require("../../utils/format")
 const util = require('util')
 
-
 const AllocateRoleToUser = {
-
     async allocateRoleToUser(ctx) {
         try {
             ctx.body = await roleAllocationService.create(ctx.request.body)
diff --git a/app/api/role-user/put.js b/app/api/role-user/put.js
index 58cf427..dbd82d8 100644
--- a/app/api/role-user/put.js
+++ b/app/api/role-user/put.js
@@ -18,8 +18,7 @@ const UpdateAllocatedRole = {
     }
 }
 
-
 module.exports = {
     update: UpdateAllocatedRole.update,
     UpdateAllocatedRole
-}
\ No newline at end of file
+}
diff --git a/app/api/role-v2/index.js b/app/api/role-v2/index.js
deleted file mode 100644
index b7ff1bc..0000000
--- a/app/api/role-v2/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-'use strict'
-
diff --git a/app/api/roles/delete.js b/app/api/roles/delete.js
index 56b6b38..a1c80fc 100644
--- a/app/api/roles/delete.js
+++ b/app/api/roles/delete.js
@@ -4,9 +4,7 @@ const roleService = require('../../dal/roleService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const DeleteRole = {
-
     async deleteRole(ctx) {
         try {
             ctx.body = await roleService.delete(ctx.request.body)
@@ -23,4 +21,4 @@ const DeleteRole = {
 module.exports = {
     deleteRole: DeleteRole.deleteRole,
     DeleteRole,
-}
\ No newline at end of file
+}
diff --git a/app/api/roles/get.js b/app/api/roles/get.js
index 37789be..b92913d 100644
--- a/app/api/roles/get.js
+++ b/app/api/roles/get.js
@@ -35,5 +35,3 @@ module.exports = {
     role: GetRole.findOne,
     GetRole
 }
-
-
diff --git a/app/api/roles/post.js b/app/api/roles/post.js
index d38fd7b..230c2ff 100644
--- a/app/api/roles/post.js
+++ b/app/api/roles/post.js
@@ -4,9 +4,7 @@ const roleService = require("../../dal/roleService")
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const AddRole = {
-
     async addNewRole(ctx) {
         try {
             ctx.body = await roleService.create(ctx.request.body)
@@ -23,4 +21,4 @@ const AddRole = {
 module.exports = {
     addNewRole: AddRole.addNewRole,
     AddRole
-}
\ No newline at end of file
+}
diff --git a/app/api/roles/put.js b/app/api/roles/put.js
index 24e1fd6..5338694 100644
--- a/app/api/roles/put.js
+++ b/app/api/roles/put.js
@@ -4,14 +4,12 @@ const roleService = require('../../dal/roleService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const UpdateRole = {
     async update(ctx) {
         try {
             ctx.body = await roleService.update(ctx.request.body)
             ctx.status = 201
             logger.info('role is updated successfully!')
-
         } catch (err) {
             ctx.body = err || 'Error occurred!'
             ctx.status = 500
@@ -23,4 +21,4 @@ const UpdateRole = {
 module.exports = {
     update: UpdateRole.update,
     UpdateRole
-}
\ No newline at end of file
+}
diff --git a/app/api/user-requests/delete.js b/app/api/user-requests/delete.js
index 2e2515d..3723d10 100644
--- a/app/api/user-requests/delete.js
+++ b/app/api/user-requests/delete.js
@@ -4,9 +4,7 @@ const userRequestService = require('../../dal/userRequestService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const UserRequest = {
-
     async delete(ctx) {
         try {
             ctx.body = await userRequestService.delete(ctx.request.body)
@@ -23,4 +21,4 @@ const UserRequest = {
 module.exports = {
     deleteRequest: UserRequest.delete,
     UserRequest
-}
\ No newline at end of file
+}
diff --git a/app/api/user-requests/get.js b/app/api/user-requests/get.js
index d682e94..18bd98c 100644
--- a/app/api/user-requests/get.js
+++ b/app/api/user-requests/get.js
@@ -4,9 +4,7 @@ const userRequestService = require('../../dal/userRequestService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const UserRequest = {
-
     async list(ctx) {
         try {
             ctx.body = await userRequestService.fetch(ctx.request.body)
@@ -36,4 +34,4 @@ module.exports = {
     fetchRequests: UserRequest.list,
     fetchPendingRequests: UserRequest.listPending,
     UserRequest
-}
\ No newline at end of file
+}
diff --git a/app/api/user-requests/post.js b/app/api/user-requests/post.js
index 9d865c9..c1b3ef2 100644
--- a/app/api/user-requests/post.js
+++ b/app/api/user-requests/post.js
@@ -5,7 +5,6 @@ const logger = require('../../utils/format')
 const util = require('util')
 
 const UserRequest = {
-
     async create(ctx) {
         try {
             ctx.body = await userRequestService.create(ctx.request.body)
@@ -17,6 +16,7 @@ const UserRequest = {
             logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
         }
     },
+
     async process(ctx) {
         try {
             ctx.body = await userRequestService.process(ctx.request.body)
@@ -47,4 +47,4 @@ module.exports = {
     processRequest: UserRequest.process,
     fetchRequestsByUser: UserRequest.listByUser,
     UserRequest
-}
\ No newline at end of file
+}
diff --git a/app/api/user-search-history/delete.js b/app/api/user-search-history/delete.js
index 2d43762..fb2ad03 100644
--- a/app/api/user-search-history/delete.js
+++ b/app/api/user-search-history/delete.js
@@ -4,9 +4,7 @@ const searchHistoryService = require('../../dal/searchHistoryService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const SearchHistory = {
-
     async delete(ctx) {
         try {
             ctx.body = await searchHistoryService.delete(ctx.request.body)
@@ -23,4 +21,4 @@ const SearchHistory = {
 module.exports = {
     deleteH: SearchHistory.delete,
     SearchHistory
-}
\ No newline at end of file
+}
diff --git a/app/api/user-search-history/get.js b/app/api/user-search-history/get.js
index 7f2b75d..33e150e 100644
--- a/app/api/user-search-history/get.js
+++ b/app/api/user-search-history/get.js
@@ -4,9 +4,7 @@ const searchHistoryService = require('../../dal/searchHistoryService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const SearchHistory = {
-
     async list(ctx) {
         try {
             ctx.body = await searchHistoryService.fetch(ctx.request.body)
@@ -23,4 +21,4 @@ const SearchHistory = {
 module.exports = {
     fetch: SearchHistory.list,
     SearchHistory
-}
\ No newline at end of file
+}
diff --git a/app/api/user-search-history/post.js b/app/api/user-search-history/post.js
index 61e2a33..c31879d 100644
--- a/app/api/user-search-history/post.js
+++ b/app/api/user-search-history/post.js
@@ -4,8 +4,7 @@ const searchHistoryService = require('../../dal/searchHistoryService')
 const logger = require('../../utils/format')
 const util = require('util')
 
-const SearchHistory = { 
-
+const SearchHistory = {
     async add(ctx) {
         try {
             ctx.body = await searchHistoryService.create(ctx.request.body)
@@ -16,10 +15,10 @@ const SearchHistory = {
             ctx.status = 500
             logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
         }
-    }  
+    }
 }
 
 module.exports = {
     add: SearchHistory.add,
     SearchHistory
-}
\ No newline at end of file
+}
diff --git a/app/api/users/delete.js b/app/api/users/delete.js
index 3ec3c0a..ceaf0ad 100644
--- a/app/api/users/delete.js
+++ b/app/api/users/delete.js
@@ -1,4 +1,3 @@
-
 'use strict'
 
 const userService = require("../../dal/userService")
@@ -6,7 +5,6 @@ const logger = require('../../utils/format')
 const util = require('util')
 
 const DeleteUser = {
-
     async deleteUser(ctx) {
         try {
             ctx.body = await userService.delete(ctx.request.body)
diff --git a/app/api/users/get.js b/app/api/users/get.js
index 9330633..7f73c7c 100644
--- a/app/api/users/get.js
+++ b/app/api/users/get.js
@@ -77,7 +77,6 @@ const GetUser = {
       logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
     }
   }
-
 };
 
 module.exports = {
diff --git a/app/api/users/post.js b/app/api/users/post.js
index a368b49..5679838 100644
--- a/app/api/users/post.js
+++ b/app/api/users/post.js
@@ -31,6 +31,7 @@ const AddUser = {
             logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
         }
     },
+
     async sendMail(ctx) {
         try {
             ctx.body = await userService.sendMail(ctx.request.body)
@@ -42,6 +43,7 @@ const AddUser = {
             logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
         }
     },
+
     async userWithGroupAndRole(ctx) {
         try {
             ctx.body = await userService.userWithGroupAndRole(ctx.request.body);
@@ -53,6 +55,7 @@ const AddUser = {
             logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
         }
     },
+
     async resetPassword(ctx) {
         try {
             ctx.body = await userService.resetPassword(ctx.request.body);
diff --git a/app/api/users/put.js b/app/api/users/put.js
index 26cf36e..74a19f1 100644
--- a/app/api/users/put.js
+++ b/app/api/users/put.js
@@ -4,9 +4,7 @@ const userService = require("../../dal/userService")
 const logger = require('../../utils/format')
 const util = require('util')
 
-
 const UpdateUser = {
-
     async update(ctx) {
         try {
             ctx.body = await userService.update(ctx.request.body)
@@ -23,4 +21,4 @@ const UpdateUser = {
 module.exports = {
     update: UpdateUser.update,
     UpdateUser
-}
\ No newline at end of file
+}
diff --git a/app/dal/groupService.js b/app/dal/groupService.js
index b2d9900..cd141c3 100644
--- a/app/dal/groupService.js
+++ b/app/dal/groupService.js
@@ -1,9 +1,6 @@
 'use strict'
 
-// const db = require('../../db');
-
 const { Group, GroupUser, GroupsPolicy } = require('../models/Group')
-
 const userService = require('./userService')
 const db = require('../../db')
 
@@ -14,31 +11,26 @@ const GroupService = {
             throw Error("The request body is empty!")
         }
 
-        if (ctx.kcId === undefined)
+        if (ctx.kcId === undefined) {
             throw Error("kcId did not supported.")
-
-        const user = await userService.detail({ kcId: ctx.kcId })
+        }
+        const user = await userService.detail({ kcId: ctx.kcId });
         if (user) {
-
             const group = await Group.findOne({
                 where: {
                     name: ctx.name,
                     user_id: user.id,
                 }
             })
-
             if (group) {
                 throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`)
             } else {
-                const newGroup = await Group.create({
+                return await Group.create({
                     name: ctx.name,
                     description: ctx.description,
                     user_id: user.id,
                 })
-
-                return newGroup
             }
-
         } else {
             throw Error('The user account could not found.')
         }
@@ -59,12 +51,10 @@ const GroupService = {
         if (groupPolicy) {
             throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`)
         } else {
-            const newGroupPolicy = await GroupsPolicy.create({
+            return await GroupsPolicy.create({
                 group_id: ctx.groupId,
                 policy_id: ctx.policyId
             })
-
-            return newGroupPolicy
         }
     },
 
@@ -73,28 +63,25 @@ const GroupService = {
             throw Error("The request body is empty!")
         }
 
-        if (ctx.kcId === undefined)
+        if (ctx.kcId === undefined) {
             throw Error("kcId did not supported.")
+        }
 
         const user = await userService.detail({ kcId: ctx.kcId })
         if (user) {
-
             const groupUser = await GroupUser.findOne({
                 where: {
                     group_id: ctx.groupId,
                     user_id: user.id
                 }
             })
-
             if (groupUser) {
                 throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`)
             } else {
-                const newGroupUser = await GroupUser.create({
+                return await GroupUser.create({
                     group_id: ctx.groupId,
                     user_id: user.id
                 })
-
-                return newGroupUser
             }
         } else {
             throw Error('The user account could not found.')
@@ -106,15 +93,13 @@ const GroupService = {
             throw Error("The request body is empty!")
         }
 
-        const group = await Group.update({
+        return await Group.update({
             name: ctx.name,
             description: ctx.description,
         }, {
-            where: { id: ctx.id, user_id: ctx.userId }
+            where: {id: ctx.id, user_id: ctx.userId}
         })
 
-        return group
-
     },
 
     async updateGroupPolicy(ctx) {
@@ -122,12 +107,10 @@ const GroupService = {
             throw Error("The request body is empty!")
         }
 
-        const groupPolicy = await GroupsPolicy.update({
+        return await GroupsPolicy.update({
             group_id: ctx.groupId,
             policy_id: ctx.policyId
-        }, { where: { id: ctx.id } })
-
-        return groupPolicy
+        }, {where: {id: ctx.id}})
     },
 
     async updateGroupUser(ctx) {
@@ -137,12 +120,10 @@ const GroupService = {
 
         const user = await userService.detail({ kcId: ctx.kcId })
         if (user) {
-            const groupUser = await GroupUser.update({
+            return await GroupUser.update({
                 group_id: ctx.groupId,
                 user_id: user.id
-            }, { where: { id: ctx.id } })
-
-            return groupUser
+            }, {where: {id: ctx.id}})
 
         } else {
             throw Error('The user account could not found.')
@@ -154,13 +135,11 @@ const GroupService = {
             throw Error("The request body is empty!")
         }
         if (ctx.id) {
-            const group = await Group.destroy({
+            return await Group.destroy({
                 where: {
                     id: ctx.id
                 }
             })
-
-            return group
         }
     },
 
@@ -169,13 +148,11 @@ const GroupService = {
             throw Error("The request body is empty!")
         }
 
-        const groupPolicy = await GroupsPolicy.destroy({
+        return await GroupsPolicy.destroy({
             where: {
                 id: ctx.id
             }
         })
-
-        return groupPolicy
     },
 
     async deleteGroupUser(ctx) {
@@ -193,20 +170,12 @@ const GroupService = {
         return groupUser
     },
 
-    async groups(ctx) {
-        /*if (!ctx) {
-            throw Error("The request body is empty!")
-        }*/
-
+    async groups() {
         return await Group.findAll({})
 
     },
 
-    async groupPolicies(ctx) {
-        /*if (!ctx) {
-            throw Error("The request body is empty!")
-        }*/
-
+    async groupPolicies() {
         return await GroupsPolicy.findAll({})
     },
 
@@ -214,16 +183,13 @@ const GroupService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         const params = { groupId: ctx.groupId }
-
         const groupUsers = await db.raw(`
               select g.id as groupId, u.id as userId, u.username, g.name, g.description from group_users gu
               inner join users u on u.id = gu.user_id
               inner join groups g on gu.group_id = g.id
               where g.id = :groupId
         `, params)
-
         return groupUsers.rows
     }
 }
@@ -245,4 +211,4 @@ module.exports = {
     groups: GroupService.groups,
     groupPolicies: GroupService.groupPolicies,
     groupUsers: GroupService.groupUsers,
-}
\ No newline at end of file
+}
diff --git a/app/dal/policyService.js b/app/dal/policyService.js
index dc2faa3..7488169 100644
--- a/app/dal/policyService.js
+++ b/app/dal/policyService.js
@@ -11,10 +11,9 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        if (ctx.kcId === undefined)
+        if (ctx.kcId === undefined) {
             throw Error("kcId did not supported.")
-
+        }
         const user = await userService.detail({ kcId: ctx.kcId })
         if (user) {
             const policy = await Policy.findOne({
@@ -28,14 +27,12 @@ const PolicyService = {
             if (policy) {
                 throw Error(`This Policy name:${ctx.name} and sourceId:${ctx.sourceId} already inserted to database!`)
             } else {
-                const newPolicy = await Policy.create({
+                return await Policy.create({
                     name: ctx.name,
                     // source_id: ctx.sourceId,
                     user_id: user.id,
                     is_default: false
                 })
-
-                return newPolicy
             }
         } else {
             throw Error('The user account could not found.')
@@ -46,7 +43,6 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         const { policyId, stdFieldId } = ctx
 
         if (policyId && stdFieldId) {
@@ -56,16 +52,13 @@ const PolicyService = {
                     std_field_id: stdFieldId,
                 }
             })
-
             if (policyField) {
                 throw Error(`This policyId:${policyId} and stdFieldId:${stdFieldId} already assigned to each other in the database!`)
             } else {
-                const newPolicyField = await PolicyField.create({
+                return await PolicyField.create({
                     policy_id: policyId,
                     std_field_id: stdFieldId,
                 })
-
-                return newPolicyField
             }
         }
     },
@@ -74,7 +67,6 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         const { policyId, sourceId } = ctx
 
         if (policyId && sourceId) {
@@ -87,11 +79,10 @@ const PolicyService = {
             if (policySource) {
                 throw Error(`This policyId:${policyId} and sourceId:${sourceId} already assigned to each other in the database!`)
             } else {
-                const newPolicySource = await PolicySource.create({
+                return await PolicySource.create({
                     policy_id: policyId,
                     source_id: sourceId,
                 })
-                return newPolicySource
             }
         }
     },
@@ -100,38 +91,31 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const policySource = await PolicySource.update({
+        return await PolicySource.update({
             source_id: ctx.sourceId,
         }, {
             where: {
                 id: ctx.id
             }
         })
-
-        return policySource
     },
 
     async deletePolicySource(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const policySource = await PolicySource.destroyi({
+        return await PolicySource.destroyi({
             where: {
                 id: ctx.id
             }
         })
-
-        return policySource
     },
 
     async updatePolicy(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const policy = await Policy.update({
+        return await Policy.update({
             name: ctx.name,
             source_id: ctx.sourceId,
             is_default: ctx.isDeafault
@@ -140,16 +124,13 @@ const PolicyService = {
                 id: ctx.id,
             }
         })
-        return policy
-
     },
 
     async updatePolicyField(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const policyField = await PolicyField.update({
+        return await PolicyField.update({
             policy_id: ctx.policyId,
             std_field_id: ctx.stdFieldId,
         }, {
@@ -157,46 +138,37 @@ const PolicyService = {
                 id: ctx.id
             }
         })
-
-        return policyField
     },
 
     async deletePolicyField(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const policyField = await PolicyField.destroy({
+        return await PolicyField.destroy({
             where: {
                 id: ctx.id
             }
         })
-
-        return policyField
     },
 
     async deletePolicy(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         const policyField = await PolicyField.destroy({
             where: {
                 policy_id: ctx.id
             }
         })
-
-        const policy = await Policy.destroy({
+        await Policy.destroy({
             where: {
                 id: ctx.id
             }
         })
-
         return policyField
     },
 
-    async policies(ctx) {
-
+    async policies() {
         return await Policy.findAll({})
     },
 
@@ -204,25 +176,19 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         try {
-
             const params = { userId: ctx.kcId }
-
             const policiesByUser = await db.raw(
                 `select DISTINCT p.id, p.name, p.user_id, p.source_id, u.kc_id from policies p
           inner join users u  on p.user_id = u.id
           where u.kc_id = :userId`, params)
-
             return policiesByUser.rows
-
         } catch (error) {
             throw new Error(error)
         }
     },
 
-    async policyFields(ctx) {
-
+    async policyFields() {
         return await PolicyField.findAll({})
     },
 
@@ -230,9 +196,7 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         const params = { policyId: ctx.policyId }
-
         const assignedPolicies = await db.raw(`
             select pf.id, sf.field_name, sf.definition_and_comment, sf.field_type, sf.values from policies p
             inner join policy_fields pf on p.id = pf.policy_id
@@ -241,7 +205,6 @@ const PolicyService = {
             inner join sources s on ps.source_id = s.id
             where p.id = :policyId
         `, params)
-
         return assignedPolicies.rows
     },
 
@@ -255,7 +218,6 @@ const PolicyService = {
                 left join policy_sources ps on p.id = ps.policy_id
                 left join sources s on ps.source_id = s.id
         `)
-
         return policiesWIthSource.rows
     },
 
@@ -263,21 +225,15 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         try {
-
             const params = { userId: ctx.kcId }
-
             const policiesByUser = await db.raw(`
                 select p.id, p.name as policyName, s.name as sourceName, p.user_id, p.source_id, u.kc_id from policies p
                 inner join users u on p.user_id = u.id
                 left join policy_sources ps on p.id = ps.policy_id
                 left join sources s on ps.source_id = s.id
                 where u.kc_id = :userId`, params)
-
-
             return policiesByUser.rows
-
         } catch (error) {
             throw new Error(error)
         }
@@ -287,7 +243,6 @@ const PolicyService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         const params = { policyId: ctx.policyId }
         const groupDetailsByPolicy = await db.raw(`
             select p.id as policyId, g.id as groupId, gp.id groupPolicyId, g.name as group_name, g.description as group_description, s.name as source_name, s.description as source_description from policies p
@@ -297,7 +252,6 @@ const PolicyService = {
             left join sources s on ps.source_id = s.id
             where p.id = :policyId
         `, params)
-
         return groupDetailsByPolicy.rows
     }
 
@@ -322,4 +276,4 @@ module.exports = {
     getPoliciesWithSources: PolicyService.getPoliciesWithSources,
     getPoliciesWithSourcesByUser: PolicyService.getPoliciesWithSourcesByUser,
     getGroupDetailsByPolicy: PolicyService.getGroupDetailsByPolicy,
-}
\ No newline at end of file
+}
diff --git a/app/dal/realmService.js b/app/dal/realmService.js
index 1b30495..c311b95 100644
--- a/app/dal/realmService.js
+++ b/app/dal/realmService.js
@@ -1,37 +1,30 @@
 'use strict'
 
-
 const db = require('../../db');
 
 const RealmService = {
-
     async create(ctx) {
-        const realm = await db('realm').insert({
+        return await db('realm').insert({
             name: ctx.name
         }).returning('*').then((result) => result[0])
-        return realm
     },
 
     async update(ctx) {
-        const realm = await db('realm').where('id', ctx.id).update({
+        return db('realm').where('id', ctx.id).update({
             name: ctx.name
-        })
-        return realm
+        });
     },
 
     async delete(ctx) {
-        const result = await db.delete().from('realm').where('id', ctx.id).timeout(1000, { cancel: true })
-        return result
+        return db.delete().from('realm').where('id', ctx.id).timeout(1000, {cancel: true});
     },
 
     async realm(ctx) {
-        const realm = await db.select().from('realm').where('id', ctx.id).timeout(1000, { cancel: true });
-        return realm
+        return db.select().from('realm').where('id', ctx.id).timeout(1000, {cancel: true});
     },
 
-    async realms(ctx) {
-        const realms = await db.select().from('realm').timeout(1000, { cancel: true });
-        return realms
+    async realms() {
+        return db.select().from('realm').timeout(1000, {cancel: true});
     }
 }
 
@@ -41,4 +34,4 @@ module.exports = {
     delete: RealmService.delete,
     realm: RealmService.realm,
     realms: RealmService.realms
-}
\ No newline at end of file
+}
diff --git a/app/dal/roleAllocationService.js b/app/dal/roleAllocationService.js
index 3454077..acf784e 100644
--- a/app/dal/roleAllocationService.js
+++ b/app/dal/roleAllocationService.js
@@ -2,8 +2,7 @@
 
 const db = require('../../db')
 
-
-const { Role, RoleUser } = require('../models/Role')
+const { RoleUser } = require('../models/Role')
 
 const RoleAllocationService = {
 
@@ -12,13 +11,11 @@ const RoleAllocationService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
         const roleUser = RoleUser.findOne({
             where: {
                 kc_id: ctx.kc_id
             }
         })
-
         if (!roleUser) {
             return await RoleUser.create({
                 role_id: ctx.role_id,
@@ -35,16 +32,14 @@ const RoleAllocationService = {
 
     // It updates allocated user.
     async update(ctx) {
-        const result = await db('roles_users').where('id', ctx.id)
+        return await db('roles_users').where('id', ctx.id)
             .update({
                 kc_id: ctx.kc_id
             }).returning('*').then((result) => result[0])
-        return result
     },
 
     async delete(ctx) {
-        const result = await db.delete().from('roles_users').where('id', ctx.id).timeout(1000, { cancel: true })
-        return result
+        return db.delete().from('roles_users').where('id', ctx.id).timeout(1000, {cancel: true});
     },
 
     // It returns allocated roles by kc_id.
@@ -54,29 +49,24 @@ const RoleAllocationService = {
                 throw Error("The request body is empty!")
             }
             if (ctx.kc_id) {
-                const allocatedRoles = await db.raw(`
+                return await db.raw(`
                     select roles.id, u.username as user, roles.name as role , roles.description from roles
                     inner join roles_users ru on roles.id = ru.role_id
                     inner join users u on ru.kc_id = u.kc_id
                     where u.kc_id = ?`, [ctx.kc_id])
-
-                return allocatedRoles
             }
         } catch (err) {
-            throw new Error(error)
+            throw new Error(err)
         }
     },
     async allocatedRoles(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const allocatedRoles = await db.raw(`
+        return db.raw(`
                 select u.username as user,r.name as role from roles r
                 inner join roles_users ru on r.id = ru.role_id
-                inner join users u on ru.kc_id = u.kc_id`)
-
-        return allocatedRoles
+                inner join users u on ru.kc_id = u.kc_id`);
     },
 }
 
@@ -85,4 +75,4 @@ module.exports = {
     allocatedRoles: RoleAllocationService.allocatedRolesByKcId,
     update: RoleAllocationService.update,
     delete: RoleAllocationService.delete
-}
\ No newline at end of file
+}
diff --git a/app/dal/roleService.js b/app/dal/roleService.js
index 8164194..036c97e 100644
--- a/app/dal/roleService.js
+++ b/app/dal/roleService.js
@@ -4,62 +4,54 @@ const db = require('../../db')
 
 const { Role, RoleUser } = require('../models/Role')
 const RoleService = {
-
     //  Get all roles
     async roles(ctx) {
-        const roles = await db.select().from('roles').timeout(1000, { cancel: true })
-        return roles
+        return db.select().from('roles').timeout(1000, {cancel: true});
     },
+
     // Get a role
-    async role(ctx) {
-        const role = await db.select().from('roles').where('id', ctx.id).timeout(1000, { cancel: true })
-        return role
+    role: async function (ctx) {
+        return db.select().from('roles').where('id', ctx.id).timeout(1000, {cancel: true});
     },
+
     // Delete role by id
     async delete(ctx) {
-        const result = await db.delete().from('roles').where('id', ctx.id).timeout(1000, { cancel: true })
-        return result
+        return db.delete().from('roles').where('id', ctx.id).timeout(1000, {cancel: true})
     },
+
     // Update role by id
     async update(ctx) {
-        const result = await db('roles').where('id', ctx.id)
+        return await db('roles').where('id', ctx.id)
             .update({
                 name: ctx.name,
                 description: ctx.description
             }).returning('*').then((result) => result[0])
-        return result
     },
+
     // Create a role
     async create(ctx) {
-        const role = await db('roles').insert({
+        return await db('roles').insert({
             name: ctx.name,
             description: ctx.description
         }).returning('*').then((result) => result[0])
-
-        return role
     },
 
+    // Delete a role
     async deleteRole(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        console.log(ctx)
-
-        const roleUser = await RoleUser.destroy({
+        await RoleUser.destroy({
             where: {
                 role_id: ctx.id
             }
         })
-
-        const role = await Role.destroy({
+        return await Role.destroy({
             where: {
                 id: ctx.id
             }
         })
-
-        return role
-    }, 
+    },
 }
 
 module.exports = {
@@ -68,4 +60,4 @@ module.exports = {
     role: RoleService.role,
     delete: RoleService.deleteRole,
     update: RoleService.update,
-}
\ No newline at end of file
+}
diff --git a/app/dal/searchHistoryService.js b/app/dal/searchHistoryService.js
index 2d5a291..e3f1b0e 100644
--- a/app/dal/searchHistoryService.js
+++ b/app/dal/searchHistoryService.js
@@ -5,27 +5,22 @@ const userService = require("./userService");
 const { SearchHistory } = require('../models/UserHistory');
 
 const SearchHistoryService = {
-
     async create(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        if (ctx.kcId === undefined)
+        if (ctx.kcId === undefined) {
             throw Error("kcId did not supported.")
-
+        }
         const user = await userService.detail({ kcId: ctx.kcId })
-
         if (user) {
-            const result = await SearchHistory.create({
+            return await SearchHistory.create({
                 kc_id: user.kc_id,
                 query: ctx.query,
                 name: ctx.name,
                 ui_structure: ctx.uiStructure,
                 description: ctx.description
             })
-
-            return result
         } else {
             throw Error('The user account could not found.')
         }
@@ -35,21 +30,16 @@ const SearchHistoryService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        if (ctx.kcId === undefined)
+        if (ctx.kcId === undefined) {
             throw Error("kcId did not supported.")
-
+        }
         const user = await userService.detail({ kcId: ctx.kcId })
-
         if (user) {
-
-            const histories = await SearchHistory.findAll({
+            return await SearchHistory.findAll({
                 where: {
                     kc_id: user.kc_id
                 }
             })
-
-            return histories
         }
     },
 
@@ -57,9 +47,9 @@ const SearchHistoryService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        if (ctx.kc_id === undefined)
+        if (ctx.kc_id === undefined) {
             throw Error("kcId did not supported.")
+        }
     },
 
     async delete(ctx) {
@@ -67,20 +57,17 @@ const SearchHistoryService = {
             throw Error("The request body is empty!")
         }
 
-        const result = await SearchHistory.destroy({
+        return await SearchHistory.destroy({
             where: {
                 id: ctx.id
             }
-        })
-
-        return result;
+        });
     }
 }
 
-
 module.exports = {
     create: SearchHistoryService.create,
     update: SearchHistoryService.update,
     delete: SearchHistoryService.delete,
     fetch: SearchHistoryService.getSearchHistories
-}
\ No newline at end of file
+}
diff --git a/app/dal/userRequestService.js b/app/dal/userRequestService.js
index b430bae..9e7518c 100644
--- a/app/dal/userRequestService.js
+++ b/app/dal/userRequestService.js
@@ -7,32 +7,26 @@ const { UserRequest } = require('../models/UserRequest');
 const db = require('../../db');
 
 const UserRequestService = {
-
     async create(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        if (ctx.kcId === undefined)
+        if (ctx.kcId === undefined) {
             throw Error("kcId did not supported.")
-
+        }
         const user = await userService.detail({ kcId: ctx.kcId })
-
         if (user) {
-            const result = await UserRequest.create({
+            return await UserRequest.create({
                 user_id: user.id,
                 request_message: ctx.message,
                 is_processed: false,
             })
-
-            return result
         } else {
             throw Error('The user account could not found.')
         }
     },
 
-    async getAllRequests(ctx) {
-
+    async getAllRequests() {
         return await UserRequest.findAll({})
     },
 
@@ -40,23 +34,12 @@ const UserRequestService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        if (ctx.kcId === undefined)
+        if (ctx.kcId === undefined) {
             throw Error("kcId did not supported.")
-
+        }
         const user = await userService.detail({ kcId: ctx.kcId })
-
         if (user) {
-
-
-            const requests = await db.select("*").from('user_requests').where('user_id', user.id).timeout(1000, { cancel: true })
-            // const requests = await UserRequest.find({
-            //     where: {
-            //         user_id: user.id
-            //     }
-            // })
-
-            return requests
+            return db.select("*").from('user_requests').where('user_id', user.id).timeout(1000, {cancel: true});
         }
     },
 
@@ -64,45 +47,36 @@ const UserRequestService = {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-        console.log("hey")
-        const requests = await UserRequest.findAll({
+        return await UserRequest.findAll({
             where: {
                 is_processed: false
             }
         })
-
-        return requests
     },
 
     async update(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const group = await UserRequest.update({
+        return await UserRequest.update({
             is_processed: true,
         }, {
-            where: { id: ctx.id }
+            where: {id: ctx.id}
         })
-        return result
     },
 
     async delete(ctx) {
         if (!ctx) {
             throw Error("The request body is empty!")
         }
-
-        const result = await UserRequest.destroy({
+        return await UserRequest.destroy({
             where: {
                 id: ctx.id
             }
-        })
-
-        return result;
+        });
     }
 }
 
-
 module.exports = {
     create: UserRequestService.create,
     process: UserRequestService.update,
@@ -110,4 +84,4 @@ module.exports = {
     fetch: UserRequestService.getAllRequests,
     fetchPending: UserRequestService.getPendingRequests,
     fetchByUser: UserRequestService.getUserRequests
-}
\ No newline at end of file
+}
diff --git a/app/dal/userService.js b/app/dal/userService.js
index e03b4ce..5741920 100644
--- a/app/dal/userService.js
+++ b/app/dal/userService.js
@@ -4,7 +4,7 @@ const KcAdminClient = require("keycloak-admin").default
 const { Issuer } = require("openid-client")
 const db = require('../../db')
 const { User } = require('../models/User')
-const { Role, RoleUser } = require('../models/Role')
+const { RoleUser } = require('../models/Role')
 const { postgresSeq } = require('../config/db')
 const { BotService, MailService } = require('@in-sylva/common')
 const { Op } = require("sequelize");
@@ -80,7 +80,6 @@ const UserService = {
         const password = await generatePassword(10);
         const salt = bcrypt.genSaltSync()
         const hashedPassword = bcrypt.hashSync(password, salt)
-        console.log("generated password: " + password);
         // Update user in insylva db.
         const [updatedRows, _] = await User.update({
           password: hashedPassword,
@@ -124,10 +123,9 @@ const UserService = {
   async users(ctx) {
     try {
       await auth()
-      const users = await keycloakAdmin.users.find({
+      return await keycloakAdmin.users.find({
         realm: process.env.KEYCLOAK_REALM
       })
-      return users
     }
     catch (err) {
       ctx.status = err.status || 500
@@ -163,7 +161,6 @@ const UserService = {
         firstname: ctx.firstName,
         lastname: ctx.lastName
       }).returning('*').then((result) => result[0])
-
     return user
   },
 
@@ -173,18 +170,14 @@ const UserService = {
       if (!ctx) {
         throw Error("The request body is empty!")
       }
-
       await auth()
-
       const userId = ctx.userId
-
       if (userId) {
         const deleted = await User.destroy({
           where: {
             kc_id: userId
           }
         })
-
         if (deleted) {
           return await keycloakAdmin.users.del({
             id: userId,
@@ -198,6 +191,7 @@ const UserService = {
       throw Error(error)
     }
   },
+
   // GET single user
   async user(ctx) {
     try {
@@ -240,10 +234,8 @@ const UserService = {
       if (!ctx) {
         throw Error("The request body is empty!")
       }
-      const user = await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, { cancel: true }).then((result) => result[0])
-      return user
-      // To-do
-      // Return user details such as roles and policies
+      return await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, {cancel: true}).then((result) => result[0])
+      // TODO return user details such as roles and policies
     } catch (error) {
       ctx.status = error.status || 500
       ctx.body = error.message
@@ -267,11 +259,13 @@ const UserService = {
             ]
           }
         })
-        if (checkUser.count > 0)
+        if (checkUser.count > 0) {
           return { user: null, status: 409, message: `"${ctx.email}" or "${ctx.username}" already exist, please try again with different credentials.` }
-        const roleId = (ctx.roleId == 0 || ctx.roleId == undefined) ? 3 : ctx.roleId
-        if (!!roleId && roleId == 0)
+        }
+        const roleId = (ctx.roleId === 0 || ctx.roleId === undefined) ? 3 : ctx.roleId
+        if (!!roleId && roleId === 0) {
           throw Error("The roleId is empty!")
+        }
         // Insert this new user into insylva db.
         const newUser = await User.create({
           username: ctx.username,
@@ -312,7 +306,6 @@ const UserService = {
                 kc_id: kcUser.id
               })
             }
-
           }
         } else {
           await t.rollback()
@@ -320,7 +313,7 @@ const UserService = {
         await t.commit()
         const date = new Date().toLocaleDateString()
         const message = `[INFO]:[User ${ctx.username} is created with this email address: ${ctx.email} successfully.]:[${date}]`
-        const subject = "In-Sylva New User Added"
+        const subject = "In-Sylva new user added"
         await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, process.env.IN_SYLVA_EMAIL_TO, subject, "", message)
         await botService.message(message)
         return { user: newUser, status: 201 }
@@ -353,33 +346,27 @@ const UserService = {
 
   },
 
-
   async getAssignedUserByRole(ctx) {
     try {
       if (!ctx) {
         throw Error("The request body is empty!")
       }
-
       const params = { roleId: ctx.id }
-
       const assignedUserByRole = await db.raw(`
         select u.username as username,u.email as useremail, r.name as rolename from roles r
         inner join roles_users ru on r.id = ru.role_id
         inner join users u on ru.kc_id = u.kc_id
         where r.id = :roleId
       `, params)
-
       return assignedUserByRole.rows
-
     } catch (error) {
       throw new Error(error)
     }
   },
 
-  async createSystemUser(ctx) {
+  async createSystemUser() {
     try {
       await auth()
-
       const checkUser = await User.findAndCountAll({
         where: {
           [Op.or]: [
@@ -389,8 +376,9 @@ const UserService = {
         }
       })
 
-      if (checkUser.count)
+      if (checkUser.count) {
         return { user: null, status: 409 }
+      }
 
       // Insert new user into keycloak db
       const kc_user = await keycloakAdmin.users.create({
@@ -420,7 +408,6 @@ const UserService = {
         password: process.env.IN_SYLVA_ADMIN_PASSWORD
       })
 
-
       await RoleUser.create({
         role_id: 1,
         kc_id: kc_user.id
@@ -432,9 +419,8 @@ const UserService = {
     }
   },
 
-  async usersWithGroupAndRole(ctx) {
+  async usersWithGroupAndRole() {
     try {
-
       const usersWithGroupsAndRole = await db.raw(
         `select DISTINCT u.id, u.kc_id, u.username, u.email, 
           g.name as groupName, g.description as groupDescription, r.name as roleName, r.description as roleDescription  from users u
@@ -442,9 +428,7 @@ const UserService = {
           inner join roles r on ru.role_id = r.id
           left join group_users gu on u.id = gu.user_id
           left join groups g on g.id = gu.group_id`)
-
       return usersWithGroupsAndRole.rows
-
     } catch (error) {
       throw new Error(error)
     }
@@ -452,9 +436,7 @@ const UserService = {
 
   async userWithGroupAndRole(ctx) {
     try {
-
       const params = { userId: ctx.id }
-
       const userWithGroupAndRole = await db.raw(
         `select DISTINCT u.id, u.kc_id, u.username, u.email, g.id as groupId,
           g.name as groupName, g.description as groupDescription, r.name as roleName, r.id as roleId, r.description as roleDescription  from users u
@@ -463,14 +445,11 @@ const UserService = {
           left join group_users gu on u.id = gu.user_id
           left join groups g on g.id = gu.group_id
           where u.kc_id = :userId`, params)
-
       return userWithGroupAndRole.rows
-
     } catch (error) {
       throw new Error(error)
     }
   }
-
 }
 
 module.exports = {
diff --git a/app/models/Group.js b/app/models/Group.js
index 5966c10..00c3764 100644
--- a/app/models/Group.js
+++ b/app/models/Group.js
@@ -1,4 +1,5 @@
 'use strict'
+
 const { postgresSeq } = require('../config/db')
 const Sequelize = require('sequelize')
 const { Policy } = require('./Policy')
@@ -26,7 +27,6 @@ Group.init({
     modelName: "groups"
 })
 
-
 GroupsPolicy.init({
     group_id: {
         type: Sequelize.INTEGER, allowNull: false,
@@ -73,44 +73,8 @@ GroupUser.init({
     modelName: "group_users"
 })
 
-// Group.belongsTo(Policy, { through: GroupsPolicy, uniqueKey: "group_policy_group_id_fkey" })
-// Policy.belongsTo(Group, { through: GroupsPolicy, uniqueKey: "group_policy_policy_id_fkey" })
-
-// User.belongsTo(Group, { through: GroupUser, uniqueKey: "group_user_group_id_fkey" })
-// Group.belongsTo(User, { through: GroupUser, uniqueKey: "group_user_user_id_fkey" })
-
-/*
-Group.hasMany(GroupsPolicy)
-Policy.hasMany(GroupsPolicy)
-Group.hasMany(GroupUser)
-User.hasMany(GroupUser)
-
-GroupsPolicy.belongsToMany(Group, {
-    foreignKey: {
-        name: "group_policy_group_id_fkey"
-    }
-})
-
-GroupsPolicy.belongsToMany(Policy, {
-    foreignKey: {
-        name: "group_policy_policy_id_fkey"
-    }
-})
-
-GroupUser.belongsToMany(Group, {
-    foreignKey: {
-        name: "group_user_group_id_fkey"
-    }
-})
-
-GroupUser.belongsTo(User, {
-    foreignKey: {
-        name: "group_user_user_id_fkey"
-    }
-}) */
-
 module.exports = {
     Group,
     GroupsPolicy,
     GroupUser,
-}
\ No newline at end of file
+}
diff --git a/app/models/Policy.js b/app/models/Policy.js
index 8c4c47e..5f79304 100644
--- a/app/models/Policy.js
+++ b/app/models/Policy.js
@@ -71,7 +71,7 @@ PolicyField.init(
     sequelize: postgresSeq,
     modelName: "policy_fields",
   })
-  
+
 PolicySource.init({
   policy_id: {
     type: Sequelize.INTEGER,
@@ -114,7 +114,7 @@ Policy.belongsToMany(StdField, {
 Policy.belongsToMany(Source, {
   through: PolicyField,
   uniqueKey: "policy_source_id_fkey",
-}); 
+});
 
 StdField.belongsToMany(Policy, {
   through: PolicyField,
@@ -132,44 +132,6 @@ UserProfile.init(
     modelName: "user_profile",
   }
 );
-/*
-Policy.belongsToMany(StdField, {
-  through: PolicyField,
-  uniqueKey: "policy_field_policy_id_fkey",
-});
-
-Policy.belongsToMany(Source, {
-  through: PolicyField,
-  uniqueKey: "policy_source_id_fkey",
-});
-
-StdField.belongsToMany(Policy, {
-  through: PolicyField,
-  uniqueKey: "std_fields_id_fkkey",
-});*/
-
-/*
-Policy.hasMany(PolicyField)
-Source.hasMany(PolicyField)
-StdField.hasMany(PolicyField)
-
-PolicyField.belongsToMany(Policy, {
-    foreignKey: {
-        name: "policy_field_policy_id_fkey"
-    }
-})
-
-PolicyField.belongsToMany(Source, {
-    foreignKey: {
-        name: "policy_field_source_id_fkey"
-    }
-})
-
-PolicyField.hasMany(StdField, {
-    foreignKey: {
-        name: "std_fields_id_fkkey"
-    }
-}) */
 
 module.exports = {
   Policy,
diff --git a/app/models/Role.js b/app/models/Role.js
index 3d8ebfd..0c2a95e 100644
--- a/app/models/Role.js
+++ b/app/models/Role.js
@@ -41,24 +41,6 @@ RoleUser.init({
     modelName: "roles_users"
 })
 
-// Role.belongsTo(User, { through: RoleUser, uniqueKey: "roles_users_role_id_fkey" })
-// User.belongsTo(Role, { through: RoleUser, uniqueKey: "roles_users_kc_id_fkey" })
-/*
-Role.hasMany(RoleUser)
-User.hasMany(Role)
-
-RoleUser.belongsToMany(Role, {
-    foreignKey: {
-        name: "roles_users_role_id_fkey"
-    }
-})
-RoleUser.hasMany(User, {
-    foreignKey: {
-        name: "roles_users_kc_id_fkey"
-    }
-}) */
-
-
 module.exports = {
     Role,
     RoleUser
diff --git a/app/models/StdField.js b/app/models/StdField.js
index 7173782..5ae463c 100644
--- a/app/models/StdField.js
+++ b/app/models/StdField.js
@@ -3,7 +3,6 @@
 const { postgresSeq } = require('../config/db')
 const Sequelize = require('sequelize')
 
-
 class StdField extends Sequelize.Model { }
 
 StdField.init({
@@ -33,9 +32,3 @@ StdField.init({
 module.exports = {
     StdField
 }
-
-
-
-
-
-
diff --git a/app/models/User.js b/app/models/User.js
index 364e98e..14f18e3 100644
--- a/app/models/User.js
+++ b/app/models/User.js
@@ -27,14 +27,11 @@ User.init({
     }
 })
 
-
 User.beforeCreate(async (user, options) => {
     const salt = bcrypt.genSaltSync()
     user.password = bcrypt.hashSync(user.password, salt)
 })
 
-
-
 module.exports = {
     User
-}
\ No newline at end of file
+}
diff --git a/app/utils/format.js b/app/utils/format.js
index 9e60ff7..118da74 100644
--- a/app/utils/format.js
+++ b/app/utils/format.js
@@ -4,7 +4,6 @@ const { createLogger, format, transports } = require('winston');
 const { combine, timestamp, printf, colorize, splat, label } = format;
 const path = require('path');
 
-
 const mFormat = printf((info) => {
     if (info.meta && info.meta instanceof Error) {
         return `${info.timestamp} ${info.level} ${info.message} : ${info.meta.stack}`;
@@ -12,12 +11,11 @@ const mFormat = printf((info) => {
     return `${info.timestamp} ${info.level} [${info.label}]: ${info.message}`;
 });
 
-const LOG_LEVEL = process.env.LOG_LEVEL || 'debug';
 const logger = createLogger({
     transports: [
         new (transports.Console)(
             {
-                level: LOG_LEVEL,
+                level: process.env.LOG_LEVEL || 'debug',
                 format: combine(
                     label({ label: path.basename(process.mainModule.filename) }),
                     colorize(),
diff --git a/app/utils/hashPass.js b/app/utils/hashPass.js
deleted file mode 100644
index 80b32c5..0000000
--- a/app/utils/hashPass.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict'
-
-const bcrypt = require('bcrypt')
-const logger = require('winston')
-
-async function hashPass(valueToHash) {
-    const rounds = 10
-
-    try {
-        const hashedValue = await bcrypt.hash(valueToHash, rounds)
-        return hashedValue
-    } catch (err) {
-        logger.error(err)
-        throw err
-    }
-}
-
-module.exports = {
-    hashPass
-}
diff --git a/app/utils/memory-store.js b/app/utils/memory-store.js
deleted file mode 100644
index b0308ce..0000000
--- a/app/utils/memory-store.js
+++ /dev/null
@@ -1,29 +0,0 @@
-function MemoryStore () {
-    this.sessions = Object.create(null);
-  }
-  
-  MemoryStore.prototype.get = function (sessionId) {
-    var sess = this.sessions[sessionId];
-    if (!sess) {
-      return;
-    }
-    sess = JSON.parse(sess);
-    if (sess.expire && sess.expire <= Date.now()) {
-      delete this.sessions[sessionId];
-      return;
-    }
-    return sess;
-  };
-  
-  MemoryStore.prototype.set = function (sessionId, session, maxAge) {
-    if (maxAge > 0) {
-      session.expire = Date.now() + maxAge;
-    }
-    this.sessions[sessionId] = JSON.stringify(session);
-  };
-  
-  MemoryStore.prototype.destroy = function (sessionId) {
-    delete this.sessions[sessionId];
-  };
-  
-  module.exports = MemoryStore;
\ No newline at end of file
diff --git a/init-keycloak.js b/init-keycloak.js
index 7f76922..c0b75b7 100644
--- a/init-keycloak.js
+++ b/init-keycloak.js
@@ -1,27 +1,13 @@
 'use strict'
 
 const KeycloakConnect = require('@in-sylva/keycloak-koa-connect').default
-const bodyStore = require('@in-sylva/keycloak-koa-connect/stores/body-store').default // If this option is used, it is legal to include the value of jwt in the body
-const queryStore = require('@in-sylva/keycloak-koa-connect/stores/query-store').default // If this option is used, it is also legal to pass a token at http://a.com?jwt=token
-// var Keycloak = require('keycloak-connect');
-
-// const KeycloakConnect = require('@pixelygroup/keycloak-koa-connect').default
-// const bodyStore = require('@pixelygroup/keycloak-koa-connect').default // If this option is used, it is legal to include the value of jwt in the body
-// const queryStore = require('@pixelygroup/keycloak-koa-connect').default // If this option is used, it is also legal to pass a token at http://a.com?jwt=token
-
 const config = require('./keycloak.js')
 
-const keycloak = new KeycloakConnect({ store: [queryStore, bodyStore]}, config)
-
-/*
-var keycloak = new Keycloak({
-    store: true
-  }, {
-    clientId: config.resource,
-    serverUrl: config["auth-server-url"],
-    realm: config.realm,
-    bearerOnly: true
-  }); */ 
+// If this option is used, it is legal to include the value of jwt in the body
+const bodyStore = require('@in-sylva/keycloak-koa-connect/stores/body-store').default
+// If this option is used, it is also legal to pass a token at http://a.com?jwt=token
+const queryStore = require('@in-sylva/keycloak-koa-connect/stores/query-store').default
 
+const keycloak = new KeycloakConnect({ store: [queryStore, bodyStore]}, config)
 
-module.exports = { keycloak }
\ No newline at end of file
+module.exports = { keycloak }
diff --git a/keycloak.js b/keycloak.js
index dcfe832..2724de9 100644
--- a/keycloak.js
+++ b/keycloak.js
@@ -1,5 +1,4 @@
 module.exports = {
-
     'realm': process.env.KEYCLOAK_REALM,
     'auth-server-url': process.env.KEYCLOAK_SERVER_URL,
     "ssl-required": "none",
@@ -13,9 +12,4 @@ module.exports = {
     'bearer-only':true,
     'use-resource-role-mappings': true,
     'realm-public-key': `${process.env.KEYCLOAK_SERVER_PUBLIC_KEY}`
-    /*
-    'ssl-required':'external',
-    "public-client": true,
-    'confidential-port': 0,
-    'realm-public-key': `${process.env.KEYCLOAK_SERVER_PUBLIC_KEY}`*/
-}
\ No newline at end of file
+}
diff --git a/server.js b/server.js
index 6f9d0ec..b41eca1 100644
--- a/server.js
+++ b/server.js
@@ -6,10 +6,6 @@ const api = require('./app/api')
 const koaLogger = require('koa-logger')
 const cors = require('koa2-cors')
 const { keycloak } = require('./init-keycloak');
-let session = require('koa-session');
-let MemoryStore = require('./app/utils/memory-store')
-
-let store = new MemoryStore();
 
 async function responseTime(ctx, next) {
     const start = Date.now();
@@ -32,27 +28,18 @@ middlewares.forEach(function (middleware) {
     app.use(middleware);
 })
 
-
 app
     .use(cors({
         origin: '*'
     }))
-    /*.use(session({
-        key: 'koa:sess',
-        maxAge: 86400000,
-        renew: false,
-        store: store,
-        signed: false
-    }, app))*/
     .use(koaLogger())
     .use(function (ctx, next) {
         return next().catch((err) => {
             if (err) {
+                // Protected resource, use Authorization header to get access\n
                 console.log(err)
                 ctx.status = 401
-                ctx.body = err //'Protected resource, use Authorization header to get access\n'
-            } else {
-                /* */
+                ctx.body = err
             }
         })
     })
@@ -65,4 +52,4 @@ app.on('error', (err) => {
     throw err
 })
 
-module.exports = app
\ No newline at end of file
+module.exports = app
-- 
GitLab


From 6dfeca85e9fda18552397a8b1362999973d82943 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Fri, 15 Nov 2024 15:28:42 +0100
Subject: [PATCH 03/13] added new routes, handlers and services for user fields
 display settings

---
 app/api/index.js                              | 155 +++++++++---------
 .../user-fields-display-settings/delete.js    |  25 +++
 app/api/user-fields-display-settings/get.js   |  37 +++++
 app/api/user-fields-display-settings/index.js |  16 ++
 app/api/user-fields-display-settings/post.js  |  24 +++
 app/api/user-fields-display-settings/put.js   |  24 +++
 app/dal/groupService.js                       |  92 +++++------
 app/dal/userFieldsDisplaySettingsService.js   | 139 ++++++++++++++++
 app/models/UserFieldsDisplaySettings.js       |  48 ++++++
 9 files changed, 433 insertions(+), 127 deletions(-)
 create mode 100644 app/api/user-fields-display-settings/delete.js
 create mode 100644 app/api/user-fields-display-settings/get.js
 create mode 100644 app/api/user-fields-display-settings/index.js
 create mode 100644 app/api/user-fields-display-settings/post.js
 create mode 100644 app/api/user-fields-display-settings/put.js
 create mode 100644 app/dal/userFieldsDisplaySettingsService.js
 create mode 100644 app/models/UserFieldsDisplaySettings.js

diff --git a/app/api/index.js b/app/api/index.js
index acc378f..e93fb17 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -1,97 +1,106 @@
 'use strict'
 
-const Router = require("koa-router")
-const bodyParser = require("koa-bodyparser")
+const Router = require("koa-router");
+const bodyParser = require("koa-bodyparser");
 /* const { keycloak } = require('../../init-keycloak') */
 
-// handlers
-const userHandler = require('./users')
-const roleHandler = require('./roles')
-const allocationRoleHandler = require('./role-user')
-const searchHistoryHandler = require('./user-search-history')
-const userRequestHandler = require('./user-requests')
-const groupHandler = require('./group')
-const policyHandler = require('./policy')
+// Handlers
+const userHandler = require('./users');
+const roleHandler = require('./roles');
+const allocationRoleHandler = require('./role-user');
+const searchHistoryHandler = require('./user-search-history');
+const userRequestHandler = require('./user-requests');
+const groupHandler = require('./group');
+const policyHandler = require('./policy');
+const UserFieldsDisplaySettingsHandler = require("./user-fields-display-settings");
 
-const routers = new Router()
+const routers = new Router();
+
+routers.use(bodyParser());
 
-routers.use(bodyParser())
 routers.get('/healthcheck', (ctx) => {
-    ctx.res.statusCode = 200
-    ctx.res.end('OK')
-})
+    ctx.res.statusCode = 200;
+    ctx.res.end('OK');
+});
 
 // Users
-routers.post('/user', userHandler.addNewUser)
-routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user)
-routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users)
-routers.delete('/user/delete',/* keycloak.protect(),*/ userHandler.deleteUser)
-routers.put('/user/update',/* keycloak.protect(),*/ userHandler.update)
-routers.post('/user/kcid', /* keycloak.protect(),*/ userHandler.kcId)
-routers.post('/user/detail', /* keycloak.protect(),*/ userHandler.detail)
-routers.post('/user/assigned-by-role', userHandler.getAssignedUserByRole)
-routers.post('/user/send-mail', userHandler.sendMail)
-routers.post('/user/reset-password', userHandler.resetPassword)
+routers.post('/user', userHandler.addNewUser);
+routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user);
+routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users);
+routers.delete('/user/delete',/* keycloak.protect(),*/ userHandler.deleteUser);
+routers.put('/user/update',/* keycloak.protect(),*/ userHandler.update);
+routers.post('/user/kcid', /* keycloak.protect(),*/ userHandler.kcId);
+routers.post('/user/detail', /* keycloak.protect(),*/ userHandler.detail);
+routers.post('/user/assigned-by-role', userHandler.getAssignedUserByRole);
+routers.post('/user/send-mail', userHandler.sendMail);
+routers.post('/user/reset-password', userHandler.resetPassword);
 
 // System admin user
-routers.post('/user/create-system-user', userHandler.createSystemUser)
-routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole)
-routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole)
+routers.post('/user/create-system-user', userHandler.createSystemUser);
+routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole);
+routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole);
 
 // Search history
-routers.post('/user/add-history', searchHistoryHandler.add)
-routers.post('/user/fetch-history', searchHistoryHandler.fetch)
-routers.delete('/user/delete-history', searchHistoryHandler.deleteH)
+routers.post('/user/add-history', searchHistoryHandler.add);
+routers.post('/user/fetch-history', searchHistoryHandler.fetch);
+routers.delete('/user/delete-history', searchHistoryHandler.deleteH);
+
+// User fields display settings
+routers.post('/user/fields-display-settings/', /* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.createUserFieldsDisplaySettings);
+routers.get('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUsersFieldsDisplaySettings);
+routers.get('/user/fields-display-settings/:userId',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUserFieldsDisplaySettings);
+routers.put('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.updateUserFieldsDisplaySettings);
+routers.delete('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.deleteUserFieldsDisplaySettings);
 
 // User requests
-routers.post('/user/create-request', userRequestHandler.createRequest)
-routers.delete('/user/delete-request', userRequestHandler.deleteRequest)
-routers.post('/user/process-request', userRequestHandler.processRequest)
-routers.get('/user/list-requests', userRequestHandler.fetchRequests)
-routers.post('/user/list-requests-by-user', userRequestHandler.fetchRequestsByUser)
-routers.get('/user/list-pending-requests', userRequestHandler.fetchPendingRequests)
+routers.post('/user/create-request', userRequestHandler.createRequest);
+routers.delete('/user/delete-request', userRequestHandler.deleteRequest);
+routers.post('/user/process-request', userRequestHandler.processRequest);
+routers.get('/user/list-requests', userRequestHandler.fetchRequests);
+routers.post('/user/list-requests-by-user', userRequestHandler.fetchRequestsByUser);
+routers.get('/user/list-pending-requests', userRequestHandler.fetchPendingRequests);
 
 // Groups
-routers.post('/user/groups', groupHandler.groups)
-routers.post('/user/group-policies', groupHandler.groupPolicies)
-routers.post('/user/group-users', groupHandler.groupUsers)
-routers.post('/user/add-group', groupHandler.createGroup)
-routers.post('/user/add-group-policy', groupHandler.createGroupPolicy)
-routers.post('/user/add-group-user', groupHandler.createGroupUser)
-routers.put('/user/update-group', groupHandler.updateGroup)
-routers.put('/user/update-group-policy', groupHandler.updateGroupPolicy)
-routers.put('/user/update-group-user', groupHandler.updateGroupUser)
-routers.delete('/user/delete-group', groupHandler.deleteGroup)
-routers.delete('/user/delete-group-policy', groupHandler.deleteGroupPolicy)
-routers.delete('/user/delete-group-user', groupHandler.deleteGroupUser)
+routers.post('/user/groups', groupHandler.groups);
+routers.post('/user/group-policies', groupHandler.groupPolicies);
+routers.post('/user/group-users', groupHandler.groupUsers);
+routers.post('/user/add-group', groupHandler.createGroup);
+routers.post('/user/add-group-policy', groupHandler.createGroupPolicy);
+routers.post('/user/add-group-user', groupHandler.createGroupUser);
+routers.put('/user/update-group', groupHandler.updateGroup);
+routers.put('/user/update-group-policy', groupHandler.updateGroupPolicy);
+routers.put('/user/update-group-user', groupHandler.updateGroupUser);
+routers.delete('/user/delete-group', groupHandler.deleteGroup);
+routers.delete('/user/delete-group-policy', groupHandler.deleteGroupPolicy);
+routers.delete('/user/delete-group-user', groupHandler.deleteGroupUser);
 
 // Policies
-routers.post('/policy/add', policyHandler.createPolicy)
-routers.delete('/policy/delete', policyHandler.deletePolicy)
-routers.put('/policy/update', policyHandler.updatePolicy)
-routers.get('/policy/list', policyHandler.policies)
-routers.post('/policy/list-by-user', policyHandler.policiesByUser)
-routers.post('/policy/assigned-fields', policyHandler.assignedPolicies)
-routers.get('/policy/policies-with-sources', policyHandler.getPoliciesWithSources)
-routers.post('/policy/policies-with-sources-by-user', policyHandler.getPoliciesWithSourcesByUser)
-routers.post('/policy/policies-with-groups', policyHandler.getGroupDetailsByPolicy)
-routers.post('/policyField/add', policyHandler.createPolicyField)
-routers.delete('/policyField/delete', policyHandler.deletePolicyField)
-routers.put('/policyField/update', policyHandler.updatePolicyField)
-routers.get('/policyField/list', policyHandler.policyFields)
-routers.post('/policySource/add', policyHandler.createPolicySource)
+routers.post('/policy/add', policyHandler.createPolicy);
+routers.delete('/policy/delete', policyHandler.deletePolicy);
+routers.put('/policy/update', policyHandler.updatePolicy);
+routers.get('/policy/list', policyHandler.policies);
+routers.post('/policy/list-by-user', policyHandler.policiesByUser);
+routers.post('/policy/assigned-fields', policyHandler.assignedPolicies);
+routers.get('/policy/policies-with-sources', policyHandler.getPoliciesWithSources);
+routers.post('/policy/policies-with-sources-by-user', policyHandler.getPoliciesWithSourcesByUser);
+routers.post('/policy/policies-with-groups', policyHandler.getGroupDetailsByPolicy);
+routers.post('/policyField/add', policyHandler.createPolicyField);
+routers.delete('/policyField/delete', policyHandler.deletePolicyField);
+routers.put('/policyField/update', policyHandler.updatePolicyField);
+routers.get('/policyField/list', policyHandler.policyFields);
+routers.post('/policySource/add', policyHandler.createPolicySource);
 
 // Roles
-routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole)
-routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles)
-routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role)
-routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole)
-routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update)
+routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole);
+routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles);
+routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role);
+routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole);
+routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update);
 
 // Role allocation to users
-routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole)
-routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles)
-routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update)
-routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole)
+routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole);
+routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles);
+routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update);
+routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole);
 
-module.exports = routers
+module.exports = routers;
diff --git a/app/api/user-fields-display-settings/delete.js b/app/api/user-fields-display-settings/delete.js
new file mode 100644
index 0000000..f1ec286
--- /dev/null
+++ b/app/api/user-fields-display-settings/delete.js
@@ -0,0 +1,25 @@
+'use strict'
+
+const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
+const logger = require('../../utils/format');
+const util = require('util');
+const {updateUserFieldsDisplaySettings} = require("./put");
+
+const UserFieldsDisplaySettings = {
+    async delete(ctx) {
+        try {
+            ctx.body = await userFieldsDisplaySettingsService.delete(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User fields display settings deleted.');
+        } catch (err) {
+            ctx.body = err || 'An error occurred.';
+            ctx.status = 500;
+            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        }
+    }
+}
+
+module.exports = {
+    deleteUserFieldsDisplaySettings: UserFieldsDisplaySettings.delete,
+    UserFieldsDisplaySettings
+};
diff --git a/app/api/user-fields-display-settings/get.js b/app/api/user-fields-display-settings/get.js
new file mode 100644
index 0000000..18e04bb
--- /dev/null
+++ b/app/api/user-fields-display-settings/get.js
@@ -0,0 +1,37 @@
+"use strict";
+
+const logger = require('../../utils/format')
+const util = require('util')
+const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
+
+const GetUserFieldsDisplaySettings = {
+    async find(ctx) {
+        try {
+            ctx.body = await userFieldsDisplaySettingsService.usersFieldsDisplaySettings(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Users fields display settings retrieved.');
+        } catch (err) {
+            ctx.body = err || 'An error occurred.';
+            ctx.status = 500;
+            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        }
+    },
+
+    async findOne(ctx) {
+        try {
+            ctx.body = await userFieldsDisplaySettingsService.userFieldsDisplaySettings(ctx.request.body)
+            ctx.status = 201
+            logger.info('User fields display settings retrieved.')
+        } catch (err) {
+            ctx.body = err || 'An error occurred.'
+            ctx.status = 500;
+            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+        }
+    },
+};
+
+module.exports = {
+    findUsersFieldsDisplaySettings: GetUserFieldsDisplaySettings.find,
+    findUserFieldsDisplaySettings: GetUserFieldsDisplaySettings.findOne,
+    GetUserFieldsDisplaySettings
+};
diff --git a/app/api/user-fields-display-settings/index.js b/app/api/user-fields-display-settings/index.js
new file mode 100644
index 0000000..338b10b
--- /dev/null
+++ b/app/api/user-fields-display-settings/index.js
@@ -0,0 +1,16 @@
+"use strict";
+
+const { createUserFieldsDisplaySettings } = require('./post');
+const { findUsersFieldsDisplaySettings, findUserFieldsDisplaySettings } = require('./get');
+const { updateUserFieldsDisplaySettings } = require('./put');
+const { deleteUserFieldsDisplaySettings } = require('./delete');
+
+const UserFieldsDisplaySettingsHandler = {
+    createUserFieldsDisplaySettings,
+    findUsersFieldsDisplaySettings,
+    findUserFieldsDisplaySettings,
+    updateUserFieldsDisplaySettings,
+    deleteUserFieldsDisplaySettings
+}
+
+module.exports = UserFieldsDisplaySettingsHandler
diff --git a/app/api/user-fields-display-settings/post.js b/app/api/user-fields-display-settings/post.js
new file mode 100644
index 0000000..556304c
--- /dev/null
+++ b/app/api/user-fields-display-settings/post.js
@@ -0,0 +1,24 @@
+'use strict'
+
+const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
+const logger = require('../../utils/format')
+const util = require('util')
+
+const CreateUserFieldsDisplaySettings = {
+    async create(ctx) {
+        try {
+            ctx.body = await userFieldsDisplaySettingsService.create(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User fields display settings created.');
+        } catch (err) {
+            ctx.body = err || 'An error occurred.';
+            ctx.status = 500;
+            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        }
+    },
+}
+
+module.exports = {
+    createUserFieldsDisplaySettings: CreateUserFieldsDisplaySettings.create,
+    CreateUserFieldsDisplaySettings
+}
diff --git a/app/api/user-fields-display-settings/put.js b/app/api/user-fields-display-settings/put.js
new file mode 100644
index 0000000..1e2d7de
--- /dev/null
+++ b/app/api/user-fields-display-settings/put.js
@@ -0,0 +1,24 @@
+'use strict'
+
+const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
+const logger = require('../../utils/format');
+const util = require('util');
+
+const UpdateUserFieldsDisplaySettings = {
+    async update(ctx) {
+        try {
+            ctx.body = await userFieldsDisplaySettingsService.update(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User fields display settings updated.');
+        } catch (err) {
+            ctx.body = err || 'An error occurred.';
+            ctx.status = 500;
+            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        }
+    }
+}
+
+module.exports = {
+    updateUserFieldsDisplaySettings: UpdateUserFieldsDisplaySettings.update,
+    UpdateUserFieldsDisplaySettings
+};
diff --git a/app/dal/groupService.js b/app/dal/groupService.js
index cd141c3..6d27ca6 100644
--- a/app/dal/groupService.js
+++ b/app/dal/groupService.js
@@ -5,14 +5,12 @@ const userService = require('./userService')
 const db = require('../../db')
 
 const GroupService = {
-
     async createGroup(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
         if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.")
+            throw Error("kcId did not supported.");
         }
         const user = await userService.detail({ kcId: ctx.kcId });
         if (user) {
@@ -21,112 +19,103 @@ const GroupService = {
                     name: ctx.name,
                     user_id: user.id,
                 }
-            })
+            });
             if (group) {
-                throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`)
+                throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`);
             } else {
                 return await Group.create({
                     name: ctx.name,
                     description: ctx.description,
                     user_id: user.id,
-                })
+                });
             }
         } else {
-            throw Error('The user account could not found.')
+            throw Error('User account not found.');
         }
     },
 
     async createGroupPolicy(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
         const groupPolicy = await GroupsPolicy.findOne({
             where: {
                 group_id: ctx.groupId,
                 policy_id: ctx.policyId
             }
-        })
-
+        });
         if (groupPolicy) {
-            throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`)
+            throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`);
         } else {
             return await GroupsPolicy.create({
                 group_id: ctx.groupId,
                 policy_id: ctx.policyId
-            })
+            });
         }
     },
 
     async createGroupUser(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
         if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.")
+            throw Error("kcId did not supported.");
         }
-
-        const user = await userService.detail({ kcId: ctx.kcId })
+        const user = await userService.detail({ kcId: ctx.kcId });
         if (user) {
             const groupUser = await GroupUser.findOne({
                 where: {
                     group_id: ctx.groupId,
                     user_id: user.id
                 }
-            })
+            });
             if (groupUser) {
-                throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`)
+                throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`);
             } else {
                 return await GroupUser.create({
                     group_id: ctx.groupId,
                     user_id: user.id
-                })
+                });
             }
         } else {
-            throw Error('The user account could not found.')
+            throw Error('The user account could not found.');
         }
     },
 
     async updateGroup(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
         return await Group.update({
             name: ctx.name,
             description: ctx.description,
         }, {
             where: {id: ctx.id, user_id: ctx.userId}
-        })
-
+        });
     },
 
     async updateGroupPolicy(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
         return await GroupsPolicy.update({
             group_id: ctx.groupId,
             policy_id: ctx.policyId
-        }, {where: {id: ctx.id}})
+        }, {where: {id: ctx.id}});
     },
 
     async updateGroupUser(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
-        const user = await userService.detail({ kcId: ctx.kcId })
+        const user = await userService.detail({ kcId: ctx.kcId });
         if (user) {
             return await GroupUser.update({
                 group_id: ctx.groupId,
                 user_id: user.id
-            }, {where: {id: ctx.id}})
-
+            }, {where: {id: ctx.id}});
         } else {
-            throw Error('The user account could not found.')
+            throw Error('The user account could not found.');
         }
     },
 
@@ -139,58 +128,53 @@ const GroupService = {
                 where: {
                     id: ctx.id
                 }
-            })
+            });
         }
     },
 
     async deleteGroupPolicy(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
         return await GroupsPolicy.destroy({
             where: {
                 id: ctx.id
             }
-        })
+        });
     },
 
     async deleteGroupUser(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-
-        const params = { groupId: ctx.groupId, userId: ctx.userId }
-
+        const params = { groupId: ctx.groupId, userId: ctx.userId };
         const groupUser = await db.raw(`
               delete from group_users
               where group_id = :groupId and user_id = :userId
-        `, params)
-
-        return groupUser
+        `, params);
+        return groupUser;
     },
 
     async groups() {
-        return await Group.findAll({})
-
+        return await Group.findAll({});
     },
 
     async groupPolicies() {
-        return await GroupsPolicy.findAll({})
+        return await GroupsPolicy.findAll({});
     },
 
     async groupUsers(ctx) {
         if (!ctx) {
-            throw Error("The request body is empty!")
+            throw Error("The request body is empty!");
         }
-        const params = { groupId: ctx.groupId }
+        const params = { groupId: ctx.groupId };
         const groupUsers = await db.raw(`
               select g.id as groupId, u.id as userId, u.username, g.name, g.description from group_users gu
               inner join users u on u.id = gu.user_id
               inner join groups g on gu.group_id = g.id
               where g.id = :groupId
-        `, params)
-        return groupUsers.rows
+        `, params);
+        return groupUsers.rows;
     }
 }
 
diff --git a/app/dal/userFieldsDisplaySettingsService.js b/app/dal/userFieldsDisplaySettingsService.js
new file mode 100644
index 0000000..49ef158
--- /dev/null
+++ b/app/dal/userFieldsDisplaySettingsService.js
@@ -0,0 +1,139 @@
+"use strict"
+
+const {UserFieldsDisplaySettings} = require("../models/UserFieldsDisplaySettings");
+const userService = require("./userService");
+
+/*
+  userFieldsDisplaySettingsService
+  Manage all users fields display settings
+  Used in search tool for results table columns
+*/
+const userFieldsDisplaySettingsService = {
+
+  // POST create fields settings for a specific user
+  // userId: id of the user
+  // stdFieldsIds: array of ids of fields selected by user
+  async create(ctx) {
+    try {
+      if (!ctx) {
+        throw Error("Empty request body.");
+      } else if (!ctx.userId) {
+        throw Error("Required parameter userId is missing.");
+      } else if (!ctx.stdFieldsIds) {
+        throw Error("Required parameter stdFieldsIds is missing.");
+      }
+      // Check if user exists
+      const user = await userService.user({id: userId});
+      console.log(user);
+      if (!user) {
+        throw Error("User does not exists.");
+      }
+      // Check if all fields ids exists
+      if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) {
+        throw new Error("One or more std_field_id do not exists.");
+      }
+      // Insert new row in user settings table
+      const [newUserFieldsSettings, isCreated] = await UserFieldsDisplaySettings.findOrCreate({
+        where: { user_id: ctx.userId }, // Unique field(s) to check for existence
+        defaults: {
+          std_fields_ids: ctx.stdFieldsIds,
+        },
+      });
+      console.log(isCreated);
+      console.log(newUserFieldsSettings);
+      if (!isCreated) {
+        throw new Error("User settings row already exists.");
+      }
+      return { userFieldsDisplaySettings: newUserFieldsSettings, status: 201 };
+    } catch (error) {
+      throw new Error(error);
+    }
+  },
+
+  // GET all users fields settings
+  async usersFieldsDisplaySettings(ctx) {
+    try {
+      return await UserFieldsDisplaySettings.findAll({});
+    }
+    catch (err) {
+      ctx.status = err.status || 500;
+      ctx.body = err.message;
+      throw Error(err);
+    }
+  },
+
+  // GET single user settings
+  // userId: id of the user
+  async userFieldsDisplaySettings(ctx) {
+    try {
+      if (!ctx) {
+        throw Error("Empty request body.");
+      } else if (!ctx.userId) {
+        throw Error("Required parameter userId is missing.");
+      }
+      return await UserFieldsDisplaySettings.findOne({ where: { user_id: ctx.userId } });
+    } catch (err) {
+      ctx.status = err.status || 500;
+      ctx.body = err.message;
+      throw Error(err);
+    }
+  },
+
+  // PUT update a user settings
+  // userId: id of the user
+  // stdFieldsIds: new array of all fields ids
+  async update(ctx) {
+    if (!ctx) {
+      throw Error("Empty request body.");
+    } else if (!ctx.userId) {
+      throw Error("Required parameter userId is missing.");
+    } else if (!ctx.stdFieldsIds) {
+      throw Error("Required parameter stdFieldsIds is missing.");
+    }
+    // Check if user exists
+    const user = await userService.user({id: userId});
+    console.log(user);
+    if (!user) {
+      throw Error("User does not exists.");
+    }
+    // Check if all fields ids exists
+    if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) {
+      throw new Error("One or more std_field_id do not exists.");
+    }
+    return await UserFieldsDisplaySettings.update({
+      std_fields_ids: ctx.stdFieldsIds,
+    }, {
+      where: {
+        user_id: userId
+      }
+    });
+  },
+
+  // DELETE the user settings
+  async delete(ctx) {
+    try {
+      if (!ctx) {
+        throw Error("Empty request body.");
+      } else if (!ctx.userId) {
+        throw Error("Required parameter userId is missing.");
+      }
+      return await UserFieldsDisplaySettings.destroy({
+        where: {
+          user_id: userId
+        }
+      });
+    } catch (error) {
+      ctx.status = error.status || 500;
+      ctx.body = error.message;
+      throw Error(error);
+    }
+  },
+}
+
+module.exports = {
+  create: userFieldsDisplaySettingsService.create,
+  usersFieldsDisplaySettings: userFieldsDisplaySettingsService.usersFieldsDisplaySettings,
+  userFieldsDisplaySettings: userFieldsDisplaySettingsService.userFieldsDisplaySettings,
+  delete: userFieldsDisplaySettingsService.delete,
+  update: userFieldsDisplaySettingsService.update,
+};
diff --git a/app/models/UserFieldsDisplaySettings.js b/app/models/UserFieldsDisplaySettings.js
new file mode 100644
index 0000000..98b7ccb
--- /dev/null
+++ b/app/models/UserFieldsDisplaySettings.js
@@ -0,0 +1,48 @@
+'use strict'
+
+const { Model, DataTypes, Deferrable} = require('sequelize');
+const { postgresSeq } = require('../config/db');
+const { User } = require('./User');
+const {StdField} = require("./StdField");
+
+class UserFieldsDisplaySettings extends Model { }
+
+UserFieldsDisplaySettings.init({
+    user_id: {
+        type: DataTypes.INTEGER,
+        allowNull: false,
+        unique: true,
+        references: {
+            model: User,
+            key: "id",
+            deferrable: Deferrable.INITIALLY_IMMEDIATE,
+        }
+    },
+    std_fields_ids: {
+        type: DataTypes.ARRAY(DataTypes.INTEGER),
+        allowNull: false,
+        references: {
+            model: StdField,
+            key: 'id',
+            deferrable: Deferrable.INITIALLY_IMMEDIATE
+        },
+    }
+}, {
+    underscored: true,
+    sequelize: postgresSeq,
+    modelName: "user_fields_display_settings"
+});
+
+// Verify if all standard fields exists in database
+UserFieldsDisplaySettings.validateStdFieldIds = async (stdFieldIds) => {
+    // Count the number of existing IDs in std_fields
+    const validIds = await StdField.count({
+        where: { id: stdFieldIds },
+    });
+    // Check if it matches the length of stdFieldIds
+    return validIds === stdFieldIds.length;
+};
+
+module.exports = {
+    UserFieldsDisplaySettings,
+};
-- 
GitLab


From 79be25e6def38467f0a56f8faa3de84b33dfae12 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Thu, 21 Nov 2024 10:57:10 +0100
Subject: [PATCH 04/13] [UserFieldsDisplaySettings] Corrected endpoints
 workflow [ErrorHandler] Added a global error handler to avoid code
 duplication and improve readability

---
 app/api/group/delete.js                       |   8 +-
 app/api/group/get.js                          |   6 +-
 app/api/group/post.js                         |   8 +-
 app/api/group/update.js                       |   2 +-
 app/api/index.js                              |   4 +-
 app/api/policy/delete.js                      |   4 +-
 app/api/policy/get.js                         |   4 +-
 app/api/policy/post.js                        |   4 +-
 app/api/policy/update.js                      |   4 +-
 app/api/realm/delete.js                       |   2 +-
 app/api/realm/get.js                          |   2 +-
 app/api/realm/post.js                         |   2 +-
 app/api/realm/put.js                          |   2 +-
 app/api/role-user/delete.js                   |   2 +-
 app/api/role-user/get.js                      |   2 +-
 app/api/role-user/post.js                     |   2 +-
 app/api/role-user/put.js                      |   2 +-
 app/api/roles/delete.js                       |   2 +-
 app/api/roles/get.js                          |   2 +-
 app/api/roles/post.js                         |   2 +-
 app/api/roles/put.js                          |   2 +-
 .../user-fields-display-settings/delete.js    |  12 +-
 app/api/user-fields-display-settings/get.js   |  23 ++--
 app/api/user-fields-display-settings/post.js  |   9 +-
 app/api/user-fields-display-settings/put.js   |   9 +-
 app/api/user-requests/delete.js               |   2 +-
 app/api/user-requests/get.js                  |   2 +-
 app/api/user-requests/post.js                 |   2 +-
 app/api/user-search-history/delete.js         |   2 +-
 app/api/user-search-history/get.js            |   2 +-
 app/api/user-search-history/post.js           |   2 +-
 app/api/users/delete.js                       |   2 +-
 app/api/users/get.js                          |   2 +-
 app/api/users/post.js                         |   2 +-
 app/api/users/put.js                          |   2 +-
 app/dal/userFieldsDisplaySettingsService.js   | 128 ++++++++----------
 app/middlewares/errorHandler.js               |  20 +++
 app/utils/{format.js => logger.js}            |   4 +-
 server.js                                     |  52 +++----
 39 files changed, 154 insertions(+), 191 deletions(-)
 create mode 100644 app/middlewares/errorHandler.js
 rename app/utils/{format.js => logger.js} (99%)

diff --git a/app/api/group/delete.js b/app/api/group/delete.js
index 90521fb..7a0949f 100644
--- a/app/api/group/delete.js
+++ b/app/api/group/delete.js
@@ -1,8 +1,7 @@
 'use strict'
 
 const groupService = require('../../dal/groupService')
-
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const Group = {
@@ -43,9 +42,8 @@ const Group = {
     },
 }
 
-
 module.exports = {
-    deleteGroup : Group.deleteGroup, 
+    deleteGroup : Group.deleteGroup,
     deleteGroupPolicy: Group.deleteGroupPolicy,
     deleteGroupUser: Group.deleteGroupUser
-}
\ No newline at end of file
+}
diff --git a/app/api/group/get.js b/app/api/group/get.js
index d380c10..c5ff2eb 100644
--- a/app/api/group/get.js
+++ b/app/api/group/get.js
@@ -2,7 +2,7 @@
 
 const groupService = require('../../dal/groupService')
 
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const Group = {
@@ -45,7 +45,7 @@ const Group = {
 }
 
 module.exports = {
-    groups: Group.groups, 
+    groups: Group.groups,
     groupPolicies: Group.groupPolicies,
     groupUsers: Group.groupUsers,
-}
\ No newline at end of file
+}
diff --git a/app/api/group/post.js b/app/api/group/post.js
index 76f4e17..8643637 100644
--- a/app/api/group/post.js
+++ b/app/api/group/post.js
@@ -2,7 +2,7 @@
 
 const groupService = require('../../dal/groupService')
 
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const Group = {
@@ -43,6 +43,6 @@ const Group = {
 
 module.exports = {
     createGroup: Group.createGroup,
-    createGroupPolicy: Group.createGroupPolicy, 
-    createGroupUser: Group.createGroupUser, 
-}
\ No newline at end of file
+    createGroupPolicy: Group.createGroupPolicy,
+    createGroupUser: Group.createGroupUser,
+}
diff --git a/app/api/group/update.js b/app/api/group/update.js
index 880fffb..09ea4d1 100644
--- a/app/api/group/update.js
+++ b/app/api/group/update.js
@@ -2,7 +2,7 @@
 
 const groupService = require('../../dal/groupService')
 
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const Group = {
diff --git a/app/api/index.js b/app/api/index.js
index e93fb17..1c73cac 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -47,10 +47,10 @@ routers.delete('/user/delete-history', searchHistoryHandler.deleteH);
 
 // User fields display settings
 routers.post('/user/fields-display-settings/', /* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.createUserFieldsDisplaySettings);
-routers.get('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUsersFieldsDisplaySettings);
 routers.get('/user/fields-display-settings/:userId',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUserFieldsDisplaySettings);
+routers.get('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.findUsersFieldsDisplaySettings);
 routers.put('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.updateUserFieldsDisplaySettings);
-routers.delete('/user/fields-display-settings/',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.deleteUserFieldsDisplaySettings);
+routers.delete('/user/fields-display-settings/:userId',/* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.deleteUserFieldsDisplaySettings);
 
 // User requests
 routers.post('/user/create-request', userRequestHandler.createRequest);
diff --git a/app/api/policy/delete.js b/app/api/policy/delete.js
index 5b7b3e3..2865466 100644
--- a/app/api/policy/delete.js
+++ b/app/api/policy/delete.js
@@ -2,7 +2,7 @@
 
 const policyService = require('../../dal/policyService')
 
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const Policy = {
@@ -35,4 +35,4 @@ const Policy = {
 module.exports = {
     deletePolicy: Policy.deletePolicy,
     deletePolicyField: Policy.deletePolicyField
-}
\ No newline at end of file
+}
diff --git a/app/api/policy/get.js b/app/api/policy/get.js
index b73c29d..9a77a0e 100644
--- a/app/api/policy/get.js
+++ b/app/api/policy/get.js
@@ -2,7 +2,7 @@
 
 const policyService = require('../../dal/policyService')
 
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const Policy = {
@@ -74,4 +74,4 @@ module.exports = {
     assignedPolicies: Policy.assignedPolicies,
     getPoliciesWithSources: Policy.getPoliciesWithSources,
     getGroupDetailsByPolicy: Policy.getGroupDetailsByPolicy
-}
\ No newline at end of file
+}
diff --git a/app/api/policy/post.js b/app/api/policy/post.js
index 41a26e1..ba78615 100644
--- a/app/api/policy/post.js
+++ b/app/api/policy/post.js
@@ -2,7 +2,7 @@
 
 const policyService = require('../../dal/policyService')
 
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const Policy = {
@@ -74,4 +74,4 @@ module.exports = {
     createPolicy: Policy.createPolicy,
     createPolicyField: Policy.createPolicyField,
     createPolicySource: Policy.createPolicySource
-}
\ No newline at end of file
+}
diff --git a/app/api/policy/update.js b/app/api/policy/update.js
index de97cfe..141bb6f 100644
--- a/app/api/policy/update.js
+++ b/app/api/policy/update.js
@@ -2,7 +2,7 @@
 
 const policyService = require('../../dal/policyService')
 
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 
@@ -36,4 +36,4 @@ const Policy = {
 module.exports = {
     updatePolicy: Policy.updatePolicy,
     updatePolicyField: Policy.updatePolicyField,
-}
\ No newline at end of file
+}
diff --git a/app/api/realm/delete.js b/app/api/realm/delete.js
index 7549275..b6b49ba 100644
--- a/app/api/realm/delete.js
+++ b/app/api/realm/delete.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const realmService = require('../../dal/realmService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const DeleteRealm = {
diff --git a/app/api/realm/get.js b/app/api/realm/get.js
index e360853..cdef5b9 100644
--- a/app/api/realm/get.js
+++ b/app/api/realm/get.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const realmService = require('../../dal/realmService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const GetRealm = {
diff --git a/app/api/realm/post.js b/app/api/realm/post.js
index b27dd6e..d60ac09 100644
--- a/app/api/realm/post.js
+++ b/app/api/realm/post.js
@@ -1,7 +1,7 @@
 "use strict"
 
 const realmService = require("../../dal/realmService")
-const logger = require("../../utils/format")
+const logger = require("../../utils/logger")
 const util = require('util')
 
 const AddRealm = {
diff --git a/app/api/realm/put.js b/app/api/realm/put.js
index 8a4b28b..adfa37c 100644
--- a/app/api/realm/put.js
+++ b/app/api/realm/put.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const realmService = require("../../dal/realmService");
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const UpdateRealm = {
diff --git a/app/api/role-user/delete.js b/app/api/role-user/delete.js
index 618849b..5189913 100644
--- a/app/api/role-user/delete.js
+++ b/app/api/role-user/delete.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/format")
+const logger = require("../../utils/logger")
 const util = require('util')
 
 
diff --git a/app/api/role-user/get.js b/app/api/role-user/get.js
index cc3d513..19d7ee5 100644
--- a/app/api/role-user/get.js
+++ b/app/api/role-user/get.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/format")
+const logger = require("../../utils/logger")
 const util = require('util')
 
 const GetAllocatedRole = {
diff --git a/app/api/role-user/post.js b/app/api/role-user/post.js
index 26313ab..11dbccb 100644
--- a/app/api/role-user/post.js
+++ b/app/api/role-user/post.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/format")
+const logger = require("../../utils/logger")
 const util = require('util')
 
 const AllocateRoleToUser = {
diff --git a/app/api/role-user/put.js b/app/api/role-user/put.js
index dbd82d8..f7d7ef0 100644
--- a/app/api/role-user/put.js
+++ b/app/api/role-user/put.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/format")
+const logger = require("../../utils/logger")
 const util = require('util')
 
 const UpdateAllocatedRole = {
diff --git a/app/api/roles/delete.js b/app/api/roles/delete.js
index a1c80fc..de2c2c3 100644
--- a/app/api/roles/delete.js
+++ b/app/api/roles/delete.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleService = require('../../dal/roleService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const DeleteRole = {
diff --git a/app/api/roles/get.js b/app/api/roles/get.js
index b92913d..9f38b47 100644
--- a/app/api/roles/get.js
+++ b/app/api/roles/get.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleService = require("../../dal/roleService")
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const GetRole = {
diff --git a/app/api/roles/post.js b/app/api/roles/post.js
index 230c2ff..19f1311 100644
--- a/app/api/roles/post.js
+++ b/app/api/roles/post.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleService = require("../../dal/roleService")
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const AddRole = {
diff --git a/app/api/roles/put.js b/app/api/roles/put.js
index 5338694..4996aa9 100644
--- a/app/api/roles/put.js
+++ b/app/api/roles/put.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const roleService = require('../../dal/roleService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const UpdateRole = {
diff --git a/app/api/user-fields-display-settings/delete.js b/app/api/user-fields-display-settings/delete.js
index f1ec286..743ae4a 100644
--- a/app/api/user-fields-display-settings/delete.js
+++ b/app/api/user-fields-display-settings/delete.js
@@ -1,20 +1,16 @@
 'use strict'
 
 const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
-const logger = require('../../utils/format');
-const util = require('util');
-const {updateUserFieldsDisplaySettings} = require("./put");
+const logger = require('../../utils/logger');
 
 const UserFieldsDisplaySettings = {
     async delete(ctx) {
         try {
-            ctx.body = await userFieldsDisplaySettingsService.delete(ctx.request.body);
+            ctx.body = await userFieldsDisplaySettingsService.delete(ctx.request.params);
             ctx.status = 201;
             logger.info('User fields display settings deleted.');
-        } catch (err) {
-            ctx.body = err || 'An error occurred.';
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        } catch (error) {
+            throw error;
         }
     }
 }
diff --git a/app/api/user-fields-display-settings/get.js b/app/api/user-fields-display-settings/get.js
index 18e04bb..e8b08ef 100644
--- a/app/api/user-fields-display-settings/get.js
+++ b/app/api/user-fields-display-settings/get.js
@@ -1,31 +1,26 @@
 "use strict";
 
-const logger = require('../../utils/format')
-const util = require('util')
+const logger = require('../../utils/logger')
 const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
 
 const GetUserFieldsDisplaySettings = {
     async find(ctx) {
         try {
-            ctx.body = await userFieldsDisplaySettingsService.usersFieldsDisplaySettings(ctx.request.body);
+            ctx.body = await userFieldsDisplaySettingsService.usersFieldsDisplaySettings();
             ctx.status = 201;
             logger.info('Users fields display settings retrieved.');
-        } catch (err) {
-            ctx.body = err || 'An error occurred.';
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        } catch (error) {
+            throw error;
         }
     },
 
     async findOne(ctx) {
         try {
-            ctx.body = await userFieldsDisplaySettingsService.userFieldsDisplaySettings(ctx.request.body)
-            ctx.status = 201
-            logger.info('User fields display settings retrieved.')
-        } catch (err) {
-            ctx.body = err || 'An error occurred.'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userFieldsDisplaySettingsService.userFieldsDisplaySettings(ctx.request.params);
+            ctx.status = 201;
+            logger.info('User fields display settings retrieved.');
+        } catch (error) {
+            throw error;
         }
     },
 };
diff --git a/app/api/user-fields-display-settings/post.js b/app/api/user-fields-display-settings/post.js
index 556304c..2b0075b 100644
--- a/app/api/user-fields-display-settings/post.js
+++ b/app/api/user-fields-display-settings/post.js
@@ -1,8 +1,7 @@
 'use strict'
 
 const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
-const logger = require('../../utils/format')
-const util = require('util')
+const logger = require('../../utils/logger')
 
 const CreateUserFieldsDisplaySettings = {
     async create(ctx) {
@@ -10,10 +9,8 @@ const CreateUserFieldsDisplaySettings = {
             ctx.body = await userFieldsDisplaySettingsService.create(ctx.request.body);
             ctx.status = 201;
             logger.info('User fields display settings created.');
-        } catch (err) {
-            ctx.body = err || 'An error occurred.';
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        } catch (error) {
+            throw error;
         }
     },
 }
diff --git a/app/api/user-fields-display-settings/put.js b/app/api/user-fields-display-settings/put.js
index 1e2d7de..066f593 100644
--- a/app/api/user-fields-display-settings/put.js
+++ b/app/api/user-fields-display-settings/put.js
@@ -1,8 +1,7 @@
 'use strict'
 
 const userFieldsDisplaySettingsService = require("../../dal/userFieldsDisplaySettingsService");
-const logger = require('../../utils/format');
-const util = require('util');
+const logger = require('../../utils/logger');
 
 const UpdateUserFieldsDisplaySettings = {
     async update(ctx) {
@@ -10,10 +9,8 @@ const UpdateUserFieldsDisplaySettings = {
             ctx.body = await userFieldsDisplaySettingsService.update(ctx.request.body);
             ctx.status = 201;
             logger.info('User fields display settings updated.');
-        } catch (err) {
-            ctx.body = err || 'An error occurred.';
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`);
+        } catch (error) {
+            throw error;
         }
     }
 }
diff --git a/app/api/user-requests/delete.js b/app/api/user-requests/delete.js
index 3723d10..170ecf5 100644
--- a/app/api/user-requests/delete.js
+++ b/app/api/user-requests/delete.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const userRequestService = require('../../dal/userRequestService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const UserRequest = {
diff --git a/app/api/user-requests/get.js b/app/api/user-requests/get.js
index 18bd98c..cd0e420 100644
--- a/app/api/user-requests/get.js
+++ b/app/api/user-requests/get.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const userRequestService = require('../../dal/userRequestService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const UserRequest = {
diff --git a/app/api/user-requests/post.js b/app/api/user-requests/post.js
index c1b3ef2..3644ebf 100644
--- a/app/api/user-requests/post.js
+++ b/app/api/user-requests/post.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const userRequestService = require('../../dal/userRequestService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const UserRequest = {
diff --git a/app/api/user-search-history/delete.js b/app/api/user-search-history/delete.js
index fb2ad03..e483e80 100644
--- a/app/api/user-search-history/delete.js
+++ b/app/api/user-search-history/delete.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const searchHistoryService = require('../../dal/searchHistoryService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const SearchHistory = {
diff --git a/app/api/user-search-history/get.js b/app/api/user-search-history/get.js
index 33e150e..7ecb996 100644
--- a/app/api/user-search-history/get.js
+++ b/app/api/user-search-history/get.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const searchHistoryService = require('../../dal/searchHistoryService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const SearchHistory = {
diff --git a/app/api/user-search-history/post.js b/app/api/user-search-history/post.js
index c31879d..30b21c4 100644
--- a/app/api/user-search-history/post.js
+++ b/app/api/user-search-history/post.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const searchHistoryService = require('../../dal/searchHistoryService')
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const SearchHistory = {
diff --git a/app/api/users/delete.js b/app/api/users/delete.js
index ceaf0ad..609c696 100644
--- a/app/api/users/delete.js
+++ b/app/api/users/delete.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const userService = require("../../dal/userService")
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const DeleteUser = {
diff --git a/app/api/users/get.js b/app/api/users/get.js
index 7f73c7c..d998078 100644
--- a/app/api/users/get.js
+++ b/app/api/users/get.js
@@ -1,7 +1,7 @@
 "use strict";
 
 const userService = require("../../dal/userService");
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const GetUser = {
diff --git a/app/api/users/post.js b/app/api/users/post.js
index 5679838..9acf501 100644
--- a/app/api/users/post.js
+++ b/app/api/users/post.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const userService = require("../../dal/userService")
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const AddUser = {
diff --git a/app/api/users/put.js b/app/api/users/put.js
index 74a19f1..b7b7322 100644
--- a/app/api/users/put.js
+++ b/app/api/users/put.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const userService = require("../../dal/userService")
-const logger = require('../../utils/format')
+const logger = require('../../utils/logger')
 const util = require('util')
 
 const UpdateUser = {
diff --git a/app/dal/userFieldsDisplaySettingsService.js b/app/dal/userFieldsDisplaySettingsService.js
index 49ef158..9bdb345 100644
--- a/app/dal/userFieldsDisplaySettingsService.js
+++ b/app/dal/userFieldsDisplaySettingsService.js
@@ -1,7 +1,6 @@
 "use strict"
 
 const {UserFieldsDisplaySettings} = require("../models/UserFieldsDisplaySettings");
-const userService = require("./userService");
 
 /*
   userFieldsDisplaySettingsService
@@ -14,23 +13,16 @@ const userFieldsDisplaySettingsService = {
   // userId: id of the user
   // stdFieldsIds: array of ids of fields selected by user
   async create(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("Empty request body.");
-      } else if (!ctx.userId) {
-        throw Error("Required parameter userId is missing.");
-      } else if (!ctx.stdFieldsIds) {
-        throw Error("Required parameter stdFieldsIds is missing.");
-      }
-      // Check if user exists
-      const user = await userService.user({id: userId});
-      console.log(user);
-      if (!user) {
-        throw Error("User does not exists.");
+      if (!ctx || !ctx.userId || !ctx.stdFieldsIds) {
+        const error = new Error("Required parameters are missing.");
+        error.status = 400;
+        throw error;
       }
       // Check if all fields ids exists
       if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) {
-        throw new Error("One or more std_field_id do not exists.");
+        const error = new Error("One or more std_field_id do not exists.");
+        error.status = 400;
+        throw error;
       }
       // Insert new row in user settings table
       const [newUserFieldsSettings, isCreated] = await UserFieldsDisplaySettings.findOrCreate({
@@ -39,94 +31,80 @@ const userFieldsDisplaySettingsService = {
           std_fields_ids: ctx.stdFieldsIds,
         },
       });
-      console.log(isCreated);
-      console.log(newUserFieldsSettings);
       if (!isCreated) {
-        throw new Error("User settings row already exists.");
+        const error = new Error("User fields display settings already exists.");
+        error.status = 400;
+        throw error;
       }
-      return { userFieldsDisplaySettings: newUserFieldsSettings, status: 201 };
-    } catch (error) {
-      throw new Error(error);
-    }
+      return { newUserFieldsSettings, status: 201 };
   },
 
   // GET all users fields settings
-  async usersFieldsDisplaySettings(ctx) {
-    try {
-      return await UserFieldsDisplaySettings.findAll({});
-    }
-    catch (err) {
-      ctx.status = err.status || 500;
-      ctx.body = err.message;
-      throw Error(err);
-    }
+  async usersFieldsDisplaySettings() {
+    return await UserFieldsDisplaySettings.findAll({});
   },
 
   // GET single user settings
   // userId: id of the user
   async userFieldsDisplaySettings(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("Empty request body.");
-      } else if (!ctx.userId) {
-        throw Error("Required parameter userId is missing.");
-      }
-      return await UserFieldsDisplaySettings.findOne({ where: { user_id: ctx.userId } });
-    } catch (err) {
-      ctx.status = err.status || 500;
-      ctx.body = err.message;
-      throw Error(err);
+    if (!ctx || !ctx.userId) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
+    }
+    const result = await UserFieldsDisplaySettings.findOne({ where: { user_id: ctx.userId } });
+    if (!result) {
+      const error = new Error("No settings found for this userId.");
+      error.status = 404;
+      throw error;
     }
+    return result;
   },
 
   // PUT update a user settings
   // userId: id of the user
   // stdFieldsIds: new array of all fields ids
   async update(ctx) {
-    if (!ctx) {
-      throw Error("Empty request body.");
-    } else if (!ctx.userId) {
-      throw Error("Required parameter userId is missing.");
-    } else if (!ctx.stdFieldsIds) {
-      throw Error("Required parameter stdFieldsIds is missing.");
-    }
-    // Check if user exists
-    const user = await userService.user({id: userId});
-    console.log(user);
-    if (!user) {
-      throw Error("User does not exists.");
+    if (!ctx || !ctx.userId || !ctx.stdFieldsIds) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
     }
     // Check if all fields ids exists
     if (!await UserFieldsDisplaySettings.validateStdFieldIds(ctx.stdFieldsIds)) {
-      throw new Error("One or more std_field_id do not exists.");
+      const error = new Error("One or more std_field_id do not exists.");
+      error.status = 400;
+      throw error;
     }
-    return await UserFieldsDisplaySettings.update({
+    const [updatedCount, updatedRows] = await UserFieldsDisplaySettings.update({
       std_fields_ids: ctx.stdFieldsIds,
-    }, {
-      where: {
-        user_id: userId
-      }
-    });
+    }, { where: { user_id: ctx.userId }});
+    if (updatedCount === 0) {
+      const error = new Error("No settings found for this userId.");
+      error.status = 404;
+      throw error;
+    }
+    return updatedRows ? updatedRows[0] : 'User fields display settings updated.';
   },
 
   // DELETE the user settings
   async delete(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("Empty request body.");
-      } else if (!ctx.userId) {
-        throw Error("Required parameter userId is missing.");
+    if (!ctx || !ctx.userId) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
+    }
+    const deletedCount = await UserFieldsDisplaySettings.destroy({
+      where: {
+        user_id: ctx.userId
       }
-      return await UserFieldsDisplaySettings.destroy({
-        where: {
-          user_id: userId
-        }
-      });
-    } catch (error) {
-      ctx.status = error.status || 500;
-      ctx.body = error.message;
-      throw Error(error);
+    });
+    if (deletedCount === 0) {
+      const error = new Error("No settings found for this userId.");
+      error.status = 404;
+      throw error;
     }
+    return 'User fields display settings deleted.';
   },
 }
 
diff --git a/app/middlewares/errorHandler.js b/app/middlewares/errorHandler.js
new file mode 100644
index 0000000..f360c03
--- /dev/null
+++ b/app/middlewares/errorHandler.js
@@ -0,0 +1,20 @@
+const logger = require("../utils/logger");
+
+/*
+ * Global error handler middleware
+ *
+ * - Catches and handles all errors thrown within services, handlers, and routes.
+ * - Logs error details for debugging and monitoring.
+ * - Ensures the application does not crash on unhandled errors.
+ */
+const errorHandler = async (ctx, next) => {
+    try {
+        await next();
+    } catch (err) {
+        logger.error(err.message);
+        ctx.status = err.status || 500;
+        ctx.body = err.message || "Internal Server Error";
+    }
+};
+
+module.exports = errorHandler;
diff --git a/app/utils/format.js b/app/utils/logger.js
similarity index 99%
rename from app/utils/format.js
rename to app/utils/logger.js
index 118da74..9d10265 100644
--- a/app/utils/format.js
+++ b/app/utils/logger.js
@@ -27,7 +27,5 @@ const logger = createLogger({
         )
     ]
 });
-module.exports = logger;
-
-
 
+module.exports = logger;
diff --git a/server.js b/server.js
index b41eca1..62fdcb4 100644
--- a/server.js
+++ b/server.js
@@ -1,55 +1,39 @@
 'use strict'
 
-const Koa = require('koa')
-const logger = require('winston')
-const api = require('./app/api')
-const koaLogger = require('koa-logger')
-const cors = require('koa2-cors')
+const Koa = require('koa');
+const api = require('./app/api');
+const koaLogger = require('koa-logger');
+const cors = require('koa2-cors');
 const { keycloak } = require('./init-keycloak');
+const errorHandler = require('./app/middlewares/errorHandler');
 
-async function responseTime(ctx, next) {
+const responseTime = async (ctx, next) => {
     const start = Date.now();
     await next();
     const ms = Date.now() - start;
     ctx.set('X-Response-Time', `${ms}ms`);
 }
 
-const app = new Koa()
+const app = new Koa();
 
-app.proxy = false
+app.use(errorHandler);
 
 const middlewares = keycloak.middleware({
     logout: '/logout',
     admin: '/',
     protected: '/protected/resource'
-})
-
+});
 middlewares.forEach(function (middleware) {
     app.use(middleware);
 })
 
-app
-    .use(cors({
-        origin: '*'
-    }))
-    .use(koaLogger())
-    .use(function (ctx, next) {
-        return next().catch((err) => {
-            if (err) {
-                // Protected resource, use Authorization header to get access\n
-                console.log(err)
-                ctx.status = 401
-                ctx.body = err
-            }
-        })
-    })
-    .use(api.routes())
-    .use(api.allowedMethods())
-    .use(responseTime)
-
-app.on('error', (err) => {
-    logger.error('Server error', { error: err.message })
-    throw err
-})
+app.proxy = false;
+app.use(cors({origin: '*'}));
+app.use(koaLogger());
+app.use(responseTime);
+
+// Register routes
+app.use(api.routes());
+app.use(api.allowedMethods());
 
-module.exports = app
+module.exports = app;
-- 
GitLab


From 802170eff2cddd8a0e0e8b8351a9a85c54f24fd1 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Thu, 21 Nov 2024 11:02:31 +0100
Subject: [PATCH 05/13] [web.js] corrected logger import

---
 web.js | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/web.js b/web.js
index f714d79..2ed23e2 100644
--- a/web.js
+++ b/web.js
@@ -1,21 +1,17 @@
 'use strict'
 
-const { promisify } = require('util')
-const http = require('http')
-const logger = require('winston')
-const app = require('./server')
-const config = require('./app/config/server')
+const { promisify } = require('util');
+const http = require('http');
+const app = require('./server');
+const config = require('./app/config/server');
+const logger = require("./app/utils/logger");
 
-logger.level = config.logger.level
+const server = http.createServer(app.callback());
+const serverListen = promisify(server.listen).bind(server);
 
-const server = http.createServer(app.callback())
-const serverListen = promisify(server.listen).bind(server)
-
-serverListen(config.port)
-    .then(() => {
-        logger.info(`in-sylva.gatekeeper service is up and running on localhost:${config.port}`)
-    })
-    .catch((err) => {
-        logger.error(err)
-        process.exit(1)
-    })
+serverListen(config.port).then(() => {
+        logger.info(`in-sylva.gatekeeper service is up and running on localhost:${config.port}`);
+    }).catch((error) => {
+        logger.error(error);
+        process.exit(1);
+    });
-- 
GitLab


From 5a052ed67eb8c7cb5f58e34681d7752940ab1379 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Thu, 21 Nov 2024 16:43:41 +0100
Subject: [PATCH 06/13] [groups] now following new error handling ; improved
 some logic

---
 app/api/group/delete.js |  39 +++++------
 app/api/group/get.js    |  41 +++++------
 app/api/group/index.js  |  13 ++--
 app/api/group/post.js   |  42 +++++------
 app/api/group/update.js |  40 +++++------
 app/dal/groupService.js | 151 ++++++++++++++++++++++------------------
 6 files changed, 157 insertions(+), 169 deletions(-)

diff --git a/app/api/group/delete.js b/app/api/group/delete.js
index 7a0949f..5a8c7cd 100644
--- a/app/api/group/delete.js
+++ b/app/api/group/delete.js
@@ -1,49 +1,42 @@
 'use strict'
 
-const groupService = require('../../dal/groupService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const groupService = require('../../dal/groupService');
+const logger = require('../../utils/logger');
 
 const Group = {
     async deleteGroup(ctx) {
         try {
-            ctx.body = await groupService.deleteGroup(ctx.request.body)
-            ctx.status = 201
-            logger.info('group is deleted successfully!')
+            ctx.body = await groupService.deleteGroup(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group deleted.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async deleteGroupPolicy(ctx) {
         try {
-            ctx.body = await groupService.deleteGroupPolicy(ctx.request.body)
-            ctx.status = 201
-            logger.info('GroupPolicy is deleted successfully!')
+            ctx.body = await groupService.deleteGroupPolicy(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group policy deleted.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async deleteGroupUser(ctx) {
         try {
-            ctx.body = await groupService.deleteGroupUser(ctx.request.body)
-            ctx.status = 201
-            logger.info('GroupUser is deleted successfully!')
+            ctx.body = await groupService.deleteGroupUser(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group user deleted.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
-}
+};
 
 module.exports = {
     deleteGroup : Group.deleteGroup,
     deleteGroupPolicy: Group.deleteGroupPolicy,
     deleteGroupUser: Group.deleteGroupUser
-}
+};
diff --git a/app/api/group/get.js b/app/api/group/get.js
index c5ff2eb..8a99ad0 100644
--- a/app/api/group/get.js
+++ b/app/api/group/get.js
@@ -1,51 +1,42 @@
 'use strict'
 
-const groupService = require('../../dal/groupService')
-
-const logger = require('../../utils/logger')
-const util = require('util')
+const groupService = require('../../dal/groupService');
+const logger = require('../../utils/logger');
 
 const Group = {
-
     async groups(ctx) {
         try {
-            ctx.body = await groupService.groups(ctx.request.body)
-            ctx.status = 201
-            logger.info('groups are fetched successfully!')
+            ctx.body = await groupService.groups();
+            ctx.status = 201;
+            logger.info('Groups fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async groupPolicies(ctx) {
         try {
-            ctx.body = await groupService.groupPolicies(ctx.request.body)
-            ctx.status = 201
-            logger.info('groupPolicies are fetched successfully!')
+            ctx.body = await groupService.groupPolicies();
+            ctx.status = 201;
+            logger.info('Group policies fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+           throw error;
         }
     },
 
     async groupUsers(ctx) {
         try {
-            ctx.body = await groupService.groupUsers(ctx.request.body)
-            ctx.status = 201
-            logger.info('groupUsers are fetched successfully!')
+            ctx.body = await groupService.groupUsers(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group users fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+           throw error;
         }
     }
-}
+};
 
 module.exports = {
     groups: Group.groups,
     groupPolicies: Group.groupPolicies,
     groupUsers: Group.groupUsers,
-}
+};
diff --git a/app/api/group/index.js b/app/api/group/index.js
index bb15fd2..32fb066 100644
--- a/app/api/group/index.js
+++ b/app/api/group/index.js
@@ -1,9 +1,10 @@
 'use strict'
 
-const { groups, groupUsers, groupPolicies } = require('./get')
-const { createGroup, createGroupPolicy, createGroupUser } = require('./post')
-const { deleteGroup, deleteGroupPolicy, deleteGroupUser } = require('./delete')
-const { updateGroup, updateGroupPolicy, updateGroupUser } = require('./update')
+const { groups, groupUsers, groupPolicies } = require('./get');
+const { createGroup, createGroupPolicy, createGroupUser } = require('./post');
+const { deleteGroup, deleteGroupPolicy, deleteGroupUser } = require('./delete');
+const { updateGroup, updateGroupPolicy, updateGroupUser } = require('./update');
+
 const GroupHandler = {
     groups,
     groupUsers,
@@ -17,6 +18,6 @@ const GroupHandler = {
     updateGroup,
     updateGroupPolicy,
     updateGroupUser
-}
+};
 
-module.exports = GroupHandler
\ No newline at end of file
+module.exports = GroupHandler;
diff --git a/app/api/group/post.js b/app/api/group/post.js
index 8643637..dd0a5b5 100644
--- a/app/api/group/post.js
+++ b/app/api/group/post.js
@@ -1,48 +1,42 @@
 'use strict'
 
-const groupService = require('../../dal/groupService')
-
-const logger = require('../../utils/logger')
-const util = require('util')
+const groupService = require('../../dal/groupService');
+const logger = require('../../utils/logger');
 
 const Group = {
     async createGroup(ctx) {
         try {
-            ctx.body = await groupService.createGroup(ctx.request.body)
-            ctx.status = 201
-            logger.info('group created successfully!')
+            ctx.body = await groupService.createGroup(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group created.');
         } catch (error) {
-            ctx.body = error || 'error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
+
     async createGroupPolicy(ctx) {
         try {
-            ctx.body = await groupService.createGroupPolicy(ctx.request.body)
-            ctx.status = 201
-            logger.info('GroupPolicy created successfully!')
+            ctx.body = await groupService.createGroupPolicy(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Assigned policy to group.');
         } catch (error) {
-            ctx.body = error || 'error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
+
     async createGroupUser(ctx) {
         try {
-            ctx.body = await groupService.createGroupUser(ctx.request.body)
-            ctx.status = 201
-            logger.info('GroupUser created successfully!')
+            ctx.body = await groupService.createGroupUser(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Assigned user to group.');
         } catch (error) {
-            ctx.body = error || 'error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     createGroup: Group.createGroup,
     createGroupPolicy: Group.createGroupPolicy,
     createGroupUser: Group.createGroupUser,
-}
+};
diff --git a/app/api/group/update.js b/app/api/group/update.js
index 09ea4d1..6241040 100644
--- a/app/api/group/update.js
+++ b/app/api/group/update.js
@@ -1,50 +1,42 @@
 'use strict'
 
-const groupService = require('../../dal/groupService')
-
-const logger = require('../../utils/logger')
-const util = require('util')
+const groupService = require('../../dal/groupService');
+const logger = require('../../utils/logger');
 
 const Group = {
     async updateGroup(ctx) {
         try {
-            ctx.body = await groupService.updateGroup(ctx.request.body)
-            ctx.status = 201
-            logger.info('group is updated successfully!')
+            ctx.body = await groupService.updateGroup(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group updated.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async updateGroupPolicy(ctx) {
         try {
-            ctx.body = await groupService.updateGroupPolicy(ctx.request.body)
-            ctx.status = 201
-            logger.info('GroupPolicy is updated successfully!')
+            ctx.body = await groupService.updateGroupPolicy(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group policy updated.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async updateGroupUser(ctx) {
         try {
-            ctx.body = await groupService.updateGroupUser(ctx.request.body)
-            ctx.status = 201
-            logger.info('GroupUser is updated successfully!')
+            ctx.body = await groupService.updateGroupUser(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group user updated.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
-}
+};
 
 module.exports = {
     updateGroup: Group.updateGroup,
     updateGroupPolicy: Group.updateGroupPolicy,
     updateGroupUser: Group.updateGroupUser,
-}
+};
diff --git a/app/dal/groupService.js b/app/dal/groupService.js
index 6d27ca6..d2a6b17 100644
--- a/app/dal/groupService.js
+++ b/app/dal/groupService.js
@@ -6,37 +6,40 @@ const db = require('../../db')
 
 const GroupService = {
     async createGroup(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
-        }
-        if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.");
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const user = await userService.detail({ kcId: ctx.kcId });
-        if (user) {
-            const group = await Group.findOne({
-                where: {
-                    name: ctx.name,
-                    user_id: user.id,
-                }
-            });
-            if (group) {
-                throw Error(`This name:${ctx.name} and userId:${user.id} already inserted to database!`);
-            } else {
-                return await Group.create({
-                    name: ctx.name,
-                    description: ctx.description,
-                    user_id: user.id,
-                });
-            }
-        } else {
-            throw Error('User account not found.');
+        if (!user) {
+            const error = new Error("User account not found.");
+            error.status = 400;
+            throw error;
         }
+        const [newGroup, isCreated] = await Group.findOrCreate(
+            {
+            where: {
+                name: ctx.name,
+                user_id: user.id,
+            },
+            defaults: {
+                description: ctx.description,
+            },
+        });
+        if (!isCreated) {
+            const error = new Error(`Group:${ctx.name} already exists.`);
+            error.status = 400;
+            throw error;
+        }
+        return newGroup;
     },
 
     async createGroupPolicy(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
+        if (!ctx || !ctx.groupId || !ctx.policyId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const groupPolicy = await GroupsPolicy.findOne({
             where: {
@@ -45,7 +48,9 @@ const GroupService = {
             }
         });
         if (groupPolicy) {
-            throw Error(`This groupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other!`);
+            const error = new Error(`GroupId:${ctx.groupId} and policyId:${ctx.policyId} already assigned to each other.`);
+            error.status = 400;
+            throw error;
         } else {
             return await GroupsPolicy.create({
                 group_id: ctx.groupId,
@@ -55,11 +60,10 @@ const GroupService = {
     },
 
     async createGroupUser(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
-        }
-        if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.");
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const user = await userService.detail({ kcId: ctx.kcId });
         if (user) {
@@ -70,7 +74,9 @@ const GroupService = {
                 }
             });
             if (groupUser) {
-                throw Error(`This groupId:${ctx.groupId} and userId:${ctx.user_id} already assigned to each other!`);
+                const error = new Error(`GroupId:${ctx.groupId} and userId:${user.id} already assigned to each other.`);
+                error.status = 400;
+                throw error;
             } else {
                 return await GroupUser.create({
                     group_id: ctx.groupId,
@@ -78,13 +84,17 @@ const GroupService = {
                 });
             }
         } else {
-            throw Error('The user account could not found.');
+            const error = new Error('User account not found.');
+            error.status = 400;
+            throw error;
         }
     },
 
     async updateGroup(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
+        if (!ctx || !ctx.name || !ctx.description || !ctx.id || !ctx.userId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await Group.update({
             name: ctx.name,
@@ -95,8 +105,10 @@ const GroupService = {
     },
 
     async updateGroupPolicy(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
+        if (!ctx || !ctx.groupId || !ctx.policyId || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await GroupsPolicy.update({
             group_id: ctx.groupId,
@@ -105,36 +117,41 @@ const GroupService = {
     },
 
     async updateGroupUser(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const user = await userService.detail({ kcId: ctx.kcId });
-        if (user) {
-            return await GroupUser.update({
-                group_id: ctx.groupId,
-                user_id: user.id
-            }, {where: {id: ctx.id}});
-        } else {
-            throw Error('The user account could not found.');
+        if (!user) {
+            const error = new Error("User account not found.");
+            error.status = 400;
+            throw error;
         }
+        return await GroupUser.update({
+            group_id: ctx.groupId,
+            user_id: user.id
+        }, {where: {id: ctx.id}});
     },
 
     async deleteGroup(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        if (ctx.id) {
-            return await Group.destroy({
-                where: {
-                    id: ctx.id
-                }
-            });
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
+        return await Group.destroy({
+            where: {
+                id: ctx.id
+            }
+        });
     },
 
     async deleteGroupPolicy(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await GroupsPolicy.destroy({
             where: {
@@ -144,15 +161,13 @@ const GroupService = {
     },
 
     async deleteGroupUser(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
+        if (!ctx || !ctx.groupId || !ctx.userId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const params = { groupId: ctx.groupId, userId: ctx.userId };
-        const groupUser = await db.raw(`
-              delete from group_users
-              where group_id = :groupId and user_id = :userId
-        `, params);
-        return groupUser;
+        return db.raw(`delete from group_users where group_id = :groupId and user_id = :userId`, params);
     },
 
     async groups() {
@@ -164,8 +179,10 @@ const GroupService = {
     },
 
     async groupUsers(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!");
+        if (!ctx || !ctx.groupId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const params = { groupId: ctx.groupId };
         const groupUsers = await db.raw(`
@@ -195,4 +212,4 @@ module.exports = {
     groups: GroupService.groups,
     groupPolicies: GroupService.groupPolicies,
     groupUsers: GroupService.groupUsers,
-}
+};
-- 
GitLab


From d5242545f6f94d25bff1278bfd41efafc66e5871 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Fri, 22 Nov 2024 10:48:31 +0100
Subject: [PATCH 07/13] [policies] now following new error handling ; improved
 some logic

---
 app/api/policy/delete.js |  31 +++---
 app/api/policy/get.js    |  61 +++++------
 app/api/policy/post.js   |  61 +++++------
 app/api/policy/update.js |  32 +++---
 app/dal/policyService.js | 227 ++++++++++++++++++++-------------------
 5 files changed, 186 insertions(+), 226 deletions(-)

diff --git a/app/api/policy/delete.js b/app/api/policy/delete.js
index 2865466..4a75dce 100644
--- a/app/api/policy/delete.js
+++ b/app/api/policy/delete.js
@@ -1,38 +1,31 @@
 'use strict'
 
-const policyService = require('../../dal/policyService')
-
-const logger = require('../../utils/logger')
-const util = require('util')
+const policyService = require('../../dal/policyService');
+const logger = require('../../utils/logger');
 
 const Policy = {
-
     async deletePolicy(ctx) {
         try {
-            ctx.body = await policyService.deletePolicy(ctx.request.body)
-            ctx.status = 201
-            logger.info('Policy is listed successfully!')
+            ctx.body = await policyService.deletePolicy(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Policy deleted.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async deletePolicyField(ctx) {
         try {
-            ctx.body = await policyService.deletePolicyField(ctx.request.body)
-            ctx.status = 201
-            logger.info('PolicyField is listed successfully!')
+            ctx.body = await policyService.deletePolicyField(ctx.request.body);
+            ctx.status = 201;
+            logger.info('PolicyField deleted.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     deletePolicy: Policy.deletePolicy,
     deletePolicyField: Policy.deletePolicyField
-}
+};
diff --git a/app/api/policy/get.js b/app/api/policy/get.js
index 9a77a0e..61abfad 100644
--- a/app/api/policy/get.js
+++ b/app/api/policy/get.js
@@ -1,72 +1,59 @@
 'use strict'
 
-const policyService = require('../../dal/policyService')
-
-const logger = require('../../utils/logger')
-const util = require('util')
+const policyService = require('../../dal/policyService');
+const logger = require('../../utils/logger');
 
 const Policy = {
-
     async policies(ctx) {
         try {
-            ctx.body = await policyService.policies(ctx.request.body)
-            ctx.status = 201
-            logger.info('Policy is listed successfully!')
+            ctx.body = await policyService.policies();
+            ctx.status = 201;
+            logger.info('Policies fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async policyFields(ctx) {
         try {
-            ctx.body = await policyService.policyFields(ctx.request.body)
-            ctx.status = 201
-            logger.info('PolicyField is listed successfully!')
+            ctx.body = await policyService.policyFields();
+            ctx.status = 201;
+            logger.info('Policy fields fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async assignedPolicies(ctx) {
         try {
-            ctx.body = await policyService.getAssignedPolicies(ctx.request.body)
-            ctx.status = 201
-            logger.info('assignedPolicies are listed successfully!')
+            ctx.body = await policyService.getAssignedPolicies(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Assigned policies fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async getPoliciesWithSources(ctx) {
         try {
-            ctx.body = await policyService.getPoliciesWithSources(ctx.request.body)
-            ctx.status = 201
-            logger.info('PoliciesWithSources are listed successfully!')
+            ctx.body = await policyService.getPoliciesWithSources();
+            ctx.status = 201;
+            logger.info('Policies with sources fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async getGroupDetailsByPolicy(ctx) {
         try {
-            ctx.body = await policyService.getGroupDetailsByPolicy(ctx.request.body)
-            ctx.status = 201
-            logger.info('Group Details by policy are listed successfully!')
+            ctx.body = await policyService.getGroupDetailsByPolicy(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Group details by policy fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     policies: Policy.policies,
@@ -74,4 +61,4 @@ module.exports = {
     assignedPolicies: Policy.assignedPolicies,
     getPoliciesWithSources: Policy.getPoliciesWithSources,
     getGroupDetailsByPolicy: Policy.getGroupDetailsByPolicy
-}
+};
diff --git a/app/api/policy/post.js b/app/api/policy/post.js
index ba78615..a04c6bb 100644
--- a/app/api/policy/post.js
+++ b/app/api/policy/post.js
@@ -1,72 +1,59 @@
 'use strict'
 
-const policyService = require('../../dal/policyService')
-
-const logger = require('../../utils/logger')
-const util = require('util')
+const policyService = require('../../dal/policyService');
+const logger = require('../../utils/logger');
 
 const Policy = {
-
     async createPolicy(ctx) {
         try {
-            ctx.body = await policyService.createPolicy(ctx.request.body)
-            ctx.status = 201
-            logger.info('Policy is created successfully!')
+            ctx.body = await policyService.createPolicy(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Policy created.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async createPolicyField(ctx) {
         try {
-            ctx.body = await policyService.createPolicyField(ctx.request.body)
-            ctx.status = 201
-            logger.info('PolicyField is created successfully!')
+            ctx.body = await policyService.createPolicyField(ctx.request.body);
+            ctx.status = 201;
+            logger.info('PolicyField created.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async createPolicySource(ctx) {
         try {
-            ctx.body = await policyService.createPolicySource(ctx.request.body)
-            ctx.status = 201
-            logger.info('PolicySource is created successfully!')
+            ctx.body = await policyService.createPolicySource(ctx.request.body);
+            ctx.status = 201;
+            logger.info('PolicySource created.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async policiesByUser(ctx) {
         try {
-            ctx.body = await policyService.policiesByUser(ctx.request.body)
-            ctx.status = 201
-            logger.info('Policies by user listed successfully!')
+            ctx.body = await policyService.policiesByUser(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Policies by user listed.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async getPoliciesWithSourcesByUser(ctx) {
         try {
-            ctx.body = await policyService.getPoliciesWithSourcesByUser(ctx.request.body)
-            ctx.status = 201
-            logger.info('Policies with sources by user listed successfully!')
+            ctx.body = await policyService.getPoliciesWithSourcesByUser(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Policies with sources by user listed.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     policiesByUser: Policy.policiesByUser,
@@ -74,4 +61,4 @@ module.exports = {
     createPolicy: Policy.createPolicy,
     createPolicyField: Policy.createPolicyField,
     createPolicySource: Policy.createPolicySource
-}
+};
diff --git a/app/api/policy/update.js b/app/api/policy/update.js
index 141bb6f..9afd22e 100644
--- a/app/api/policy/update.js
+++ b/app/api/policy/update.js
@@ -1,39 +1,31 @@
 'use strict'
 
-const policyService = require('../../dal/policyService')
-
-const logger = require('../../utils/logger')
-const util = require('util')
-
+const policyService = require('../../dal/policyService');
+const logger = require('../../utils/logger');
 
 const Policy = {
-
     async updatePolicy(ctx) {
         try {
-            ctx.body = await policyService.updatePolicy(ctx.request.body)
-            ctx.status = 201
-            logger.info('Policy is updated successfully!')
+            ctx.body = await policyService.updatePolicy(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Policy updated.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async updatePolicyField(ctx) {
         try {
-            ctx.body = await policyService.updatePolicyField(ctx.request.body)
-            ctx.status = 201
-            logger.info('PolicyField is updated successfully!')
+            ctx.body = await policyService.updatePolicyField(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Policy field updated.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     updatePolicy: Policy.updatePolicy,
     updatePolicyField: Policy.updatePolicyField,
-}
+};
diff --git a/app/dal/policyService.js b/app/dal/policyService.js
index 7488169..a101a67 100644
--- a/app/dal/policyService.js
+++ b/app/dal/policyService.js
@@ -1,95 +1,87 @@
 'use strict'
 
 const { Policy, PolicyField, PolicySource } = require('../models/Policy')
-
 const db = require('../../db');
 const userService = require('./userService')
 
 const PolicyService = {
-
     async createPolicy(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.")
+        const user = await userService.detail({ kcId: ctx.kcId });
+        if (!user) {
+            const error = new Error("User account not found.");
+            error.status = 400;
+            throw error;
         }
-        const user = await userService.detail({ kcId: ctx.kcId })
-        if (user) {
-            const policy = await Policy.findOne({
+        const [newPolicy, isCreated] = await Policy.findOrCreate(
+            {
                 where: {
                     name: ctx.name,
-                    // source_id: ctx.sourceId,
-                    user_id: user.id,
-                    is_default: false
-                }
-            })
-            if (policy) {
-                throw Error(`This Policy name:${ctx.name} and sourceId:${ctx.sourceId} already inserted to database!`)
-            } else {
-                return await Policy.create({
-                    name: ctx.name,
-                    // source_id: ctx.sourceId,
                     user_id: user.id,
+                },
+                defaults: {
                     is_default: false
-                })
-            }
-        } else {
-            throw Error('The user account could not found.')
+                },
+            });
+        if (!isCreated) {
+            const error = new Error(`Policy:${ctx.name} already exists.`);
+            error.status = 400;
+            throw error;
         }
+        return newPolicy;
     },
 
     async createPolicyField(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.policyId || !ctx.stdFieldId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        const { policyId, stdFieldId } = ctx
-
-        if (policyId && stdFieldId) {
-            const policyField = await PolicyField.findOne({
+        const [newPolicyField, isCreated] = await PolicyField.findOrCreate(
+            {
                 where: {
-                    policy_id: policyId,
-                    std_field_id: stdFieldId,
-                }
-            })
-            if (policyField) {
-                throw Error(`This policyId:${policyId} and stdFieldId:${stdFieldId} already assigned to each other in the database!`)
-            } else {
-                return await PolicyField.create({
-                    policy_id: policyId,
-                    std_field_id: stdFieldId,
-                })
-            }
+                    policy_id: ctx.policyId,
+                    std_field_id: ctx.stdFieldId,
+                },
+            });
+        if (!isCreated) {
+            const error = new Error("Policy and stdField already assigned to each other.");
+            error.status = 400;
+            throw error;
         }
+        return newPolicyField;
     },
 
     async createPolicySource(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.policyId || !ctx.sourceId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        const { policyId, sourceId } = ctx
-
-        if (policyId && sourceId) {
-            const policySource = await PolicySource.findOne({
+        const [newPolicySource, isCreated] = await PolicySource.findOrCreate(
+            {
                 where: {
-                    policy_id: policyId,
-                    source_id: sourceId,
-                }
-            })
-            if (policySource) {
-                throw Error(`This policyId:${policyId} and sourceId:${sourceId} already assigned to each other in the database!`)
-            } else {
-                return await PolicySource.create({
-                    policy_id: policyId,
-                    source_id: sourceId,
-                })
-            }
+                    policy_id: ctx.policyId,
+                    source_id: ctx.sourceId,
+                },
+            });
+        if (!isCreated) {
+            const error = new Error("Policy and source already assigned to each other.");
+            error.status = 400;
+            throw error;
         }
+        return newPolicySource;
     },
 
     async updatePolicySource(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id || !ctx.sourceId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await PolicySource.update({
             source_id: ctx.sourceId,
@@ -101,10 +93,12 @@ const PolicyService = {
     },
 
     async deletePolicySource(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        return await PolicySource.destroyi({
+        return await PolicySource.destroy({
             where: {
                 id: ctx.id
             }
@@ -112,13 +106,15 @@ const PolicyService = {
     },
 
     async updatePolicy(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id || !ctx.name || !ctx.sourceId || !ctx.isDefault) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await Policy.update({
             name: ctx.name,
             source_id: ctx.sourceId,
-            is_default: ctx.isDeafault
+            is_default: ctx.isDefault
         }, {
             where: {
                 id: ctx.id,
@@ -127,8 +123,10 @@ const PolicyService = {
     },
 
     async updatePolicyField(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id || !ctx.policyId || !ctx.stdFieldId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await PolicyField.update({
             policy_id: ctx.policyId,
@@ -141,62 +139,67 @@ const PolicyService = {
     },
 
     async deletePolicyField(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await PolicyField.destroy({
             where: {
                 id: ctx.id
             }
-        })
+        });
     },
 
     async deletePolicy(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const policyField = await PolicyField.destroy({
             where: {
                 policy_id: ctx.id
             }
-        })
+        });
         await Policy.destroy({
             where: {
                 id: ctx.id
             }
-        })
-        return policyField
+        });
+        return policyField;
     },
 
     async policies() {
-        return await Policy.findAll({})
+        return await Policy.findAll({});
     },
 
     async policiesByUser(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         try {
-            const params = { userId: ctx.kcId }
-            const policiesByUser = await db.raw(
-                `select DISTINCT p.id, p.name, p.user_id, p.source_id, u.kc_id from policies p
-          inner join users u  on p.user_id = u.id
-          where u.kc_id = :userId`, params)
-            return policiesByUser.rows
+            const params = { userId: ctx.kcId };
+            const policiesByUser = await db.raw(`select DISTINCT p.id, p.name, p.user_id, p.source_id, u.kc_id from policies p inner join users u  on p.user_id = u.id where u.kc_id = :userId`, params);
+            return policiesByUser.rows;
         } catch (error) {
-            throw new Error(error)
+            throw new Error(error);
         }
     },
 
     async policyFields() {
-        return await PolicyField.findAll({})
+        return await PolicyField.findAll({});
     },
 
     async getAssignedPolicies(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.policyId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        const params = { policyId: ctx.policyId }
+        const params = { policyId: ctx.policyId };
         const assignedPolicies = await db.raw(`
             select pf.id, sf.field_name, sf.definition_and_comment, sf.field_type, sf.values from policies p
             inner join policy_fields pf on p.id = pf.policy_id
@@ -204,15 +207,11 @@ const PolicyService = {
             inner join policy_sources ps on p.id = ps.policy_id
             inner join sources s on ps.source_id = s.id
             where p.id = :policyId
-        `, params)
-        return assignedPolicies.rows
+        `, params);
+        return assignedPolicies.rows;
     },
 
-    async getPoliciesWithSources(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        // remark: list all policies as usual, domain free
+    async getPoliciesWithSources() {
         const policiesWIthSource = await db.raw(`
             select p.id, p.name as policyName, s.name as sourceName from policies p
                 left join policy_sources ps on p.id = ps.policy_id
@@ -222,28 +221,32 @@ const PolicyService = {
     },
 
     async getPoliciesWithSourcesByUser(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         try {
-            const params = { userId: ctx.kcId }
+            const params = { userId: ctx.kcId };
             const policiesByUser = await db.raw(`
                 select p.id, p.name as policyName, s.name as sourceName, p.user_id, p.source_id, u.kc_id from policies p
                 inner join users u on p.user_id = u.id
                 left join policy_sources ps on p.id = ps.policy_id
                 left join sources s on ps.source_id = s.id
                 where u.kc_id = :userId`, params)
-            return policiesByUser.rows
+            return policiesByUser.rows;
         } catch (error) {
-            throw new Error(error)
+            throw new Error(error);
         }
     },
 
     async getGroupDetailsByPolicy(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.policyId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        const params = { policyId: ctx.policyId }
+        const params = { policyId: ctx.policyId };
         const groupDetailsByPolicy = await db.raw(`
             select p.id as policyId, g.id as groupId, gp.id groupPolicyId, g.name as group_name, g.description as group_description, s.name as source_name, s.description as source_description from policies p
             inner join groups_policies gp on p.id = gp.policy_id
@@ -251,12 +254,10 @@ const PolicyService = {
             left join policy_sources ps on p.id = ps.policy_id
             left join sources s on ps.source_id = s.id
             where p.id = :policyId
-        `, params)
-        return groupDetailsByPolicy.rows
+        `, params);
+        return groupDetailsByPolicy.rows;
     }
-
-}
-
+};
 
 module.exports = {
     createPolicy: PolicyService.createPolicy,
@@ -276,4 +277,4 @@ module.exports = {
     getPoliciesWithSources: PolicyService.getPoliciesWithSources,
     getPoliciesWithSourcesByUser: PolicyService.getPoliciesWithSourcesByUser,
     getGroupDetailsByPolicy: PolicyService.getGroupDetailsByPolicy,
-}
+};
-- 
GitLab


From 80d6c48be371b2d2a5bfe7264f0fc7d6ff705b18 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Fri, 22 Nov 2024 14:20:33 +0100
Subject: [PATCH 08/13] [roleAllocation] now following new error handling ;
 improved some logic

---
 app/api/index.js                 |  2 +-
 app/api/role-user/delete.js      | 26 ++++-----
 app/api/role-user/get.js         | 23 ++++----
 app/api/role-user/index.js       | 14 ++---
 app/api/role-user/post.js        | 25 ++++-----
 app/api/role-user/put.js         | 21 ++++----
 app/dal/roleAllocationService.js | 93 ++++++++++++++++----------------
 7 files changed, 94 insertions(+), 110 deletions(-)

diff --git a/app/api/index.js b/app/api/index.js
index 1c73cac..43be607 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -98,7 +98,7 @@ routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole);
 routers.put('/role/update', /* keycloak.protect(),*/ roleHandler.update);
 
 // Role allocation to users
-routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.allocateRole);
+routers.post('/allocate-role-to-user', /* keycloak.protect(),*/allocationRoleHandler.create);
 routers.post('/allocatedRoles', /* keycloak.protect(),*/allocationRoleHandler.allocatedRoles);
 routers.put('/allocatedRoles/update', /* keycloak.protect(),*/allocationRoleHandler.update);
 routers.delete('/allocatedRoles/delete',/* keycloak.protect(),*/allocationRoleHandler.deleteAllocatedRole);
diff --git a/app/api/role-user/delete.js b/app/api/role-user/delete.js
index 5189913..ef7c9d1 100644
--- a/app/api/role-user/delete.js
+++ b/app/api/role-user/delete.js
@@ -1,25 +1,21 @@
 'use strict'
 
-const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/logger")
-const util = require('util')
-
+const roleAllocationService = require("../../dal/roleAllocationService");
+const logger = require("../../utils/logger");
 
 const DeleteAllocatedRole = {
-    async deleteAllocatedRole(ctx) {
+    async delete(ctx) {
         try {
-            ctx.body = await roleAllocationService.delete(ctx.request.body)
-            ctx.status = 201
-            logger.info('Allocated role is deleted successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleAllocationService.delete(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Role allocated to user deleted.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
-    deleteAllocatedRole: DeleteAllocatedRole.deleteAllocatedRole,
+    deleteAllocatedRole: DeleteAllocatedRole.delete,
     DeleteAllocatedRole
-}
+};
diff --git a/app/api/role-user/get.js b/app/api/role-user/get.js
index 19d7ee5..9936076 100644
--- a/app/api/role-user/get.js
+++ b/app/api/role-user/get.js
@@ -1,26 +1,21 @@
 'use strict'
 
-const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/logger")
-const util = require('util')
+const roleAllocationService = require("../../dal/roleAllocationService");
+const logger = require("../../utils/logger");
 
 const GetAllocatedRole = {
     async find(ctx) {
         try {
-            const allocatedRoles = await roleAllocationService.allocatedRoles(ctx.request.body)
-            ctx.body = allocatedRoles.rows
-            ctx.status = 201
-            logger.info('Allocated roles are listed by kc_id')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleAllocationService.allocatedRoles(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User allocated roles fetched.');
+        } catch (error) {
+            throw error;
         }
     }
-}
-
+};
 
 module.exports = {
     allocatedRoles: GetAllocatedRole.find,
     GetAllocatedRole
-}
+};
diff --git a/app/api/role-user/index.js b/app/api/role-user/index.js
index f927a56..19a8e52 100644
--- a/app/api/role-user/index.js
+++ b/app/api/role-user/index.js
@@ -1,15 +1,15 @@
 'use strict'
 
-const { allocateRole } = require("./post")
-const { allocatedRoles } = require('./get')
-const { update } = require('./put')
-const { deleteAllocatedRole } = require('./delete')
+const { create } = require("./post");
+const { allocatedRoles } = require('./get');
+const { update } = require('./put');
+const { deleteAllocatedRole } = require('./delete');
 
 const AllocationRoleHandler = {
-    allocateRole,
+    create,
     allocatedRoles,
     update,
     deleteAllocatedRole,
-}
+};
 
-module.exports = AllocationRoleHandler
\ No newline at end of file
+module.exports = AllocationRoleHandler;
diff --git a/app/api/role-user/post.js b/app/api/role-user/post.js
index 11dbccb..0e1c04b 100644
--- a/app/api/role-user/post.js
+++ b/app/api/role-user/post.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/logger")
-const util = require('util')
+const roleAllocationService = require("../../dal/roleAllocationService");
+const logger = require("../../utils/logger");
 
 const AllocateRoleToUser = {
-    async allocateRoleToUser(ctx) {
+    async create(ctx) {
         try {
-            ctx.body = await roleAllocationService.create(ctx.request.body)
-            ctx.status = 201
-            logger.info('role is allocated to user successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleAllocationService.create(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Role allocated to user.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
-    allocateRole: AllocateRoleToUser.allocateRoleToUser,
+    create: AllocateRoleToUser.create,
     AllocateRoleToUser
-}
+};
diff --git a/app/api/role-user/put.js b/app/api/role-user/put.js
index f7d7ef0..9cebeae 100644
--- a/app/api/role-user/put.js
+++ b/app/api/role-user/put.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const roleAllocationService = require("../../dal/roleAllocationService")
-const logger = require("../../utils/logger")
-const util = require('util')
+const roleAllocationService = require("../../dal/roleAllocationService");
+const logger = require("../../utils/logger");
 
 const UpdateAllocatedRole = {
     async update(ctx) {
         try {
-            ctx.body = await roleAllocationService.update(ctx.request.body)
-            ctx.status = 201
-            logger.info('Allocated role is updated successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleAllocationService.update(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Role allocated to user updated.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     update: UpdateAllocatedRole.update,
     UpdateAllocatedRole
-}
+};
diff --git a/app/dal/roleAllocationService.js b/app/dal/roleAllocationService.js
index acf784e..09af151 100644
--- a/app/dal/roleAllocationService.js
+++ b/app/dal/roleAllocationService.js
@@ -1,78 +1,77 @@
 'use strict'
 
-const db = require('../../db')
-
-const { RoleUser } = require('../models/Role')
+const db = require('../../db');
+const { RoleUser } = require('../models/Role');
 
 const RoleAllocationService = {
-
-    // It allocates the role to user.
+    // Allocates a role to a user. If a role is already allocated to this user, updates it.
     async create(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.kc_id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        const roleUser = RoleUser.findOne({
-            where: {
-                kc_id: ctx.kc_id
-            }
-        })
-        if (!roleUser) {
-            return await RoleUser.create({
-                role_id: ctx.role_id,
-                kc_id: ctx.kc_id
-            })
-        } else {
+        const [roleUser, created] = await RoleUser.findOrCreate({
+            where: { kc_id: ctx.kc_id },
+            defaults: { role_id: ctx.role_id }
+        });
+        if (!created) {
             return await RoleUser.update({ role_id: ctx.role_id, }, {
                 where: {
                     kc_id: ctx.kc_id
                 }
-            })
+            });
         }
+        return roleUser;
     },
 
-    // It updates allocated user.
+    // Updates roles allocated to a user.
     async update(ctx) {
-        return await db('roles_users').where('id', ctx.id)
-            .update({
+        if (!ctx || !ctx.kc_id || !ctx.role_id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
+        }
+        return await RoleUser.update({ role_id: ctx.role_id, }, {
+            where: {
                 kc_id: ctx.kc_id
-            }).returning('*').then((result) => result[0])
+            }
+        });
     },
 
+    // Deletes roles allocated to a user.
     async delete(ctx) {
-        return db.delete().from('roles_users').where('id', ctx.id).timeout(1000, {cancel: true});
+        if (!ctx || !ctx.kc_id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
+        }
+        return await RoleUser.destroy({
+            where: {
+                kc_id: ctx.kc_id
+            }
+        });
     },
 
-    // It returns allocated roles by kc_id.
+    // Get allocated roles by user kc_id.
     async allocatedRolesByKcId(ctx) {
-        try {
-            if (!ctx) {
-                throw Error("The request body is empty!")
-            }
-            if (ctx.kc_id) {
-                return await db.raw(`
+        if (!ctx || !ctx.kc_id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
+        }
+        const allocatedRoles = await db.raw(`
                     select roles.id, u.username as user, roles.name as role , roles.description from roles
                     inner join roles_users ru on roles.id = ru.role_id
                     inner join users u on ru.kc_id = u.kc_id
-                    where u.kc_id = ?`, [ctx.kc_id])
-            }
-        } catch (err) {
-            throw new Error(err)
-        }
-    },
-    async allocatedRoles(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        return db.raw(`
-                select u.username as user,r.name as role from roles r
-                inner join roles_users ru on r.id = ru.role_id
-                inner join users u on ru.kc_id = u.kc_id`);
+                    where u.kc_id = ?`, [ctx.kc_id]);
+        return allocatedRoles.rows;
     },
-}
+};
 
 module.exports = {
     create: RoleAllocationService.create,
     allocatedRoles: RoleAllocationService.allocatedRolesByKcId,
     update: RoleAllocationService.update,
     delete: RoleAllocationService.delete
-}
+};
-- 
GitLab


From 2bce9e79e2e3206d2b756d604fbb78faee8c92e7 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Fri, 22 Nov 2024 14:20:56 +0100
Subject: [PATCH 09/13] [Policy] Removed useless model in file

---
 app/models/Policy.js | 43 -------------------------------------------
 1 file changed, 43 deletions(-)

diff --git a/app/models/Policy.js b/app/models/Policy.js
index 5f79304..7b2a923 100644
--- a/app/models/Policy.js
+++ b/app/models/Policy.js
@@ -26,15 +26,6 @@ Policy.init(
         deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE,
       }
     },
-    /*source_id: {
-      type: Sequelize.INTEGER,
-      allowNull: false,
-      references: {
-        model: Source,
-        key: "id",
-        deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE,
-      },
-    },*/
   },
   {
     underscored: true,
@@ -99,40 +90,6 @@ PolicySource.init({
     modelName: "policy_sources",
 })
 
-// StdField.belongsTo(Policy, { through: PolicyField, foreignKey: "policy_field_policy_id_fkey", constraints: true })
-// Policy.belongsToMany(StdField, { through: PolicyField, foreignKey: "std_fields_id_fkkey", constraints: true })
-// Policy.belongsTo(StdField, { foreignKey: "std_fields_id_fkkey" })
-// StdField.belongsTo(Policy, { foreignKey: "policy_field_policy_id_fkey" })
-// Policy.belongsTo(StdField, { through: PolicyField, foreignKey: "std_fields_id_fkkey", constraints: false })
-// StdField.belongsTo(Policy, { through: PolicyField, foreignKey: "policy_field_policy_id_fkey", constraints: false })
-/*
-Policy.belongsToMany(StdField, {
-  through: PolicyField,
-  uniqueKey: "policy_field_policy_id_fkey",
-});
-
-Policy.belongsToMany(Source, {
-  through: PolicyField,
-  uniqueKey: "policy_source_id_fkey",
-});
-
-StdField.belongsToMany(Policy, {
-  through: PolicyField,
-  uniqueKey: "std_fields_id_fkkey",
-}); */
-
-
-class UserProfile extends Sequelize.Model { }
-
-UserProfile.init(
-  {},
-  {
-    underscored: true,
-    sequelize: postgresSeq,
-    modelName: "user_profile",
-  }
-);
-
 module.exports = {
   Policy,
   PolicyField,
-- 
GitLab


From e96de405cfc2f2a4a595b487c6e61f500d8b346c Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Mon, 25 Nov 2024 07:45:56 +0100
Subject: [PATCH 10/13] [roles] now following new error handling ; improved
 some logic

---
 app/api/index.js        |  2 +-
 app/api/roles/delete.js | 21 ++++++--------
 app/api/roles/get.js    | 33 ++++++++++------------
 app/api/roles/index.js  | 16 +++++------
 app/api/roles/post.js   | 25 ++++++++---------
 app/api/roles/put.js    | 21 ++++++--------
 app/dal/roleService.js  | 62 ++++++++++++++++++++++-------------------
 7 files changed, 86 insertions(+), 94 deletions(-)

diff --git a/app/api/index.js b/app/api/index.js
index 43be607..3328c06 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -91,7 +91,7 @@ routers.get('/policyField/list', policyHandler.policyFields);
 routers.post('/policySource/add', policyHandler.createPolicySource);
 
 // Roles
-routers.post('/role',/* keycloak.protect(),*/ roleHandler.addNewRole);
+routers.post('/role',/* keycloak.protect(),*/ roleHandler.createRole);
 routers.get('/role/find', /* keycloak.protect(),*/ roleHandler.roles);
 routers.get('/role/findOne', /* keycloak.protect(),*/ roleHandler.role);
 routers.delete('/role/delete', /* keycloak.protect(),*/ roleHandler.deleteRole);
diff --git a/app/api/roles/delete.js b/app/api/roles/delete.js
index de2c2c3..cd63774 100644
--- a/app/api/roles/delete.js
+++ b/app/api/roles/delete.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const roleService = require('../../dal/roleService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const roleService = require('../../dal/roleService');
+const logger = require('../../utils/logger');
 
 const DeleteRole = {
     async deleteRole(ctx) {
         try {
-            ctx.body = await roleService.delete(ctx.request.body)
-            ctx.status = 201
-            logger.info('role is deleted successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleService.delete(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Role deleted.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     deleteRole: DeleteRole.deleteRole,
     DeleteRole,
-}
+};
diff --git a/app/api/roles/get.js b/app/api/roles/get.js
index 9f38b47..9ae5a0f 100644
--- a/app/api/roles/get.js
+++ b/app/api/roles/get.js
@@ -1,37 +1,32 @@
 'use strict'
 
-const roleService = require("../../dal/roleService")
-const logger = require('../../utils/logger')
-const util = require('util')
+const roleService = require("../../dal/roleService");
+const logger = require('../../utils/logger');
 
 const GetRole = {
     async find(ctx) {
         try {
-            ctx.body = await roleService.roles()
-            ctx.status = 201
-            logger.info('roles are listed successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleService.roles();
+            ctx.status = 201;
+            logger.info('Roles fetched.');
+        } catch (error) {
+            throw error;
         }
     },
 
     async findOne(ctx) {
         try {
-            ctx.body = await roleService.role(ctx.request.body)
-            ctx.status = 201
-            logger.info('role is found successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleService.role(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Role fetched.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     roles: GetRole.find,
     role: GetRole.findOne,
     GetRole
-}
+};
diff --git a/app/api/roles/index.js b/app/api/roles/index.js
index 8e24e08..0cc31da 100644
--- a/app/api/roles/index.js
+++ b/app/api/roles/index.js
@@ -1,17 +1,17 @@
 'use strict'
 
-const { addNewRole } = require('./post')
-const { roles } = require('./get')
-const { role } = require('./get')
-const { deleteRole } = require('./delete')
-const { update } = require('./put')
+const { createRole } = require('./post');
+const { roles } = require('./get');
+const { role } = require('./get');
+const { deleteRole } = require('./delete');
+const { update } = require('./put');
 
 const RoleHandler = {
-    addNewRole,
+    createRole,
     roles,
     role,
     deleteRole,
     update,
-}
+};
 
-module.exports = RoleHandler
\ No newline at end of file
+module.exports = RoleHandler;
diff --git a/app/api/roles/post.js b/app/api/roles/post.js
index 19f1311..58c83a5 100644
--- a/app/api/roles/post.js
+++ b/app/api/roles/post.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const roleService = require("../../dal/roleService")
-const logger = require('../../utils/logger')
-const util = require('util')
+const roleService = require("../../dal/roleService");
+const logger = require('../../utils/logger');
 
 const AddRole = {
-    async addNewRole(ctx) {
+    async create(ctx) {
         try {
-            ctx.body = await roleService.create(ctx.request.body)
-            ctx.status = 201
-            logger.info('role is created successfully!')
-        } catch (err) {
-            ctx.body = err.response.data || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleService.create(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Role created.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
-    addNewRole: AddRole.addNewRole,
+    createRole: AddRole.create,
     AddRole
-}
+};
diff --git a/app/api/roles/put.js b/app/api/roles/put.js
index 4996aa9..9ed289b 100644
--- a/app/api/roles/put.js
+++ b/app/api/roles/put.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const roleService = require('../../dal/roleService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const roleService = require('../../dal/roleService');
+const logger = require('../../utils/logger');
 
 const UpdateRole = {
     async update(ctx) {
         try {
-            ctx.body = await roleService.update(ctx.request.body)
-            ctx.status = 201
-            logger.info('role is updated successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await roleService.update(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Role updated.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     update: UpdateRole.update,
     UpdateRole
-}
+};
diff --git a/app/dal/roleService.js b/app/dal/roleService.js
index 036c97e..8589381 100644
--- a/app/dal/roleService.js
+++ b/app/dal/roleService.js
@@ -1,31 +1,38 @@
 "use strict"
 
-const db = require('../../db')
+const db = require('../../db');
+const { Role, RoleUser } = require('../models/Role');
 
-const { Role, RoleUser } = require('../models/Role')
 const RoleService = {
     //  Get all roles
-    async roles(ctx) {
-        return db.select().from('roles').timeout(1000, {cancel: true});
+    async roles() {
+        return await Role.findAll();
     },
 
     // Get a role
-    role: async function (ctx) {
-        return db.select().from('roles').where('id', ctx.id).timeout(1000, {cancel: true});
+    async role(ctx) {
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
+        }
+        return await Role.findAll({where: {'id': ctx.id}});
     },
 
-    // Delete role by id
-    async delete(ctx) {
-        return db.delete().from('roles').where('id', ctx.id).timeout(1000, {cancel: true})
-    },
 
     // Update role by id
     async update(ctx) {
-        return await db('roles').where('id', ctx.id)
-            .update({
-                name: ctx.name,
-                description: ctx.description
-            }).returning('*').then((result) => result[0])
+        if (!ctx || !ctx.id || !ctx.name || !ctx.description) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
+        }
+        return await Role.update({
+            'name': ctx.name,
+            'description': ctx.description
+        }, {
+            where: {'id': ctx.id}
+        });
     },
 
     // Create a role
@@ -33,24 +40,23 @@ const RoleService = {
         return await db('roles').insert({
             name: ctx.name,
             description: ctx.description
-        }).returning('*').then((result) => result[0])
+        }).returning('*').then((result) => result[0]);
     },
 
-    // Delete a role
-    async deleteRole(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+
+    // Delete role
+    async delete(ctx) {
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         await RoleUser.destroy({
             where: {
                 role_id: ctx.id
             }
-        })
-        return await Role.destroy({
-            where: {
-                id: ctx.id
-            }
-        })
+        });
+        return await Role.destroy({where: {'id': ctx.id}});
     },
 }
 
@@ -58,6 +64,6 @@ module.exports = {
     create: RoleService.create,
     roles: RoleService.roles,
     role: RoleService.role,
-    delete: RoleService.deleteRole,
+    delete: RoleService.delete,
     update: RoleService.update,
-}
+};
-- 
GitLab


From 84d27368d28d7d1b96de8be20d1f0ced6e326d3a Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Mon, 25 Nov 2024 08:14:23 +0100
Subject: [PATCH 11/13] [userRequests] now following new error handling ;
 improved some logic

---
 app/api/user-requests/delete.js | 21 ++++-----
 app/api/user-requests/get.js    | 29 +++++--------
 app/api/user-requests/index.js  | 10 ++---
 app/api/user-requests/post.js   | 43 ++++++++----------
 app/dal/userRequestService.js   | 77 +++++++++++++++++----------------
 5 files changed, 83 insertions(+), 97 deletions(-)

diff --git a/app/api/user-requests/delete.js b/app/api/user-requests/delete.js
index 170ecf5..d1be7f9 100644
--- a/app/api/user-requests/delete.js
+++ b/app/api/user-requests/delete.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const userRequestService = require('../../dal/userRequestService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const userRequestService = require('../../dal/userRequestService');
+const logger = require('../../utils/logger');
 
 const UserRequest = {
     async delete(ctx) {
         try {
-            ctx.body = await userRequestService.delete(ctx.request.body)
-            ctx.status = 201
-            logger.info('user request deleted successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userRequestService.delete(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User request deleted.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     deleteRequest: UserRequest.delete,
     UserRequest
-}
+};
diff --git a/app/api/user-requests/get.js b/app/api/user-requests/get.js
index cd0e420..b62ee08 100644
--- a/app/api/user-requests/get.js
+++ b/app/api/user-requests/get.js
@@ -1,37 +1,32 @@
 'use strict'
 
-const userRequestService = require('../../dal/userRequestService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const userRequestService = require('../../dal/userRequestService');
+const logger = require('../../utils/logger');
 
 const UserRequest = {
     async list(ctx) {
         try {
-            ctx.body = await userRequestService.fetch(ctx.request.body)
-            ctx.status = 201
-            logger.info('user requests fetched successfully!')
+            ctx.body = await userRequestService.fetch();
+            ctx.status = 201;
+            logger.info('User requests fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     },
 
     async listPending(ctx) {
         try {
-            ctx.body = await userRequestService.fetchPending(ctx.request.body)
-            ctx.status = 201
-            logger.info('user requests fetched successfully!')
+            ctx.body = await userRequestService.fetchPending();
+            ctx.status = 201;
+            logger.info('Pending user requests fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     fetchRequests: UserRequest.list,
     fetchPendingRequests: UserRequest.listPending,
     UserRequest
-}
+};
diff --git a/app/api/user-requests/index.js b/app/api/user-requests/index.js
index 310ac8d..8d0a9ea 100644
--- a/app/api/user-requests/index.js
+++ b/app/api/user-requests/index.js
@@ -1,8 +1,8 @@
 'use strict'
 
-const { createRequest, processRequest, fetchRequestsByUser } = require('./post')
-const { fetchRequests, fetchPendingRequests } = require('./get')
-const { deleteRequest } = require('./delete')
+const { createRequest, processRequest, fetchRequestsByUser } = require('./post');
+const { fetchRequests, fetchPendingRequests } = require('./get');
+const { deleteRequest } = require('./delete');
 
 const UserRequestHandler = {
     createRequest,
@@ -11,6 +11,6 @@ const UserRequestHandler = {
     fetchPendingRequests,
     fetchRequestsByUser,
     deleteRequest
-}
+};
 
-module.exports = UserRequestHandler
\ No newline at end of file
+module.exports = UserRequestHandler;
diff --git a/app/api/user-requests/post.js b/app/api/user-requests/post.js
index 3644ebf..d0b90af 100644
--- a/app/api/user-requests/post.js
+++ b/app/api/user-requests/post.js
@@ -1,50 +1,43 @@
 'use strict'
 
-const userRequestService = require('../../dal/userRequestService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const userRequestService = require('../../dal/userRequestService');
+const logger = require('../../utils/logger');
 
 const UserRequest = {
     async create(ctx) {
         try {
-            ctx.body = await userRequestService.create(ctx.request.body)
-            ctx.status = 201
-            logger.info('user request created successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userRequestService.create(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User request created.');
+        } catch (error) {
+            throw error;
         }
     },
 
     async process(ctx) {
         try {
-            ctx.body = await userRequestService.process(ctx.request.body)
-            ctx.status = 201
-            logger.info('user request processed successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userRequestService.process(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User request processed.');
+        } catch (error) {
+            throw error;
         }
     },
 
     async listByUser(ctx) {
         try {
-            ctx.body = await userRequestService.fetchByUser(ctx.request.body)
-            ctx.status = 201
-            logger.info('user requests fetched successfully!')
+            ctx.body = await userRequestService.fetchByUser(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User requests fetched by user.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     createRequest: UserRequest.create,
     processRequest: UserRequest.process,
     fetchRequestsByUser: UserRequest.listByUser,
     UserRequest
-}
+};
diff --git a/app/dal/userRequestService.js b/app/dal/userRequestService.js
index 9e7518c..d0c0c10 100644
--- a/app/dal/userRequestService.js
+++ b/app/dal/userRequestService.js
@@ -1,73 +1,74 @@
 'use strict'
 
 const userService = require("./userService");
-
 const { UserRequest } = require('../models/UserRequest');
 
-const db = require('../../db');
-
 const UserRequestService = {
     async create(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.")
+        if (!ctx || !ctx.kcId || !ctx.message) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        const user = await userService.detail({ kcId: ctx.kcId })
-        if (user) {
-            return await UserRequest.create({
-                user_id: user.id,
-                request_message: ctx.message,
-                is_processed: false,
-            })
-        } else {
-            throw Error('The user account could not found.')
+        const user = await userService.detail({ kcId: ctx.kcId });
+        if (!user) {
+            const error = new Error("User account not found.");
+            error.status = 400;
+            throw error;
         }
+        return await UserRequest.create({
+            user_id: user.id,
+            request_message: ctx.message,
+            is_processed: false,
+        });
     },
 
     async getAllRequests() {
-        return await UserRequest.findAll({})
+        return await UserRequest.findAll({});
     },
 
     async getUserRequests(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.")
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         const user = await userService.detail({ kcId: ctx.kcId })
         if (user) {
-            return db.select("*").from('user_requests').where('user_id', user.id).timeout(1000, {cancel: true});
+            return await UserRequest.findAll({
+                where: {
+                    user_id: user.id
+                }
+            });
         }
     },
 
-    async getPendingRequests(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
+    async getPendingRequests() {
         return await UserRequest.findAll({
             where: {
                 is_processed: false
             }
-        })
+        });
     },
 
-    async update(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+    async process(ctx) {
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await UserRequest.update({
             is_processed: true,
         }, {
             where: {id: ctx.id}
-        })
+        });
     },
 
     async delete(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
         return await UserRequest.destroy({
             where: {
@@ -79,9 +80,9 @@ const UserRequestService = {
 
 module.exports = {
     create: UserRequestService.create,
-    process: UserRequestService.update,
-    delete: UserRequestService.delete,
     fetch: UserRequestService.getAllRequests,
     fetchPending: UserRequestService.getPendingRequests,
-    fetchByUser: UserRequestService.getUserRequests
+    fetchByUser: UserRequestService.getUserRequests,
+    process: UserRequestService.process,
+    delete: UserRequestService.delete,
 }
-- 
GitLab


From b4ca83753715d3351cd55db9a58a823968a7b82a Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Mon, 25 Nov 2024 13:35:52 +0100
Subject: [PATCH 12/13] [userSearchHistory] now following new error handling ;
 improved some logic

---
 app/api/index.js                      |  5 +-
 app/api/user-search-history/delete.js | 21 +++----
 app/api/user-search-history/get.js    | 19 +++----
 app/api/user-search-history/index.js  | 14 ++---
 app/api/user-search-history/post.js   | 23 ++++----
 app/dal/searchHistoryService.js       | 80 +++++++++++++--------------
 6 files changed, 75 insertions(+), 87 deletions(-)

diff --git a/app/api/index.js b/app/api/index.js
index 3328c06..ee7c2fb 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -13,6 +13,7 @@ const userRequestHandler = require('./user-requests');
 const groupHandler = require('./group');
 const policyHandler = require('./policy');
 const UserFieldsDisplaySettingsHandler = require("./user-fields-display-settings");
+const {deleteUserSearchHistory} = require("./user-search-history/delete");
 
 const routers = new Router();
 
@@ -41,9 +42,9 @@ routers.get('/user/with-groups-and-roles', userHandler.usersWithGroupAndRole);
 routers.post('/user/one-with-groups-and-roles', userHandler.userWithGroupAndRole);
 
 // Search history
-routers.post('/user/add-history', searchHistoryHandler.add);
+routers.post('/user/add-history', searchHistoryHandler.create);
 routers.post('/user/fetch-history', searchHistoryHandler.fetch);
-routers.delete('/user/delete-history', searchHistoryHandler.deleteH);
+routers.delete('/user/delete-history', searchHistoryHandler.deleteUserSearchHistory);
 
 // User fields display settings
 routers.post('/user/fields-display-settings/', /* keycloak.protect(),*/ UserFieldsDisplaySettingsHandler.createUserFieldsDisplaySettings);
diff --git a/app/api/user-search-history/delete.js b/app/api/user-search-history/delete.js
index e483e80..a1f7ef9 100644
--- a/app/api/user-search-history/delete.js
+++ b/app/api/user-search-history/delete.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const searchHistoryService = require('../../dal/searchHistoryService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const searchHistoryService = require('../../dal/searchHistoryService');
+const logger = require('../../utils/logger');
 
 const SearchHistory = {
     async delete(ctx) {
         try {
-            ctx.body = await searchHistoryService.delete(ctx.request.body)
-            ctx.status = 201
-            logger.info('search history is deleted successfully!')
+            ctx.body = await searchHistoryService.delete(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User search history deleted.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
-    deleteH: SearchHistory.delete,
+    deleteUserSearchHistory: SearchHistory.delete,
     SearchHistory
-}
+};
diff --git a/app/api/user-search-history/get.js b/app/api/user-search-history/get.js
index 7ecb996..e8cc7b7 100644
--- a/app/api/user-search-history/get.js
+++ b/app/api/user-search-history/get.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const searchHistoryService = require('../../dal/searchHistoryService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const searchHistoryService = require('../../dal/searchHistoryService');
+const logger = require('../../utils/logger');
 
 const SearchHistory = {
     async list(ctx) {
         try {
-            ctx.body = await searchHistoryService.fetch(ctx.request.body)
-            ctx.status = 201
-            logger.info('search history is fetched successfully!')
+            ctx.body = await searchHistoryService.fetch(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User search history fetched.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     fetch: SearchHistory.list,
     SearchHistory
-}
+};
diff --git a/app/api/user-search-history/index.js b/app/api/user-search-history/index.js
index ec1d92b..7dab270 100644
--- a/app/api/user-search-history/index.js
+++ b/app/api/user-search-history/index.js
@@ -1,13 +1,13 @@
 'use strict'
 
-const { add } = require('./post')
-const { fetch } = require('./get')
-const { deleteH } = require('./delete')
+const { create } = require('./post');
+const { fetch } = require('./get');
+const { deleteUserSearchHistory } = require('./delete');
 
 const SearchHistoryHandler = {
-    add,
+    create,
     fetch,
-    deleteH
-}
+    deleteUserSearchHistory
+};
 
-module.exports = SearchHistoryHandler
\ No newline at end of file
+module.exports = SearchHistoryHandler;
diff --git a/app/api/user-search-history/post.js b/app/api/user-search-history/post.js
index 30b21c4..5739977 100644
--- a/app/api/user-search-history/post.js
+++ b/app/api/user-search-history/post.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const searchHistoryService = require('../../dal/searchHistoryService')
-const logger = require('../../utils/logger')
-const util = require('util')
+const searchHistoryService = require('../../dal/searchHistoryService');
+const logger = require('../../utils/logger');
 
 const SearchHistory = {
-    async add(ctx) {
+    async create(ctx) {
         try {
-            ctx.body = await searchHistoryService.create(ctx.request.body)
-            ctx.status = 201
-            logger.info('search history is created successfully!')
+            ctx.body = await searchHistoryService.create(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Search history created.');
         } catch (error) {
-            ctx.body = error.response || 'erroror occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(error, { compact: false, depth: 1, breakLength: 80 }))}`)
+           throw error;
         }
     }
-}
+};
 
 module.exports = {
-    add: SearchHistory.add,
+    create: SearchHistory.create,
     SearchHistory
-}
+};
diff --git a/app/dal/searchHistoryService.js b/app/dal/searchHistoryService.js
index e3f1b0e..0fb9df3 100644
--- a/app/dal/searchHistoryService.js
+++ b/app/dal/searchHistoryService.js
@@ -1,73 +1,69 @@
 'use strict'
 
 const userService = require("./userService");
-
 const { SearchHistory } = require('../models/UserHistory');
 
 const SearchHistoryService = {
     async create(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.")
+        if (!ctx || !ctx.kcId || !ctx.query || !ctx.name || !ctx.uiStructure || !ctx.description) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-        const user = await userService.detail({ kcId: ctx.kcId })
-        if (user) {
-            return await SearchHistory.create({
-                kc_id: user.kc_id,
-                query: ctx.query,
-                name: ctx.name,
-                ui_structure: ctx.uiStructure,
-                description: ctx.description
-            })
-        } else {
-            throw Error('The user account could not found.')
+        const user = await userService.detail({ kcId: ctx.kcId });
+        if (!user) {
+            const error = new Error("User account not found.");
+            error.status = 400;
+            throw error;
         }
+        return await SearchHistory.create({
+            kc_id: user.kc_id,
+            query: ctx.query,
+            name: ctx.name,
+            ui_structure: ctx.uiStructure,
+            description: ctx.description
+        })
     },
 
-    async getSearchHistories(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        if (ctx.kcId === undefined) {
-            throw Error("kcId did not supported.")
-        }
-        const user = await userService.detail({ kcId: ctx.kcId })
-        if (user) {
-            return await SearchHistory.findAll({
-                where: {
-                    kc_id: user.kc_id
-                }
-            })
+    async fetchUserSearchHistory(ctx) {
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
+        return await SearchHistory.findAll({
+            where: {
+                kc_id: ctx.kcId
+            }
+        });
     },
 
     async update(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
-        }
-        if (ctx.kc_id === undefined) {
-            throw Error("kcId did not supported.")
+        if (!ctx || !ctx.kcId) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
+        // Not finished ? I don't know why there is no method call to update db.
     },
 
     async delete(ctx) {
-        if (!ctx) {
-            throw Error("The request body is empty!")
+        if (!ctx || !ctx.id) {
+            const error = new Error("Required parameters are missing.");
+            error.status = 400;
+            throw error;
         }
-
         return await SearchHistory.destroy({
             where: {
                 id: ctx.id
             }
         });
     }
-}
+};
 
 module.exports = {
     create: SearchHistoryService.create,
     update: SearchHistoryService.update,
     delete: SearchHistoryService.delete,
-    fetch: SearchHistoryService.getSearchHistories
-}
+    fetch: SearchHistoryService.fetchUserSearchHistory
+};
-- 
GitLab


From eac5ea552c31b4eb0362ba62bb4d054c6d8a7574 Mon Sep 17 00:00:00 2001
From: rbisson <remi.bisson@inrae.fr>
Date: Tue, 26 Nov 2024 15:52:08 +0100
Subject: [PATCH 13/13] [users] now following new error handling ; improved
 some logic

---
 app/api/index.js        |   3 +-
 app/api/users/delete.js |  19 +-
 app/api/users/get.js    |  64 ++--
 app/api/users/index.js  |  16 +-
 app/api/users/post.js   |  64 ++--
 app/api/users/put.js    |  21 +-
 app/dal/userService.js  | 685 ++++++++++++++++++----------------------
 7 files changed, 380 insertions(+), 492 deletions(-)

diff --git a/app/api/index.js b/app/api/index.js
index ee7c2fb..a69d35f 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -13,7 +13,6 @@ const userRequestHandler = require('./user-requests');
 const groupHandler = require('./group');
 const policyHandler = require('./policy');
 const UserFieldsDisplaySettingsHandler = require("./user-fields-display-settings");
-const {deleteUserSearchHistory} = require("./user-search-history/delete");
 
 const routers = new Router();
 
@@ -25,7 +24,7 @@ routers.get('/healthcheck', (ctx) => {
 });
 
 // Users
-routers.post('/user', userHandler.addNewUser);
+routers.post('/user', userHandler.create);
 routers.post('/user/findOne',/* keycloak.protect(),*/ userHandler.user);
 routers.get('/user/find',/* keycloak.protect(),*/ userHandler.users);
 routers.delete('/user/delete',/* keycloak.protect(),*/ userHandler.deleteUser);
diff --git a/app/api/users/delete.js b/app/api/users/delete.js
index 609c696..ebe5496 100644
--- a/app/api/users/delete.js
+++ b/app/api/users/delete.js
@@ -1,22 +1,19 @@
 'use strict'
 
-const userService = require("../../dal/userService")
-const logger = require('../../utils/logger')
-const util = require('util')
+const userService = require("../../dal/userService");
+const logger = require('../../utils/logger');
 
 const DeleteUser = {
     async deleteUser(ctx) {
         try {
-            ctx.body = await userService.delete(ctx.request.body)
-            ctx.status = 201
-            logger.info('user is deleted successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userService.delete(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User deleted.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     deleteUser: DeleteUser.deleteUser,
diff --git a/app/api/users/get.js b/app/api/users/get.js
index d998078..f35efd2 100644
--- a/app/api/users/get.js
+++ b/app/api/users/get.js
@@ -1,44 +1,36 @@
 "use strict";
 
 const userService = require("../../dal/userService");
-const logger = require('../../utils/logger')
-const util = require('util')
+const logger = require('../../utils/logger');
 
 const GetUser = {
   async find(ctx) {
     try {
-      ctx.body = await userService.users()
-      ctx.status = 201
-      logger.info('users is listed successfully!')
-    } catch (err) {
-      ctx.body = err || 'Error occurred!'
-      ctx.status = 500;
-      logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
-
+      ctx.body = await userService.users();
+      ctx.status = 201;
+      logger.info('Users fetched.');
+    } catch (error) {
+      throw error;
     }
   },
 
   async findOne(ctx) {
     try {
-      ctx.body = await userService.user(ctx.request.body)
-      ctx.status = 201
-      logger.info('user is found successfully!')
-    } catch (err) {
-      ctx.body = err || 'Error occurred!'
-      ctx.status = 500;
-      logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+      ctx.body = await userService.user(ctx.request.body);
+      ctx.status = 201;
+      logger.info('User fetched.');
+    } catch (error) {
+      throw error;
     }
   },
 
   async kcId(ctx) {
     try {
       ctx.body = await userService.kcId(ctx.request.body);
-      ctx.status = 201
-      logger.info('kcId is found successfully!')
-    } catch (err) {
-      ctx.body = err || 'Error occurred!'
-      ctx.status = 500;
-      logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+      ctx.status = 201;
+      logger.info('User kc_id fetched.');
+    } catch (error) {
+      throw error;
     }
   },
 
@@ -46,11 +38,9 @@ const GetUser = {
     try {
       ctx.body = await userService.detail(ctx.request.body);
       ctx.status = 201;
-      logger.info('user_detail is found successfully!')
-    } catch (err) {
-      ctx.body = err || 'Error occurred!'
-      ctx.status = 500;
-      logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+      logger.info('User details fetched.');
+    } catch (error) {
+      throw error;
     }
   },
 
@@ -58,23 +48,19 @@ const GetUser = {
     try {
       ctx.body = await userService.getAssignedUserByRole(ctx.request.body);
       ctx.status = 201;
-      logger.info('Assigned users listed successfully by Role!')
-    } catch (err) {
-      ctx.body = err || 'Error occurred!'
-      ctx.status = 500;
-      logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+      logger.info('Users fetched by role.');
+    } catch (error) {
+      throw error;
     }
   },
 
   async usersWithGroupAndRole(ctx) {
     try {
-      ctx.body = await userService.usersWithGroupAndRole(ctx.request.body);
+      ctx.body = await userService.usersWithGroupAndRole();
       ctx.status = 201;
-      logger.info('Users listed with groups and roles successfully!')
-    } catch (err) {
-      ctx.body = err || 'Error occurred!'
-      ctx.status = 500;
-      logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+      logger.info('Users with groups and roles fetched.');
+    } catch (error) {
+      throw error;
     }
   }
 };
diff --git a/app/api/users/index.js b/app/api/users/index.js
index 7def803..c228799 100644
--- a/app/api/users/index.js
+++ b/app/api/users/index.js
@@ -1,14 +1,12 @@
 "use strict";
 
-const { addNewUser, createSystemUser, sendMail, userWithGroupAndRole, resetPassword } = require('./post')
-const { user, detail, getAssignedUserByRole, usersWithGroupAndRole } = require('./get')
-const { users } = require('./get')
-const { deleteUser } = require('./delete')
-const { update } = require('./put')
-const { kcId } = require('./get')
+const { create, createSystemUser, sendMail, userWithGroupAndRole, resetPassword } = require('./post');
+const { user, users, kcId, detail, getAssignedUserByRole, usersWithGroupAndRole } = require('./get');
+const { deleteUser } = require('./delete');
+const { update } = require('./put');
 
 const UserHandler = {
-    addNewUser,
+    create,
     user,
     users,
     deleteUser,
@@ -21,6 +19,6 @@ const UserHandler = {
     userWithGroupAndRole,
     sendMail,
     resetPassword
-}
+};
 
-module.exports = UserHandler
+module.exports = UserHandler;
diff --git a/app/api/users/post.js b/app/api/users/post.js
index 9acf501..87e5d64 100644
--- a/app/api/users/post.js
+++ b/app/api/users/post.js
@@ -1,46 +1,36 @@
 'use strict'
 
-const userService = require("../../dal/userService")
-const logger = require('../../utils/logger')
-const util = require('util')
+const userService = require("../../dal/userService");
+const logger = require('../../utils/logger');
 
 const AddUser = {
-    /**
-     * @param {username,email} ctx
-     */
-    async addNewUser(ctx) {
+    async create(ctx) {
         try {
-            ctx.body = await userService.create(ctx.request.body)
-            ctx.status = 201
-            logger.info('user is created successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userService.create(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User created.');
+        } catch (error) {
+            throw error;
         }
     },
 
     async createSystemUser(ctx) {
         try {
-            ctx.body = await userService.createSystemUser(ctx.request.body)
-            ctx.status = 201
-            logger.info('System user (admin) is created successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userService.createSystemUser();
+            ctx.status = 201;
+            logger.info('System user (admin) created.');
+        } catch (error) {
+            throw error;
         }
     },
 
     async sendMail(ctx) {
         try {
-            ctx.body = await userService.sendMail(ctx.request.body)
-            ctx.status = 201
-            logger.info('mail sent successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userService.sendMail(ctx.request.body);
+            ctx.status = 201;
+            logger.info('Mail sent.');
+        } catch (error) {
+            throw error;
         }
     },
 
@@ -48,11 +38,9 @@ const AddUser = {
         try {
             ctx.body = await userService.userWithGroupAndRole(ctx.request.body);
             ctx.status = 201;
-            logger.info('Found user with groups and roles successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            logger.info('User with groups and roles fetched.');
+        } catch (error) {
+            throw error;
         }
     },
 
@@ -60,17 +48,15 @@ const AddUser = {
         try {
             ctx.body = await userService.resetPassword(ctx.request.body);
             ctx.status = 201;
-            logger.info('Reset password successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500;
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            logger.info('Password reset.');
+        } catch (error) {
+            throw error;
         }
     }
 }
 
 module.exports = {
-    addNewUser: AddUser.addNewUser,
+    create: AddUser.create,
     createSystemUser: AddUser.createSystemUser,
     sendMail: AddUser.sendMail,
     userWithGroupAndRole: AddUser.userWithGroupAndRole,
diff --git a/app/api/users/put.js b/app/api/users/put.js
index b7b7322..3d5db10 100644
--- a/app/api/users/put.js
+++ b/app/api/users/put.js
@@ -1,24 +1,21 @@
 'use strict'
 
-const userService = require("../../dal/userService")
-const logger = require('../../utils/logger')
-const util = require('util')
+const userService = require("../../dal/userService");
+const logger = require('../../utils/logger');
 
 const UpdateUser = {
     async update(ctx) {
         try {
-            ctx.body = await userService.update(ctx.request.body)
-            ctx.status = 201
-            logger.info('user is updated successfully!')
-        } catch (err) {
-            ctx.body = err || 'Error occurred!'
-            ctx.status = 500
-            logger.error(`Caught error: ${JSON.stringify(util.inspect(err, { compact: false, depth: 1, breakLength: 80 }))}`)
+            ctx.body = await userService.update(ctx.request.body);
+            ctx.status = 201;
+            logger.info('User updated.');
+        } catch (error) {
+            throw error;
         }
     }
-}
+};
 
 module.exports = {
     update: UpdateUser.update,
     UpdateUser
-}
+};
diff --git a/app/dal/userService.js b/app/dal/userService.js
index 5741920..aed849e 100644
--- a/app/dal/userService.js
+++ b/app/dal/userService.js
@@ -1,469 +1,394 @@
 "use strict"
 
-const KcAdminClient = require("keycloak-admin").default
-const { Issuer } = require("openid-client")
-const db = require('../../db')
-const { User } = require('../models/User')
-const { RoleUser } = require('../models/Role')
-const { postgresSeq } = require('../config/db')
-const { BotService, MailService } = require('@in-sylva/common')
+const KcAdminClient = require("keycloak-admin").default;
+const db = require('../../db');
+const { User } = require('../models/User');
+const { RoleUser } = require('../models/Role');
+const { postgresSeq } = require('../config/db');
+const { BotService, MailService } = require('@in-sylva/common');
 const { Op } = require("sequelize");
-const bcrypt = require('bcrypt')
+const bcrypt = require('bcrypt');
 
-const mailService = new MailService()
+const mailService = new MailService();
+mailService.auth_user = process.env.IN_SYLVA_EMAIL;
+mailService.auth_pass = process.env.IN_SYLVA_EMAIL_PASSWORD;
+mailService.smtp_host = process.env.IN_SYLVA_SMTP_HOST;
+mailService.smtp_port = process.env.IN_SYLVA_SMTP_PORT;
+mailService.smtp_secure = true;
 
-mailService.auth_user = process.env.IN_SYLVA_EMAIL
-mailService.auth_pass = process.env.IN_SYLVA_EMAIL_PASSWORD
-mailService.smtp_host = process.env.IN_SYLVA_SMTP_HOST
-mailService.smtp_port = process.env.IN_SYLVA_SMTP_PORT
-mailService.smtp_secure = true
-
-const botService = new BotService()
-
-botService.token = process.env.BOT_SERVICE_TOKEN
-botService.channel = process.env.BOT_SERVICE_CHANNEL
+const botService = new BotService();
+botService.token = process.env.BOT_SERVICE_TOKEN;
+botService.channel = process.env.BOT_SERVICE_CHANNEL;
 
 const keycloakAdmin = new KcAdminClient({
   baseUrl: `${process.env.IN_SYLVA_KEYCLOAK_HOST}:${process.env.IN_SYLVA_KEYCLOAK_PORT}/keycloak/auth`,
   realmName: "master"
-})
+});
 
-async function auth() {
+const auth = async () => {
   await keycloakAdmin.auth({
     username: process.env.KEYCLOAK_USERNAME,
     password: process.env.KEYCLOAK_PASSWORD,
     grantType: process.env.KEYCLOAK_GRANT_TYPE,
     clientId: process.env.KEYCLOAK_CLIENT_ID,
-  })
+  });
 }
 
-async function generatePassword(length) {
-  const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
-    retVal = []
+const generatePassword = async (length) => {
+  const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", retVal = [];
   for (let i = 0, n = charset.length; i < length; ++i) {
-    retVal.push(charset.charAt(Math.floor(Math.random() * n)))
+    retVal.push(charset.charAt(Math.floor(Math.random() * n)));
   }
-  return retVal.join("")
-}
-
-async function tokenRefresher() {
-  const keycloakIssuer = await Issuer.discover(
-    `${process.env.IN_SYLVA_KEYCLOAK_HOST}:${process.env.IN_SYLVA_KEYCLOAK_PORT}/auth/realms/master`
-  )
-
-  const client = new keycloakIssuer.Client({
-    client_id: "admin-cli" // Same as `clientId` passed to client.auth()
-  })
-
-  // Periodically using refresh_token grant flow to get new access token here
-  setInterval(async () => {
-    const refreshToken = tokenSet.refresh_token
-    tokenSet = await client.refresh(keycloakAdmin.accessToken)
-    kcAdminClient.setAccessToken(tokenSet.access_token)
-  }, 58 * 1000) // 58 seconds
+  const password = retVal.join("");
+  const salt = bcrypt.genSaltSync();
+  return bcrypt.hashSync(password, salt);
 }
 
 const UserService = {
-  async resetPassword(ctx) {
+  // POST Create a user account
+  async create(ctx) {
+    if (!ctx || !ctx.username || !ctx.email || !ctx.password) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
+    }
+    // Check roleId or assign to default role "normal-user"
+    const roleId = ctx.roleId || 3;
+    // TODO fetch roles ids and verify that ctx.roleId is included
+    // TODO assign roleId of normal-user dynamically ? instead of hard-coded value 3
+    if (![1, 2, 3].includes(roleId)) {
+      const error = new Error("RoleId must be either 1, 2 or 3.");
+      error.status = 400;
+      throw error;
+    }
     const t = await postgresSeq.transaction();
-    try {
-      if (!ctx) {
-        throw Error("The request body is empty!");
-      }
-      await auth();
-      const users = await keycloakAdmin.users.find({
+    await auth();
+    const [newUser, isCreated] = await User.findOrCreate({
+      where: {
+        username: ctx.username,
         email: ctx.email,
-        realm: process.env.KEYCLOAK_REALM,
-      });
-      if (users.length > 0) {
-        const user = users[0];
-        const password = await generatePassword(10);
-        const salt = bcrypt.genSaltSync()
-        const hashedPassword = bcrypt.hashSync(password, salt)
-        // Update user in insylva db.
-        const [updatedRows, _] = await User.update({
-          password: hashedPassword,
-        }, {
-          where: {
-            kc_id: user.id,
-          },
-        });
-        if (updatedRows > 0) {
-          // Update user in keycloak db.
-          await keycloakAdmin.users.resetPassword({
-            id: user.id,
-            credential: {
-              temporary: false,
-              type: 'password',
-              value: password,
-            },
-            realm: process.env.KEYCLOAK_REALM,
-          });
-          this.sendMail({ ...ctx, subject: "Password reset", message: `Your new password is ${password}` });
-          t.commit();
-          return { status: 200, message: "Password reset successfully" };
-        }
-        else {
-          t.rollback();
-          return { status: 500, message: "Password reset failed" };
-        }
-      }
+      },
+      defaults: {
+        password: ctx.password
+      },
+    });
+    if (!isCreated) {
+      const error = new Error(`User ${ctx.email} or ${ctx.username} already exists.`);
+      error.status = 400;
+      throw error;
     }
-    catch (err) {
-      t.rollback();
-      ctx.status = err.status || 500
-      ctx.body = err.message
-      throw Error(err)
+    // Insert new user into keycloak db
+    const kcUser = await keycloakAdmin.users.create({
+      username: ctx.username,
+      email: ctx.email,
+      emailVerified: true,
+      enabled: true,
+      realm: process.env.KEYCLOAK_REALM,
+    });
+    if (!kcUser.id) {
+      await t.rollback();
     }
+    // Set new user's password in kc
+    await keycloakAdmin.users.resetPassword({
+      id: kcUser.id,
+      credential: {
+        temporary: false,
+        type: 'password',
+        value: ctx.password
+      },
+      realm: process.env.KEYCLOAK_REALM,
+    });
+    // Set user kc_id in db
+    await User.update({
+      kc_id: kcUser.id
+    }, {
+      where: {
+        id: newUser.id
+      }
+    });
+    // User Role allocation, default user is normal-user
+    await RoleUser.create({
+      role_id: roleId,
+      kc_id: kcUser.id
+    })
+    await t.commit();
+    const date = new Date().toLocaleDateString();
+    const message = `[INFO]:[User ${ctx.username} is created with this email address: ${ctx.email} successfully.]:[${date}]`;
+    const subject = "In-Sylva new user added";
+    await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, process.env.IN_SYLVA_EMAIL_TO, subject, "", message);
+    await botService.message(message);
+    return newUser;
   },
 
   // GET list users
-  // Backlog: security vulnerability
-  // Realm structure should implement here.
-  async users(ctx) {
-    try {
-      await auth()
+  // Backlog: security vulnerability. Realm structure should implement here.
+  async users(){
+      await auth();
       return await keycloakAdmin.users.find({
         realm: process.env.KEYCLOAK_REALM
-      })
-    }
-    catch (err) {
-      ctx.status = err.status || 500
-      ctx.body = err.message
-      throw Error(err)
-    }
-  },
-
-  // PUT update the user.
-  async update(ctx) {
-    await auth()
-    const userId = ctx.id
-    keycloakAdmin.setConfig({
-      realmName: process.env.KEYCLOAK_REALM
-    })
-
-    await keycloakAdmin.users.update(
-      { id: userId },
-      {
-        firstName: ctx.firstName,
-        lastName: ctx.lastName,
-        // email: ctx.email,
-        //requiredActions: [RequiredActionAlias.UPDATE_PASSWORD],
-        emailVerified: true,
-      })
-
-    const user = await keycloakAdmin.users.findOne({
-      id: userId, realm: process.env.KEYCLOAK_REALM,
-    })
-
-    await db('users').where('kc_id', userId)
-      .update({
-        firstname: ctx.firstName,
-        lastname: ctx.lastName
-      }).returning('*').then((result) => result[0])
-    return user
-  },
-
-  // DELETE the user
-  async delete(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("The request body is empty!")
-      }
-      await auth()
-      const userId = ctx.userId
-      if (userId) {
-        const deleted = await User.destroy({
-          where: {
-            kc_id: userId
-          }
-        })
-        if (deleted) {
-          return await keycloakAdmin.users.del({
-            id: userId,
-            realm: process.env.KEYCLOAK_REALM
-          })
-        }
-      }
-    } catch (error) {
-      ctx.status = error.status || 500
-      ctx.body = error.message
-      throw Error(error)
-    }
+      });
   },
 
-  // GET single user
+  // GET Fetch single user
   async user(ctx) {
-    try {
-      await auth()
-      return await keycloakAdmin.users.findOne({
-        id: ctx.id, realm: process.env.KEYCLOAK_REALM,
-      })
-    } catch (err) {
-      ctx.status = err.status || 500
-      ctx.body = err.message
-      throw Error(err)
+    if (!ctx || !ctx.id) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
     }
+    await auth();
+    return await keycloakAdmin.users.findOne({
+      id: ctx.id, realm: process.env.KEYCLOAK_REALM,
+    });
   },
 
+  // GET kc_id from email
   async kcId(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("The request body is empty!")
-      }
-      if (!ctx.email) {
-        throw Error("The email field is empty!")
-      }
-      const { kc_id } = await db.select('kc_id').from('users').where('email', ctx.email).timeout(1000, { cancel: true }).then((result) => result[0])
-      const role = await RoleUser.findOne({
-        attributes: ['role_id'],
-        where: {
-          kc_id: kc_id
-        }
-      })
-      return { kcId: kc_id, role: role }
-    } catch (err) {
-      ctx.status = err.status || 500
-      ctx.body = err.message
-      throw Error(err)
+    if (!ctx || !ctx.email) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
     }
+    const { kc_id } = await db.select('kc_id').from('users').where('email', ctx.email).timeout(1000, { cancel: true }).then((result) => result[0]);
+    const role = await RoleUser.findOne({
+      attributes: ['role_id'],
+      where: {
+        kc_id: kc_id
+      }
+    });
+    return { kcId: kc_id, role: role };
   },
 
+  // GET user account details
+  // TODO return user details such as roles and policies
   async detail(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("The request body is empty!")
-      }
-      return await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, {cancel: true}).then((result) => result[0])
-      // TODO return user details such as roles and policies
-    } catch (error) {
-      ctx.status = error.status || 500
-      ctx.body = error.message
-      throw Error(error)
+    if (!ctx || !ctx.kcId) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
     }
+    return await db.select("*").from('users').where('kc_id', ctx.kcId).timeout(1000, {cancel: true}).then((result) => result[0]);
   },
 
-  async create(ctx) {
-    const t = await postgresSeq.transaction()
-    try {
-      await auth()
-      if (!ctx) {
-        throw Error("The request body is empty!")
-      }
-      if (ctx.username && ctx.email && ctx.password) {
-        const checkUser = await User.findAndCountAll({
-          where: {
-            [Op.or]: [
-              { username: ctx.username },
-              { email: ctx.email }
-            ]
-          }
-        })
-        if (checkUser.count > 0) {
-          return { user: null, status: 409, message: `"${ctx.email}" or "${ctx.username}" already exist, please try again with different credentials.` }
-        }
-        const roleId = (ctx.roleId === 0 || ctx.roleId === undefined) ? 3 : ctx.roleId
-        if (!!roleId && roleId === 0) {
-          throw Error("The roleId is empty!")
-        }
-        // Insert this new user into insylva db.
-        const newUser = await User.create({
-          username: ctx.username,
-          email: ctx.email,
-          password: ctx.password
-        })
-        if (newUser.id) {
-          // Insert new user into keycloak db
-          const kcUser = await keycloakAdmin.users.create({
-            username: ctx.username,
-            email: ctx.email,
-            emailVerified: true,
-            enabled: true,
-            realm: process.env.KEYCLOAK_REALM,
-          })
-          if (kcUser.id) {
-            // Set new user's password
-            await keycloakAdmin.users.resetPassword({
-              id: kcUser.id,
-              credential: {
-                temporary: false,
-                type: 'password',
-                value: ctx.password
-              },
-              realm: process.env.KEYCLOAK_REALM,
-            })
-            const update = await User.update({
-              kc_id: kcUser.id
-            }, {
-              where: {
-                id: newUser.id
-              }
-            })
-            if (update) {
-              // User Role allocation, default user is normal-user
-              await RoleUser.create({
-                role_id: roleId,
-                kc_id: kcUser.id
-              })
-            }
-          }
-        } else {
-          await t.rollback()
-        }
-        await t.commit()
-        const date = new Date().toLocaleDateString()
-        const message = `[INFO]:[User ${ctx.username} is created with this email address: ${ctx.email} successfully.]:[${date}]`
-        const subject = "In-Sylva new user added"
-        await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, process.env.IN_SYLVA_EMAIL_TO, subject, "", message)
-        await botService.message(message)
-        return { user: newUser, status: 201 }
-      }
-    } catch (error) {
-      await t.rollback()
-      throw new Error(error)
+  // GET users assigned to a role
+  async getAssignedUserByRole(ctx) {
+    if (!ctx || !ctx.id) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
     }
+    const params = { roleId: ctx.id };
+    const assignedUserByRole = await db.raw(`
+      select u.username as username,u.email as useremail, r.name as rolename from roles r
+      inner join roles_users ru on r.id = ru.role_id
+      inner join users u on ru.kc_id = u.kc_id
+      where r.id = :roleId
+    `, params);
+    return assignedUserByRole.rows;
   },
 
-  async sendMail(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("The request body is empty!")
-      }
-      if (ctx.subject && ctx.message) {
-        const subject = ctx.subject
-        const message = ctx.message
-        await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, ctx.email, subject, "", message)
-        await botService.message(message)
-        return { status: 201 }
-      } else {
-        throw Error("The message is missing!")
-      }
-    } catch (error) {
-      ctx.status = error.status || 500
-      ctx.body = error.message
-      throw Error(error)
+  // PUT update the user.
+  async update(ctx) {
+    if (!ctx || !ctx.id) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
     }
-
+    await auth();
+    const userId = ctx.id
+    keycloakAdmin.setConfig({
+      realmName: process.env.KEYCLOAK_REALM
+    });
+    await keycloakAdmin.users.update(
+        { id: userId },
+        {
+          firstName: ctx.firstName,
+          lastName: ctx.lastName,
+          // email: ctx.email,
+          emailVerified: true,
+        });
+    const user = await keycloakAdmin.users.findOne({
+      id: userId, realm: process.env.KEYCLOAK_REALM,
+    });
+    await db('users').where('kc_id', userId).update({
+          firstname: ctx.firstName,
+          lastname: ctx.lastName
+        }).returning('*').then((result) => result[0]);
+    return user;
   },
 
-  async getAssignedUserByRole(ctx) {
-    try {
-      if (!ctx) {
-        throw Error("The request body is empty!")
-      }
-      const params = { roleId: ctx.id }
-      const assignedUserByRole = await db.raw(`
-        select u.username as username,u.email as useremail, r.name as rolename from roles r
-        inner join roles_users ru on r.id = ru.role_id
-        inner join users u on ru.kc_id = u.kc_id
-        where r.id = :roleId
-      `, params)
-      return assignedUserByRole.rows
-    } catch (error) {
-      throw new Error(error)
+  // DELETE a user
+  async delete(ctx) {
+    if (!ctx || !ctx.userId) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
+    }
+    await auth();
+    const deleted = await User.destroy({
+      where: { kc_id: ctx.userId }
+    });
+    if (deleted) {
+      return await keycloakAdmin.users.del({
+        id: ctx.userId,
+        realm: process.env.KEYCLOAK_REALM
+      })
     }
   },
 
+  // POST create the system admin.
+  // It should be used once at system start-up.
   async createSystemUser() {
-    try {
-      await auth()
-      const checkUser = await User.findAndCountAll({
-        where: {
-          [Op.or]: [
-            { username: "admin" },
-            { email: "admin@inrae.fr" }
-          ]
-        }
-      })
-
-      if (checkUser.count) {
-        return { user: null, status: 409 }
+    await auth();
+    const checkUser = await User.findAndCountAll({
+      where: {
+        [Op.or]: [
+          { username: "admin" },
+          { email: "admin@inrae.fr" }
+        ]
       }
-
-      // Insert new user into keycloak db
-      const kc_user = await keycloakAdmin.users.create({
-        username: "admin",
-        email: process.env.IN_SYLVA_ADMIN_USERNAME,
-        emailVerified: true,
-        enabled: true,
+    });
+    if (checkUser.count) {
+      return { user: null, status: 409 };
+    }
+    // Insert new user into keycloak db
+    const kc_user = await keycloakAdmin.users.create({
+      username: "admin",
+      email: process.env.IN_SYLVA_ADMIN_USERNAME,
+      emailVerified: true,
+      enabled: true,
+      realm: process.env.KEYCLOAK_REALM,
+    });
+    // Set new user's password
+    if (kc_user) {
+      await keycloakAdmin.users.resetPassword({
+        id: kc_user.id,
+        credential: {
+          temporary: false,
+          type: 'password',
+          value: process.env.IN_SYLVA_ADMIN_PASSWORD
+        },
         realm: process.env.KEYCLOAK_REALM,
-      })
-      // Set new user's password
-      if (kc_user) {
-        await keycloakAdmin.users.resetPassword({
-          id: kc_user.id,
-          credential: {
-            temporary: false,
-            type: 'password',
-            value: process.env.IN_SYLVA_ADMIN_PASSWORD
-          },
-          realm: process.env.KEYCLOAK_REALM,
-        })
-      }
-
-      const pg_user = await User.create({
-        kc_id: kc_user.id,
-        username: "admin",
-        email: process.env.IN_SYLVA_ADMIN_USERNAME,
-        password: process.env.IN_SYLVA_ADMIN_PASSWORD
-      })
-
-      await RoleUser.create({
-        role_id: 1,
-        kc_id: kc_user.id
-      })
-
-      return { user: pg_user, status: 201 }
-    } catch (error) {
-      throw new Error(error)
+      });
     }
+    const pg_user = await User.create({
+      kc_id: kc_user.id,
+      username: "admin",
+      email: process.env.IN_SYLVA_ADMIN_USERNAME,
+      password: process.env.IN_SYLVA_ADMIN_PASSWORD
+    });
+    await RoleUser.create({
+      role_id: 1,
+      kc_id: kc_user.id
+    });
+    return { user: pg_user, status: 201 };
   },
 
+  // GET Fetch all users and their group and role
   async usersWithGroupAndRole() {
-    try {
-      const usersWithGroupsAndRole = await db.raw(
+    const usersWithGroupsAndRole = await db.raw(
         `select DISTINCT u.id, u.kc_id, u.username, u.email, 
           g.name as groupName, g.description as groupDescription, r.name as roleName, r.description as roleDescription  from users u
           inner join roles_users ru on u.kc_id = ru.kc_id
           inner join roles r on ru.role_id = r.id
           left join group_users gu on u.id = gu.user_id
-          left join groups g on g.id = gu.group_id`)
-      return usersWithGroupsAndRole.rows
-    } catch (error) {
-      throw new Error(error)
-    }
+          left join groups g on g.id = gu.group_id`);
+    return usersWithGroupsAndRole.rows;
   },
 
+  // GET Fetch a user and their group and role
   async userWithGroupAndRole(ctx) {
-    try {
-      const params = { userId: ctx.id }
-      const userWithGroupAndRole = await db.raw(
+    if (!ctx || !ctx.id) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
+    }
+    const params = { userId: ctx.id };
+    const userWithGroupAndRole = await db.raw(
         `select DISTINCT u.id, u.kc_id, u.username, u.email, g.id as groupId,
           g.name as groupName, g.description as groupDescription, r.name as roleName, r.id as roleId, r.description as roleDescription  from users u
           inner join roles_users ru on u.kc_id = ru.kc_id
           inner join roles r on ru.role_id = r.id
           left join group_users gu on u.id = gu.user_id
           left join groups g on g.id = gu.group_id
-          where u.kc_id = :userId`, params)
-      return userWithGroupAndRole.rows
-    } catch (error) {
-      throw new Error(error)
+          where u.kc_id = :userId`, params);
+    return userWithGroupAndRole.rows;
+  },
+
+  // POST Email a user
+  async sendMail(ctx) {
+    if (!ctx || !ctx.subject || !ctx.message) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
     }
-  }
+    await mailService.send(process.env.IN_SYLVA_EMAIL_FROM, ctx.email, ctx.subject, "", ctx.message);
+    await botService.message(ctx.message);
+    return "Mail sent.";
+  },
+
+  // POST Reset a user password.
+  async resetPassword(ctx) {
+    if (!ctx || !ctx.email) {
+      const error = new Error("Required parameters are missing.");
+      error.status = 400;
+      throw error;
+    }
+    const t = await postgresSeq.transaction();
+    await auth();
+    const users = await keycloakAdmin.users.find({
+      email: ctx.email,
+      realm: process.env.KEYCLOAK_REALM,
+    });
+    if (!users || users.length === 0) {
+      const error = new Error("User account not found.");
+      error.status = 400;
+      throw error;
+    }
+    const user = users[0];
+    const hashedPassword = await generatePassword(10);
+    // Update user in insylva db.
+    const [updatedRowsCount, updatedRows] = await User.update({
+      password: hashedPassword,
+    }, {
+      where: {
+        kc_id: user.id,
+      },
+    });
+    if (!updatedRowsCount || updatedRowsCount <= 0) {
+      t.rollback();
+      const error = new Error("Reset password failed.");
+      error.status = 500;
+      throw error;
+    }
+    // Update user in keycloak db.
+    await keycloakAdmin.users.resetPassword({
+      id: user.id,
+      credential: {
+        temporary: false,
+        type: 'password',
+        value: password,
+      },
+      realm: process.env.KEYCLOAK_REALM,
+    });
+    await this.sendMail({...ctx, subject: "Password reset", message: `Your new password is ${password}`});
+    t.commit();
+    return "Password reset successfully";
+  },
 }
 
 module.exports = {
   create: UserService.create,
-  users: UserService.users,
   user: UserService.user,
-  delete: UserService.delete,
-  update: UserService.update,
+  users: UserService.users,
   kcId: UserService.kcId,
+  update: UserService.update,
   detail: UserService.detail,
+  delete: UserService.delete,
   getAssignedUserByRole: UserService.getAssignedUserByRole,
   createSystemUser: UserService.createSystemUser,
   usersWithGroupAndRole: UserService.usersWithGroupAndRole,
   userWithGroupAndRole: UserService.userWithGroupAndRole,
   sendMail: UserService.sendMail,
   resetPassword: UserService.resetPassword
-}
+};
-- 
GitLab