@shadimakhoul/ggcoach 1.0.0 → 1.0.2
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/config/index.ts +2 -1
- package/config/initExpress.ts +3 -3
- package/config/redis.ts +1 -4
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/initExpress.d.ts +1 -1
- package/dist/config/initExpress.d.ts.map +1 -1
- package/dist/config/initExpress.js +2 -2
- package/dist/config/initExpress.js.map +1 -1
- package/dist/config/redis.d.ts +1 -1
- package/dist/config/redis.d.ts.map +1 -1
- package/dist/config/redis.js +1 -3
- package/dist/config/redis.js.map +1 -1
- package/dist/middleware/auth.d.ts +2 -2
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +2 -3
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/cors.d.ts +9 -0
- package/dist/middleware/cors.d.ts.map +1 -1
- package/dist/middleware/cors.js +40 -36
- package/dist/middleware/cors.js.map +1 -1
- package/dist/middleware/errorHandler.d.ts +1 -1
- package/dist/middleware/errorHandler.d.ts.map +1 -1
- package/dist/middleware/errorHandler.js +2 -2
- package/dist/middleware/errorHandler.js.map +1 -1
- package/dist/middleware/internalAuth.d.ts +1 -1
- package/dist/middleware/internalAuth.d.ts.map +1 -1
- package/dist/middleware/internalAuth.js +3 -3
- package/dist/middleware/internalAuth.js.map +1 -1
- package/dist/middleware/swagger.d.ts +1 -1
- package/dist/middleware/swagger.d.ts.map +1 -1
- package/dist/middleware/swagger.js +4 -4
- package/dist/middleware/swagger.js.map +1 -1
- package/dist/utils/jwt.d.ts +4 -4
- package/dist/utils/jwt.d.ts.map +1 -1
- package/dist/utils/jwt.js +4 -6
- package/dist/utils/jwt.js.map +1 -1
- package/logs/combined.log +129 -0
- package/logs/error.log +54 -0
- package/middleware/auth.ts +49 -55
- package/middleware/cors.ts +46 -40
- package/middleware/internalAuth.ts +19 -17
- package/middleware/swagger.ts +3 -3
- package/package.json +1 -1
- package/utils/jwt.ts +5 -7
- package/config/config.ts +0 -7
package/config/index.ts
CHANGED
package/config/initExpress.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { stream } from "../utils";
|
|
|
7
7
|
|
|
8
8
|
dotenv.config();
|
|
9
9
|
|
|
10
|
-
export function initExpress() {
|
|
10
|
+
export function initExpress(isDevelopment: boolean) {
|
|
11
11
|
const app = express();
|
|
12
12
|
|
|
13
13
|
app.use(helmet());
|
|
@@ -17,8 +17,8 @@ export function initExpress() {
|
|
|
17
17
|
app.use(express.json({ limit: "10mb" }));
|
|
18
18
|
app.use(express.urlencoded({ extended: true, limit: "10mb" }));
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
app.use(morgan("dev", { stream } as any));
|
|
21
|
+
if (isDevelopment) {
|
|
22
22
|
} else {
|
|
23
23
|
app.use(morgan("combined", { stream } as any));
|
|
24
24
|
}
|
package/config/redis.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { createClient } from 'redis';
|
|
2
2
|
|
|
3
3
|
import { logger } from '../utils';
|
|
4
|
-
import { config } from './config';
|
|
5
|
-
|
|
6
|
-
const REDIS_URL = config.redis.REDIS_URL;
|
|
7
4
|
|
|
8
5
|
export type RedisClient = ReturnType<typeof createClient>;
|
|
9
6
|
|
|
10
7
|
let redisClient: RedisClient | null = null;
|
|
11
8
|
|
|
12
|
-
export const initializeRedis = async (): Promise<RedisClient> => {
|
|
9
|
+
export const initializeRedis = async (REDIS_URL: string): Promise<RedisClient> => {
|
|
13
10
|
if (redisClient && redisClient.isOpen) {
|
|
14
11
|
return redisClient;
|
|
15
12
|
}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../config/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../config/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC"}
|
package/dist/config/index.js
CHANGED
|
@@ -16,4 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./initExpress"), exports);
|
|
18
18
|
__exportStar(require("./redis"), exports);
|
|
19
|
+
__exportStar(require("./swagger-ui"), exports);
|
|
19
20
|
//# sourceMappingURL=index.js.map
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../config/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,0CAAwB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../config/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,0CAAwB;AACxB,+CAA6B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function initExpress(): import("express-serve-static-core").Express;
|
|
1
|
+
export declare function initExpress(isDevelopment: boolean): import("express-serve-static-core").Express;
|
|
2
2
|
//# sourceMappingURL=initExpress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initExpress.d.ts","sourceRoot":"","sources":["../../config/initExpress.ts"],"names":[],"mappings":"AASA,wBAAgB,WAAW,
|
|
1
|
+
{"version":3,"file":"initExpress.d.ts","sourceRoot":"","sources":["../../config/initExpress.ts"],"names":[],"mappings":"AASA,wBAAgB,WAAW,CAAC,aAAa,EAAE,OAAO,+CAiBjD"}
|
|
@@ -11,14 +11,14 @@ const morgan_1 = __importDefault(require("morgan"));
|
|
|
11
11
|
const middleware_1 = require("../middleware");
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
13
|
dotenv_1.default.config();
|
|
14
|
-
function initExpress() {
|
|
14
|
+
function initExpress(isDevelopment) {
|
|
15
15
|
const app = (0, express_1.default)();
|
|
16
16
|
app.use((0, helmet_1.default)());
|
|
17
17
|
app.use(middleware_1.corsMiddleware);
|
|
18
18
|
app.use(middleware_1.generalRateLimiter);
|
|
19
19
|
app.use(express_1.default.json({ limit: "10mb" }));
|
|
20
20
|
app.use(express_1.default.urlencoded({ extended: true, limit: "10mb" }));
|
|
21
|
-
if (
|
|
21
|
+
if (isDevelopment) {
|
|
22
22
|
app.use((0, morgan_1.default)("dev", { stream: utils_1.stream }));
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initExpress.js","sourceRoot":"","sources":["../../config/initExpress.ts"],"names":[],"mappings":";;;;;AASA,kCAiBC;AA1BD,sDAA8B;AAC9B,oDAA4B;AAC5B,oDAA4B;AAC5B,oDAA4B;AAC5B,8CAAmE;AACnE,oCAAoC;AAEpC,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,SAAgB,WAAW;
|
|
1
|
+
{"version":3,"file":"initExpress.js","sourceRoot":"","sources":["../../config/initExpress.ts"],"names":[],"mappings":";;;;;AASA,kCAiBC;AA1BD,sDAA8B;AAC9B,oDAA4B;AAC5B,oDAA4B;AAC5B,oDAA4B;AAC5B,8CAAmE;AACnE,oCAAoC;AAEpC,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,SAAgB,WAAW,CAAC,aAAsB;IAChD,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IAEtB,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,GAAE,CAAC,CAAC;IAClB,GAAG,CAAC,GAAG,CAAC,2BAAc,CAAC,CAAC;IACxB,GAAG,CAAC,GAAG,CAAC,+BAAkB,CAAC,CAAC;IAE5B,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAE/D,IAAI,aAAa,EAAE,CAAC;QAClB,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,EAAC,KAAK,EAAE,EAAE,MAAM,EAAN,cAAM,EAAS,CAAC,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,EAAC,UAAU,EAAE,EAAE,MAAM,EAAN,cAAM,EAAS,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/config/redis.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createClient } from 'redis';
|
|
2
2
|
export type RedisClient = ReturnType<typeof createClient>;
|
|
3
|
-
export declare const initializeRedis: () => Promise<RedisClient>;
|
|
3
|
+
export declare const initializeRedis: (REDIS_URL: string) => Promise<RedisClient>;
|
|
4
4
|
export declare const getRedisClient: () => RedisClient;
|
|
5
5
|
export declare const closeRedis: () => Promise<void>;
|
|
6
6
|
//# sourceMappingURL=redis.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../config/redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../config/redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAIrC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AAI1D,eAAO,MAAM,eAAe,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,WAAW,CAY5E,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,WAKjC,CAAC;AAEF,eAAO,MAAM,UAAU,QAAa,OAAO,CAAC,IAAI,CAK/C,CAAC"}
|
package/dist/config/redis.js
CHANGED
|
@@ -3,10 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.closeRedis = exports.getRedisClient = exports.initializeRedis = void 0;
|
|
4
4
|
const redis_1 = require("redis");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
|
-
const config_1 = require("./config");
|
|
7
|
-
const REDIS_URL = config_1.config.redis.REDIS_URL;
|
|
8
6
|
let redisClient = null;
|
|
9
|
-
const initializeRedis = async () => {
|
|
7
|
+
const initializeRedis = async (REDIS_URL) => {
|
|
10
8
|
if (redisClient && redisClient.isOpen) {
|
|
11
9
|
return redisClient;
|
|
12
10
|
}
|
package/dist/config/redis.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../config/redis.ts"],"names":[],"mappings":";;;AAAA,iCAAqC;AAErC,oCAAkC;
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../config/redis.ts"],"names":[],"mappings":";;;AAAA,iCAAqC;AAErC,oCAAkC;AAIlC,IAAI,WAAW,GAAuB,IAAI,CAAC;AAEpC,MAAM,eAAe,GAAG,KAAK,EAAE,SAAiB,EAAwB,EAAE;IAC/E,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,WAAW,GAAG,IAAA,oBAAY,EAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IAE/C,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,cAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1E,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,cAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAElE,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAZW,QAAA,eAAe,mBAY1B;AAEK,MAAM,cAAc,GAAG,GAAgB,EAAE;IAC9C,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AALW,QAAA,cAAc,kBAKzB;AAEK,MAAM,UAAU,GAAG,KAAK,IAAmB,EAAE;IAClD,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QACtC,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;QACzB,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC,CAAC;AALW,QAAA,UAAU,cAKrB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from "express";
|
|
2
|
-
export declare const authenticateToken: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3
|
-
export declare const optionalAuth: (req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
2
|
+
export declare const authenticateToken: (JWT_SECRET: string, req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3
|
+
export declare const optionalAuth: (JWT_SECRET: string, req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
4
4
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAU1D,eAAO,MAAM,iBAAiB,GAC5B,YAAY,MAAM,EAClB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,OAAO,CAAC,IAAI,CAmCd,CAAC;AAsBF,eAAO,MAAM,YAAY,GACvB,YAAY,MAAM,EAClB,KAAK,OAAO,EACZ,MAAM,QAAQ,EACd,MAAM,YAAY,KACjB,OAAO,CAAC,IAAI,CAsBd,CAAC"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -7,9 +7,8 @@ exports.optionalAuth = exports.authenticateToken = void 0;
|
|
|
7
7
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
8
|
const utils_1 = require("../utils");
|
|
9
9
|
const config_1 = require("../config");
|
|
10
|
-
const JWT_SECRET = process.env.JWT_SECRET || "your-super-secret-jwt-key-change-in-production";
|
|
11
10
|
const TOKEN_VERSION_PREFIX = "auth:token-version:";
|
|
12
|
-
const authenticateToken = async (req, res, next) => {
|
|
11
|
+
const authenticateToken = async (JWT_SECRET, req, res, next) => {
|
|
13
12
|
const authHeader = req.headers["authorization"];
|
|
14
13
|
const token = authHeader && authHeader.split(" ")[1];
|
|
15
14
|
if (!token) {
|
|
@@ -61,7 +60,7 @@ const validateTokenWithRedis = async (decoded) => {
|
|
|
61
60
|
return false;
|
|
62
61
|
}
|
|
63
62
|
};
|
|
64
|
-
const optionalAuth = async (req, _res, next) => {
|
|
63
|
+
const optionalAuth = async (JWT_SECRET, req, _res, next) => {
|
|
65
64
|
const authHeader = req.headers["authorization"];
|
|
66
65
|
const token = authHeader && authHeader.split(" ")[1];
|
|
67
66
|
if (token) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../middleware/auth.ts"],"names":[],"mappings":";;;;;;AACA,gEAA+B;AAE/B,oCAAkC;AAClC,sCAA2C;AAI3C,MAAM,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../middleware/auth.ts"],"names":[],"mappings":";;;;;;AACA,gEAA+B;AAE/B,oCAAkC;AAClC,sCAA2C;AAI3C,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;AAE5C,MAAM,iBAAiB,GAAG,KAAK,EACpC,UAAkB,EAClB,GAAY,EACZ,GAAa,EACb,IAAkB,EACH,EAAE;IACjB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,uBAAuB;SACjC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE;YAC5C,MAAM,EAAE,sBAAsB;YAC9B,QAAQ,EAAE,aAAa;SACxB,CAAe,CAAC;QAEjB,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,0BAA0B;aACpC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC;QACnB,IAAI,EAAE,CAAC;IACT,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,0BAA0B;SACpC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAxCW,QAAA,iBAAiB,qBAwC5B;AAEF,MAAM,sBAAsB,GAAG,KAAK,EAAE,OAAmB,EAAoB,EAAE;IAC7E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,uBAAc,GAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,oBAAoB,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC;QAC/C,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,KAAK,YAAY,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,cAAM,CAAC,IAAI,CAAC,oCAAoC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEK,MAAM,YAAY,GAAG,KAAK,EAC/B,UAAkB,EAClB,GAAY,EACZ,IAAc,EACd,IAAkB,EACH,EAAE;IACjB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE;gBAC5C,MAAM,EAAE,sBAAsB;gBAC9B,QAAQ,EAAE,aAAa;aACxB,CAAe,CAAC;YACjB,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,OAAO,EAAE,CAAC;gBACZ,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC;YACrB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,cAAM,CAAC,IAAI,CAAC,mCAAmC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AA3BW,QAAA,YAAY,gBA2BvB"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import cors from "cors";
|
|
2
|
+
export declare const createCorsOptions: (allowedOrigins?: string[]) => {
|
|
3
|
+
origin: (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => void;
|
|
4
|
+
credentials: boolean;
|
|
5
|
+
methods: string[];
|
|
6
|
+
allowedHeaders: string[];
|
|
7
|
+
exposedHeaders: string[];
|
|
8
|
+
preflightContinue: boolean;
|
|
9
|
+
optionsSuccessStatus: number;
|
|
10
|
+
};
|
|
2
11
|
export declare const corsOptions: {
|
|
3
12
|
origin: (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => void;
|
|
4
13
|
credentials: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAgBxB,eAAO,MAAM,iBAAiB,GAAI,iBAAiB,MAAM,EAAE;qBAQ7C,MAAM,GAAG,SAAS,YAChB,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI;;;;;;;CAuB3D,CAAC;AAGF,eAAO,MAAM,WAAW;qBA3BV,MAAM,GAAG,SAAS,YAChB,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI;;;;;;;CA0Bd,CAAC;AAE/C,eAAO,MAAM,cAAc;cAFE,CAAC;;;aAGiB,CAAC,sBADD,CAAC"}
|
package/dist/middleware/cors.js
CHANGED
|
@@ -3,43 +3,47 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.corsMiddleware = exports.corsOptions = void 0;
|
|
6
|
+
exports.corsMiddleware = exports.corsOptions = exports.createCorsOptions = void 0;
|
|
7
7
|
const cors_1 = __importDefault(require("cors"));
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
8
|
+
const DEFAULT_ORIGINS = [
|
|
9
|
+
"http://localhost:4000",
|
|
10
|
+
"http://localhost:4001",
|
|
11
|
+
"http://localhost:4002",
|
|
12
|
+
"http://localhost:4003",
|
|
13
|
+
"http://localhost:4004",
|
|
14
|
+
"http://localhost:4005",
|
|
15
|
+
"http://localhost:8080",
|
|
16
|
+
"http://localhost:3000",
|
|
17
|
+
"http://localhost:3001",
|
|
18
|
+
"https://gg.staging.brainexy.com",
|
|
19
|
+
"https://gg.register.brainexy.com",
|
|
20
|
+
];
|
|
21
|
+
const createCorsOptions = (allowedOrigins) => {
|
|
22
|
+
const origins = allowedOrigins || DEFAULT_ORIGINS;
|
|
23
|
+
const finalAllowedOrigins = Array.from(new Set([...origins].map(o => o.toLowerCase())));
|
|
24
|
+
return {
|
|
25
|
+
origin: (origin, callback) => {
|
|
26
|
+
if (!origin)
|
|
27
|
+
return callback(null, true);
|
|
28
|
+
if (finalAllowedOrigins.includes(origin.toLowerCase())) {
|
|
29
|
+
return callback(null, true);
|
|
30
|
+
}
|
|
31
|
+
return callback(new Error("Not allowed by CORS"));
|
|
32
|
+
},
|
|
33
|
+
credentials: true,
|
|
34
|
+
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
|
35
|
+
allowedHeaders: [
|
|
36
|
+
"Content-Type",
|
|
37
|
+
"Authorization",
|
|
38
|
+
"X-Requested-With",
|
|
39
|
+
"X-Request-ID",
|
|
40
|
+
],
|
|
41
|
+
exposedHeaders: ["X-Request-ID"],
|
|
42
|
+
preflightContinue: false,
|
|
43
|
+
optionsSuccessStatus: 200,
|
|
44
|
+
};
|
|
43
45
|
};
|
|
46
|
+
exports.createCorsOptions = createCorsOptions;
|
|
47
|
+
exports.corsOptions = (0, exports.createCorsOptions)();
|
|
44
48
|
exports.corsMiddleware = (0, cors_1.default)(exports.corsOptions);
|
|
45
49
|
//# sourceMappingURL=cors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../middleware/cors.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../middleware/cors.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAExB,MAAM,eAAe,GAAG;IACtB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,iCAAiC;IACjC,kCAAkC;CACnC,CAAC;AAEK,MAAM,iBAAiB,GAAG,CAAC,cAAyB,EAAE,EAAE;IAC7D,MAAM,OAAO,GAAG,cAAc,IAAI,eAAe,CAAC;IAClD,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CACpC,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,CAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CACjD,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,CACN,MAA0B,EAC1B,QAAsD,EACtD,EAAE;YAEF,IAAI,CAAC,MAAM;gBAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACzC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBACvD,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC9B,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;QAC7D,cAAc,EAAE;YACd,cAAc;YACd,eAAe;YACf,kBAAkB;YAClB,cAAc;SACf;QACD,cAAc,EAAE,CAAC,cAAc,CAAC;QAChC,iBAAiB,EAAE,KAAK;QACxB,oBAAoB,EAAE,GAAG;KAC1B,CAAC;AACJ,CAAC,CAAC;AAhCW,QAAA,iBAAiB,qBAgC5B;AAGW,QAAA,WAAW,GAAG,IAAA,yBAAiB,GAAE,CAAC;AAElC,QAAA,cAAc,GAAG,IAAA,cAAI,EAAC,mBAAW,CAAC,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
-
export declare const errorHandler: (err: any, req: Request, res: Response, next: NextFunction) => void;
|
|
2
|
+
export declare const errorHandler: (isDevelopment: boolean, err: any, req: Request, res: Response, next: NextFunction) => void;
|
|
3
3
|
//# sourceMappingURL=errorHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../middleware/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,eAAO,MAAM,YAAY,GAAI,KAAK,GAAG,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../middleware/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,eAAO,MAAM,YAAY,GAAI,eAAe,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IA0DhH,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.errorHandler = void 0;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
|
-
const errorHandler = (err, req, res, next) => {
|
|
5
|
+
const errorHandler = (isDevelopment, err, req, res, next) => {
|
|
6
6
|
utils_1.logger.error(`Error: ${err}`);
|
|
7
7
|
if (err.code === 'ECONNREFUSED') {
|
|
8
8
|
res.status(503).json({
|
|
@@ -48,7 +48,7 @@ const errorHandler = (err, req, res, next) => {
|
|
|
48
48
|
success: false,
|
|
49
49
|
message: err.message || 'Internal server error',
|
|
50
50
|
code: err.code || 'INTERNAL_ERROR',
|
|
51
|
-
...(
|
|
51
|
+
...(isDevelopment && {
|
|
52
52
|
stack: err.stack,
|
|
53
53
|
requestId: req.headers['x-request-id']
|
|
54
54
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../middleware/errorHandler.ts"],"names":[],"mappings":";;;AACA,oCAAkC;AAE3B,MAAM,YAAY,GAAG,CAAC,GAAQ,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../middleware/errorHandler.ts"],"names":[],"mappings":";;;AACA,oCAAkC;AAE3B,MAAM,YAAY,GAAG,CAAC,aAAsB,EAAE,GAAQ,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;IACtH,cAAM,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;IAG9B,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAChC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,iCAAiC;YAC1C,IAAI,EAAE,qBAAqB;SAC5B,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,iBAAiB;YAC1B,IAAI,EAAE,iBAAiB;SACxB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACnC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,kBAAkB;YAC3B,MAAM,EAAE,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;SACrC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,0BAA0B,EAAE,CAAC;QAC5C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,kBAAkB;YAC3B,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;SAC9C,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,gCAAgC,EAAE,CAAC;QAClD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,yBAAyB;YAClC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,SAAS;SACxC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QACjC,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,uBAAuB;QAC/C,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,gBAAgB;QAClC,GAAG,CAAC,aAAa,IAAI;YACnB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC;SACvC,CAAC;KACH,CAAC,CAAC;AACL,CAAC,CAAC;AA1DW,QAAA,YAAY,gBA0DvB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
|
-
export declare const requireInternalToken: (req: Request, res: Response, next: NextFunction) => void;
|
|
2
|
+
export declare const requireInternalToken: (ALLOW_DIRECT_ACCESS: boolean, INTERNAL_SERVICE_TOKEN: string, req: Request, res: Response, next: NextFunction) => void;
|
|
3
3
|
export default requireInternalToken;
|
|
4
4
|
//# sourceMappingURL=internalAuth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internalAuth.d.ts","sourceRoot":"","sources":["../../middleware/internalAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,eAAO,MAAM,oBAAoB,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,
|
|
1
|
+
{"version":3,"file":"internalAuth.d.ts","sourceRoot":"","sources":["../../middleware/internalAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,eAAO,MAAM,oBAAoB,GAAI,qBAAqB,OAAO,EAAE,wBAAwB,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IAoBpJ,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.requireInternalToken = void 0;
|
|
4
|
-
const requireInternalToken = (req, res, next) => {
|
|
5
|
-
if (
|
|
4
|
+
const requireInternalToken = (ALLOW_DIRECT_ACCESS, INTERNAL_SERVICE_TOKEN, req, res, next) => {
|
|
5
|
+
if (ALLOW_DIRECT_ACCESS) {
|
|
6
6
|
next();
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
|
-
const token =
|
|
9
|
+
const token = INTERNAL_SERVICE_TOKEN;
|
|
10
10
|
if (!token) {
|
|
11
11
|
res.status(403).json({ success: false, message: 'Internal access token not configured' });
|
|
12
12
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internalAuth.js","sourceRoot":"","sources":["../../middleware/internalAuth.ts"],"names":[],"mappings":";;;AAEO,MAAM,oBAAoB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"internalAuth.js","sourceRoot":"","sources":["../../middleware/internalAuth.ts"],"names":[],"mappings":";;;AAEO,MAAM,oBAAoB,GAAG,CAAC,mBAA4B,EAAE,sBAA8B,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;IAC1J,IAAI,mBAAmB,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC;QACP,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,sBAAsB,CAAC;IACrC,IAAI,CAAC,KAAK,EAAE,CAAC;QAEX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,sCAAsC,EAAE,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAI,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAY,IAAI,EAAE,CAAC;IACnE,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AApBW,QAAA,oBAAoB,wBAoB/B;AAEF,kBAAe,4BAAoB,CAAC"}
|
|
@@ -11,6 +11,6 @@ type SwaggerSetupOptions = {
|
|
|
11
11
|
swaggerUiUrls?: SwaggerUiUrl[];
|
|
12
12
|
swaggerUiPrimaryName?: string;
|
|
13
13
|
};
|
|
14
|
-
export declare const setupSwagger: (app: Express, options?: SwaggerSetupOptions) => void;
|
|
14
|
+
export declare const setupSwagger: (PORT: number, app: Express, options?: SwaggerSetupOptions) => void;
|
|
15
15
|
export {};
|
|
16
16
|
//# sourceMappingURL=swagger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swagger.d.ts","sourceRoot":"","sources":["../../middleware/swagger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKlC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IACnD,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAcF,eAAO,MAAM,YAAY,GAAI,KAAK,OAAO,EAAE,UAAS,mBAAwB,
|
|
1
|
+
{"version":3,"file":"swagger.d.ts","sourceRoot":"","sources":["../../middleware/swagger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKlC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IACnD,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAcF,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,KAAK,OAAO,EAAE,UAAS,mBAAwB,SAoCzF,CAAC"}
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.setupSwagger = void 0;
|
|
7
7
|
const swagger_ui_express_1 = __importDefault(require("swagger-ui-express"));
|
|
8
|
-
const
|
|
8
|
+
const config_1 = require("../config");
|
|
9
9
|
const utils_1 = require("../utils");
|
|
10
10
|
const resolveSpec = async (options) => {
|
|
11
11
|
if (options.getSpec) {
|
|
@@ -16,7 +16,7 @@ const resolveSpec = async (options) => {
|
|
|
16
16
|
}
|
|
17
17
|
return {};
|
|
18
18
|
};
|
|
19
|
-
const setupSwagger = (app, options = {}) => {
|
|
19
|
+
const setupSwagger = (PORT, app, options = {}) => {
|
|
20
20
|
const basePath = options.basePath ?? '/api-docs';
|
|
21
21
|
app.get(`${basePath}/swagger.json`, async (_req, res) => {
|
|
22
22
|
try {
|
|
@@ -31,7 +31,7 @@ const setupSwagger = (app, options = {}) => {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
app.use(basePath, swagger_ui_express_1.default.serve, swagger_ui_express_1.default.setup(undefined, {
|
|
34
|
-
...
|
|
34
|
+
...config_1.swaggerUiOptions,
|
|
35
35
|
swaggerOptions: {
|
|
36
36
|
...(options.swaggerUiUrls && options.swaggerUiUrls.length > 0
|
|
37
37
|
? {
|
|
@@ -43,7 +43,7 @@ const setupSwagger = (app, options = {}) => {
|
|
|
43
43
|
: { url: `${basePath}/swagger.json` }),
|
|
44
44
|
},
|
|
45
45
|
}));
|
|
46
|
-
utils_1.logger.info(`📚 Swagger documentation available at: http://localhost:${
|
|
46
|
+
utils_1.logger.info(`📚 Swagger documentation available at: http://localhost:${PORT}${basePath}`);
|
|
47
47
|
};
|
|
48
48
|
exports.setupSwagger = setupSwagger;
|
|
49
49
|
//# sourceMappingURL=swagger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swagger.js","sourceRoot":"","sources":["../../middleware/swagger.ts"],"names":[],"mappings":";;;;;;AACA,4EAA2C;AAC3C,
|
|
1
|
+
{"version":3,"file":"swagger.js","sourceRoot":"","sources":["../../middleware/swagger.ts"],"names":[],"mappings":";;;;;;AACA,4EAA2C;AAC3C,sCAA6C;AAC7C,oCAAkC;AAiBlC,MAAM,WAAW,GAAG,KAAK,EAAE,OAA4B,EAAwB,EAAE;IAC/E,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,OAAO,CAAC,IAAI,CAAC;IACtB,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEK,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,GAAY,EAAE,UAA+B,EAAE,EAAE,EAAE;IAC5F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,CAAC;IAEjD,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACtD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;YACxC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,cAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CACL,QAAQ,EACR,4BAAS,CAAC,KAAK,EACf,4BAAS,CAAC,KAAK,CAAC,SAAS,EAAE;QACzB,GAAG,yBAAgB;QACnB,cAAc,EAAE;YACd,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;gBAC3D,CAAC,CAAC;oBACE,IAAI,EAAE,OAAO,CAAC,aAAa;oBAC3B,GAAG,CAAC,OAAO,CAAC,oBAAoB;wBAC9B,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,oBAAoB,EAAE;wBACnD,CAAC,CAAC,EAAE,CAAC;iBACR;gBACH,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,QAAQ,eAAe,EAAE,CAAC;SACzC;KACF,CAAC,CACH,CAAC;IAEF,cAAM,CAAC,IAAI,CACT,2DAA2D,IAAI,GAAG,QAAQ,EAAE,CAC7E,CAAC;AACJ,CAAC,CAAC;AApCW,QAAA,YAAY,gBAoCvB"}
|
package/dist/utils/jwt.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { JWTPayload, UserAttributes } from '../types
|
|
2
|
-
export declare const generateToken: (user: UserAttributes) => string;
|
|
3
|
-
export declare const verifyToken: (token: string) => JWTPayload;
|
|
4
|
-
export declare const generateRefreshToken: (user: UserAttributes) => string;
|
|
1
|
+
import { JWTPayload, UserAttributes } from '../types';
|
|
2
|
+
export declare const generateToken: (JWT_SECRET: string, JWT_EXPIRES_IN: string, user: UserAttributes) => string;
|
|
3
|
+
export declare const verifyToken: (JWT_SECRET: string, token: string) => JWTPayload;
|
|
4
|
+
export declare const generateRefreshToken: (JWT_SECRET: string, JWT_EXPIRES_IN: string, user: UserAttributes) => string;
|
|
5
5
|
//# sourceMappingURL=jwt.d.ts.map
|
package/dist/utils/jwt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../utils/jwt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../utils/jwt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGtD,eAAO,MAAM,aAAa,GAAI,YAAY,MAAM,EAAE,gBAAgB,MAAM,EAAE,MAAM,cAAc,KAAG,MAsBhG,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,YAAY,MAAM,EAAE,OAAO,MAAM,KAAG,UAW/D,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,YAAY,MAAM,EAAE,gBAAgB,MAAM,EAAE,MAAM,cAAc,KAAG,MAsBvG,CAAC"}
|
package/dist/utils/jwt.js
CHANGED
|
@@ -5,9 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.generateRefreshToken = exports.verifyToken = exports.generateToken = void 0;
|
|
7
7
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
|
-
const
|
|
9
|
-
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d';
|
|
10
|
-
const generateToken = (user) => {
|
|
8
|
+
const generateToken = (JWT_SECRET, JWT_EXPIRES_IN, user) => {
|
|
11
9
|
const payload = {
|
|
12
10
|
id: user.id,
|
|
13
11
|
email: user.email,
|
|
@@ -29,7 +27,7 @@ const generateToken = (user) => {
|
|
|
29
27
|
return jsonwebtoken_1.default.sign(payload, JWT_SECRET, options);
|
|
30
28
|
};
|
|
31
29
|
exports.generateToken = generateToken;
|
|
32
|
-
const verifyToken = (token) => {
|
|
30
|
+
const verifyToken = (JWT_SECRET, token) => {
|
|
33
31
|
try {
|
|
34
32
|
const decoded = jsonwebtoken_1.default.verify(token, JWT_SECRET, {
|
|
35
33
|
issuer: 'ggcoach-auth-service',
|
|
@@ -42,7 +40,7 @@ const verifyToken = (token) => {
|
|
|
42
40
|
}
|
|
43
41
|
};
|
|
44
42
|
exports.verifyToken = verifyToken;
|
|
45
|
-
const generateRefreshToken = (user) => {
|
|
43
|
+
const generateRefreshToken = (JWT_SECRET, JWT_EXPIRES_IN, user) => {
|
|
46
44
|
const payload = {
|
|
47
45
|
id: user.id,
|
|
48
46
|
email: user.email,
|
|
@@ -57,7 +55,7 @@ const generateRefreshToken = (user) => {
|
|
|
57
55
|
tokenType: 'refresh',
|
|
58
56
|
};
|
|
59
57
|
const options = {
|
|
60
|
-
expiresIn:
|
|
58
|
+
expiresIn: JWT_EXPIRES_IN,
|
|
61
59
|
issuer: 'ggcoach-auth-service',
|
|
62
60
|
audience: 'ggcoach-app'
|
|
63
61
|
};
|
package/dist/utils/jwt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../utils/jwt.ts"],"names":[],"mappings":";;;;;;AAAA,gEAA+B;
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../utils/jwt.ts"],"names":[],"mappings":";;;;;;AAAA,gEAA+B;AAIxB,MAAM,aAAa,GAAG,CAAC,UAAkB,EAAE,cAAsB,EAAE,IAAoB,EAAU,EAAE;IACxG,MAAM,OAAO,GAAe;QAC1B,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC;QACpC,SAAS,EAAE,QAAQ;KACpB,CAAC;IAEF,MAAM,OAAO,GAAoB;QAC/B,SAAS,EAAE,cAAc;QACzB,MAAM,EAAE,sBAAsB;QAC9B,QAAQ,EAAE,aAAa;KACL,CAAC;IAErB,OAAO,sBAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC,CAAC;AAtBW,QAAA,aAAa,iBAsBxB;AAEK,MAAM,WAAW,GAAG,CAAC,UAAkB,EAAE,KAAa,EAAc,EAAE;IAC3E,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE;YAC5C,MAAM,EAAE,sBAAsB;YAC9B,QAAQ,EAAE,aAAa;SACxB,CAAe,CAAC;QAEjB,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC,CAAC;AAXW,QAAA,WAAW,eAWtB;AAEK,MAAM,oBAAoB,GAAG,CAAC,UAAkB,EAAE,cAAsB,EAAE,IAAoB,EAAU,EAAE;IAC/G,MAAM,OAAO,GAAe;QAC1B,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,CAAC;QACpC,SAAS,EAAE,SAAS;KACrB,CAAC;IAEF,MAAM,OAAO,GAAoB;QAC/B,SAAS,EAAE,cAAc;QACzB,MAAM,EAAE,sBAAsB;QAC9B,QAAQ,EAAE,aAAa;KACL,CAAC;IAErB,OAAO,sBAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC,CAAC;AAtBW,QAAA,oBAAoB,wBAsB/B"}
|
package/logs/combined.log
CHANGED
|
@@ -85180,3 +85180,132 @@ SIGINT received, shutting down gracefully...
|
|
|
85180
85180
|
2026-02-22T12:02:49.954Z [info]: ✅ Database connection established successfully.
|
|
85181
85181
|
2026-02-22T12:02:50.209Z [crit]:
|
|
85182
85182
|
SIGINT received, shutting down gracefully...
|
|
85183
|
+
2026-02-22T12:49:31.351Z [info]: 📚 Swagger documentation available at: http://localhost:4006/api-docs
|
|
85184
|
+
2026-02-22T12:49:31.355Z [info]: All required environment variables are present
|
|
85185
|
+
2026-02-22T12:49:31.365Z [info]: Tracking service running on port 4006
|
|
85186
|
+
2026-02-22T12:49:31.544Z [info]: 📚 Swagger documentation available at: http://localhost:4000/api-docs
|
|
85187
|
+
2026-02-22T12:49:31.548Z [info]: 🚀 API Gateway running on port 4000
|
|
85188
|
+
2026-02-22T12:49:31.548Z [info]: 📊 Health check: http://localhost:4000/health
|
|
85189
|
+
2026-02-22T12:49:31.549Z [info]: 📈 Service status: http://localhost:4000/status
|
|
85190
|
+
2026-02-22T12:49:31.549Z [info]: 🔐 Auth endpoints: http://localhost:4001/api/auth
|
|
85191
|
+
2026-02-22T12:49:31.550Z [info]: 🔐 User endpoints: http://localhost:4002/api/user
|
|
85192
|
+
2026-02-22T12:49:31.550Z [info]: 🔐 Media endpoints: http://localhost:4003/api/media
|
|
85193
|
+
2026-02-22T12:49:31.550Z [info]: 🔐 Messaging endpoints: http://localhost:4004/api/messaging
|
|
85194
|
+
2026-02-22T12:49:31.552Z [info]: 🔐 Marketing endpoints: http://localhost:4005/api/marketing
|
|
85195
|
+
2026-02-22T12:49:31.552Z [info]: 🔐 Tracking endpoints: http://localhost:4006/api/tracking
|
|
85196
|
+
2026-02-22T12:49:31.552Z [info]: 🌍 Environment: development
|
|
85197
|
+
2026-02-22T12:49:31.785Z [info]: 📚 Swagger documentation available at: http://localhost:4003/api-docs
|
|
85198
|
+
2026-02-22T12:49:32.112Z [info]: 📚 Swagger documentation available at: http://localhost:4005/api-docs
|
|
85199
|
+
2026-02-22T12:49:32.191Z [info]: 📚 Swagger documentation available at: http://localhost:4001/api-docs
|
|
85200
|
+
2026-02-22T12:49:32.274Z [info]: 📚 Swagger documentation available at: http://localhost:4002/api-docs
|
|
85201
|
+
2026-02-22T12:49:32.482Z [info]: 📚 Swagger documentation available at: http://localhost:4004/api-docs
|
|
85202
|
+
2026-02-22T12:49:32.484Z [info]: All required environment variables are present
|
|
85203
|
+
2026-02-22T12:49:32.521Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85204
|
+
2026-02-22T12:49:32.548Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85205
|
+
2026-02-22T12:49:32.626Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85206
|
+
2026-02-22T12:49:32.751Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85207
|
+
2026-02-22T12:49:32.926Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85208
|
+
2026-02-22T12:49:33.150Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85209
|
+
2026-02-22T12:49:33.425Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85210
|
+
2026-02-22T12:49:33.749Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85211
|
+
2026-02-22T12:49:34.127Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85212
|
+
2026-02-22T12:49:34.550Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85213
|
+
2026-02-22T12:49:34.770Z [info]: ✅ Database connection established successfully.
|
|
85214
|
+
2026-02-22T12:49:34.956Z [crit]:
|
|
85215
|
+
SIGINT received, shutting down gracefully...
|
|
85216
|
+
2026-02-22T12:49:34.955Z [crit]:
|
|
85217
|
+
SIGINT received, shutting down gracefully...
|
|
85218
|
+
2026-02-22T12:49:34.955Z [info]: Graceful shutdown initiated
|
|
85219
|
+
2026-02-22T12:49:34.955Z [crit]:
|
|
85220
|
+
SIGINT received, shutting down gracefully...
|
|
85221
|
+
2026-02-22T12:49:34.955Z [crit]:
|
|
85222
|
+
SIGINT received, shutting down gracefully...
|
|
85223
|
+
2026-02-22T12:49:34.962Z [crit]:
|
|
85224
|
+
SIGINT received, shutting down gracefully...
|
|
85225
|
+
2026-02-22T12:49:34.962Z [crit]:
|
|
85226
|
+
SIGINT received. Shutting down gracefully...
|
|
85227
|
+
2026-02-22T12:49:35.001Z [info]: ✅ Redis connection established successfully.
|
|
85228
|
+
2026-02-22T12:49:35.004Z [info]: ✅ Message queue initialized.
|
|
85229
|
+
2026-02-22T12:49:35.006Z [info]: ✅ Message worker initialized.
|
|
85230
|
+
2026-02-22T12:49:35.036Z [error]: Message Queue Error: getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
85231
|
+
2026-02-22T12:49:35.054Z [info]: Marketing service Database connection established successfully.
|
|
85232
|
+
2026-02-22T12:49:35.271Z [info]: ✅ Database connection established successfully.
|
|
85233
|
+
2026-02-22T12:49:35.275Z [info]: ✅ Database connection established successfully.
|
|
85234
|
+
2026-02-22T12:49:35.745Z [crit]:
|
|
85235
|
+
SIGINT received, shutting down gracefully...
|
|
85236
|
+
2026-02-22T12:54:14.271Z [info]: 📚 Swagger documentation available at: http://localhost:4005/api-docs
|
|
85237
|
+
2026-02-22T12:54:14.304Z [info]: 📚 Swagger documentation available at: http://localhost:4002/api-docs
|
|
85238
|
+
2026-02-22T12:54:17.110Z [info]: ✅ Database connection established successfully.
|
|
85239
|
+
2026-02-22T12:54:17.308Z [info]: Marketing service Database connection established successfully.
|
|
85240
|
+
2026-02-22T12:54:19.405Z [info]: ✅ Database synchronized successfully.
|
|
85241
|
+
2026-02-22T12:54:19.407Z [info]: ✅ Associations set up successfully.
|
|
85242
|
+
2026-02-22T12:54:19.408Z [info]: User service running on port 4002
|
|
85243
|
+
2026-02-22T12:54:20.241Z [info]: Marketing service Database synchronized successfully.
|
|
85244
|
+
2026-02-22T12:54:20.243Z [info]: 📣 Marketing service running on port 4005
|
|
85245
|
+
2026-02-22T12:54:23.002Z [info]: ::ffff:127.0.0.1 - - [22/Feb/2026:12:54:23 +0000] "GET /health HTTP/1.1" 200 134 "-" "node"
|
|
85246
|
+
2026-02-22T12:54:23.006Z [info]: ::ffff:127.0.0.1 - - [22/Feb/2026:12:54:23 +0000] "GET /health HTTP/1.1" 200 144 "-" "node"
|
|
85247
|
+
2026-02-22T12:54:29.531Z [info]: ::ffff:127.0.0.1 - - [22/Feb/2026:12:54:29 +0000] "GET /health HTTP/1.1" 200 134 "-" "node"
|
|
85248
|
+
2026-02-22T12:54:29.532Z [info]: ::ffff:127.0.0.1 - - [22/Feb/2026:12:54:29 +0000] "GET /health HTTP/1.1" 200 144 "-" "node"
|
|
85249
|
+
2026-02-22T12:54:44.499Z [crit]:
|
|
85250
|
+
SIGINT received, shutting down gracefully...
|
|
85251
|
+
2026-02-22T12:54:44.499Z [crit]:
|
|
85252
|
+
SIGINT received, shutting down gracefully...
|
|
85253
|
+
2026-02-22T12:54:44.500Z [info]: ✅ Database connection closed successfully.
|
|
85254
|
+
2026-02-22T12:54:44.500Z [info]: ✅ Database connection closed successfully.
|
|
85255
|
+
2026-02-22T13:16:43.500Z [info]: 📚 Swagger documentation available at: http://localhost:4005/api-docs
|
|
85256
|
+
2026-02-22T13:16:43.603Z [info]: 📚 Swagger documentation available at: http://localhost:4002/api-docs
|
|
85257
|
+
2026-02-22T13:16:47.090Z [info]: ✅ Database connection established successfully.
|
|
85258
|
+
2026-02-22T13:16:47.090Z [info]: Marketing service Database connection established successfully.
|
|
85259
|
+
2026-02-22T13:16:49.325Z [info]: ✅ Database synchronized successfully.
|
|
85260
|
+
2026-02-22T13:16:49.327Z [info]: ✅ Associations set up successfully.
|
|
85261
|
+
2026-02-22T13:16:49.329Z [info]: User service running on port 4002
|
|
85262
|
+
2026-02-22T13:16:49.957Z [info]: Marketing service Database synchronized successfully.
|
|
85263
|
+
2026-02-22T13:16:49.959Z [info]: 📣 Marketing service running on port 4005
|
|
85264
|
+
2026-02-22T13:18:21.350Z [crit]:
|
|
85265
|
+
SIGINT received, shutting down gracefully...
|
|
85266
|
+
2026-02-22T13:18:21.351Z [crit]:
|
|
85267
|
+
SIGINT received, shutting down gracefully...
|
|
85268
|
+
2026-02-22T13:18:21.352Z [info]: ✅ Database connection closed successfully.
|
|
85269
|
+
2026-02-22T13:18:21.352Z [info]: ✅ Database connection closed successfully.
|
|
85270
|
+
2026-02-22T13:22:30.331Z [info]: 📚 Swagger documentation available at: http://localhost:4005/api-docs
|
|
85271
|
+
2026-02-22T13:22:30.401Z [info]: 📚 Swagger documentation available at: http://localhost:4002/api-docs
|
|
85272
|
+
2026-02-22T13:22:33.716Z [info]: ✅ Database connection established successfully.
|
|
85273
|
+
2026-02-22T13:22:33.716Z [info]: Marketing service Database connection established successfully.
|
|
85274
|
+
2026-02-22T13:22:36.074Z [info]: ✅ Database synchronized successfully.
|
|
85275
|
+
2026-02-22T13:22:36.076Z [info]: ✅ Associations set up successfully.
|
|
85276
|
+
2026-02-22T13:22:36.078Z [info]: User service running on port 4002
|
|
85277
|
+
2026-02-22T13:22:36.580Z [info]: Marketing service Database synchronized successfully.
|
|
85278
|
+
2026-02-22T13:22:36.581Z [info]: 📣 Marketing service running on port 4005
|
|
85279
|
+
2026-02-22T13:23:40.758Z [crit]:
|
|
85280
|
+
SIGINT received, shutting down gracefully...
|
|
85281
|
+
2026-02-22T13:23:40.758Z [crit]:
|
|
85282
|
+
SIGINT received, shutting down gracefully...
|
|
85283
|
+
2026-02-22T13:23:40.759Z [info]: ✅ Database connection closed successfully.
|
|
85284
|
+
2026-02-22T13:23:40.760Z [info]: ✅ Database connection closed successfully.
|
|
85285
|
+
2026-02-22T13:23:43.695Z [info]: 📚 Swagger documentation available at: http://localhost:4005/api-docs
|
|
85286
|
+
2026-02-22T13:23:43.719Z [info]: 📚 Swagger documentation available at: http://localhost:4002/api-docs
|
|
85287
|
+
2026-02-22T13:23:47.066Z [info]: Marketing service Database connection established successfully.
|
|
85288
|
+
2026-02-22T13:23:47.339Z [info]: ✅ Database connection established successfully.
|
|
85289
|
+
2026-02-22T13:23:49.294Z [info]: ✅ Database synchronized successfully.
|
|
85290
|
+
2026-02-22T13:23:49.297Z [info]: ✅ Associations set up successfully.
|
|
85291
|
+
2026-02-22T13:23:49.298Z [info]: User service running on port 4002
|
|
85292
|
+
2026-02-22T13:23:49.533Z [info]: Marketing service Database synchronized successfully.
|
|
85293
|
+
2026-02-22T13:23:49.534Z [info]: 📣 Marketing service running on port 4005
|
|
85294
|
+
2026-02-22T13:26:07.872Z [crit]:
|
|
85295
|
+
SIGINT received, shutting down gracefully...
|
|
85296
|
+
2026-02-22T13:26:07.873Z [crit]:
|
|
85297
|
+
SIGINT received, shutting down gracefully...
|
|
85298
|
+
2026-02-22T13:26:07.873Z [info]: ✅ Database connection closed successfully.
|
|
85299
|
+
2026-02-22T13:26:07.874Z [info]: ✅ Database connection closed successfully.
|
|
85300
|
+
2026-02-22T13:26:10.333Z [info]: 📚 Swagger documentation available at: http://localhost:4005/api-docs
|
|
85301
|
+
2026-02-22T13:26:10.345Z [info]: 📚 Swagger documentation available at: http://localhost:4002/api-docs
|
|
85302
|
+
2026-02-22T13:26:12.444Z [crit]:
|
|
85303
|
+
SIGINT received, shutting down gracefully...
|
|
85304
|
+
2026-02-22T13:26:12.444Z [crit]:
|
|
85305
|
+
SIGINT received, shutting down gracefully...
|
|
85306
|
+
2026-02-22T13:26:13.187Z [crit]:
|
|
85307
|
+
SIGINT received, shutting down gracefully...
|
|
85308
|
+
2026-02-22T13:26:13.188Z [crit]:
|
|
85309
|
+
SIGINT received, shutting down gracefully...
|
|
85310
|
+
2026-02-22T13:26:13.249Z [info]: ✅ Database connection established successfully.
|
|
85311
|
+
2026-02-22T13:26:13.254Z [info]: Marketing service Database connection established successfully.
|
package/logs/error.log
CHANGED
|
@@ -48812,3 +48812,57 @@ SIGINT received, shutting down gracefully...
|
|
|
48812
48812
|
2026-02-22T12:02:49.956Z [crit]: Unable to start server:
|
|
48813
48813
|
2026-02-22T12:02:50.209Z [crit]:
|
|
48814
48814
|
SIGINT received, shutting down gracefully...
|
|
48815
|
+
2026-02-22T12:49:32.521Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48816
|
+
2026-02-22T12:49:32.548Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48817
|
+
2026-02-22T12:49:32.626Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48818
|
+
2026-02-22T12:49:32.751Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48819
|
+
2026-02-22T12:49:32.926Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48820
|
+
2026-02-22T12:49:33.150Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48821
|
+
2026-02-22T12:49:33.425Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48822
|
+
2026-02-22T12:49:33.749Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48823
|
+
2026-02-22T12:49:34.127Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48824
|
+
2026-02-22T12:49:34.550Z [error]: Redis Client Error getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48825
|
+
2026-02-22T12:49:34.955Z [crit]:
|
|
48826
|
+
SIGINT received, shutting down gracefully...
|
|
48827
|
+
2026-02-22T12:49:34.955Z [crit]:
|
|
48828
|
+
SIGINT received, shutting down gracefully...
|
|
48829
|
+
2026-02-22T12:49:34.955Z [crit]:
|
|
48830
|
+
SIGINT received, shutting down gracefully...
|
|
48831
|
+
2026-02-22T12:49:34.955Z [crit]:
|
|
48832
|
+
SIGINT received, shutting down gracefully...
|
|
48833
|
+
2026-02-22T12:49:34.959Z [crit]:
|
|
48834
|
+
SIGINT received, shutting down gracefully...
|
|
48835
|
+
2026-02-22T12:49:34.961Z [crit]:
|
|
48836
|
+
SIGINT received. Shutting down gracefully...
|
|
48837
|
+
2026-02-22T12:49:35.036Z [error]: Message Queue Error: getaddrinfo ENOTFOUND redis {"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"redis","stack":"Error: getaddrinfo ENOTFOUND redis\n at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)"}
|
|
48838
|
+
2026-02-22T12:49:35.056Z [crit]: Unable to start server:
|
|
48839
|
+
2026-02-22T12:49:35.274Z [crit]: Unable to start server:
|
|
48840
|
+
2026-02-22T12:49:35.277Z [crit]: Unable to start server:
|
|
48841
|
+
2026-02-22T12:49:35.745Z [crit]:
|
|
48842
|
+
SIGINT received, shutting down gracefully...
|
|
48843
|
+
2026-02-22T12:54:44.499Z [crit]:
|
|
48844
|
+
SIGINT received, shutting down gracefully...
|
|
48845
|
+
2026-02-22T12:54:44.499Z [crit]:
|
|
48846
|
+
SIGINT received, shutting down gracefully...
|
|
48847
|
+
2026-02-22T13:18:21.350Z [crit]:
|
|
48848
|
+
SIGINT received, shutting down gracefully...
|
|
48849
|
+
2026-02-22T13:18:21.351Z [crit]:
|
|
48850
|
+
SIGINT received, shutting down gracefully...
|
|
48851
|
+
2026-02-22T13:23:40.758Z [crit]:
|
|
48852
|
+
SIGINT received, shutting down gracefully...
|
|
48853
|
+
2026-02-22T13:23:40.758Z [crit]:
|
|
48854
|
+
SIGINT received, shutting down gracefully...
|
|
48855
|
+
2026-02-22T13:26:07.872Z [crit]:
|
|
48856
|
+
SIGINT received, shutting down gracefully...
|
|
48857
|
+
2026-02-22T13:26:07.873Z [crit]:
|
|
48858
|
+
SIGINT received, shutting down gracefully...
|
|
48859
|
+
2026-02-22T13:26:12.444Z [crit]:
|
|
48860
|
+
SIGINT received, shutting down gracefully...
|
|
48861
|
+
2026-02-22T13:26:12.444Z [crit]:
|
|
48862
|
+
SIGINT received, shutting down gracefully...
|
|
48863
|
+
2026-02-22T13:26:13.187Z [crit]:
|
|
48864
|
+
SIGINT received, shutting down gracefully...
|
|
48865
|
+
2026-02-22T13:26:13.187Z [crit]:
|
|
48866
|
+
SIGINT received, shutting down gracefully...
|
|
48867
|
+
2026-02-22T13:26:13.251Z [crit]: Unable to start server:
|
|
48868
|
+
2026-02-22T13:26:13.256Z [crit]: Unable to start server:
|
package/middleware/auth.ts
CHANGED
|
@@ -6,49 +6,45 @@ import { getRedisClient } from "../config";
|
|
|
6
6
|
|
|
7
7
|
import { JWTPayload } from "../types";
|
|
8
8
|
|
|
9
|
-
const JWT_SECRET =
|
|
10
|
-
process.env.JWT_SECRET || "your-super-secret-jwt-key-change-in-production";
|
|
11
9
|
const TOKEN_VERSION_PREFIX = "auth:token-version:";
|
|
12
10
|
|
|
13
|
-
export const authenticateToken =
|
|
14
|
-
req: Request,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
): Promise<void> => {
|
|
18
|
-
const authHeader = req.headers["authorization"];
|
|
19
|
-
const token = authHeader && authHeader.split(" ")[1]; // Bearer TOKEN
|
|
11
|
+
export const authenticateToken = (JWT_SECRET: string) => {
|
|
12
|
+
return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
|
13
|
+
const authHeader = req.headers["authorization"];
|
|
14
|
+
const token = authHeader && authHeader.split(" ")[1]; // Bearer TOKEN
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
if (!token) {
|
|
17
|
+
res.status(401).json({
|
|
18
|
+
success: false,
|
|
19
|
+
message: "Access token required",
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
try {
|
|
25
|
+
const decoded = jwt.verify(token, JWT_SECRET, {
|
|
26
|
+
issuer: "ggcoach-auth-service",
|
|
27
|
+
audience: "ggcoach-app",
|
|
28
|
+
}) as JWTPayload;
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
const isValid = await validateTokenWithRedis(decoded);
|
|
31
|
+
if (!isValid) {
|
|
32
|
+
res.status(403).json({
|
|
33
|
+
success: false,
|
|
34
|
+
message: "Invalid or expired token",
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
req.user = decoded;
|
|
40
|
+
next();
|
|
41
|
+
} catch (error) {
|
|
37
42
|
res.status(403).json({
|
|
38
43
|
success: false,
|
|
39
44
|
message: "Invalid or expired token",
|
|
40
45
|
});
|
|
41
|
-
return;
|
|
42
46
|
}
|
|
43
|
-
|
|
44
|
-
req.user = decoded;
|
|
45
|
-
next();
|
|
46
|
-
} catch (error) {
|
|
47
|
-
res.status(403).json({
|
|
48
|
-
success: false,
|
|
49
|
-
message: "Invalid or expired token",
|
|
50
|
-
});
|
|
51
|
-
}
|
|
47
|
+
};
|
|
52
48
|
};
|
|
53
49
|
|
|
54
50
|
const validateTokenWithRedis = async (decoded: JWTPayload): Promise<boolean> => {
|
|
@@ -71,30 +67,28 @@ const validateTokenWithRedis = async (decoded: JWTPayload): Promise<boolean> =>
|
|
|
71
67
|
}
|
|
72
68
|
};
|
|
73
69
|
|
|
74
|
-
export const optionalAuth =
|
|
75
|
-
req: Request,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
): Promise<void> => {
|
|
79
|
-
const authHeader = req.headers["authorization"];
|
|
80
|
-
const token = authHeader && authHeader.split(" ")[1];
|
|
70
|
+
export const optionalAuth = (JWT_SECRET: string) => {
|
|
71
|
+
return async (req: Request, _res: Response, next: NextFunction): Promise<void> => {
|
|
72
|
+
const authHeader = req.headers["authorization"];
|
|
73
|
+
const token = authHeader && authHeader.split(" ")[1];
|
|
81
74
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
75
|
+
if (token) {
|
|
76
|
+
try {
|
|
77
|
+
const decoded = jwt.verify(token, JWT_SECRET, {
|
|
78
|
+
issuer: "ggcoach-auth-service",
|
|
79
|
+
audience: "ggcoach-app",
|
|
80
|
+
}) as JWTPayload;
|
|
81
|
+
const isValid = await validateTokenWithRedis(decoded);
|
|
82
|
+
if (isValid) {
|
|
83
|
+
req.user = decoded;
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
// Token is invalid, but we continue without user info
|
|
87
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
88
|
+
logger.warn(`Invalid token in optional auth: ${err.message}`);
|
|
91
89
|
}
|
|
92
|
-
} catch (error) {
|
|
93
|
-
// Token is invalid, but we continue without user info
|
|
94
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
95
|
-
logger.warn(`Invalid token in optional auth: ${err.message}`);
|
|
96
90
|
}
|
|
97
|
-
}
|
|
98
91
|
|
|
99
|
-
|
|
92
|
+
next();
|
|
93
|
+
};
|
|
100
94
|
};
|
package/middleware/cors.ts
CHANGED
|
@@ -1,48 +1,54 @@
|
|
|
1
1
|
import cors from "cors";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"http://localhost:3000",
|
|
17
|
-
"http://localhost:3001",
|
|
18
|
-
"https://gg.staging.brainexy.com",
|
|
19
|
-
"https://gg.register.brainexy.com",
|
|
20
|
-
];
|
|
21
|
-
const envOrigins = process.env.ALLOWED_ORIGINS?.split(",").map(o => o.trim()) || [];
|
|
22
|
-
const allowedOrigins = Array.from(
|
|
23
|
-
new Set([...defaultOrigins, ...envOrigins].map(o => o.toLowerCase()))
|
|
24
|
-
);
|
|
3
|
+
const DEFAULT_ORIGINS = [
|
|
4
|
+
"http://localhost:4000",
|
|
5
|
+
"http://localhost:4001",
|
|
6
|
+
"http://localhost:4002",
|
|
7
|
+
"http://localhost:4003",
|
|
8
|
+
"http://localhost:4004",
|
|
9
|
+
"http://localhost:4005",
|
|
10
|
+
"http://localhost:8080",
|
|
11
|
+
"http://localhost:3000",
|
|
12
|
+
"http://localhost:3001",
|
|
13
|
+
"https://gg.staging.brainexy.com",
|
|
14
|
+
"https://gg.register.brainexy.com",
|
|
15
|
+
];
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
export const createCorsOptions = (allowedOrigins?: string[]) => {
|
|
18
|
+
const origins = allowedOrigins || DEFAULT_ORIGINS;
|
|
19
|
+
const finalAllowedOrigins = Array.from(
|
|
20
|
+
new Set([...origins ].map(o => o.toLowerCase()))
|
|
21
|
+
);
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
return {
|
|
24
|
+
origin: (
|
|
25
|
+
origin: string | undefined,
|
|
26
|
+
callback: (err: Error | null, allow?: boolean) => void
|
|
27
|
+
) => {
|
|
28
|
+
// Allow no-origin requests (Postman, mobile apps)
|
|
29
|
+
if (!origin) return callback(null, true);
|
|
30
|
+
if (finalAllowedOrigins.includes(origin.toLowerCase())) {
|
|
31
|
+
return callback(null, true);
|
|
32
|
+
}
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
return callback(new Error("Not allowed by CORS"));
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
credentials: true,
|
|
38
|
+
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
|
39
|
+
allowedHeaders: [
|
|
40
|
+
"Content-Type",
|
|
41
|
+
"Authorization",
|
|
42
|
+
"X-Requested-With",
|
|
43
|
+
"X-Request-ID",
|
|
44
|
+
],
|
|
45
|
+
exposedHeaders: ["X-Request-ID"], // optional but useful
|
|
46
|
+
preflightContinue: false,
|
|
47
|
+
optionsSuccessStatus: 200,
|
|
48
|
+
};
|
|
46
49
|
};
|
|
47
50
|
|
|
51
|
+
// Default cors options using DEFAULT_ORIGINS
|
|
52
|
+
export const corsOptions = createCorsOptions();
|
|
53
|
+
|
|
48
54
|
export const corsMiddleware = cors(corsOptions);
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import { Request, Response, NextFunction } from 'express';
|
|
2
2
|
|
|
3
|
-
export const requireInternalToken = (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
export const requireInternalToken = (ALLOW_DIRECT_ACCESS: boolean, INTERNAL_SERVICE_TOKEN: string) => {
|
|
4
|
+
return (req: Request, res: Response, next: NextFunction): void => {
|
|
5
|
+
if (ALLOW_DIRECT_ACCESS) {
|
|
6
|
+
next();
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const token = INTERNAL_SERVICE_TOKEN;
|
|
11
|
+
if (!token) {
|
|
12
|
+
// If token isn't set, reject to be safe
|
|
13
|
+
res.status(403).json({ success: false, message: 'Internal access token not configured' });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const incoming = (req.headers['x-internal-token'] as string) || '';
|
|
18
|
+
if (incoming !== token) {
|
|
19
|
+
res.status(403).json({ success: false, message: 'Forbidden' });
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
next();
|
|
24
|
+
};
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
export default requireInternalToken;
|
package/middleware/swagger.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
2
|
import swaggerUi from 'swagger-ui-express';
|
|
3
|
-
import { swaggerUiOptions } from '../config
|
|
3
|
+
import { swaggerUiOptions } from '../config';
|
|
4
4
|
import { logger } from '../utils';
|
|
5
5
|
|
|
6
6
|
type OpenApiSpec = Record<string, unknown>;
|
|
@@ -30,7 +30,7 @@ const resolveSpec = async (options: SwaggerSetupOptions): Promise<OpenApiSpec> =
|
|
|
30
30
|
return {};
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
export const setupSwagger = (app: Express, options: SwaggerSetupOptions = {}) => {
|
|
33
|
+
export const setupSwagger = (PORT: number, app: Express, options: SwaggerSetupOptions = {}) => {
|
|
34
34
|
const basePath = options.basePath ?? '/api-docs';
|
|
35
35
|
|
|
36
36
|
app.get(`${basePath}/swagger.json`, async (_req, res) => {
|
|
@@ -64,6 +64,6 @@ export const setupSwagger = (app: Express, options: SwaggerSetupOptions = {}) =>
|
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
logger.info(
|
|
67
|
-
`📚 Swagger documentation available at: http://localhost:${
|
|
67
|
+
`📚 Swagger documentation available at: http://localhost:${PORT}${basePath}`
|
|
68
68
|
);
|
|
69
69
|
};
|
package/package.json
CHANGED
package/utils/jwt.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import jwt from 'jsonwebtoken';
|
|
2
|
-
import { JWTPayload, UserAttributes } from '../types
|
|
2
|
+
import { JWTPayload, UserAttributes } from '../types';
|
|
3
3
|
|
|
4
|
-
const JWT_SECRET = process.env.JWT_SECRET || 'your-super-secret-jwt-key-change-in-production';
|
|
5
|
-
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d';
|
|
6
4
|
|
|
7
|
-
export const generateToken = (user: UserAttributes): string => {
|
|
5
|
+
export const generateToken = (JWT_SECRET: string, JWT_EXPIRES_IN: string, user: UserAttributes): string => {
|
|
8
6
|
const payload: JWTPayload = {
|
|
9
7
|
id: user.id,
|
|
10
8
|
email: user.email,
|
|
@@ -28,7 +26,7 @@ export const generateToken = (user: UserAttributes): string => {
|
|
|
28
26
|
return jwt.sign(payload, JWT_SECRET, options);
|
|
29
27
|
};
|
|
30
28
|
|
|
31
|
-
export const verifyToken = (token: string): JWTPayload => {
|
|
29
|
+
export const verifyToken = (JWT_SECRET: string, token: string): JWTPayload => {
|
|
32
30
|
try {
|
|
33
31
|
const decoded = jwt.verify(token, JWT_SECRET, {
|
|
34
32
|
issuer: 'ggcoach-auth-service',
|
|
@@ -41,7 +39,7 @@ export const verifyToken = (token: string): JWTPayload => {
|
|
|
41
39
|
}
|
|
42
40
|
};
|
|
43
41
|
|
|
44
|
-
export const generateRefreshToken = (user: UserAttributes): string => {
|
|
42
|
+
export const generateRefreshToken = (JWT_SECRET: string, JWT_EXPIRES_IN: string, user: UserAttributes): string => {
|
|
45
43
|
const payload: JWTPayload = {
|
|
46
44
|
id: user.id,
|
|
47
45
|
email: user.email,
|
|
@@ -57,7 +55,7 @@ export const generateRefreshToken = (user: UserAttributes): string => {
|
|
|
57
55
|
};
|
|
58
56
|
|
|
59
57
|
const options: jwt.SignOptions = {
|
|
60
|
-
expiresIn:
|
|
58
|
+
expiresIn: JWT_EXPIRES_IN,
|
|
61
59
|
issuer: 'ggcoach-auth-service',
|
|
62
60
|
audience: 'ggcoach-app'
|
|
63
61
|
} as jwt.SignOptions;
|