aloux-iam 1.0.1 → 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.
- package/.claude/settings.local.json +9 -0
- package/lib/config/utils.js +26 -0
- package/lib/controllers/business.js +3 -1
- package/lib/controllers/company.js +3 -1
- package/lib/controllers/functions.js +4 -3
- package/lib/controllers/label.js +4 -3
- package/lib/controllers/menu.js +4 -3
- package/lib/controllers/permission.js +4 -3
- package/lib/models/Business.js +2 -0
- package/lib/models/Permission.js +1 -0
- package/lib/models/User.js +2 -0
- package/lib/router.js +1 -0
- package/lib/services/auth.js +1 -2
- package/lib/services/user.js +6 -6
- package/package.json +1 -1
package/lib/config/utils.js
CHANGED
|
@@ -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:
|
|
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:
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
}
|
package/lib/controllers/label.js
CHANGED
|
@@ -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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
}
|
package/lib/controllers/menu.js
CHANGED
|
@@ -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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
}
|
package/lib/models/Business.js
CHANGED
package/lib/models/Permission.js
CHANGED
|
@@ -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;
|
package/lib/models/User.js
CHANGED
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
|
|
package/lib/services/auth.js
CHANGED
|
@@ -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
|
};
|
package/lib/services/user.js
CHANGED
|
@@ -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) => {
|
|
@@ -27,7 +27,10 @@ self.create = async (body) => {
|
|
|
27
27
|
user = new User(body)
|
|
28
28
|
user.createdAt = new Date().getTime()
|
|
29
29
|
user.status = body?.status ?? 'Activo'
|
|
30
|
-
user.data = {
|
|
30
|
+
user.data = {
|
|
31
|
+
...(body.data || {}),
|
|
32
|
+
changePwd: body.data?.changePwd ?? false
|
|
33
|
+
}
|
|
31
34
|
|
|
32
35
|
try {
|
|
33
36
|
await user.save()
|
|
@@ -111,10 +114,7 @@ self.update = async (USER_ID, body) => {
|
|
|
111
114
|
await User.updateOne({ _id }, { 'validateKey.validatePhone.validCodePhone': false })
|
|
112
115
|
}
|
|
113
116
|
|
|
114
|
-
const
|
|
115
|
-
const safeBody = Object.fromEntries(
|
|
116
|
-
Object.entries(body).filter(([key]) => !BLOCKED_FIELDS.includes(key))
|
|
117
|
-
);
|
|
117
|
+
const safeBody = pickFromSchema(User, body);
|
|
118
118
|
safeBody.lastUpdate = new Date().getTime();
|
|
119
119
|
const result = await User.updateOne({ _id }, { $set: safeBody })
|
|
120
120
|
|