@codisolutions23/node-utils 1.1.0 → 1.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/CHANGELOG.md +51 -0
- package/dist/index.d.mts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +68 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/.changeset/comprehensive-improvements.md +0 -29
- package/README.md +0 -517
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# @codisolutions23/node-utils
|
|
2
|
+
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4ef458f: # 🚀 Comprehensive Package Enhancement
|
|
8
|
+
|
|
9
|
+
## ✨ New Features
|
|
10
|
+
|
|
11
|
+
- **NEW**: `ConflictError` class for HTTP 409 responses
|
|
12
|
+
- **NEW**: Enhanced `AuthenticatedRequest` interface with better TypeScript support
|
|
13
|
+
- **NEW**: Comprehensive README documentation with usage examples and API reference
|
|
14
|
+
|
|
15
|
+
## 🔧 Improvements
|
|
16
|
+
|
|
17
|
+
- **Enhanced**: Auth middleware with improved token handling and error messages
|
|
18
|
+
- **Improved**: Error handler middleware with better import paths
|
|
19
|
+
- **Simplified**: Configuration system for better flexibility
|
|
20
|
+
- **Updated**: All AWS SDK packages to latest versions (3.857.x → 3.859.x)
|
|
21
|
+
- **Updated**: Redis ecosystem packages (redis 5.6.1 → 5.8.0, ioredis 5.6.1 → 5.7.0)
|
|
22
|
+
- **Updated**: TypeScript to 5.9.2 for improved type safety
|
|
23
|
+
|
|
24
|
+
## 📚 Documentation
|
|
25
|
+
|
|
26
|
+
- Complete README overhaul with detailed usage examples
|
|
27
|
+
- API reference for all utilities and middleware
|
|
28
|
+
- Best practices and configuration guides
|
|
29
|
+
- Testing support examples and mock utilities
|
|
30
|
+
|
|
31
|
+
## 🛡️ Security & Performance
|
|
32
|
+
|
|
33
|
+
- Latest security patches through dependency updates
|
|
34
|
+
- Improved error handling and logging
|
|
35
|
+
- Better TypeScript type definitions
|
|
36
|
+
|
|
37
|
+
- f57eb57: # 🚀 Comprehensive Package Enhancement
|
|
38
|
+
|
|
39
|
+
## ✨ New Features
|
|
40
|
+
|
|
41
|
+
- **NEW**: Added `validate-request.middleware` for request validation
|
|
42
|
+
- **NEW**: Introduced `token.utils` for token-related operations
|
|
43
|
+
|
|
44
|
+
## 🔧 Improvements
|
|
45
|
+
|
|
46
|
+
- **Updated**: Configuration file with minor adjustments
|
|
47
|
+
- **Enhanced**: `auth.middleware` with better token handling and error responses
|
|
48
|
+
|
|
49
|
+
## 🛡️ Security & Performance
|
|
50
|
+
|
|
51
|
+
- Minor internal optimizations for better stability
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
2
|
import jwt, { JwtPayload } from 'jsonwebtoken';
|
|
3
|
+
import { Schema } from 'joi';
|
|
3
4
|
import { MongoClient, Db, ObjectId } from 'mongodb';
|
|
4
5
|
import Redis from 'ioredis';
|
|
5
6
|
import * as winston from 'winston';
|
|
@@ -7,11 +8,12 @@ import { RedisClientType } from 'redis';
|
|
|
7
8
|
|
|
8
9
|
interface AuthenticatedRequest extends Request {
|
|
9
10
|
user?: JwtPayload & {
|
|
11
|
+
user?: string;
|
|
10
12
|
id?: string;
|
|
11
13
|
};
|
|
12
14
|
token?: string;
|
|
13
15
|
}
|
|
14
|
-
declare function authenticate(secretKey?: string): (req: AuthenticatedRequest, res: Response, next: NextFunction) => void
|
|
16
|
+
declare function authenticate(secretKey?: string): (req: AuthenticatedRequest, res: Response, next: NextFunction) => Promise<void>;
|
|
15
17
|
|
|
16
18
|
declare class HttpError extends Error {
|
|
17
19
|
readonly statusCode: number;
|
|
@@ -42,6 +44,8 @@ declare class InternalServerError extends HttpError {
|
|
|
42
44
|
|
|
43
45
|
declare const errorHandler: (error: HttpError, req: Request, res: Response, next: NextFunction) => void;
|
|
44
46
|
|
|
47
|
+
declare function validate(schema: Schema): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
48
|
+
|
|
45
49
|
interface AtlasConfig {
|
|
46
50
|
uri: string;
|
|
47
51
|
db: string;
|
|
@@ -56,8 +60,6 @@ declare class useAtlas {
|
|
|
56
60
|
static close(): Promise<void>;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
declare function buildCacheKey(prefix: string, values: Record<string, any>): string;
|
|
60
|
-
|
|
61
63
|
declare function useCache(): {
|
|
62
64
|
get: <T = unknown>(cacheKey: string) => Promise<T | null>;
|
|
63
65
|
set: <T = unknown>(cacheKey: string, data: T, ttl?: number, group?: string) => Promise<void>;
|
|
@@ -65,6 +67,8 @@ declare function useCache(): {
|
|
|
65
67
|
clearGroup: (group: string) => Promise<void>;
|
|
66
68
|
};
|
|
67
69
|
|
|
70
|
+
declare function buildCacheKey(prefix: string, values: Record<string, any>): string;
|
|
71
|
+
|
|
68
72
|
declare function getTemplatePath(directory: string, filePath: string): string;
|
|
69
73
|
|
|
70
74
|
interface CompileOptions {
|
|
@@ -149,4 +153,6 @@ declare class useS3 {
|
|
|
149
153
|
deleteObject(key: string): Promise<string>;
|
|
150
154
|
}
|
|
151
155
|
|
|
152
|
-
|
|
156
|
+
declare function hashToken(token: string): string;
|
|
157
|
+
|
|
158
|
+
export { type AuthenticatedRequest, BadRequestError, ConflictError, ForbiddenError, HttpError, InternalServerError, NotFoundError, UnauthorizedError, UnprocessableEntityError, authenticate, buildCacheKey, comparePasswords, errorHandler, getTemplatePath, hashPassword, hashToken, initRedisClient, logger, paginate, renderHandlebarsTemplate, signJwtToken, toObjectId, useAtlas, useCache, useMailer, useRedis, useRedisClient, useS3, validate };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
2
|
import jwt, { JwtPayload } from 'jsonwebtoken';
|
|
3
|
+
import { Schema } from 'joi';
|
|
3
4
|
import { MongoClient, Db, ObjectId } from 'mongodb';
|
|
4
5
|
import Redis from 'ioredis';
|
|
5
6
|
import * as winston from 'winston';
|
|
@@ -7,11 +8,12 @@ import { RedisClientType } from 'redis';
|
|
|
7
8
|
|
|
8
9
|
interface AuthenticatedRequest extends Request {
|
|
9
10
|
user?: JwtPayload & {
|
|
11
|
+
user?: string;
|
|
10
12
|
id?: string;
|
|
11
13
|
};
|
|
12
14
|
token?: string;
|
|
13
15
|
}
|
|
14
|
-
declare function authenticate(secretKey?: string): (req: AuthenticatedRequest, res: Response, next: NextFunction) => void
|
|
16
|
+
declare function authenticate(secretKey?: string): (req: AuthenticatedRequest, res: Response, next: NextFunction) => Promise<void>;
|
|
15
17
|
|
|
16
18
|
declare class HttpError extends Error {
|
|
17
19
|
readonly statusCode: number;
|
|
@@ -42,6 +44,8 @@ declare class InternalServerError extends HttpError {
|
|
|
42
44
|
|
|
43
45
|
declare const errorHandler: (error: HttpError, req: Request, res: Response, next: NextFunction) => void;
|
|
44
46
|
|
|
47
|
+
declare function validate(schema: Schema): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
48
|
+
|
|
45
49
|
interface AtlasConfig {
|
|
46
50
|
uri: string;
|
|
47
51
|
db: string;
|
|
@@ -56,8 +60,6 @@ declare class useAtlas {
|
|
|
56
60
|
static close(): Promise<void>;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
declare function buildCacheKey(prefix: string, values: Record<string, any>): string;
|
|
60
|
-
|
|
61
63
|
declare function useCache(): {
|
|
62
64
|
get: <T = unknown>(cacheKey: string) => Promise<T | null>;
|
|
63
65
|
set: <T = unknown>(cacheKey: string, data: T, ttl?: number, group?: string) => Promise<void>;
|
|
@@ -65,6 +67,8 @@ declare function useCache(): {
|
|
|
65
67
|
clearGroup: (group: string) => Promise<void>;
|
|
66
68
|
};
|
|
67
69
|
|
|
70
|
+
declare function buildCacheKey(prefix: string, values: Record<string, any>): string;
|
|
71
|
+
|
|
68
72
|
declare function getTemplatePath(directory: string, filePath: string): string;
|
|
69
73
|
|
|
70
74
|
interface CompileOptions {
|
|
@@ -149,4 +153,6 @@ declare class useS3 {
|
|
|
149
153
|
deleteObject(key: string): Promise<string>;
|
|
150
154
|
}
|
|
151
155
|
|
|
152
|
-
|
|
156
|
+
declare function hashToken(token: string): string;
|
|
157
|
+
|
|
158
|
+
export { type AuthenticatedRequest, BadRequestError, ConflictError, ForbiddenError, HttpError, InternalServerError, NotFoundError, UnauthorizedError, UnprocessableEntityError, authenticate, buildCacheKey, comparePasswords, errorHandler, getTemplatePath, hashPassword, hashToken, initRedisClient, logger, paginate, renderHandlebarsTemplate, signJwtToken, toObjectId, useAtlas, useCache, useMailer, useRedis, useRedisClient, useS3, validate };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
8
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
9
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -19,6 +21,7 @@ var __spreadValues = (a, b) => {
|
|
|
19
21
|
}
|
|
20
22
|
return a;
|
|
21
23
|
};
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
22
25
|
var __export = (target, all) => {
|
|
23
26
|
for (var name in all)
|
|
24
27
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -78,6 +81,7 @@ __export(index_exports, {
|
|
|
78
81
|
errorHandler: () => errorHandler,
|
|
79
82
|
getTemplatePath: () => getTemplatePath,
|
|
80
83
|
hashPassword: () => hashPassword,
|
|
84
|
+
hashToken: () => hashToken,
|
|
81
85
|
initRedisClient: () => initRedisClient,
|
|
82
86
|
logger: () => logger,
|
|
83
87
|
paginate: () => paginate,
|
|
@@ -89,7 +93,8 @@ __export(index_exports, {
|
|
|
89
93
|
useMailer: () => useMailer,
|
|
90
94
|
useRedis: () => useRedis,
|
|
91
95
|
useRedisClient: () => useRedisClient,
|
|
92
|
-
useS3: () => useS3
|
|
96
|
+
useS3: () => useS3,
|
|
97
|
+
validate: () => validate
|
|
93
98
|
});
|
|
94
99
|
module.exports = __toCommonJS(index_exports);
|
|
95
100
|
|
|
@@ -161,7 +166,7 @@ var InternalServerError = class extends HttpError {
|
|
|
161
166
|
|
|
162
167
|
// src/middleware/auth.middleware.ts
|
|
163
168
|
function authenticate(secretKey = process.env.ACCESS_TOKEN_SECRET || "") {
|
|
164
|
-
return (req, res, next) => {
|
|
169
|
+
return (req, res, next) => __async(null, null, function* () {
|
|
165
170
|
const authHeader = req.headers.authorization;
|
|
166
171
|
const token = authHeader == null ? void 0 : authHeader.split(" ")[1];
|
|
167
172
|
if (!token) {
|
|
@@ -170,20 +175,22 @@ function authenticate(secretKey = process.env.ACCESS_TOKEN_SECRET || "") {
|
|
|
170
175
|
new UnauthorizedError("Access token is required to proceed.")
|
|
171
176
|
);
|
|
172
177
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
"Your session has expired or the token is invalid. Please log in again."
|
|
179
|
-
)
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
req.user = decoded;
|
|
178
|
+
try {
|
|
179
|
+
const decoded = import_jsonwebtoken.default.verify(token, secretKey);
|
|
180
|
+
req.user = __spreadProps(__spreadValues({}, decoded), {
|
|
181
|
+
id: decoded.user || decoded.id
|
|
182
|
+
});
|
|
183
183
|
req.token = token;
|
|
184
184
|
next();
|
|
185
|
-
})
|
|
186
|
-
|
|
185
|
+
} catch (error) {
|
|
186
|
+
logger.error("Failed to verify access token.", error);
|
|
187
|
+
return next(
|
|
188
|
+
new UnauthorizedError(
|
|
189
|
+
"Your session has expired or the token is invalid. Please log in again."
|
|
190
|
+
)
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
187
194
|
}
|
|
188
195
|
|
|
189
196
|
// src/middleware/error-handler.middleware.ts
|
|
@@ -197,6 +204,28 @@ var errorHandler = (error, req, res, next) => {
|
|
|
197
204
|
return;
|
|
198
205
|
};
|
|
199
206
|
|
|
207
|
+
// src/middleware/validate-request.middleware.ts
|
|
208
|
+
function validate(schema) {
|
|
209
|
+
return (req, res, next) => __async(null, null, function* () {
|
|
210
|
+
try {
|
|
211
|
+
const validationOptions = {
|
|
212
|
+
abortEarly: false
|
|
213
|
+
// Return all validation errors
|
|
214
|
+
};
|
|
215
|
+
const { error, value } = schema.validate(req.body, validationOptions);
|
|
216
|
+
if (error) {
|
|
217
|
+
throw new BadRequestError(
|
|
218
|
+
`Request body validation failed: ${error.details.map((detail) => detail.message).join(", ")}`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
req.body = value;
|
|
222
|
+
next();
|
|
223
|
+
} catch (error) {
|
|
224
|
+
next(error);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
200
229
|
// src/utils/atlas.ts
|
|
201
230
|
var import_mongodb = require("mongodb");
|
|
202
231
|
var useAtlas = class {
|
|
@@ -270,14 +299,6 @@ var useAtlas = class {
|
|
|
270
299
|
useAtlas.mongoClient = null;
|
|
271
300
|
useAtlas.mongoDb = null;
|
|
272
301
|
|
|
273
|
-
// src/utils/cache-key.ts
|
|
274
|
-
function buildCacheKey(prefix, values) {
|
|
275
|
-
const query = Object.entries(values).sort(([a], [b]) => a.localeCompare(b)).map(
|
|
276
|
-
([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`
|
|
277
|
-
).join("&");
|
|
278
|
-
return `${prefix}:${query}`;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
302
|
// src/utils/ioredis.ts
|
|
282
303
|
var import_ioredis = __toESM(require("ioredis"));
|
|
283
304
|
var redisClient = null;
|
|
@@ -399,6 +420,14 @@ function useCache() {
|
|
|
399
420
|
};
|
|
400
421
|
}
|
|
401
422
|
|
|
423
|
+
// src/utils/cache-key.ts
|
|
424
|
+
function buildCacheKey(prefix, values) {
|
|
425
|
+
const query = Object.entries(values).sort(([a], [b]) => a.localeCompare(b)).map(
|
|
426
|
+
([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`
|
|
427
|
+
).join("&");
|
|
428
|
+
return `${prefix}:${query}`;
|
|
429
|
+
}
|
|
430
|
+
|
|
402
431
|
// src/utils/get-template-path.ts
|
|
403
432
|
var import_path = __toESM(require("path"));
|
|
404
433
|
function getTemplatePath(directory, filePath) {
|
|
@@ -596,10 +625,16 @@ function getEnvNumber(key, fallback) {
|
|
|
596
625
|
if (fallback !== void 0) return fallback;
|
|
597
626
|
throw new Error(`Missing required environment variable: ${key}`);
|
|
598
627
|
}
|
|
599
|
-
|
|
628
|
+
function getEnvBoolean(key, fallback) {
|
|
629
|
+
const value = process.env[key];
|
|
630
|
+
if (value !== void 0) return value === "true";
|
|
631
|
+
if (fallback !== void 0) return fallback;
|
|
632
|
+
throw new Error(`Missing required environment variable: ${key}`);
|
|
633
|
+
}
|
|
600
634
|
var REDIS_HOST = getEnv("REDIS_HOST");
|
|
601
635
|
var REDIS_PORT = getEnvNumber("REDIS_PORT", 6379);
|
|
602
636
|
var REDIS_PASSWORD = getEnv("REDIS_PASSWORD");
|
|
637
|
+
var REDIS_TLS = getEnvBoolean("REDIS_TLS", true);
|
|
603
638
|
|
|
604
639
|
// src/utils/redis.ts
|
|
605
640
|
var redisClient2 = null;
|
|
@@ -696,6 +731,13 @@ var useS3 = class {
|
|
|
696
731
|
});
|
|
697
732
|
}
|
|
698
733
|
};
|
|
734
|
+
|
|
735
|
+
// src/utils/token.ts
|
|
736
|
+
var import_crypto = __toESM(require("crypto"));
|
|
737
|
+
var TOKEN_HASH_SALT = process.env.REFRESH_TOKEN_HASH_SALT || "";
|
|
738
|
+
function hashToken(token) {
|
|
739
|
+
return import_crypto.default.createHash("sha256").update(TOKEN_HASH_SALT + token).digest("hex");
|
|
740
|
+
}
|
|
699
741
|
// Annotate the CommonJS export names for ESM import in node:
|
|
700
742
|
0 && (module.exports = {
|
|
701
743
|
BadRequestError,
|
|
@@ -712,6 +754,7 @@ var useS3 = class {
|
|
|
712
754
|
errorHandler,
|
|
713
755
|
getTemplatePath,
|
|
714
756
|
hashPassword,
|
|
757
|
+
hashToken,
|
|
715
758
|
initRedisClient,
|
|
716
759
|
logger,
|
|
717
760
|
paginate,
|
|
@@ -723,6 +766,7 @@ var useS3 = class {
|
|
|
723
766
|
useMailer,
|
|
724
767
|
useRedis,
|
|
725
768
|
useRedisClient,
|
|
726
|
-
useS3
|
|
769
|
+
useS3,
|
|
770
|
+
validate
|
|
727
771
|
});
|
|
728
772
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/middleware/auth.middleware.ts","../src/utils/logger.ts","../src/utils/http-error.ts","../src/middleware/error-handler.middleware.ts","../src/utils/atlas.ts","../src/utils/cache-key.ts","../src/utils/ioredis.ts","../src/utils/cache.ts","../src/utils/get-template-path.ts","../src/utils/handlebars-compiler.ts","../src/utils/jwt.ts","../src/utils/mailer.ts","../src/utils/objectid-converter.ts","../src/utils/paginate.ts","../src/utils/password.ts","../src/utils/redis.ts","../src/config.ts","../src/utils/s3.ts"],"sourcesContent":["export * from \"./middleware\";\r\nexport * from \"./utils\";\r\n","import { NextFunction, Request, Response } from \"express\";\r\nimport jwt, { JwtPayload } from \"jsonwebtoken\";\r\nimport { logger } from \"./../utils/logger\";\r\nimport { UnauthorizedError } from \"./../utils/http-error\";\r\n\r\nexport interface AuthenticatedRequest extends Request {\r\n user?: JwtPayload & { id?: string };\r\n token?: string;\r\n}\r\n\r\nexport function authenticate(\r\n secretKey: string = process.env.ACCESS_TOKEN_SECRET || \"\"\r\n) {\r\n return (req: AuthenticatedRequest, res: Response, next: NextFunction) => {\r\n const authHeader = req.headers.authorization;\r\n const token = authHeader?.split(\" \")[1];\r\n\r\n if (!token) {\r\n logger.error(\"No access token provided in the request.\");\r\n return next(\r\n new UnauthorizedError(\"Access token is required to proceed.\")\r\n );\r\n }\r\n\r\n jwt.verify(token, secretKey, (error, decoded) => {\r\n if (error) {\r\n logger.error(\"Failed to verify access token.\", error);\r\n return next(\r\n new UnauthorizedError(\r\n \"Your session has expired or the token is invalid. Please log in again.\"\r\n )\r\n );\r\n }\r\n\r\n req.user = decoded as JwtPayload & { id?: string };\r\n req.token = token;\r\n next();\r\n });\r\n };\r\n}\r\n","import * as winston from \"winston\";\r\n\r\nconst transports = [\r\n new winston.transports.File({ filename: \"error.log\", level: \"error\" }),\r\n new winston.transports.File({ filename: \"combined.log\" }),\r\n];\r\n\r\nexport const logger = winston.createLogger({\r\n level: \"info\",\r\n format: winston.format.combine(\r\n winston.format.timestamp(),\r\n winston.format.json()\r\n ),\r\n transports,\r\n});\r\n","export class HttpError extends Error {\r\n public readonly statusCode: number;\r\n public readonly isOperational: boolean;\r\n\r\n constructor(\r\n message: string,\r\n statusCode: number,\r\n isOperational: boolean = true\r\n ) {\r\n super(message);\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n\r\n this.statusCode = statusCode;\r\n this.isOperational = isOperational;\r\n\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, this.constructor);\r\n }\r\n }\r\n}\r\n\r\nexport class BadRequestError extends HttpError {\r\n constructor(\r\n message: string = \"The request could not be processed. Please review your input and try again.\"\r\n ) {\r\n super(message, 400, true);\r\n }\r\n}\r\n\r\nexport class UnauthorizedError extends HttpError {\r\n constructor(\r\n message: string = \"Authentication is required to access this resource.\"\r\n ) {\r\n super(message, 401, true);\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends HttpError {\r\n constructor(\r\n message: string = \"You do not have the necessary permissions to perform this action.\"\r\n ) {\r\n super(message, 403, true);\r\n }\r\n}\r\n\r\nexport class NotFoundError extends HttpError {\r\n constructor(message: string = \"The requested resource could not be found.\") {\r\n super(message, 404, true);\r\n }\r\n}\r\n\r\nexport class ConflictError extends HttpError {\r\n constructor(\r\n message: string = \"A resource with the provided values already exists.\"\r\n ) {\r\n super(message, 409, true);\r\n }\r\n}\r\n\r\nexport class UnprocessableEntityError extends HttpError {\r\n constructor(\r\n message: string = \"The request could not be completed due to invalid or incomplete information.\"\r\n ) {\r\n super(message, 422, true);\r\n }\r\n}\r\n\r\nexport class InternalServerError extends HttpError {\r\n constructor(\r\n message: string = \"An internal server error occurred. Please try again later.\"\r\n ) {\r\n super(message, 500, true);\r\n }\r\n}\r\n","import { NextFunction, Request, Response } from \"express\";\r\nimport { HttpError, InternalServerError } from \"./../utils/http-error\";\r\nimport { logger } from \"./../utils/logger\";\r\n\r\nexport const errorHandler = (\r\n error: HttpError,\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n) => {\r\n if (error.isOperational) {\r\n res\r\n .status(error.statusCode)\r\n .json({ status: \"error\", message: error.message });\r\n } else {\r\n logger.error({ message: error.message });\r\n res\r\n .status(500)\r\n .json({ status: \"error\", message: new InternalServerError().message });\r\n }\r\n\r\n return;\r\n};\r\n","import { Db, MongoClient } from \"mongodb\";\r\nimport { logger } from \"./logger\";\r\nimport {\r\n BadRequestError,\r\n InternalServerError,\r\n NotFoundError,\r\n} from \"./http-error\";\r\n\r\ninterface AtlasConfig {\r\n uri: string;\r\n db: string;\r\n name?: string;\r\n}\r\n\r\nexport class useAtlas {\r\n private static mongoClient: MongoClient | null = null;\r\n private static mongoDb: Db | null = null;\r\n\r\n public static async connect(config: AtlasConfig): Promise<void> {\r\n if (this.mongoClient) {\r\n logger.warn(\r\n \"[MongoDB][Connect] Client is already connected. Skipping new connection.\"\r\n );\r\n throw new BadRequestError(\"A MongoDB connection is already established.\");\r\n }\r\n\r\n const { db, uri } = config;\r\n this.mongoClient = new MongoClient(uri, {\r\n maxPoolSize: 10,\r\n maxIdleTimeMS: 60000,\r\n connectTimeoutMS: 60000,\r\n });\r\n\r\n try {\r\n await this.mongoClient.connect();\r\n this.mongoDb = this.mongoClient.db(db);\r\n\r\n logger.info(\r\n `[MongoDB][Connect] Connected to database \"${this.mongoDb.databaseName}\".`\r\n );\r\n } catch (error) {\r\n this.mongoClient = null;\r\n\r\n logger.error(\r\n `[MongoDB][Connect] Failed to connect: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\r\n \"Failed to connect to the database. Please try again later.\"\r\n );\r\n }\r\n }\r\n\r\n public static getClient(): MongoClient | null {\r\n if (!this.mongoClient) {\r\n logger.warn(`[MongoDB][GetClient] Client is not initialized.`);\r\n throw new NotFoundError(\"MongoDB client is not initialized.\");\r\n }\r\n\r\n return this.mongoClient;\r\n }\r\n\r\n public static getDb(): Db | null {\r\n if (!this.mongoDb) {\r\n logger.warn(`[MongoDB][GetDb] Database instance is not available.`);\r\n throw new NotFoundError(\"MongoDB database instance is not available.\");\r\n }\r\n\r\n return this.mongoDb;\r\n }\r\n\r\n public static async close(): Promise<void> {\r\n if (this.mongoClient) {\r\n try {\r\n await this.mongoClient.close();\r\n\r\n logger.info(`[MongoDB][Close] Connection closed.`);\r\n } catch (error) {\r\n logger.error(\r\n `[MongoDB][Close] Error closing connection: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to close MongoDB connection.\");\r\n } finally {\r\n this.mongoClient = null;\r\n this.mongoDb = null;\r\n }\r\n } else {\r\n logger.warn(`[MongoDB][Close] No client to disconnect.`);\r\n throw new BadRequestError(\"No MongoDB connection exists to close.\");\r\n }\r\n }\r\n}\r\n","export function buildCacheKey(\r\n prefix: string,\r\n values: Record<string, any>\r\n): string {\r\n const query = Object.entries(values)\r\n .sort(([a], [b]) => a.localeCompare(b))\r\n .map(\r\n ([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`\r\n )\r\n .join(\"&\");\r\n\r\n return `${prefix}:${query}`;\r\n}\r\n","import Redis from \"ioredis\";\r\nimport { logger } from \"./logger\";\r\nimport { BadRequestError } from \"./http-error\";\r\n\r\nlet redisClient: Redis | null = null;\r\n\r\ntype RedisOptions = {\r\n host?: string;\r\n port?: number;\r\n username?: string;\r\n password?: string;\r\n};\r\n\r\nexport function useRedis() {\r\n function initialize(options: RedisOptions) {\r\n if (redisClient) {\r\n logger.info(\"[Redis][Init] Redis connection is already established.\");\r\n return redisClient;\r\n }\r\n\r\n options.host = options.host ?? \"localhost\";\r\n options.port = options.port ?? 6379;\r\n options.username = options.username ?? \"default\";\r\n options.password = options.password ?? \"\";\r\n\r\n redisClient = new Redis({\r\n host: options.host,\r\n port: options.port,\r\n ...(options.username && { username: options.username }),\r\n ...(options.password && { password: options.password }),\r\n });\r\n\r\n redisClient.on(\"connect\", () => {\r\n logger.info(\r\n `[Redis][Connect] Redis client connected at ${options.host}:${options.port}.`\r\n );\r\n });\r\n\r\n redisClient.on(\"error\", (error) => {\r\n logger.error(\r\n `[Redis][Error] Failed to connect: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n });\r\n\r\n return redisClient;\r\n }\r\n\r\n function getClient(): Redis {\r\n if (!redisClient) {\r\n logger.error(\r\n \"[Redis][GetClient] Redis connection has not been initialized.\"\r\n );\r\n throw new BadRequestError(\r\n \"Redis connection is not initialized. Please call initialize() first.\"\r\n );\r\n }\r\n\r\n return redisClient;\r\n }\r\n\r\n function disconnect() {\r\n if (redisClient) {\r\n redisClient.quit();\r\n logger.info(\"[Redis][Disconnect] Redis connection has been closed.\");\r\n redisClient = null;\r\n } else {\r\n logger.warn(\"[Redis][Disconnect] No Redis client to disconnect.\");\r\n }\r\n }\r\n\r\n return {\r\n initialize,\r\n getClient,\r\n disconnect,\r\n };\r\n}\r\n","import { useRedis } from \"./ioredis\";\r\nimport { logger } from \"./logger\";\r\n\r\nconst DEFAULT_TTL = 300;\r\n\r\nexport function useCache() {\r\n const redisClient = useRedis().getClient();\r\n\r\n async function get<T = unknown>(cacheKey: string): Promise<T | null> {\r\n try {\r\n const value = await redisClient.get(cacheKey);\r\n\r\n return value ? (JSON.parse(value) as T) : null;\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][Get] Failed to retrieve key \"${cacheKey}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n\r\n return null;\r\n }\r\n }\r\n\r\n async function set<T = unknown>(\r\n cacheKey: string,\r\n data: T,\r\n ttl: number = DEFAULT_TTL,\r\n group?: string\r\n ): Promise<void> {\r\n try {\r\n await redisClient.set(cacheKey, JSON.stringify(data), \"EX\", ttl);\r\n logger.info(`[Cache][Set] Stored key \"${cacheKey}\" with TTL ${ttl}s.`);\r\n\r\n if (group) await redisClient.sadd(`cache:group:${group}`, cacheKey);\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][Set] Failed to store key \"${cacheKey}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async function remove(cacheKey: string): Promise<void> {\r\n try {\r\n await redisClient.del(cacheKey);\r\n logger.info(`[Cache][Remove] Key \"${cacheKey}\" has been deleted.`);\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][Remove] Failed to delete key \"${cacheKey}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async function clearGroup(group: string): Promise<void> {\r\n try {\r\n const keys = await redisClient.smembers(`cache:group:${group}`);\r\n if (keys.length) await redisClient.del(...keys);\r\n\r\n await redisClient.del(`cache:group:${group}`);\r\n logger.info(`[Cache][ClearGroup] Cleared group \"${group}\" and its keys.`);\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][ClearGroup] Failed to clear group \"${group}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n }\r\n }\r\n\r\n return {\r\n get,\r\n set,\r\n remove,\r\n clearGroup,\r\n };\r\n}\r\n","import path from \"path\";\r\n\r\nexport function getTemplatePath(directory: string, filePath: string) {\r\n const ext = \".hbs\";\r\n const file = filePath.endsWith(ext) ? filePath : `${filePath}${ext}`;\r\n return path.resolve(directory, file);\r\n}\r\n","import Handlebars from \"handlebars\";\r\nimport { promises as fs } from \"fs\";\r\nimport { InternalServerError } from \"./http-error\";\r\nimport { logger } from \"./logger\";\r\n\r\ninterface CompileOptions {\r\n context?: Record<string, any>;\r\n filePath: string;\r\n}\r\n\r\nconst handlebarsTemplateCache = new Map<string, Handlebars.TemplateDelegate>();\r\n\r\nexport async function renderHandlebarsTemplate({\r\n context = {},\r\n filePath,\r\n}: CompileOptions): Promise<string> {\r\n try {\r\n let compiledTemplate = handlebarsTemplateCache.get(filePath);\r\n\r\n if (!compiledTemplate) {\r\n logger.info(\r\n `[Template][Compile] Compiling and caching template from \"${filePath}\".`\r\n );\r\n const fileContent = await fs.readFile(filePath, \"utf8\");\r\n compiledTemplate = Handlebars.compile(fileContent);\r\n handlebarsTemplateCache.set(filePath, compiledTemplate);\r\n } else {\r\n logger.info(`[Template][Cache] Using cached template for \"${filePath}\".`);\r\n }\r\n\r\n return compiledTemplate(context);\r\n } catch (error) {\r\n logger.error(\r\n `[Template][Render] Failed to render template \"${filePath}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to render Handlebars template.\");\r\n }\r\n}\r\n","import jwt from \"jsonwebtoken\";\r\nimport { BadRequestError } from \"./http-error\";\r\nimport { logger } from \"./logger\";\r\n\r\ninterface JwtSignParams {\r\n payload?: Record<string, unknown>;\r\n secretKey: string;\r\n signOptions?: jwt.SignOptions;\r\n}\r\n\r\nexport function signJwtToken({\r\n payload = {},\r\n secretKey = \"\",\r\n signOptions = {},\r\n}: JwtSignParams): string {\r\n if (!secretKey) {\r\n logger.error(`[JWT][Sign] Secret key is missing. Cannot sign token.`);\r\n throw new BadRequestError(\"A JWT secret key must be provided.\");\r\n }\r\n\r\n try {\r\n logger.info(`[JWT][Sign] Signing JWT token.`);\r\n return jwt.sign(payload, secretKey, signOptions);\r\n } catch (error) {\r\n logger.error(\r\n `[JWT][Sign] Failed to sign JWT token: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw error;\r\n }\r\n}\r\n","import { createTransport, SendMailOptions, Transporter } from \"nodemailer\";\r\nimport { logger } from \"./logger\";\r\nimport { InternalServerError } from \"./http-error\";\r\n\r\ninterface MailerConfig {\r\n email: string;\r\n password: string;\r\n host: string;\r\n port: number;\r\n secure: boolean;\r\n}\r\n\r\nexport class useMailer {\r\n private transporter: Transporter;\r\n\r\n constructor(private config: MailerConfig) {\r\n this.transporter = createTransport({\r\n host: config.host,\r\n port: config.port,\r\n secure: config.secure,\r\n auth: { user: config.email, pass: config.password },\r\n });\r\n }\r\n\r\n async sendMail({\r\n sender,\r\n to,\r\n subject,\r\n text,\r\n html,\r\n }: {\r\n sender?: string;\r\n to: string;\r\n subject: string;\r\n text?: string;\r\n html?: string;\r\n }): Promise<string> {\r\n const from = sender\r\n ? `${sender} <${this.config.email}>`\r\n : this.config.email;\r\n\r\n const mailOptions: SendMailOptions = {\r\n from,\r\n to,\r\n subject,\r\n ...(text && { text }),\r\n ...(html && { html }),\r\n };\r\n\r\n try {\r\n await this.transporter.sendMail(mailOptions);\r\n logger.info(\r\n `[Mailer][Send] Email sent to \"${to}\" with subject \"${subject}\".`\r\n );\r\n\r\n return \"Mail sent successfully.\";\r\n } catch (error) {\r\n logger.error(\r\n `[Mailer][Send] Failed to send email to \"${to}\" with subject \"${subject}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to send email.\");\r\n }\r\n }\r\n}\r\n","import { ObjectId } from \"mongodb\";\r\nimport { logger } from \"./logger\";\r\nimport { BadRequestError } from \"./http-error\";\r\n\r\nexport function toObjectId(id: string | ObjectId): ObjectId {\r\n if (!id) {\r\n logger.error(\r\n `[ObjectId][Convert] No value provided for MongoDB ObjectId conversion.`\r\n );\r\n throw new BadRequestError(\r\n \"A value must be provided for ObjectId conversion.\"\r\n );\r\n }\r\n\r\n if (id instanceof ObjectId) return id;\r\n\r\n if (!/^[0-9a-fA-F]{24}$/.test(id)) {\r\n logger.error(\r\n `[ObjectId][Convert] Provided value is not a valid 24-character hex string.`\r\n );\r\n throw new BadRequestError(\r\n \"Invalid ObjectId: must be a 24-character hexadecimal string.\"\r\n );\r\n }\r\n\r\n try {\r\n return new ObjectId(id);\r\n } catch (err) {\r\n logger.error(\r\n `[ObjectId][Convert] Failed to convert value to ObjectId: ${\r\n err instanceof Error ? err.message : err\r\n }`\r\n );\r\n throw new BadRequestError(\"Failed to convert value into a valid ObjectId.\");\r\n }\r\n}\r\n","export function paginate<T>(\r\n items: T[],\r\n page: number = 0,\r\n limit: number = 10,\r\n total: number\r\n) {\r\n if (total === 0) {\r\n return {\r\n items: [],\r\n pages: 0,\r\n pageRange: \"0-0 of 0\",\r\n };\r\n }\r\n\r\n const startIndex = page * limit + 1;\r\n const endIndex = Math.min(startIndex + items.length - 1, total);\r\n\r\n return {\r\n items,\r\n pages: Math.ceil(total / limit),\r\n pageRange: `${startIndex}-${endIndex} of ${total}`,\r\n };\r\n}\r\n","import bcrypt from \"bcrypt\";\r\nimport { InternalServerError } from \"./http-error\";\r\nimport { logger } from \"./logger\";\r\n\r\nconst DEFAULT_SALT_ROUNDS = 10;\r\n\r\nexport async function comparePasswords(\r\n password: string,\r\n hashed: string\r\n): Promise<boolean> {\r\n try {\r\n return await bcrypt.compare(password, hashed);\r\n } catch (error) {\r\n logger.error(\r\n `[Password][Compare] Failed to compare passwords: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n return false;\r\n }\r\n}\r\n\r\nexport async function hashPassword(\r\n password: string,\r\n saltRounds: number = DEFAULT_SALT_ROUNDS\r\n): Promise<string> {\r\n try {\r\n return await bcrypt.hash(password, saltRounds);\r\n } catch (error) {\r\n logger.error(\r\n `[Password][Hash] Failed to hash password: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to hash password.\");\r\n }\r\n}\r\n","import { createClient, RedisClientType } from \"redis\";\r\nimport { REDIS_HOST, REDIS_PASSWORD, REDIS_PORT } from \"./../config\";\r\nimport { logger } from \"./logger\";\r\n\r\nlet redisClient: RedisClientType | null = null;\r\n\r\nexport async function initRedisClient() {\r\n if (redisClient) {\r\n logger.info(\"[Redis][Init] Redis connection is already established.\");\r\n return redisClient;\r\n }\r\n\r\n redisClient = createClient({\r\n password: REDIS_PASSWORD,\r\n socket: {\r\n host: REDIS_HOST,\r\n port: REDIS_PORT,\r\n },\r\n });\r\n}\r\n\r\nexport function useRedisClient(): RedisClientType {\r\n if (!redisClient) {\r\n logger.error(\r\n \"[Redis][GetClient] Redis connection has not been initialized.\"\r\n );\r\n throw new Error(\r\n \"[Redis][GetClient] Redis connection is not initialized. Call initRedisClient() first.\"\r\n );\r\n }\r\n\r\n return redisClient;\r\n}\r\n","import * as dotenv from \"dotenv\";\r\n\r\ndotenv.config();\r\n\r\nfunction getEnv(key: string, fallback?: string): string {\r\n const value = process.env[key];\r\n if (value !== undefined) return value as string;\r\n if (fallback !== undefined) return fallback;\r\n throw new Error(`Missing required environment variable: ${key}`);\r\n}\r\n\r\nfunction getEnvNumber(key: string, fallback?: number): number {\r\n const value = process.env[key];\r\n if (value !== undefined) return Number(value);\r\n if (fallback !== undefined) return fallback;\r\n throw new Error(`Missing required environment variable: ${key}`);\r\n}\r\n\r\n// App Environment\r\nexport const isDev = process.env.NODE_ENV !== \"production\";\r\n\r\n// Redis Configuration\r\nexport const REDIS_HOST = getEnv(\"REDIS_HOST\");\r\nexport const REDIS_PORT = getEnvNumber(\"REDIS_PORT\", 6379);\r\nexport const REDIS_PASSWORD = getEnv(\"REDIS_PASSWORD\");\r\n","import {\r\n DeleteObjectCommand,\r\n PutObjectCommand,\r\n S3Client,\r\n} from \"@aws-sdk/client-s3\";\r\nimport { Readable } from \"stream\";\r\nimport { logger } from \"./logger\";\r\n\r\ninterface S3Config {\r\n accessKeyId: string;\r\n secretAccessKey: string;\r\n endpoint: string;\r\n region: string;\r\n bucket: string;\r\n forcePathStyle: boolean;\r\n}\r\n\r\nexport class useS3 {\r\n private client: S3Client;\r\n\r\n constructor(private config: S3Config) {\r\n this.client = new S3Client({\r\n endpoint: config.endpoint,\r\n region: config.region,\r\n credentials: {\r\n accessKeyId: config.accessKeyId,\r\n secretAccessKey: config.secretAccessKey,\r\n },\r\n forcePathStyle: config.forcePathStyle,\r\n });\r\n }\r\n\r\n async uploadObject({\r\n key,\r\n body,\r\n metadata = {},\r\n contentType,\r\n }: {\r\n key: string;\r\n body: string | Buffer;\r\n metadata?: Record<string, string>;\r\n contentType?: string;\r\n }): Promise<string> {\r\n try {\r\n await this.client.send(\r\n new PutObjectCommand({\r\n Bucket: this.config.bucket,\r\n Key: key,\r\n Body:\r\n typeof body === \"string\" || Buffer.isBuffer(body)\r\n ? body\r\n : Readable.from(body),\r\n ACL: \"public-read\",\r\n Metadata: metadata,\r\n ContentType: contentType,\r\n ContentLength:\r\n typeof body === \"string\" ? Buffer.byteLength(body) : body.length,\r\n })\r\n );\r\n\r\n logger.info(\r\n `[S3][Upload] Uploaded \"${key}\" to bucket \"${this.config.bucket}\".`\r\n );\r\n return \"Successfully uploaded file.\";\r\n } catch (error) {\r\n logger.error(\r\n `[S3][Upload][Error] Failed to upload \"${key}\" to bucket \"${\r\n this.config.bucket\r\n }\": ${error instanceof Error ? error.message : error}`\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n async deleteObject(key: string) {\r\n try {\r\n await this.client.send(\r\n new DeleteObjectCommand({ Key: key, Bucket: this.config.bucket })\r\n );\r\n\r\n logger.info(\r\n `[S3][Delete] Deleted \"${key}\" from bucket \"${this.config.bucket}\".`\r\n );\r\n return \"Successfully deleted file.\";\r\n } catch (error) {\r\n logger.error(\r\n `[S3][Delete][Error] Failed to delete \"${key}\" from bucket \"${\r\n this.config.bucket\r\n }\": ${error instanceof Error ? error.message : error}`\r\n );\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["transports","jwt","config","Redis","redisClient","path","fs","Handlebars","import_jsonwebtoken","jwt","config","import_mongodb","bcrypt","redisClient","config"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/middleware/auth.middleware.ts","../src/utils/logger.ts","../src/utils/http-error.ts","../src/middleware/error-handler.middleware.ts","../src/middleware/validate-request.middleware.ts","../src/utils/atlas.ts","../src/utils/ioredis.ts","../src/utils/cache.ts","../src/utils/cache-key.ts","../src/utils/get-template-path.ts","../src/utils/handlebars-compiler.ts","../src/utils/jwt.ts","../src/utils/mailer.ts","../src/utils/objectid-converter.ts","../src/utils/paginate.ts","../src/utils/password.ts","../src/utils/redis.ts","../src/config.ts","../src/utils/s3.ts","../src/utils/token.ts"],"sourcesContent":["export * from \"./middleware\";\r\nexport * from \"./utils\";\r\n","import { NextFunction, Request, Response } from \"express\";\r\nimport jwt, { JwtPayload } from \"jsonwebtoken\";\r\nimport { logger } from \"./../utils/logger\";\r\nimport { UnauthorizedError } from \"./../utils/http-error\";\r\n\r\nexport interface AuthenticatedRequest extends Request {\r\n user?: JwtPayload & { user?: string; id?: string };\r\n token?: string;\r\n}\r\n\r\nexport function authenticate(\r\n secretKey: string = process.env.ACCESS_TOKEN_SECRET || \"\"\r\n) {\r\n return async (\r\n req: AuthenticatedRequest,\r\n res: Response,\r\n next: NextFunction\r\n ) => {\r\n const authHeader = req.headers.authorization;\r\n const token = authHeader?.split(\" \")[1];\r\n\r\n if (!token) {\r\n logger.error(\"No access token provided in the request.\");\r\n return next(\r\n new UnauthorizedError(\"Access token is required to proceed.\")\r\n );\r\n }\r\n\r\n try {\r\n const decoded = jwt.verify(token, secretKey) as JwtPayload & {\r\n user?: string;\r\n id?: string;\r\n };\r\n\r\n req.user = {\r\n ...(decoded as any),\r\n id: (decoded as any).user || (decoded as any).id,\r\n };\r\n req.token = token;\r\n next();\r\n } catch (error) {\r\n logger.error(\"Failed to verify access token.\", error);\r\n return next(\r\n new UnauthorizedError(\r\n \"Your session has expired or the token is invalid. Please log in again.\"\r\n )\r\n );\r\n }\r\n };\r\n}\r\n","import * as winston from \"winston\";\r\n\r\nconst transports = [\r\n new winston.transports.File({ filename: \"error.log\", level: \"error\" }),\r\n new winston.transports.File({ filename: \"combined.log\" }),\r\n];\r\n\r\nexport const logger = winston.createLogger({\r\n level: \"info\",\r\n format: winston.format.combine(\r\n winston.format.timestamp(),\r\n winston.format.json()\r\n ),\r\n transports,\r\n});\r\n","export class HttpError extends Error {\r\n public readonly statusCode: number;\r\n public readonly isOperational: boolean;\r\n\r\n constructor(\r\n message: string,\r\n statusCode: number,\r\n isOperational: boolean = true\r\n ) {\r\n super(message);\r\n\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n\r\n this.statusCode = statusCode;\r\n this.isOperational = isOperational;\r\n\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, this.constructor);\r\n }\r\n }\r\n}\r\n\r\nexport class BadRequestError extends HttpError {\r\n constructor(\r\n message: string = \"The request could not be processed. Please review your input and try again.\"\r\n ) {\r\n super(message, 400, true);\r\n }\r\n}\r\n\r\nexport class UnauthorizedError extends HttpError {\r\n constructor(\r\n message: string = \"Authentication is required to access this resource.\"\r\n ) {\r\n super(message, 401, true);\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends HttpError {\r\n constructor(\r\n message: string = \"You do not have the necessary permissions to perform this action.\"\r\n ) {\r\n super(message, 403, true);\r\n }\r\n}\r\n\r\nexport class NotFoundError extends HttpError {\r\n constructor(message: string = \"The requested resource could not be found.\") {\r\n super(message, 404, true);\r\n }\r\n}\r\n\r\nexport class ConflictError extends HttpError {\r\n constructor(\r\n message: string = \"A resource with the provided values already exists.\"\r\n ) {\r\n super(message, 409, true);\r\n }\r\n}\r\n\r\nexport class UnprocessableEntityError extends HttpError {\r\n constructor(\r\n message: string = \"The request could not be completed due to invalid or incomplete information.\"\r\n ) {\r\n super(message, 422, true);\r\n }\r\n}\r\n\r\nexport class InternalServerError extends HttpError {\r\n constructor(\r\n message: string = \"An internal server error occurred. Please try again later.\"\r\n ) {\r\n super(message, 500, true);\r\n }\r\n}\r\n","import { NextFunction, Request, Response } from \"express\";\r\nimport { HttpError, InternalServerError } from \"./../utils/http-error\";\r\nimport { logger } from \"./../utils/logger\";\r\n\r\nexport const errorHandler = (\r\n error: HttpError,\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n) => {\r\n if (error.isOperational) {\r\n res\r\n .status(error.statusCode)\r\n .json({ status: \"error\", message: error.message });\r\n } else {\r\n logger.error({ message: error.message });\r\n res\r\n .status(500)\r\n .json({ status: \"error\", message: new InternalServerError().message });\r\n }\r\n\r\n return;\r\n};\r\n","import { Request, Response, NextFunction } from \"express\";\r\nimport { Schema } from \"joi\";\r\nimport { BadRequestError } from \"./../utils/http-error\";\r\n\r\nexport function validate(schema: Schema) {\r\n return async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const validationOptions = {\r\n abortEarly: false, // Return all validation errors\r\n };\r\n\r\n // Validate request body\r\n const { error, value } = schema.validate(req.body, validationOptions);\r\n if (error) {\r\n throw new BadRequestError(\r\n `Request body validation failed: ${error.details\r\n .map((detail) => detail.message)\r\n .join(\", \")}`\r\n );\r\n }\r\n req.body = value;\r\n\r\n next();\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n","import { Db, MongoClient } from \"mongodb\";\r\nimport { logger } from \"./logger\";\r\nimport {\r\n BadRequestError,\r\n InternalServerError,\r\n NotFoundError,\r\n} from \"./http-error\";\r\n\r\ninterface AtlasConfig {\r\n uri: string;\r\n db: string;\r\n name?: string;\r\n}\r\n\r\nexport class useAtlas {\r\n private static mongoClient: MongoClient | null = null;\r\n private static mongoDb: Db | null = null;\r\n\r\n public static async connect(config: AtlasConfig): Promise<void> {\r\n if (this.mongoClient) {\r\n logger.warn(\r\n \"[MongoDB][Connect] Client is already connected. Skipping new connection.\"\r\n );\r\n throw new BadRequestError(\"A MongoDB connection is already established.\");\r\n }\r\n\r\n const { db, uri } = config;\r\n this.mongoClient = new MongoClient(uri, {\r\n maxPoolSize: 10,\r\n maxIdleTimeMS: 60000,\r\n connectTimeoutMS: 60000,\r\n });\r\n\r\n try {\r\n await this.mongoClient.connect();\r\n this.mongoDb = this.mongoClient.db(db);\r\n\r\n logger.info(\r\n `[MongoDB][Connect] Connected to database \"${this.mongoDb.databaseName}\".`\r\n );\r\n } catch (error) {\r\n this.mongoClient = null;\r\n\r\n logger.error(\r\n `[MongoDB][Connect] Failed to connect: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\r\n \"Failed to connect to the database. Please try again later.\"\r\n );\r\n }\r\n }\r\n\r\n public static getClient(): MongoClient | null {\r\n if (!this.mongoClient) {\r\n logger.warn(`[MongoDB][GetClient] Client is not initialized.`);\r\n throw new NotFoundError(\"MongoDB client is not initialized.\");\r\n }\r\n\r\n return this.mongoClient;\r\n }\r\n\r\n public static getDb(): Db | null {\r\n if (!this.mongoDb) {\r\n logger.warn(`[MongoDB][GetDb] Database instance is not available.`);\r\n throw new NotFoundError(\"MongoDB database instance is not available.\");\r\n }\r\n\r\n return this.mongoDb;\r\n }\r\n\r\n public static async close(): Promise<void> {\r\n if (this.mongoClient) {\r\n try {\r\n await this.mongoClient.close();\r\n\r\n logger.info(`[MongoDB][Close] Connection closed.`);\r\n } catch (error) {\r\n logger.error(\r\n `[MongoDB][Close] Error closing connection: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to close MongoDB connection.\");\r\n } finally {\r\n this.mongoClient = null;\r\n this.mongoDb = null;\r\n }\r\n } else {\r\n logger.warn(`[MongoDB][Close] No client to disconnect.`);\r\n throw new BadRequestError(\"No MongoDB connection exists to close.\");\r\n }\r\n }\r\n}\r\n","import Redis from \"ioredis\";\r\nimport { logger } from \"./logger\";\r\nimport { BadRequestError } from \"./http-error\";\r\n\r\nlet redisClient: Redis | null = null;\r\n\r\ntype RedisOptions = {\r\n host?: string;\r\n port?: number;\r\n username?: string;\r\n password?: string;\r\n};\r\n\r\nexport function useRedis() {\r\n function initialize(options: RedisOptions) {\r\n if (redisClient) {\r\n logger.info(\"[Redis][Init] Redis connection is already established.\");\r\n return redisClient;\r\n }\r\n\r\n options.host = options.host ?? \"localhost\";\r\n options.port = options.port ?? 6379;\r\n options.username = options.username ?? \"default\";\r\n options.password = options.password ?? \"\";\r\n\r\n redisClient = new Redis({\r\n host: options.host,\r\n port: options.port,\r\n ...(options.username && { username: options.username }),\r\n ...(options.password && { password: options.password }),\r\n });\r\n\r\n redisClient.on(\"connect\", () => {\r\n logger.info(\r\n `[Redis][Connect] Redis client connected at ${options.host}:${options.port}.`\r\n );\r\n });\r\n\r\n redisClient.on(\"error\", (error) => {\r\n logger.error(\r\n `[Redis][Error] Failed to connect: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n });\r\n\r\n return redisClient;\r\n }\r\n\r\n function getClient(): Redis {\r\n if (!redisClient) {\r\n logger.error(\r\n \"[Redis][GetClient] Redis connection has not been initialized.\"\r\n );\r\n throw new BadRequestError(\r\n \"Redis connection is not initialized. Please call initialize() first.\"\r\n );\r\n }\r\n\r\n return redisClient;\r\n }\r\n\r\n function disconnect() {\r\n if (redisClient) {\r\n redisClient.quit();\r\n logger.info(\"[Redis][Disconnect] Redis connection has been closed.\");\r\n redisClient = null;\r\n } else {\r\n logger.warn(\"[Redis][Disconnect] No Redis client to disconnect.\");\r\n }\r\n }\r\n\r\n return {\r\n initialize,\r\n getClient,\r\n disconnect,\r\n };\r\n}\r\n","import { useRedis } from \"./ioredis\";\r\nimport { logger } from \"./logger\";\r\n\r\nconst DEFAULT_TTL = 300;\r\n\r\nexport function useCache() {\r\n const redisClient = useRedis().getClient();\r\n\r\n async function get<T = unknown>(cacheKey: string): Promise<T | null> {\r\n try {\r\n const value = await redisClient.get(cacheKey);\r\n\r\n return value ? (JSON.parse(value) as T) : null;\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][Get] Failed to retrieve key \"${cacheKey}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n\r\n return null;\r\n }\r\n }\r\n\r\n async function set<T = unknown>(\r\n cacheKey: string,\r\n data: T,\r\n ttl: number = DEFAULT_TTL,\r\n group?: string\r\n ): Promise<void> {\r\n try {\r\n await redisClient.set(cacheKey, JSON.stringify(data), \"EX\", ttl);\r\n logger.info(`[Cache][Set] Stored key \"${cacheKey}\" with TTL ${ttl}s.`);\r\n\r\n if (group) await redisClient.sadd(`cache:group:${group}`, cacheKey);\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][Set] Failed to store key \"${cacheKey}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async function remove(cacheKey: string): Promise<void> {\r\n try {\r\n await redisClient.del(cacheKey);\r\n logger.info(`[Cache][Remove] Key \"${cacheKey}\" has been deleted.`);\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][Remove] Failed to delete key \"${cacheKey}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async function clearGroup(group: string): Promise<void> {\r\n try {\r\n const keys = await redisClient.smembers(`cache:group:${group}`);\r\n if (keys.length) await redisClient.del(...keys);\r\n\r\n await redisClient.del(`cache:group:${group}`);\r\n logger.info(`[Cache][ClearGroup] Cleared group \"${group}\" and its keys.`);\r\n } catch (error) {\r\n logger.error(\r\n `[Cache][ClearGroup] Failed to clear group \"${group}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n }\r\n }\r\n\r\n return {\r\n get,\r\n set,\r\n remove,\r\n clearGroup,\r\n };\r\n}\r\n","export function buildCacheKey(\r\n prefix: string,\r\n values: Record<string, any>\r\n): string {\r\n const query = Object.entries(values)\r\n .sort(([a], [b]) => a.localeCompare(b))\r\n .map(\r\n ([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`\r\n )\r\n .join(\"&\");\r\n\r\n return `${prefix}:${query}`;\r\n}\r\n","import path from \"path\";\r\n\r\nexport function getTemplatePath(directory: string, filePath: string) {\r\n const ext = \".hbs\";\r\n const file = filePath.endsWith(ext) ? filePath : `${filePath}${ext}`;\r\n return path.resolve(directory, file);\r\n}\r\n","import Handlebars from \"handlebars\";\r\nimport { promises as fs } from \"fs\";\r\nimport { InternalServerError } from \"./http-error\";\r\nimport { logger } from \"./logger\";\r\n\r\ninterface CompileOptions {\r\n context?: Record<string, any>;\r\n filePath: string;\r\n}\r\n\r\nconst handlebarsTemplateCache = new Map<string, Handlebars.TemplateDelegate>();\r\n\r\nexport async function renderHandlebarsTemplate({\r\n context = {},\r\n filePath,\r\n}: CompileOptions): Promise<string> {\r\n try {\r\n let compiledTemplate = handlebarsTemplateCache.get(filePath);\r\n\r\n if (!compiledTemplate) {\r\n logger.info(\r\n `[Template][Compile] Compiling and caching template from \"${filePath}\".`\r\n );\r\n const fileContent = await fs.readFile(filePath, \"utf8\");\r\n compiledTemplate = Handlebars.compile(fileContent);\r\n handlebarsTemplateCache.set(filePath, compiledTemplate);\r\n } else {\r\n logger.info(`[Template][Cache] Using cached template for \"${filePath}\".`);\r\n }\r\n\r\n return compiledTemplate(context);\r\n } catch (error) {\r\n logger.error(\r\n `[Template][Render] Failed to render template \"${filePath}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to render Handlebars template.\");\r\n }\r\n}\r\n","import jwt from \"jsonwebtoken\";\r\nimport { BadRequestError } from \"./http-error\";\r\nimport { logger } from \"./logger\";\r\n\r\ninterface JwtSignParams {\r\n payload?: Record<string, unknown>;\r\n secretKey: string;\r\n signOptions?: jwt.SignOptions;\r\n}\r\n\r\nexport function signJwtToken({\r\n payload = {},\r\n secretKey = \"\",\r\n signOptions = {},\r\n}: JwtSignParams): string {\r\n if (!secretKey) {\r\n logger.error(`[JWT][Sign] Secret key is missing. Cannot sign token.`);\r\n throw new BadRequestError(\"A JWT secret key must be provided.\");\r\n }\r\n\r\n try {\r\n logger.info(`[JWT][Sign] Signing JWT token.`);\r\n return jwt.sign(payload, secretKey, signOptions);\r\n } catch (error) {\r\n logger.error(\r\n `[JWT][Sign] Failed to sign JWT token: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw error;\r\n }\r\n}\r\n","import { createTransport, SendMailOptions, Transporter } from \"nodemailer\";\r\nimport { logger } from \"./logger\";\r\nimport { InternalServerError } from \"./http-error\";\r\n\r\ninterface MailerConfig {\r\n email: string;\r\n password: string;\r\n host: string;\r\n port: number;\r\n secure: boolean;\r\n}\r\n\r\nexport class useMailer {\r\n private transporter: Transporter;\r\n\r\n constructor(private config: MailerConfig) {\r\n this.transporter = createTransport({\r\n host: config.host,\r\n port: config.port,\r\n secure: config.secure,\r\n auth: { user: config.email, pass: config.password },\r\n });\r\n }\r\n\r\n async sendMail({\r\n sender,\r\n to,\r\n subject,\r\n text,\r\n html,\r\n }: {\r\n sender?: string;\r\n to: string;\r\n subject: string;\r\n text?: string;\r\n html?: string;\r\n }): Promise<string> {\r\n const from = sender\r\n ? `${sender} <${this.config.email}>`\r\n : this.config.email;\r\n\r\n const mailOptions: SendMailOptions = {\r\n from,\r\n to,\r\n subject,\r\n ...(text && { text }),\r\n ...(html && { html }),\r\n };\r\n\r\n try {\r\n await this.transporter.sendMail(mailOptions);\r\n logger.info(\r\n `[Mailer][Send] Email sent to \"${to}\" with subject \"${subject}\".`\r\n );\r\n\r\n return \"Mail sent successfully.\";\r\n } catch (error) {\r\n logger.error(\r\n `[Mailer][Send] Failed to send email to \"${to}\" with subject \"${subject}\": ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to send email.\");\r\n }\r\n }\r\n}\r\n","import { ObjectId } from \"mongodb\";\r\nimport { logger } from \"./logger\";\r\nimport { BadRequestError } from \"./http-error\";\r\n\r\nexport function toObjectId(id: string | ObjectId): ObjectId {\r\n if (!id) {\r\n logger.error(\r\n `[ObjectId][Convert] No value provided for MongoDB ObjectId conversion.`\r\n );\r\n throw new BadRequestError(\r\n \"A value must be provided for ObjectId conversion.\"\r\n );\r\n }\r\n\r\n if (id instanceof ObjectId) return id;\r\n\r\n if (!/^[0-9a-fA-F]{24}$/.test(id)) {\r\n logger.error(\r\n `[ObjectId][Convert] Provided value is not a valid 24-character hex string.`\r\n );\r\n throw new BadRequestError(\r\n \"Invalid ObjectId: must be a 24-character hexadecimal string.\"\r\n );\r\n }\r\n\r\n try {\r\n return new ObjectId(id);\r\n } catch (err) {\r\n logger.error(\r\n `[ObjectId][Convert] Failed to convert value to ObjectId: ${\r\n err instanceof Error ? err.message : err\r\n }`\r\n );\r\n throw new BadRequestError(\"Failed to convert value into a valid ObjectId.\");\r\n }\r\n}\r\n","export function paginate<T>(\r\n items: T[],\r\n page: number = 0,\r\n limit: number = 10,\r\n total: number\r\n) {\r\n if (total === 0) {\r\n return {\r\n items: [],\r\n pages: 0,\r\n pageRange: \"0-0 of 0\",\r\n };\r\n }\r\n\r\n const startIndex = page * limit + 1;\r\n const endIndex = Math.min(startIndex + items.length - 1, total);\r\n\r\n return {\r\n items,\r\n pages: Math.ceil(total / limit),\r\n pageRange: `${startIndex}-${endIndex} of ${total}`,\r\n };\r\n}\r\n","import bcrypt from \"bcrypt\";\r\nimport { InternalServerError } from \"./http-error\";\r\nimport { logger } from \"./logger\";\r\n\r\nconst DEFAULT_SALT_ROUNDS = 10;\r\n\r\nexport async function comparePasswords(\r\n password: string,\r\n hashed: string\r\n): Promise<boolean> {\r\n try {\r\n return await bcrypt.compare(password, hashed);\r\n } catch (error) {\r\n logger.error(\r\n `[Password][Compare] Failed to compare passwords: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n return false;\r\n }\r\n}\r\n\r\nexport async function hashPassword(\r\n password: string,\r\n saltRounds: number = DEFAULT_SALT_ROUNDS\r\n): Promise<string> {\r\n try {\r\n return await bcrypt.hash(password, saltRounds);\r\n } catch (error) {\r\n logger.error(\r\n `[Password][Hash] Failed to hash password: ${\r\n error instanceof Error ? error.message : error\r\n }`\r\n );\r\n throw new InternalServerError(\"Failed to hash password.\");\r\n }\r\n}\r\n","import { createClient, RedisClientType } from \"redis\";\r\nimport { REDIS_HOST, REDIS_PASSWORD, REDIS_PORT } from \"./../config\";\r\nimport { logger } from \"./logger\";\r\n\r\nlet redisClient: RedisClientType | null = null;\r\n\r\nexport async function initRedisClient() {\r\n if (redisClient) {\r\n logger.info(\"[Redis][Init] Redis connection is already established.\");\r\n return redisClient;\r\n }\r\n\r\n redisClient = createClient({\r\n password: REDIS_PASSWORD,\r\n socket: {\r\n host: REDIS_HOST,\r\n port: REDIS_PORT,\r\n },\r\n });\r\n}\r\n\r\nexport function useRedisClient(): RedisClientType {\r\n if (!redisClient) {\r\n logger.error(\r\n \"[Redis][GetClient] Redis connection has not been initialized.\"\r\n );\r\n throw new Error(\r\n \"[Redis][GetClient] Redis connection is not initialized. Call initRedisClient() first.\"\r\n );\r\n }\r\n\r\n return redisClient;\r\n}\r\n","import * as dotenv from \"dotenv\";\r\n\r\ndotenv.config();\r\n\r\nfunction getEnv(key: string, fallback?: string): string {\r\n const value = process.env[key];\r\n if (value !== undefined) return value as string;\r\n if (fallback !== undefined) return fallback;\r\n throw new Error(`Missing required environment variable: ${key}`);\r\n}\r\n\r\nfunction getEnvNumber(key: string, fallback?: number): number {\r\n const value = process.env[key];\r\n if (value !== undefined) return Number(value);\r\n if (fallback !== undefined) return fallback;\r\n throw new Error(`Missing required environment variable: ${key}`);\r\n}\r\n\r\nfunction getEnvBoolean(key: string, fallback?: boolean): boolean {\r\n const value = process.env[key];\r\n if (value !== undefined) return value === \"true\";\r\n if (fallback !== undefined) return fallback;\r\n throw new Error(`Missing required environment variable: ${key}`);\r\n}\r\n\r\n// Redis\r\nexport const REDIS_HOST = getEnv(\"REDIS_HOST\");\r\nexport const REDIS_PORT = getEnvNumber(\"REDIS_PORT\", 6379);\r\nexport const REDIS_PASSWORD = getEnv(\"REDIS_PASSWORD\");\r\nexport const REDIS_TLS = getEnvBoolean(\"REDIS_TLS\", true);\r\n","import {\r\n DeleteObjectCommand,\r\n PutObjectCommand,\r\n S3Client,\r\n} from \"@aws-sdk/client-s3\";\r\nimport { Readable } from \"stream\";\r\nimport { logger } from \"./logger\";\r\n\r\ninterface S3Config {\r\n accessKeyId: string;\r\n secretAccessKey: string;\r\n endpoint: string;\r\n region: string;\r\n bucket: string;\r\n forcePathStyle: boolean;\r\n}\r\n\r\nexport class useS3 {\r\n private client: S3Client;\r\n\r\n constructor(private config: S3Config) {\r\n this.client = new S3Client({\r\n endpoint: config.endpoint,\r\n region: config.region,\r\n credentials: {\r\n accessKeyId: config.accessKeyId,\r\n secretAccessKey: config.secretAccessKey,\r\n },\r\n forcePathStyle: config.forcePathStyle,\r\n });\r\n }\r\n\r\n async uploadObject({\r\n key,\r\n body,\r\n metadata = {},\r\n contentType,\r\n }: {\r\n key: string;\r\n body: string | Buffer;\r\n metadata?: Record<string, string>;\r\n contentType?: string;\r\n }): Promise<string> {\r\n try {\r\n await this.client.send(\r\n new PutObjectCommand({\r\n Bucket: this.config.bucket,\r\n Key: key,\r\n Body:\r\n typeof body === \"string\" || Buffer.isBuffer(body)\r\n ? body\r\n : Readable.from(body),\r\n ACL: \"public-read\",\r\n Metadata: metadata,\r\n ContentType: contentType,\r\n ContentLength:\r\n typeof body === \"string\" ? Buffer.byteLength(body) : body.length,\r\n })\r\n );\r\n\r\n logger.info(\r\n `[S3][Upload] Uploaded \"${key}\" to bucket \"${this.config.bucket}\".`\r\n );\r\n return \"Successfully uploaded file.\";\r\n } catch (error) {\r\n logger.error(\r\n `[S3][Upload][Error] Failed to upload \"${key}\" to bucket \"${\r\n this.config.bucket\r\n }\": ${error instanceof Error ? error.message : error}`\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n async deleteObject(key: string) {\r\n try {\r\n await this.client.send(\r\n new DeleteObjectCommand({ Key: key, Bucket: this.config.bucket })\r\n );\r\n\r\n logger.info(\r\n `[S3][Delete] Deleted \"${key}\" from bucket \"${this.config.bucket}\".`\r\n );\r\n return \"Successfully deleted file.\";\r\n } catch (error) {\r\n logger.error(\r\n `[S3][Delete][Error] Failed to delete \"${key}\" from bucket \"${\r\n this.config.bucket\r\n }\": ${error instanceof Error ? error.message : error}`\r\n );\r\n throw error;\r\n }\r\n }\r\n}\r\n","import crypto from \"crypto\";\r\n\r\n// Deterministic hash for tokens at rest (do NOT use bcrypt here)\r\n// Optionally salt via env if provided\r\nconst TOKEN_HASH_SALT = process.env.REFRESH_TOKEN_HASH_SALT || \"\";\r\n\r\nexport function hashToken(token: string): string {\r\n return crypto\r\n .createHash(\"sha256\")\r\n .update(TOKEN_HASH_SALT + token)\r\n .digest(\"hex\");\r\n}\r\n"],"mappings":"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","names":["transports","jwt","config","Redis","redisClient","path","fs","Handlebars","import_jsonwebtoken","jwt","config","import_mongodb","bcrypt","redisClient","config","crypto"]}
|