@codisolutions23/node-utils 3.0.2 → 3.2.0
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/.changeset/README.md +8 -8
- package/.changeset/config.json +11 -11
- package/CHANGELOG.md +10 -0
- package/dist/index.d.mts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +68 -114
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -114
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/.changeset/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Changesets
|
|
2
|
-
|
|
3
|
-
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
-
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
-
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
-
|
|
7
|
-
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
-
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
package/.changeset/config.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
|
|
3
|
-
"changelog": "@changesets/cli/changelog",
|
|
4
|
-
"commit": false,
|
|
5
|
-
"fixed": [],
|
|
6
|
-
"linked": [],
|
|
7
|
-
"access": "restricted",
|
|
8
|
-
"baseBranch": "main",
|
|
9
|
-
"updateInternalDependencies": "patch",
|
|
10
|
-
"ignore": []
|
|
11
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "restricted",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @codisolutions23/node-utils
|
|
2
2
|
|
|
3
|
+
## 3.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3e1d36f: Enhanced cache system with clearer function names (`getCache`, `setCache`, `delCache`, `delCacheGroup`) and configurable TTL via environment variables. Improved error handling by replacing generic Error with NotFoundError for missing environment variables. Optimized authentication middleware logging to reduce production noise. Updated AWS SDK dependencies to latest versions.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Extended `DecodedToken` and `AuthenticatedRequest` interfaces with index signatures to support additional JWT claims and user properties. This improves flexibility for handling custom data without TypeScript errors while maintaining backward compatibility.
|
|
12
|
+
|
|
3
13
|
## 3.0.2
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -11,10 +11,12 @@ interface DecodedToken extends JwtPayload {
|
|
|
11
11
|
id?: string;
|
|
12
12
|
jti?: string;
|
|
13
13
|
role?: string;
|
|
14
|
+
[key: string]: any;
|
|
14
15
|
}
|
|
15
16
|
interface AuthenticatedRequest extends Request {
|
|
16
17
|
user?: DecodedToken & {
|
|
17
18
|
id: string;
|
|
19
|
+
[key: string]: any;
|
|
18
20
|
};
|
|
19
21
|
token?: string;
|
|
20
22
|
}
|
|
@@ -72,10 +74,10 @@ declare class useAtlas {
|
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
declare function useCache(): {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
getCache: <T = unknown>(cacheKey: string) => Promise<T | null>;
|
|
78
|
+
setCache: <T = unknown>(cacheKey: string, data: T, ttl?: number, group?: string) => Promise<void>;
|
|
79
|
+
delCache: (cacheKey: string) => Promise<void>;
|
|
80
|
+
delCacheGroup: (group: string) => Promise<void>;
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
declare function buildCacheKey(prefix: string, values: Record<string, any>): string;
|
package/dist/index.d.ts
CHANGED
|
@@ -11,10 +11,12 @@ interface DecodedToken extends JwtPayload {
|
|
|
11
11
|
id?: string;
|
|
12
12
|
jti?: string;
|
|
13
13
|
role?: string;
|
|
14
|
+
[key: string]: any;
|
|
14
15
|
}
|
|
15
16
|
interface AuthenticatedRequest extends Request {
|
|
16
17
|
user?: DecodedToken & {
|
|
17
18
|
id: string;
|
|
19
|
+
[key: string]: any;
|
|
18
20
|
};
|
|
19
21
|
token?: string;
|
|
20
22
|
}
|
|
@@ -72,10 +74,10 @@ declare class useAtlas {
|
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
declare function useCache(): {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
getCache: <T = unknown>(cacheKey: string) => Promise<T | null>;
|
|
78
|
+
setCache: <T = unknown>(cacheKey: string, data: T, ttl?: number, group?: string) => Promise<void>;
|
|
79
|
+
delCache: (cacheKey: string) => Promise<void>;
|
|
80
|
+
delCacheGroup: (group: string) => Promise<void>;
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
declare function buildCacheKey(prefix: string, values: Record<string, any>): string;
|
package/dist/index.js
CHANGED
|
@@ -167,23 +167,16 @@ var InternalServerError = class extends HttpError {
|
|
|
167
167
|
|
|
168
168
|
// src/middleware/auth.middleware.ts
|
|
169
169
|
function extractToken(authHeader) {
|
|
170
|
-
logger.debug("Attempting to extract token from Authorization header");
|
|
171
170
|
if (!authHeader) {
|
|
172
|
-
logger.debug("No Authorization header provided");
|
|
173
171
|
return null;
|
|
174
172
|
}
|
|
175
173
|
if (!authHeader.startsWith("Bearer ")) {
|
|
176
|
-
logger.warn("Authorization header
|
|
177
|
-
|
|
174
|
+
logger.warn("Invalid Authorization header format", {
|
|
175
|
+
format: "Expected 'Bearer <token>'"
|
|
178
176
|
});
|
|
179
177
|
return null;
|
|
180
178
|
}
|
|
181
|
-
|
|
182
|
-
logger.debug("Token extraction result", {
|
|
183
|
-
hasToken: !!token,
|
|
184
|
-
tokenLength: token == null ? void 0 : token.length
|
|
185
|
-
});
|
|
186
|
-
return token;
|
|
179
|
+
return authHeader.split(" ")[1] || null;
|
|
187
180
|
}
|
|
188
181
|
function authenticateToken(req, options) {
|
|
189
182
|
return __async(this, null, function* () {
|
|
@@ -193,13 +186,14 @@ function authenticateToken(req, options) {
|
|
|
193
186
|
requiredRole
|
|
194
187
|
} = options;
|
|
195
188
|
const requestId = req.headers["x-request-id"] || "unknown";
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
189
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
190
|
+
if (isDev) {
|
|
191
|
+
logger.debug("Starting authentication process", {
|
|
192
|
+
requestId,
|
|
193
|
+
path: req.path,
|
|
194
|
+
requiredRole
|
|
195
|
+
});
|
|
196
|
+
}
|
|
203
197
|
const token = extractToken(req.headers.authorization);
|
|
204
198
|
if (!token) {
|
|
205
199
|
logger.error("Authentication failed: No access token provided", {
|
|
@@ -208,36 +202,27 @@ function authenticateToken(req, options) {
|
|
|
208
202
|
});
|
|
209
203
|
throw new UnauthorizedError("Access token is required to proceed.");
|
|
210
204
|
}
|
|
211
|
-
logger.debug("Token extracted successfully, proceeding with verification", {
|
|
212
|
-
requestId,
|
|
213
|
-
tokenLength: token.length
|
|
214
|
-
});
|
|
215
205
|
let decoded;
|
|
216
206
|
try {
|
|
217
|
-
logger.debug("Verifying JWT token", { requestId });
|
|
218
207
|
decoded = import_jsonwebtoken.default.verify(token, secretKey);
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
208
|
+
if (isDev) {
|
|
209
|
+
logger.debug("JWT token verified", {
|
|
210
|
+
requestId,
|
|
211
|
+
userId: decoded.user || decoded.id,
|
|
212
|
+
role: decoded.role
|
|
213
|
+
});
|
|
214
|
+
}
|
|
226
215
|
} catch (error) {
|
|
227
216
|
logger.error("JWT verification failed", {
|
|
228
217
|
requestId,
|
|
229
|
-
error: error instanceof Error ? error.message : "
|
|
230
|
-
|
|
218
|
+
error: error instanceof Error ? error.message : "Invalid token",
|
|
219
|
+
path: req.path
|
|
231
220
|
});
|
|
232
221
|
throw new UnauthorizedError(
|
|
233
222
|
"Your session has expired or the token is invalid. Please log in again."
|
|
234
223
|
);
|
|
235
224
|
}
|
|
236
225
|
if (isTokenRevoked && decoded.jti) {
|
|
237
|
-
logger.debug("Checking token revocation status", {
|
|
238
|
-
requestId,
|
|
239
|
-
jti: decoded.jti
|
|
240
|
-
});
|
|
241
226
|
const isRevoked = yield isTokenRevoked(decoded.jti);
|
|
242
227
|
if (isRevoked) {
|
|
243
228
|
logger.warn("Authentication failed: Token is revoked", {
|
|
@@ -249,10 +234,6 @@ function authenticateToken(req, options) {
|
|
|
249
234
|
"Your session has expired or the token is invalid. Please log in again."
|
|
250
235
|
);
|
|
251
236
|
}
|
|
252
|
-
logger.debug("Token revocation check passed", {
|
|
253
|
-
requestId,
|
|
254
|
-
jti: decoded.jti
|
|
255
|
-
});
|
|
256
237
|
}
|
|
257
238
|
if (requiredRole && decoded.role !== requiredRole) {
|
|
258
239
|
logger.warn("Authorization failed: Insufficient permissions", {
|
|
@@ -270,31 +251,22 @@ function authenticateToken(req, options) {
|
|
|
270
251
|
id: decoded.user || decoded.id || ""
|
|
271
252
|
});
|
|
272
253
|
req.token = token;
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
254
|
+
if (isDev) {
|
|
255
|
+
logger.debug("Authentication completed successfully", {
|
|
256
|
+
requestId,
|
|
257
|
+
userId: req.user.id,
|
|
258
|
+
role: req.user.role
|
|
259
|
+
});
|
|
260
|
+
}
|
|
280
261
|
});
|
|
281
262
|
}
|
|
282
263
|
function authenticate(secretKey = process.env.ACCESS_TOKEN_SECRET || "", isTokenRevoked) {
|
|
283
264
|
return (req, res, next) => __async(null, null, function* () {
|
|
284
|
-
const requestId = req.headers["x-request-id"] || "unknown";
|
|
285
|
-
logger.debug("Authenticate middleware invoked", {
|
|
286
|
-
requestId,
|
|
287
|
-
path: req.path
|
|
288
|
-
});
|
|
289
265
|
try {
|
|
290
266
|
yield authenticateToken(req, { secretKey, isTokenRevoked });
|
|
291
|
-
logger.debug("Authenticate middleware completed successfully", {
|
|
292
|
-
requestId
|
|
293
|
-
});
|
|
294
267
|
next();
|
|
295
268
|
} catch (error) {
|
|
296
269
|
logger.error("Authenticate middleware failed", {
|
|
297
|
-
requestId,
|
|
298
270
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
299
271
|
});
|
|
300
272
|
next(error);
|
|
@@ -303,24 +275,15 @@ function authenticate(secretKey = process.env.ACCESS_TOKEN_SECRET || "", isToken
|
|
|
303
275
|
}
|
|
304
276
|
function requireAdmin(secretKey = process.env.ACCESS_TOKEN_SECRET || "", isTokenRevoked) {
|
|
305
277
|
return (req, res, next) => __async(null, null, function* () {
|
|
306
|
-
const requestId = req.headers["x-request-id"] || "unknown";
|
|
307
|
-
logger.debug("RequireAdmin middleware invoked", {
|
|
308
|
-
requestId,
|
|
309
|
-
path: req.path
|
|
310
|
-
});
|
|
311
278
|
try {
|
|
312
279
|
yield authenticateToken(req, {
|
|
313
280
|
secretKey,
|
|
314
281
|
isTokenRevoked,
|
|
315
282
|
requiredRole: "admin"
|
|
316
283
|
});
|
|
317
|
-
logger.debug("RequireAdmin middleware completed successfully", {
|
|
318
|
-
requestId
|
|
319
|
-
});
|
|
320
284
|
next();
|
|
321
285
|
} catch (error) {
|
|
322
286
|
logger.error("RequireAdmin middleware failed", {
|
|
323
|
-
requestId,
|
|
324
287
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
325
288
|
});
|
|
326
289
|
next(error);
|
|
@@ -329,24 +292,13 @@ function requireAdmin(secretKey = process.env.ACCESS_TOKEN_SECRET || "", isToken
|
|
|
329
292
|
}
|
|
330
293
|
function requireRole(role, options) {
|
|
331
294
|
return (req, res, next) => __async(null, null, function* () {
|
|
332
|
-
const requestId = req.headers["x-request-id"] || "unknown";
|
|
333
|
-
logger.debug("RequireRole middleware invoked", {
|
|
334
|
-
requestId,
|
|
335
|
-
path: req.path,
|
|
336
|
-
requiredRole: role
|
|
337
|
-
});
|
|
338
295
|
try {
|
|
339
296
|
yield authenticateToken(req, __spreadProps(__spreadValues({}, options), {
|
|
340
297
|
requiredRole: role
|
|
341
298
|
}));
|
|
342
|
-
logger.debug("RequireRole middleware completed successfully", {
|
|
343
|
-
requestId,
|
|
344
|
-
role
|
|
345
|
-
});
|
|
346
299
|
next();
|
|
347
300
|
} catch (error) {
|
|
348
301
|
logger.error("RequireRole middleware failed", {
|
|
349
|
-
requestId,
|
|
350
302
|
requiredRole: role,
|
|
351
303
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
352
304
|
});
|
|
@@ -447,6 +399,34 @@ var useAtlas = class {
|
|
|
447
399
|
useAtlas.mongoClient = null;
|
|
448
400
|
useAtlas.mongoDb = null;
|
|
449
401
|
|
|
402
|
+
// src/config.ts
|
|
403
|
+
var dotenv = __toESM(require("dotenv"));
|
|
404
|
+
dotenv.config();
|
|
405
|
+
function getEnv(key, fallback) {
|
|
406
|
+
const value = process.env[key];
|
|
407
|
+
if (value !== void 0) return value;
|
|
408
|
+
if (fallback !== void 0) return fallback;
|
|
409
|
+
throw new NotFoundError(`Missing required environment variable: ${key}`);
|
|
410
|
+
}
|
|
411
|
+
function getEnvNumber(key, fallback) {
|
|
412
|
+
const value = process.env[key];
|
|
413
|
+
if (value !== void 0) return Number(value);
|
|
414
|
+
if (fallback !== void 0) return fallback;
|
|
415
|
+
throw new NotFoundError(`Missing required environment variable: ${key}`);
|
|
416
|
+
}
|
|
417
|
+
function getEnvBoolean(key, fallback) {
|
|
418
|
+
const value = process.env[key];
|
|
419
|
+
if (value !== void 0) return value === "true";
|
|
420
|
+
if (fallback !== void 0) return fallback;
|
|
421
|
+
throw new NotFoundError(`Missing required environment variable: ${key}`);
|
|
422
|
+
}
|
|
423
|
+
var REDIS_HOST = getEnv("REDIS_HOST");
|
|
424
|
+
var REDIS_PORT = getEnvNumber("REDIS_PORT", 6379);
|
|
425
|
+
var REDIS_PASSWORD = getEnv("REDIS_PASSWORD");
|
|
426
|
+
var REDIS_TLS = getEnvBoolean("REDIS_TLS", true);
|
|
427
|
+
var CACHE_SHORT_TTL = getEnvNumber("CACHE_SHORT_TTL", 300);
|
|
428
|
+
var CACHE_LONG_TTL = getEnvNumber("CACHE_LONG_TTL", 3600);
|
|
429
|
+
|
|
450
430
|
// src/utils/ioredis.ts
|
|
451
431
|
var import_ioredis = __toESM(require("ioredis"));
|
|
452
432
|
var redisClient = null;
|
|
@@ -505,12 +485,11 @@ function useRedis() {
|
|
|
505
485
|
}
|
|
506
486
|
|
|
507
487
|
// src/utils/cache.ts
|
|
508
|
-
var DEFAULT_TTL = 300;
|
|
509
488
|
function useCache() {
|
|
510
489
|
function getRedisClient() {
|
|
511
490
|
return useRedis().getClient();
|
|
512
491
|
}
|
|
513
|
-
function
|
|
492
|
+
function getCache(cacheKey) {
|
|
514
493
|
return __async(this, null, function* () {
|
|
515
494
|
try {
|
|
516
495
|
const redisClient3 = getRedisClient();
|
|
@@ -524,13 +503,16 @@ function useCache() {
|
|
|
524
503
|
}
|
|
525
504
|
});
|
|
526
505
|
}
|
|
527
|
-
function
|
|
528
|
-
return __async(this, arguments, function* (cacheKey, data, ttl =
|
|
506
|
+
function setCache(_0, _1) {
|
|
507
|
+
return __async(this, arguments, function* (cacheKey, data, ttl = CACHE_SHORT_TTL, group) {
|
|
529
508
|
try {
|
|
530
509
|
const redisClient3 = getRedisClient();
|
|
531
510
|
yield redisClient3.set(cacheKey, JSON.stringify(data), "EX", ttl);
|
|
532
511
|
logger.info(`[Cache][Set] Stored key "${cacheKey}" with TTL ${ttl}s.`);
|
|
533
|
-
if (group)
|
|
512
|
+
if (group) {
|
|
513
|
+
yield redisClient3.sadd(`cache:group:${group}`, cacheKey);
|
|
514
|
+
yield redisClient3.expire(`cache:group:${group}`, CACHE_LONG_TTL);
|
|
515
|
+
}
|
|
534
516
|
} catch (error) {
|
|
535
517
|
logger.error(
|
|
536
518
|
`[Cache][Set] Failed to store key "${cacheKey}": ${error instanceof Error ? error.message : error}`
|
|
@@ -538,7 +520,7 @@ function useCache() {
|
|
|
538
520
|
}
|
|
539
521
|
});
|
|
540
522
|
}
|
|
541
|
-
function
|
|
523
|
+
function delCache(cacheKey) {
|
|
542
524
|
return __async(this, null, function* () {
|
|
543
525
|
try {
|
|
544
526
|
const redisClient3 = getRedisClient();
|
|
@@ -551,7 +533,7 @@ function useCache() {
|
|
|
551
533
|
}
|
|
552
534
|
});
|
|
553
535
|
}
|
|
554
|
-
function
|
|
536
|
+
function delCacheGroup(group) {
|
|
555
537
|
return __async(this, null, function* () {
|
|
556
538
|
try {
|
|
557
539
|
const redisClient3 = getRedisClient();
|
|
@@ -567,10 +549,10 @@ function useCache() {
|
|
|
567
549
|
});
|
|
568
550
|
}
|
|
569
551
|
return {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
552
|
+
getCache,
|
|
553
|
+
setCache,
|
|
554
|
+
delCache,
|
|
555
|
+
delCacheGroup
|
|
574
556
|
};
|
|
575
557
|
}
|
|
576
558
|
|
|
@@ -815,34 +797,6 @@ function hashPassword(_0) {
|
|
|
815
797
|
|
|
816
798
|
// src/utils/redis.ts
|
|
817
799
|
var import_redis = require("redis");
|
|
818
|
-
|
|
819
|
-
// src/config.ts
|
|
820
|
-
var dotenv = __toESM(require("dotenv"));
|
|
821
|
-
dotenv.config();
|
|
822
|
-
function getEnv(key, fallback) {
|
|
823
|
-
const value = process.env[key];
|
|
824
|
-
if (value !== void 0) return value;
|
|
825
|
-
if (fallback !== void 0) return fallback;
|
|
826
|
-
throw new Error(`Missing required environment variable: ${key}`);
|
|
827
|
-
}
|
|
828
|
-
function getEnvNumber(key, fallback) {
|
|
829
|
-
const value = process.env[key];
|
|
830
|
-
if (value !== void 0) return Number(value);
|
|
831
|
-
if (fallback !== void 0) return fallback;
|
|
832
|
-
throw new Error(`Missing required environment variable: ${key}`);
|
|
833
|
-
}
|
|
834
|
-
function getEnvBoolean(key, fallback) {
|
|
835
|
-
const value = process.env[key];
|
|
836
|
-
if (value !== void 0) return value === "true";
|
|
837
|
-
if (fallback !== void 0) return fallback;
|
|
838
|
-
throw new Error(`Missing required environment variable: ${key}`);
|
|
839
|
-
}
|
|
840
|
-
var REDIS_HOST = getEnv("REDIS_HOST");
|
|
841
|
-
var REDIS_PORT = getEnvNumber("REDIS_PORT", 6379);
|
|
842
|
-
var REDIS_PASSWORD = getEnv("REDIS_PASSWORD");
|
|
843
|
-
var REDIS_TLS = getEnvBoolean("REDIS_TLS", true);
|
|
844
|
-
|
|
845
|
-
// src/utils/redis.ts
|
|
846
800
|
var redisClient2 = null;
|
|
847
801
|
function initRedisClient() {
|
|
848
802
|
return __async(this, null, function* () {
|