aloux-iam 0.0.115 → 0.0.116
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/.gitattributes +2 -2
- package/CONTRIBUTING.md +1 -1
- package/LICENSE +21 -21
- package/README.md +271 -271
- package/index.js +38 -38
- package/lib/config/utils.js +13 -13
- package/lib/controllers/auth.js +166 -166
- package/lib/controllers/functions.js +86 -86
- package/lib/controllers/history.js +97 -97
- package/lib/controllers/menu.js +101 -101
- package/lib/controllers/operationsAWS.js +228 -228
- package/lib/controllers/permission.js +90 -90
- package/lib/controllers/user.js +848 -880
- package/lib/middleware.js +146 -146
- package/lib/models/Business.js +14 -14
- package/lib/models/Functions.js +13 -13
- package/lib/models/History.js +15 -15
- package/lib/models/Menu.js +17 -17
- package/lib/models/Permission.js +16 -16
- package/lib/models/User.js +115 -115
- package/lib/models/UserProvisional.js +10 -10
- package/lib/router.js +82 -104
- package/lib/services/auth.js +956 -956
- package/lib/services/bigQuery.js +87 -87
- package/lib/services/s3.js +71 -71
- package/lib/services/ses.js +97 -97
- package/lib/services/sns.js +21 -21
- package/lib/services/user.js +99 -99
- package/lib/swagger.yaml +1231 -1231
- package/package.json +38 -38
- package/lib/controllers/label.js +0 -82
- package/lib/controllers/log.js +0 -268
- package/lib/models/Label.js +0 -13
- package/lib/models/Log.js +0 -11
package/lib/models/User.js
CHANGED
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
const mongoose = require("mongoose")
|
|
2
|
-
const bcrypt = require("bcryptjs")
|
|
3
|
-
const jwt = require("jsonwebtoken")
|
|
4
|
-
const ObjectId = mongoose.Schema.Types.ObjectId
|
|
5
|
-
|
|
6
|
-
const adminSchema = mongoose.Schema({
|
|
7
|
-
name: { type: String, required: true, trim: true },
|
|
8
|
-
lastName: { type: String, required: false, trim: true },
|
|
9
|
-
email: { type: String, required: true, trim: true, unique: true, lowercase: true },
|
|
10
|
-
pwd: { type: String, trim: true, minLength: 8 },
|
|
11
|
-
phone: { type: String, trim: true, maxLength: 13 },
|
|
12
|
-
phoneObj: {
|
|
13
|
-
e164: { type: String, trim: true, maxLength: 13 },
|
|
14
|
-
input: { type: String, trim: true, maxLength: 12 },
|
|
15
|
-
international: { type: String, trim: true, maxLength: 20 },
|
|
16
|
-
national: { type: String, trim: true, maxLength: 13 },
|
|
17
|
-
rfc3966: { type: String, trim: true, maxLength: 30 },
|
|
18
|
-
significant: { type: String, trim: true, maxLength: 10 },
|
|
19
|
-
country: { type: String, trim: true, maxLength: 10 },
|
|
20
|
-
dialCode: { type: String, trim: true, maxLength: 10 },
|
|
21
|
-
icon: { type: String, trim: true, maxLength: 10 },
|
|
22
|
-
regionCode: { type: String, trim: true, maxLength: 10 }
|
|
23
|
-
},
|
|
24
|
-
urlImg: { type: String },
|
|
25
|
-
data: {
|
|
26
|
-
type: Object,
|
|
27
|
-
default: { changePwd: false }
|
|
28
|
-
},
|
|
29
|
-
validateKey: {
|
|
30
|
-
failedAttempts: { type: Number, default: 0 },
|
|
31
|
-
limitCodeTime: { type: Number },
|
|
32
|
-
resetPassword: {
|
|
33
|
-
resetCode: { type: Number },
|
|
34
|
-
validCode: { type: Boolean, default: false },
|
|
35
|
-
},
|
|
36
|
-
validateEmail: {
|
|
37
|
-
emailVerified: { type: Boolean, default: false },
|
|
38
|
-
verifyMailToken: { type: String },
|
|
39
|
-
},
|
|
40
|
-
validatePhone: {
|
|
41
|
-
codeVerifyPhone: { type: Number },
|
|
42
|
-
validCodePhone: { type: Boolean, default: false },
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
_functions: [
|
|
46
|
-
{
|
|
47
|
-
type: ObjectId, required: true, ref: 'Functions'
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
_business: [
|
|
51
|
-
{
|
|
52
|
-
type: ObjectId, ref: 'Business'
|
|
53
|
-
}
|
|
54
|
-
],
|
|
55
|
-
_client: [
|
|
56
|
-
{
|
|
57
|
-
type: ObjectId, ref: 'Client'
|
|
58
|
-
}
|
|
59
|
-
],
|
|
60
|
-
tokens: [
|
|
61
|
-
{
|
|
62
|
-
token: { type: String, required: true },
|
|
63
|
-
date: { type: Number },
|
|
64
|
-
dateEnd: { type: Number }
|
|
65
|
-
}
|
|
66
|
-
],
|
|
67
|
-
|
|
68
|
-
status: { type: String, required: true, enum: ['Activo','Inactivo','Bloqueado'], default: 'Activo' },
|
|
69
|
-
createdAt: { type: Number },
|
|
70
|
-
lastUpdate: { type: Number }
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
adminSchema.pre("save", async function (next) {
|
|
74
|
-
const user = this
|
|
75
|
-
|
|
76
|
-
if (user.isModified("pwd")) {
|
|
77
|
-
user.pwd = await bcrypt.hash(user.pwd, 8)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
next()
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
adminSchema.methods.generateAuthToken = async function () {
|
|
84
|
-
const user = this
|
|
85
|
-
|
|
86
|
-
const token = jwt.sign({ _id: user._id }, process.env.AUTH_SECRET)
|
|
87
|
-
const currentDate = (new Date()).getTime()
|
|
88
|
-
const dateEnd = currentDate + process.env.SESSION_TIME * 60 * 1000;
|
|
89
|
-
user.tokens = user.tokens.concat({ token, date: currentDate, dateEnd })
|
|
90
|
-
|
|
91
|
-
await user.save()
|
|
92
|
-
|
|
93
|
-
return token
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
adminSchema.statics.findByCredentials = async (email, pwd) => {
|
|
97
|
-
try {
|
|
98
|
-
const user = await User.findOne({ email: email })
|
|
99
|
-
|
|
100
|
-
if (!user) {
|
|
101
|
-
throw new Error({ error: "Invalid login credentials" })
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const isPasswordMatch = await bcrypt.compare(pwd, user.pwd)
|
|
105
|
-
|
|
106
|
-
if (!isPasswordMatch) {
|
|
107
|
-
throw new Error({ error: "Invalid login credentials" })
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return user
|
|
111
|
-
} catch (error) { }
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const User = mongoose.model("User", adminSchema)
|
|
115
|
-
module.exports = User
|
|
1
|
+
const mongoose = require("mongoose")
|
|
2
|
+
const bcrypt = require("bcryptjs")
|
|
3
|
+
const jwt = require("jsonwebtoken")
|
|
4
|
+
const ObjectId = mongoose.Schema.Types.ObjectId
|
|
5
|
+
|
|
6
|
+
const adminSchema = mongoose.Schema({
|
|
7
|
+
name: { type: String, required: true, trim: true },
|
|
8
|
+
lastName: { type: String, required: false, trim: true },
|
|
9
|
+
email: { type: String, required: true, trim: true, unique: true, lowercase: true },
|
|
10
|
+
pwd: { type: String, trim: true, minLength: 8 },
|
|
11
|
+
phone: { type: String, trim: true, maxLength: 13 },
|
|
12
|
+
phoneObj: {
|
|
13
|
+
e164: { type: String, trim: true, maxLength: 13 },
|
|
14
|
+
input: { type: String, trim: true, maxLength: 12 },
|
|
15
|
+
international: { type: String, trim: true, maxLength: 20 },
|
|
16
|
+
national: { type: String, trim: true, maxLength: 13 },
|
|
17
|
+
rfc3966: { type: String, trim: true, maxLength: 30 },
|
|
18
|
+
significant: { type: String, trim: true, maxLength: 10 },
|
|
19
|
+
country: { type: String, trim: true, maxLength: 10 },
|
|
20
|
+
dialCode: { type: String, trim: true, maxLength: 10 },
|
|
21
|
+
icon: { type: String, trim: true, maxLength: 10 },
|
|
22
|
+
regionCode: { type: String, trim: true, maxLength: 10 }
|
|
23
|
+
},
|
|
24
|
+
urlImg: { type: String },
|
|
25
|
+
data: {
|
|
26
|
+
type: Object,
|
|
27
|
+
default: { changePwd: false }
|
|
28
|
+
},
|
|
29
|
+
validateKey: {
|
|
30
|
+
failedAttempts: { type: Number, default: 0 },
|
|
31
|
+
limitCodeTime: { type: Number },
|
|
32
|
+
resetPassword: {
|
|
33
|
+
resetCode: { type: Number },
|
|
34
|
+
validCode: { type: Boolean, default: false },
|
|
35
|
+
},
|
|
36
|
+
validateEmail: {
|
|
37
|
+
emailVerified: { type: Boolean, default: false },
|
|
38
|
+
verifyMailToken: { type: String },
|
|
39
|
+
},
|
|
40
|
+
validatePhone: {
|
|
41
|
+
codeVerifyPhone: { type: Number },
|
|
42
|
+
validCodePhone: { type: Boolean, default: false },
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
_functions: [
|
|
46
|
+
{
|
|
47
|
+
type: ObjectId, required: true, ref: 'Functions'
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
_business: [
|
|
51
|
+
{
|
|
52
|
+
type: ObjectId, ref: 'Business'
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
_client: [
|
|
56
|
+
{
|
|
57
|
+
type: ObjectId, ref: 'Client'
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
tokens: [
|
|
61
|
+
{
|
|
62
|
+
token: { type: String, required: true },
|
|
63
|
+
date: { type: Number },
|
|
64
|
+
dateEnd: { type: Number }
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
|
|
68
|
+
status: { type: String, required: true, enum: ['Activo','Inactivo','Bloqueado'], default: 'Activo' },
|
|
69
|
+
createdAt: { type: Number },
|
|
70
|
+
lastUpdate: { type: Number }
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
adminSchema.pre("save", async function (next) {
|
|
74
|
+
const user = this
|
|
75
|
+
|
|
76
|
+
if (user.isModified("pwd")) {
|
|
77
|
+
user.pwd = await bcrypt.hash(user.pwd, 8)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
next()
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
adminSchema.methods.generateAuthToken = async function () {
|
|
84
|
+
const user = this
|
|
85
|
+
|
|
86
|
+
const token = jwt.sign({ _id: user._id }, process.env.AUTH_SECRET)
|
|
87
|
+
const currentDate = (new Date()).getTime()
|
|
88
|
+
const dateEnd = currentDate + process.env.SESSION_TIME * 60 * 1000;
|
|
89
|
+
user.tokens = user.tokens.concat({ token, date: currentDate, dateEnd })
|
|
90
|
+
|
|
91
|
+
await user.save()
|
|
92
|
+
|
|
93
|
+
return token
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
adminSchema.statics.findByCredentials = async (email, pwd) => {
|
|
97
|
+
try {
|
|
98
|
+
const user = await User.findOne({ email: email })
|
|
99
|
+
|
|
100
|
+
if (!user) {
|
|
101
|
+
throw new Error({ error: "Invalid login credentials" })
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const isPasswordMatch = await bcrypt.compare(pwd, user.pwd)
|
|
105
|
+
|
|
106
|
+
if (!isPasswordMatch) {
|
|
107
|
+
throw new Error({ error: "Invalid login credentials" })
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return user
|
|
111
|
+
} catch (error) { }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const User = mongoose.model("User", adminSchema)
|
|
115
|
+
module.exports = User
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const mongoose = require("mongoose")
|
|
2
|
-
|
|
3
|
-
const userProvisional = mongoose.Schema({
|
|
4
|
-
email: { type: String, required: true, trim: true, unique: true, lowercase: true },
|
|
5
|
-
code: { type: Number, required: true },
|
|
6
|
-
createdAt: { type: Number },
|
|
7
|
-
lastUpdate: { type: Number }
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
const UserProvisional = mongoose.model("UserProvisional", userProvisional)
|
|
1
|
+
const mongoose = require("mongoose")
|
|
2
|
+
|
|
3
|
+
const userProvisional = mongoose.Schema({
|
|
4
|
+
email: { type: String, required: true, trim: true, unique: true, lowercase: true },
|
|
5
|
+
code: { type: Number, required: true },
|
|
6
|
+
createdAt: { type: Number },
|
|
7
|
+
lastUpdate: { type: Number }
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
const UserProvisional = mongoose.model("UserProvisional", userProvisional)
|
|
11
11
|
module.exports = UserProvisional
|
package/lib/router.js
CHANGED
|
@@ -1,104 +1,82 @@
|
|
|
1
|
-
const express = require("express");
|
|
2
|
-
const middleware = require("./middleware.js");
|
|
3
|
-
const router = express.Router();
|
|
4
|
-
|
|
5
|
-
const auth = require("./controllers/auth");
|
|
6
|
-
const user = require("./controllers/user");
|
|
7
|
-
const menu = require("./controllers/menu");
|
|
8
|
-
const permission = require("./controllers/permission");
|
|
9
|
-
const functions = require("./controllers/functions");
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
router.post("/iam/auth/
|
|
17
|
-
router.post("/iam/auth/
|
|
18
|
-
router.
|
|
19
|
-
router.post("/iam/auth/
|
|
20
|
-
router.post("/iam/auth/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
router.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
router.
|
|
27
|
-
router.
|
|
28
|
-
router.
|
|
29
|
-
router.
|
|
30
|
-
router.
|
|
31
|
-
router.post("/iam/auth/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
router.post("/iam/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
router.
|
|
38
|
-
router.
|
|
39
|
-
router.
|
|
40
|
-
router.
|
|
41
|
-
router.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
router.
|
|
45
|
-
router.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
router.
|
|
49
|
-
router.
|
|
50
|
-
router.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
router.
|
|
54
|
-
router.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
router.
|
|
67
|
-
router.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
router.
|
|
71
|
-
router.
|
|
72
|
-
router.
|
|
73
|
-
router.get("/iam/menu", middleware, menu.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
router.post("/iam/
|
|
77
|
-
router.get("/iam/
|
|
78
|
-
|
|
79
|
-
//
|
|
80
|
-
router.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// Utilities
|
|
84
|
-
router.patch("/iam/add/time/:TOKEN", user.addTimeToken);
|
|
85
|
-
|
|
86
|
-
// IAM / Label
|
|
87
|
-
router.post("/iam/label", middleware, label.create);
|
|
88
|
-
router.patch("/iam/label/:LABEL_ID", middleware, label.update);
|
|
89
|
-
router.put("/iam/label/:LABEL_ID/status", middleware, label.status);
|
|
90
|
-
router.get("/iam/label", middleware, label.retrieve);
|
|
91
|
-
router.get("/iam/label/:LABEL_ID", middleware, label.get);
|
|
92
|
-
router.delete("/iam/label/:LABEL_ID", middleware, label.delete);
|
|
93
|
-
router.get("/iam/label/count/all", middleware, label.count);
|
|
94
|
-
|
|
95
|
-
// IAM / Log
|
|
96
|
-
router.post("/iam/log", middleware, log.create);
|
|
97
|
-
router.patch("/iam/log/:LOG_ID", middleware, log.update);
|
|
98
|
-
router.put("/iam/log/:LOG_ID/status", middleware, log.status);
|
|
99
|
-
router.post("/iam/log/retrieve", middleware, log.retrieve);
|
|
100
|
-
router.get("/iam/log/:LOG_ID", middleware, log.get);
|
|
101
|
-
router.delete("/iam/log/:LOG_ID", middleware, log.delete);
|
|
102
|
-
router.get("/iam/log/count/all", middleware, log.count);
|
|
103
|
-
|
|
104
|
-
module.exports = router;
|
|
1
|
+
const express = require("express");
|
|
2
|
+
const middleware = require("./middleware.js");
|
|
3
|
+
const router = express.Router();
|
|
4
|
+
|
|
5
|
+
const auth = require("./controllers/auth");
|
|
6
|
+
const user = require("./controllers/user");
|
|
7
|
+
const menu = require("./controllers/menu");
|
|
8
|
+
const permission = require("./controllers/permission");
|
|
9
|
+
const functions = require("./controllers/functions");
|
|
10
|
+
const history = require("./controllers/history.js");
|
|
11
|
+
|
|
12
|
+
// User / user self (no auth)
|
|
13
|
+
router.post("/iam/auth/email", auth.email);
|
|
14
|
+
router.post("/iam/auth/login", auth.login);
|
|
15
|
+
router.post("/iam/auth/forgot/password", auth.recoverpassword);
|
|
16
|
+
router.post("/iam/auth/validate/code", auth.verifyCode);
|
|
17
|
+
router.post("/iam/auth/verify/mail", auth.sendVerifyMailAccount);
|
|
18
|
+
router.get("/iam/auth/verify/mail/token/:token", auth.verifyMailTokenAccount);
|
|
19
|
+
router.post("/iam/auth/reset/password", auth.resetPassword);
|
|
20
|
+
router.post("/iam/auth/signup", auth.createCustomer);
|
|
21
|
+
|
|
22
|
+
// User / user self
|
|
23
|
+
router.get("/iam/auth/me", middleware, auth.me);
|
|
24
|
+
router.patch("/iam/auth/profile", middleware, auth.updateAny);
|
|
25
|
+
router.put("/iam/auth/profile/pictura", middleware, auth.updatePicture);
|
|
26
|
+
router.put("/iam/auth/reset/password", middleware, auth.resetPass);
|
|
27
|
+
router.post("/iam/auth/send/verify/phone", middleware, auth.verifyPhone);
|
|
28
|
+
router.post("/iam/auth/verify/phone", middleware, auth.validatePhone);
|
|
29
|
+
router.post("/iam/auth/logout", middleware, auth.logout);
|
|
30
|
+
router.patch("/iam/auth/mail", middleware, auth.mailChange);
|
|
31
|
+
router.post("/iam/auth/validate/mail", middleware, auth.validatEmailChange);
|
|
32
|
+
|
|
33
|
+
// IAM / User
|
|
34
|
+
router.post("/iam/user", middleware, user.create);
|
|
35
|
+
router.get("/iam/user", middleware, user.retrieve);
|
|
36
|
+
router.get("/iam/user/:USER_ID", middleware, user.get);
|
|
37
|
+
router.patch("/iam/user/:USER_ID", middleware, user.update);
|
|
38
|
+
router.put("/iam/user/:USER_ID/status", middleware, user.status);
|
|
39
|
+
router.put("/iam/user/password/:USER_ID", middleware, user.updatepassword);
|
|
40
|
+
router.delete("/iam/user/:USER_ID", middleware, user.delete);
|
|
41
|
+
router.get("/iam/user/count/all", middleware, user.count);
|
|
42
|
+
|
|
43
|
+
// IAM / Function
|
|
44
|
+
router.post("/iam/functions", middleware, functions.create);
|
|
45
|
+
router.patch("/iam/functions/:FUNCTION_ID", middleware, functions.update);
|
|
46
|
+
router.put("/iam/functions/:FUNCTION_ID/status", middleware, functions.status);
|
|
47
|
+
router.get("/iam/functions", middleware, functions.retrieve);
|
|
48
|
+
router.get("/iam/functions/:FUNCTION_ID", middleware, functions.get);
|
|
49
|
+
router.delete("/iam/functions/:FUNCTION_ID", middleware, functions.delete);
|
|
50
|
+
router.get("/iam/functions/count/all", middleware, functions.count);
|
|
51
|
+
|
|
52
|
+
// IAM / Permission
|
|
53
|
+
router.post("/iam/permission", middleware, permission.create);
|
|
54
|
+
router.patch("/iam/permission/:PERMISSION_ID", middleware, permission.update);
|
|
55
|
+
router.put(
|
|
56
|
+
"/iam/permission/:PERMISSION_ID/status",
|
|
57
|
+
middleware,
|
|
58
|
+
permission.status
|
|
59
|
+
);
|
|
60
|
+
router.get("/iam/permission", middleware, permission.retrieve);
|
|
61
|
+
router.get("/iam/permission/:PERMISSION_ID", middleware, permission.get);
|
|
62
|
+
router.delete("/iam/permission/:PERMISSION_ID", middleware, permission.delete);
|
|
63
|
+
router.get("/iam/permission/count/all", middleware, permission.count);
|
|
64
|
+
|
|
65
|
+
// IAM / Menu
|
|
66
|
+
router.post("/iam/menu", middleware, menu.create);
|
|
67
|
+
router.patch("/iam/menu/:MENU_ID", middleware, menu.update);
|
|
68
|
+
router.put("/iam/menu/:MENU_ID/status", middleware, menu.status);
|
|
69
|
+
router.get("/iam/menu", middleware, menu.retrieve);
|
|
70
|
+
router.get("/iam/menu/:MENU_ID", middleware, menu.get);
|
|
71
|
+
router.delete("/iam/menu/:MENU_ID", middleware, menu.delete);
|
|
72
|
+
router.post("/iam/menu/order", middleware, menu.order);
|
|
73
|
+
router.get("/iam/menu/count/all", middleware, menu.count);
|
|
74
|
+
|
|
75
|
+
// IAM / History
|
|
76
|
+
router.post("/iam/retrieve/history", middleware, history.retrieve);
|
|
77
|
+
router.get("/iam/history/:HISTORY_ID", middleware, history.detail);
|
|
78
|
+
|
|
79
|
+
// Utilities
|
|
80
|
+
router.patch("/iam/add/time/:TOKEN", user.addTimeToken);
|
|
81
|
+
|
|
82
|
+
module.exports = router;
|