aloux-iam 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(grep *)",
5
+ "Bash(npm run *)",
6
+ "Bash(curl -s http://localhost:5173)"
7
+ ]
8
+ }
9
+ }
@@ -106,6 +106,32 @@ self.hashCode = (code) => {
106
106
  return crypto.createHash('sha256').update(String(code)).digest('hex');
107
107
  };
108
108
 
109
+ // Extrae del body solo los campos definidos en el schema del modelo.
110
+ // Campos de tipo Object libre (ej. data) se aplanan a dot-notation para que
111
+ // $set haga merge en lugar de reemplazar el objeto completo.
112
+ self.pickFromSchema = (Model, body) => {
113
+ const nonEditable = new Set(Model.schema.options.nonEditable || []);
114
+ const BASE_BLOCKED = new Set(['_id', '__v', 'createdAt', 'lastUpdate']);
115
+ const schemaObj = Model.schema.obj;
116
+ const allowed = Object.keys(schemaObj).filter(k => !BASE_BLOCKED.has(k) && !nonEditable.has(k));
117
+
118
+ const result = {};
119
+ for (const [k, v] of Object.entries(body)) {
120
+ if (!allowed.includes(k)) continue;
121
+ const fieldDef = schemaObj[k];
122
+ const isFreeObject = (fieldDef === Object || fieldDef?.type === Object) &&
123
+ v && typeof v === 'object' && !Array.isArray(v);
124
+ if (isFreeObject) {
125
+ for (const [dk, dv] of Object.entries(v)) {
126
+ result[`${k}.${dk}`] = dv;
127
+ }
128
+ } else {
129
+ result[k] = v;
130
+ }
131
+ }
132
+ return result;
133
+ };
134
+
109
135
  self.sanitizeSort = (sort, allowedFields) => {
110
136
  if (!sort || typeof sort !== 'object' || Array.isArray(sort)) return null;
111
137
  const safe = {};
@@ -143,9 +143,11 @@ self.detail = async (req, res) => {
143
143
 
144
144
  self.update = async (req, res) => {
145
145
  try {
146
+ const payload = errorController.pickFromSchema(Business, req.body);
147
+ payload.lastUpdate = new Date().getTime();
146
148
  const update = await Business.updateOne(
147
149
  { _id: req.params.BUSINESS_ID },
148
- { $set: req.body, lastUpdate: new Date().getTime() }
150
+ { $set: payload }
149
151
  );
150
152
  res.status(202).send(update);
151
153
  } catch (error) {
@@ -59,9 +59,11 @@ self.detail = async (req, res) => {
59
59
 
60
60
  self.update = async (req, res) => {
61
61
  try {
62
+ const payload = errorController.pickFromSchema(Company, req.body);
63
+ payload.lastUpdate = new Date().getTime();
62
64
  const update = await Company.updateOne(
63
65
  { _id: req.params.COMPANY_ID },
64
- { $set: req.body, lastUpdate: new Date().getTime() }
66
+ { $set: payload }
65
67
  );
66
68
  res.status(202).send(update);
67
69
  } catch (error) {
@@ -19,9 +19,10 @@ self.update = async (req, res) => {
19
19
  const count = await Functions.exists({ _id: req.params.FUNCTION_ID })
20
20
  if (!count)
21
21
  throw new Error('Upss! No se encontró el registro')
22
- req.body.lastUpdate = (new Date()).getTime()
23
- await Functions.updateOne({ _id: req.params.FUNCTION_ID }, { $set: req.body })
24
- res.status(200).send(req.body)
22
+ const payload = utils.pickFromSchema(Functions, req.body)
23
+ payload.lastUpdate = (new Date()).getTime()
24
+ await Functions.updateOne({ _id: req.params.FUNCTION_ID }, { $set: payload })
25
+ res.status(200).send(payload)
25
26
  } catch (error) {
26
27
  utils.responseError(res, error)
27
28
  }
@@ -19,9 +19,10 @@ self.update = async (req, res) => {
19
19
  const _id = req.params.LABEL_ID;
20
20
  const exists = await Label.exists({ _id });
21
21
  if (!exists) throw new Error("Upss! No se encontró el registro");
22
- req.body.lastUpdate = new Date().getTime();
23
- await Label.updateOne({ _id }, req.body);
24
- res.status(200).send(req.body);
22
+ const payload = utils.pickFromSchema(Label, req.body);
23
+ payload.lastUpdate = new Date().getTime();
24
+ await Label.updateOne({ _id }, payload);
25
+ res.status(200).send(payload);
25
26
  } catch (error) {
26
27
  utils.responseError(res, error);
27
28
  }
@@ -20,9 +20,10 @@ self.update = async (req, res) => {
20
20
  const count = await Menu.exists({ _id })
21
21
  if (!count)
22
22
  throw new Error('Upss! No se encontró el registro')
23
- req.body.lastUpdate = (new Date()).getTime()
24
- await Menu.updateOne({ _id }, { $set: req.body })
25
- res.status(200).send(req.body)
23
+ const payload = utils.pickFromSchema(Menu, req.body)
24
+ payload.lastUpdate = (new Date()).getTime()
25
+ await Menu.updateOne({ _id }, { $set: payload })
26
+ res.status(200).send(payload)
26
27
  } catch (error) {
27
28
  utils.responseError(res, error)
28
29
  }
@@ -28,9 +28,10 @@ self.update = async (req, res) => {
28
28
  const count = await Permission.exists({ _id })
29
29
  if (!count)
30
30
  throw new Error('Upss! No se encontró el registro')
31
- req.body.lastUpdate = (new Date()).getTime()
32
- await Permission.updateOne({ _id }, { $set: req.body })
33
- res.status(200).send(req.body)
31
+ const payload = utils.pickFromSchema(Permission, req.body)
32
+ payload.lastUpdate = (new Date()).getTime()
33
+ await Permission.updateOne({ _id }, { $set: payload })
34
+ res.status(200).send(payload)
34
35
  } catch (error) {
35
36
  utils.responseError(res, error)
36
37
  }
@@ -43,5 +43,7 @@ const businessSchema = mongoose.Schema({
43
43
  environment: { type: String, enum: ["dev", "qa", "prod"] },
44
44
  });
45
45
 
46
+ businessSchema.set('nonEditable', ['gkey']);
47
+
46
48
  const Business = mongoose.model("Business", businessSchema);
47
49
  module.exports = Business;
@@ -13,6 +13,7 @@ const permissionSchema = mongoose.Schema({
13
13
  });
14
14
 
15
15
  permissionSchema.index({ method: 1, endpoint: 1 }, { unique: true });
16
+ permissionSchema.set('nonEditable', ['method', 'endpoint']);
16
17
 
17
18
  const Permission = mongoose.model("Permission", permissionSchema);
18
19
  module.exports = Permission;
@@ -94,6 +94,8 @@ const adminSchema = mongoose.Schema({
94
94
  lastUpdate: { type: Number },
95
95
  });
96
96
 
97
+ adminSchema.set('nonEditable', ['pwd', 'tokens', 'validateKey']);
98
+
97
99
  adminSchema.pre("save", async function () {
98
100
  const user = this;
99
101
 
package/lib/router.js CHANGED
@@ -47,6 +47,7 @@ router.put("/iam/auth/reset/password", middleware, auth.resetPass);
47
47
  router.post("/iam/auth/send/verify/phone", middleware, auth.verifyPhone);
48
48
  router.post("/iam/auth/verify/phone", middleware, auth.validatePhone);
49
49
  router.post("/iam/auth/logout", middleware, auth.logout);
50
+ router.post("/iam/auth/logout-all", middleware, auth.logoutAll);
50
51
  router.patch("/iam/auth/mail", middleware, auth.mailChange);
51
52
  router.post("/iam/auth/validate/mail", middleware, auth.validatEmailChange);
52
53
 
@@ -244,8 +244,7 @@ self.logout = async (req, res) => {
244
244
  };
245
245
 
246
246
  self.logoutAll = async (req, res) => {
247
- req.user.tokens = [];
248
- await req.user.save();
247
+ await User.updateOne({ _id: req.user._id }, { $set: { tokens: [] } });
249
248
  res.clearCookie("token");
250
249
  return true;
251
250
  };
@@ -1,6 +1,6 @@
1
1
  const jwt = require("jsonwebtoken")
2
2
  const User = require('../models/User')
3
- const { hashToken } = require('../config/utils')
3
+ const { hashToken, pickFromSchema } = require('../config/utils')
4
4
  const self = module.exports
5
5
 
6
6
  self.create = async (body) => {
@@ -114,10 +114,7 @@ self.update = async (USER_ID, body) => {
114
114
  await User.updateOne({ _id }, { 'validateKey.validatePhone.validCodePhone': false })
115
115
  }
116
116
 
117
- const BLOCKED_FIELDS = ['tokens', 'pwd', 'validateKey', 'createdAt', '_id'];
118
- const safeBody = Object.fromEntries(
119
- Object.entries(body).filter(([key]) => !BLOCKED_FIELDS.includes(key))
120
- );
117
+ const safeBody = pickFromSchema(User, body);
121
118
  safeBody.lastUpdate = new Date().getTime();
122
119
  const result = await User.updateOne({ _id }, { $set: safeBody })
123
120
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aloux-iam",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Aloux IAM for APIs ",
5
5
  "main": "index.js",
6
6
  "scripts": {