propro-utils 1.7.32 → 1.7.38
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-lock.json +9951 -0
- package/package.json +1 -1
- package/src/index.js +2 -0
- package/src/server/middleware/verifyToken.js +33 -25
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -118,12 +118,14 @@ class ProProAuthMiddleware {
|
|
|
118
118
|
|
|
119
119
|
middleware() {
|
|
120
120
|
return (req, res, next) => {
|
|
121
|
+
console.log("MIDDLEWARE: Entered")
|
|
121
122
|
try {
|
|
122
123
|
if (this.options.useServerAuth) {
|
|
123
124
|
return this.initializeServerAuth()(req, res, next);
|
|
124
125
|
} else if (this.options.useClientAuth) {
|
|
125
126
|
return this.initializeClientAuth()(req, res, next);
|
|
126
127
|
} else {
|
|
128
|
+
console.log("MIDDLEWARE: next()")
|
|
127
129
|
next();
|
|
128
130
|
}
|
|
129
131
|
} catch (error) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const axios = require(
|
|
2
|
-
const jwt = require(
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const jwt = require("jsonwebtoken");
|
|
3
3
|
const tokenCache = new Map();
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -8,18 +8,26 @@ const tokenCache = new Map();
|
|
|
8
8
|
* @param {string} secret - The secret used to sign the JWT.
|
|
9
9
|
* @returns {promise<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 =
|
|
11
|
+
async function verifyJWT(token, secret = "thisisasamplesecret") {
|
|
12
|
+
if (!secret) {
|
|
13
|
+
// Require JWT_SECRET from environment variables
|
|
14
|
+
if (!process.env.JWT_SECRET) {
|
|
15
|
+
throw new Error("JWT_SECRET environment variable is required");
|
|
16
|
+
}
|
|
17
|
+
secret = process.env.JWT_SECRET;
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
try {
|
|
13
21
|
return jwt.verify(token, secret);
|
|
14
22
|
} catch (err) {
|
|
15
|
-
try{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
}catch(e){
|
|
21
|
-
return null
|
|
23
|
+
try {
|
|
24
|
+
if (err.name === "TokenExpiredError") {
|
|
25
|
+
const newTokenData = await callTokenEndpoint(token);
|
|
26
|
+
return newTokenData ? jwt?.verify?.(newTokenData, secret) : null;
|
|
22
27
|
}
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
23
31
|
return null;
|
|
24
32
|
}
|
|
25
33
|
}
|
|
@@ -59,22 +67,22 @@ async function exchangeToken(
|
|
|
59
67
|
try {
|
|
60
68
|
const formattedRedirectUri = formatRedirectUrl(authUrl);
|
|
61
69
|
const response = await axios.post(
|
|
62
|
-
formattedRedirectUri +
|
|
70
|
+
formattedRedirectUri + "/api/v1/auth/authorize",
|
|
63
71
|
{
|
|
64
|
-
grantType:
|
|
72
|
+
grantType: "authorization_code",
|
|
65
73
|
code: code,
|
|
66
74
|
redirectUri: redirectUri,
|
|
67
75
|
clientId: clientId,
|
|
68
76
|
clientSecret: clientSecret,
|
|
69
77
|
},
|
|
70
78
|
{
|
|
71
|
-
headers: {
|
|
79
|
+
headers: { "Content-Type": "application/json" },
|
|
72
80
|
}
|
|
73
81
|
);
|
|
74
82
|
|
|
75
83
|
return response.data;
|
|
76
84
|
} catch (error) {
|
|
77
|
-
console.error(
|
|
85
|
+
console.error("Error exchanging token:", error);
|
|
78
86
|
return null;
|
|
79
87
|
}
|
|
80
88
|
}
|
|
@@ -84,11 +92,11 @@ async function exchangeToken(
|
|
|
84
92
|
* @param {Array} requiredPermissions - Array of required permissions for the user
|
|
85
93
|
* @returns {Function} - Express middleware function
|
|
86
94
|
*/
|
|
87
|
-
const VerifyAccount = requiredPermissions => {
|
|
95
|
+
const VerifyAccount = (requiredPermissions) => {
|
|
88
96
|
return async (req, res, next) => {
|
|
89
|
-
const accessToken = req.headers.authorization?.split(
|
|
97
|
+
const accessToken = req.headers.authorization?.split(" ")[1];
|
|
90
98
|
if (!accessToken) {
|
|
91
|
-
return res.status(401).json({ error:
|
|
99
|
+
return res.status(401).json({ error: "Access token is required" });
|
|
92
100
|
}
|
|
93
101
|
|
|
94
102
|
// Check if token is in cache
|
|
@@ -100,7 +108,7 @@ const VerifyAccount = requiredPermissions => {
|
|
|
100
108
|
try {
|
|
101
109
|
const decoded = jwt.verify(accessToken, process.env.JWT_SECRET);
|
|
102
110
|
if (!isValid(decoded, requiredPermissions)) {
|
|
103
|
-
return res.status(403).json({ error:
|
|
111
|
+
return res.status(403).json({ error: "Invalid permissions" });
|
|
104
112
|
}
|
|
105
113
|
tokenCache.set(accessToken, decoded);
|
|
106
114
|
req.user = decoded;
|
|
@@ -117,14 +125,14 @@ const VerifyAccount = requiredPermissions => {
|
|
|
117
125
|
);
|
|
118
126
|
|
|
119
127
|
if (!isValid(userResponse.data, requiredPermissions)) {
|
|
120
|
-
|
|
128
|
+
return res.status(403).json({ error: "Invalid permissions" });
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
tokenCache.set(accessToken, userResponse.data);
|
|
124
132
|
req.user = userResponse.data;
|
|
125
133
|
return next();
|
|
126
134
|
} catch (networkError) {
|
|
127
|
-
return res.status(401).json({ error:
|
|
135
|
+
return res.status(401).json({ error: "Error validating token" });
|
|
128
136
|
}
|
|
129
137
|
}
|
|
130
138
|
};
|
|
@@ -137,7 +145,7 @@ const VerifyAccount = requiredPermissions => {
|
|
|
137
145
|
* @returns {boolean} - Returns true if the decoded token has all the required permissions, false otherwise.
|
|
138
146
|
*/
|
|
139
147
|
function isValid(decodedToken, requiredPermissions) {
|
|
140
|
-
return requiredPermissions.every(permission =>
|
|
148
|
+
return requiredPermissions.every((permission) =>
|
|
141
149
|
decodedToken.permissions.includes(permission)
|
|
142
150
|
);
|
|
143
151
|
}
|
|
@@ -152,12 +160,12 @@ function formatRedirectUrl(redirectUrl) {
|
|
|
152
160
|
let urlToRedirect;
|
|
153
161
|
|
|
154
162
|
if (
|
|
155
|
-
!redirectUrl.startsWith(
|
|
156
|
-
!redirectUrl.startsWith(
|
|
163
|
+
!redirectUrl.startsWith("http://") &&
|
|
164
|
+
!redirectUrl.startsWith("https://")
|
|
157
165
|
) {
|
|
158
166
|
if (
|
|
159
|
-
redirectUrl.includes(
|
|
160
|
-
redirectUrl.includes(
|
|
167
|
+
redirectUrl.includes("localhost") |
|
|
168
|
+
redirectUrl.includes("host.docker.internal")
|
|
161
169
|
) {
|
|
162
170
|
urlToRedirect = `http://${redirectUrl}`;
|
|
163
171
|
} else {
|