propro-utils 1.4.18 → 1.4.19
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/package.json
CHANGED
package/src/server/index.js
CHANGED
|
@@ -8,28 +8,28 @@ const tokenCache = new Map();
|
|
|
8
8
|
* @param {string} secret - The secret used to sign the JWT.
|
|
9
9
|
* @returns {object|null} - The decoded payload of the JWT if it is valid, or null if it is not valid.
|
|
10
10
|
*/
|
|
11
|
-
async function verifyJWT(token, secret= "thisisasamplesecret") {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
async function verifyJWT(token, secret = "thisisasamplesecret") {
|
|
12
|
+
try {
|
|
13
|
+
return jwt.verify(token, secret);
|
|
14
|
+
} catch (err) {
|
|
15
|
+
if (err.name === 'TokenExpiredError') {
|
|
16
|
+
const newTokenData = await callTokenEndpoint(token);
|
|
17
|
+
return newTokenData ? jwt.verify(newTokenData, secret) : null;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
18
20
|
}
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
async function callTokenEndpoint(token) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
try {
|
|
25
|
+
const response = await axios.post(`${process.env.AUTH_URL}/api/v1/tokens`, {
|
|
26
|
+
refreshToken: token,
|
|
27
|
+
});
|
|
28
|
+
return response.data.tokens ? response.data.tokens.access.token : null;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error('Error during token refresh:', error);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -42,27 +42,32 @@ async function callTokenEndpoint(token) {
|
|
|
42
42
|
* @returns {Promise<Object>} - The response data containing the access token.
|
|
43
43
|
*/
|
|
44
44
|
async function exchangeToken(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
authUrl,
|
|
46
|
+
code,
|
|
47
|
+
clientId,
|
|
48
|
+
clientSecret,
|
|
49
|
+
redirectUri
|
|
50
50
|
) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
try {
|
|
52
|
+
const response = await axios.post(
|
|
53
|
+
authUrl + "/api/v1/auth/authorize",
|
|
54
|
+
{
|
|
55
|
+
grantType: "authorization_code",
|
|
56
|
+
code: code,
|
|
57
|
+
redirectUri: redirectUri,
|
|
58
|
+
clientId: clientId,
|
|
59
|
+
clientSecret: clientSecret,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
headers: {"Content-Type": "application/json"},
|
|
63
|
+
}
|
|
64
|
+
);
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
return response.data;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error("Error exchanging token:", error);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
/**
|
|
@@ -71,49 +76,49 @@ async function exchangeToken(
|
|
|
71
76
|
* @returns {Function} - Express middleware function
|
|
72
77
|
*/
|
|
73
78
|
const VerifyAccount = (requiredPermissions) => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
return async (req, res, next) => {
|
|
80
|
+
const accessToken = req.headers.authorization?.split(" ")[1];
|
|
81
|
+
if (!accessToken) {
|
|
82
|
+
return res.status(401).json({error: "Access token is required"});
|
|
83
|
+
}
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
// Check if token is in cache
|
|
86
|
+
if (tokenCache.has(accessToken)) {
|
|
87
|
+
req.user = tokenCache.get(accessToken);
|
|
88
|
+
return next();
|
|
89
|
+
}
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
91
|
+
try {
|
|
92
|
+
const decoded = jwt.verify(accessToken, process.env.JWT_SECRET);
|
|
93
|
+
if (!isValid(decoded, requiredPermissions)) {
|
|
94
|
+
return res.status(403).json({error: "Invalid permissions"});
|
|
95
|
+
}
|
|
96
|
+
tokenCache.set(accessToken, decoded);
|
|
97
|
+
req.user = decoded;
|
|
98
|
+
return next();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
try {
|
|
101
|
+
const userResponse = await axios.get(
|
|
102
|
+
`${process.env.AUTH_URL}/api/user`,
|
|
103
|
+
{
|
|
104
|
+
headers: {
|
|
105
|
+
Authorization: `Bearer ${accessToken}`,
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
);
|
|
104
109
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
if (!isValid(userResponse.data, requiredPermissions)) {
|
|
111
|
+
return res.status(403).json({error: "Invalid permissions"});
|
|
112
|
+
}
|
|
108
113
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
tokenCache.set(accessToken, userResponse.data);
|
|
115
|
+
req.user = userResponse.data;
|
|
116
|
+
return next();
|
|
117
|
+
} catch (networkError) {
|
|
118
|
+
return res.status(500).json({error: "Error validating token"});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
117
122
|
};
|
|
118
123
|
|
|
119
124
|
/**
|
|
@@ -123,13 +128,13 @@ const VerifyAccount = (requiredPermissions) => {
|
|
|
123
128
|
* @returns {boolean} - Returns true if the decoded token has all the required permissions, false otherwise.
|
|
124
129
|
*/
|
|
125
130
|
function isValid(decodedToken, requiredPermissions) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
return requiredPermissions.every((permission) =>
|
|
132
|
+
decodedToken.permissions.includes(permission)
|
|
133
|
+
);
|
|
129
134
|
}
|
|
130
135
|
|
|
131
136
|
module.exports = {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
VerifyAccount,
|
|
138
|
+
exchangeToken,
|
|
139
|
+
verifyJWT,
|
|
135
140
|
};
|