fiberx-backend-toolkit 0.0.39 → 0.0.41

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.
@@ -9,6 +9,11 @@ export declare const SEEDERS_DIR: string;
9
9
  export declare const SEQUELIZE_META_TABLE_NAME = "sequelize_database_tables_meta";
10
10
  export declare const SEQUELIZE_SEEDER_META_TABLE_NAME = "sequelize_database_table_seeder_meta";
11
11
  export declare const REQUEST_ID_COOKIE_MAX_AGE: number;
12
+ export declare const REQUEST_ID_COOKIE_NAME = "request_id";
13
+ export declare const REQUEST_ID_HEADERS_NAME = "X-Request-Id";
14
+ export declare const DEVICE_ID_COOKIE_MAX_AGE: number;
15
+ export declare const DEVICE_ID_COOKIE_NAME = "device_id";
16
+ export declare const DEVICE_ID_HEADERS_NAME = "X-Device-Id";
12
17
  export declare const CORS_ALLOWED_METHODS: string[];
13
18
  export declare const CORS_ALLOWED_HEADERS: string[];
14
19
  export declare const CORS_MAX_AGE_IN_SECONDS = 600;
@@ -3,7 +3,7 @@ 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.ALPHABET_CORPUS = exports.REQUEST_RATE_LIMITTER_OPTIONS = exports.CORS_MAX_AGE_IN_MICRO_SECONDS = exports.CORS_MAX_AGE_IN_SECONDS = exports.CORS_ALLOWED_HEADERS = exports.CORS_ALLOWED_METHODS = exports.REQUEST_ID_COOKIE_MAX_AGE = exports.SEQUELIZE_SEEDER_META_TABLE_NAME = exports.SEQUELIZE_META_TABLE_NAME = exports.SEEDERS_DIR = exports.MIGRATIONS_DIR = exports.MODELS_DIR = exports.SCHEMA_SNAPSHOTS_DIR = exports.SCHEMAS_DIR = exports.ENV_VAR_DIR = exports.LOG_DIR = exports.BASE_DIR = void 0;
6
+ exports.ALPHABET_CORPUS = exports.REQUEST_RATE_LIMITTER_OPTIONS = exports.CORS_MAX_AGE_IN_MICRO_SECONDS = exports.CORS_MAX_AGE_IN_SECONDS = exports.CORS_ALLOWED_HEADERS = exports.CORS_ALLOWED_METHODS = exports.DEVICE_ID_HEADERS_NAME = exports.DEVICE_ID_COOKIE_NAME = exports.DEVICE_ID_COOKIE_MAX_AGE = exports.REQUEST_ID_HEADERS_NAME = exports.REQUEST_ID_COOKIE_NAME = exports.REQUEST_ID_COOKIE_MAX_AGE = exports.SEQUELIZE_SEEDER_META_TABLE_NAME = exports.SEQUELIZE_META_TABLE_NAME = exports.SEEDERS_DIR = exports.MIGRATIONS_DIR = exports.MODELS_DIR = exports.SCHEMA_SNAPSHOTS_DIR = exports.SCHEMAS_DIR = exports.ENV_VAR_DIR = exports.LOG_DIR = exports.BASE_DIR = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  // Database constants
9
9
  exports.BASE_DIR = process.cwd();
@@ -16,10 +16,15 @@ exports.MIGRATIONS_DIR = path_1.default.join(exports.BASE_DIR, "src/database/mig
16
16
  exports.SEEDERS_DIR = path_1.default.join(exports.BASE_DIR, "src/database/seeders");
17
17
  exports.SEQUELIZE_META_TABLE_NAME = "sequelize_database_tables_meta";
18
18
  exports.SEQUELIZE_SEEDER_META_TABLE_NAME = "sequelize_database_table_seeder_meta";
19
- exports.REQUEST_ID_COOKIE_MAX_AGE = (1000 * 60 * 60 * 24 * 7); // 7 days
19
+ exports.REQUEST_ID_COOKIE_MAX_AGE = (1000 * 60 * 60 * 24 * 30); // 7 days
20
+ exports.REQUEST_ID_COOKIE_NAME = "request_id";
21
+ exports.REQUEST_ID_HEADERS_NAME = "X-Request-Id";
22
+ exports.DEVICE_ID_COOKIE_MAX_AGE = (1000 * 60 * 60 * 24 * 180); // 180 days
23
+ exports.DEVICE_ID_COOKIE_NAME = "device_id";
24
+ exports.DEVICE_ID_HEADERS_NAME = "X-Device-Id";
20
25
  // CORS constants
21
26
  exports.CORS_ALLOWED_METHODS = ["GET", "POST", "PATCH", "DELETE", "OPTIONS"];
22
- exports.CORS_ALLOWED_HEADERS = ["Content-Type", "Authorization", "X-Device-Id", "X-Device-Name", "User-Agent"];
27
+ exports.CORS_ALLOWED_HEADERS = ["Content-Type", "Authorization", exports.REQUEST_ID_HEADERS_NAME, exports.DEVICE_ID_HEADERS_NAME, "X-Device-Name", "User-Agent"];
23
28
  exports.CORS_MAX_AGE_IN_SECONDS = (600); // default: 10 min
24
29
  exports.CORS_MAX_AGE_IN_MICRO_SECONDS = (1000 * 60 * 10); // 10 minutes
25
30
  // Rate limitter
@@ -5,9 +5,17 @@ declare class CookieManagerMiddleWare {
5
5
  private logger;
6
6
  private readonly default_cookie_options;
7
7
  private request_id_max_age;
8
+ private request_id_cookie_name;
9
+ private request_id_header_name;
8
10
  private request_id_generator;
11
+ private device_id_max_age;
12
+ private device_id_cookie_name;
13
+ private device_id_header_name;
14
+ private device_id_generator;
9
15
  constructor(options?: CookieManagerOptions);
10
16
  private getDefaultCookieOptions;
17
+ private handleRequestId;
18
+ private handleDeviceId;
11
19
  /** Get cookie value safely */
12
20
  get(req: Request, name: string): string | undefined;
13
21
  /** Set cookie with enforced defaults */
@@ -20,10 +20,23 @@ class CookieManagerMiddleWare {
20
20
  logger = new main_1.LoggerUtil(this.name);
21
21
  default_cookie_options = this.getDefaultCookieOptions();
22
22
  request_id_max_age;
23
+ request_id_cookie_name;
24
+ request_id_header_name;
23
25
  request_id_generator;
26
+ device_id_max_age;
27
+ device_id_cookie_name;
28
+ device_id_header_name;
29
+ device_id_generator;
24
30
  constructor(options = {}) {
25
31
  this.request_id_max_age = options?.request_id_max_age || constants_1.REQUEST_ID_COOKIE_MAX_AGE;
32
+ this.request_id_cookie_name = options.request_id_cookie_name || constants_1.REQUEST_ID_COOKIE_NAME;
33
+ this.request_id_header_name = options.request_id_header_name || constants_1.REQUEST_ID_HEADERS_NAME;
26
34
  this.request_id_generator = options?.request_id_generator || crypto_1.default.randomUUID;
35
+ // device id
36
+ this.device_id_max_age = options.device_id_max_age || constants_1.DEVICE_ID_COOKIE_MAX_AGE;
37
+ this.device_id_cookie_name = options.device_id_cookie_name || constants_1.DEVICE_ID_COOKIE_NAME;
38
+ this.device_id_header_name = options.device_id_header_name || constants_1.DEVICE_ID_HEADERS_NAME;
39
+ this.device_id_generator = options.device_id_generator || crypto_1.default.randomUUID;
27
40
  main_1.SafeExecuteUtil.setNamedInstance(this.name, this);
28
41
  }
29
42
  // Method to get default cookie options
@@ -35,6 +48,34 @@ class CookieManagerMiddleWare {
35
48
  secure: main_1.InputValidatorUtil.isProduction(),
36
49
  };
37
50
  }
51
+ // Method to Ensure request_id exists + rolling expiration
52
+ handleRequestId(req, res) {
53
+ let request_id = this.get(req, "request_id");
54
+ if (!request_id) {
55
+ request_id = this.request_id_generator();
56
+ this.logger.info(`Generated request_id: ${request_id}`);
57
+ }
58
+ // ALWAYS refresh TTL (rolling expiration)
59
+ this.set(res, "request_id", request_id, {
60
+ max_age: this.request_id_max_age,
61
+ });
62
+ res.setHeader("X-Request-Id", request_id);
63
+ return request_id;
64
+ }
65
+ // Method to Ensure device_id exists (long-lived)
66
+ handleDeviceId(req, res) {
67
+ let device_id = this.get(req, this.device_id_cookie_name);
68
+ if (!device_id) {
69
+ device_id = this.device_id_generator();
70
+ this.logger.info(`Generated device_id: ${device_id}`);
71
+ }
72
+ // persist long term
73
+ this.set(res, this.device_id_cookie_name, device_id, {
74
+ max_age: this.device_id_max_age,
75
+ });
76
+ res.setHeader(this.device_id_header_name, device_id);
77
+ return device_id;
78
+ }
38
79
  /** Get cookie value safely */
39
80
  get(req, name) {
40
81
  return req.cookies?.[name];
@@ -54,16 +95,11 @@ class CookieManagerMiddleWare {
54
95
  req.getCookie = (name) => this.get(req, name);
55
96
  req.setCookie = (name, value, options = {}) => this.set(res, name, value, options);
56
97
  req.clearCookie = (name) => this.clear(res, name);
57
- // Request ID handling
58
- let request_id = req.getCookie("request_id");
59
- if (!request_id) {
60
- request_id = this.request_id_generator();
61
- this.set(res, "request_id", request_id, { max_age: this.request_id_max_age });
62
- res.setHeader("X-Request-Id", request_id);
63
- this.logger.info(`Generated request_id: ${request_id}`);
64
- }
65
- this.logger.info(`[REQ:${request_id}] ${req.method} ${req.originalUrl}`);
98
+ const request_id = this.handleRequestId(req, res);
99
+ const device_id = this.handleDeviceId(req, res);
66
100
  req.request_id = request_id;
101
+ req.device_id = device_id;
102
+ this.logger.info(`[REQ:${request_id}] [DEV:${device_id}] ${req.method} ${req.originalUrl}`);
67
103
  return next();
68
104
  }
69
105
  }
@@ -13,6 +13,7 @@ declare module "express-serve-static-core" {
13
13
  }) => void;
14
14
  clearCookie: (name: string) => void;
15
15
  request_id?: string;
16
+ device_id?: string;
16
17
  clientIp?: string;
17
18
  }
18
19
  }
@@ -20,7 +20,13 @@ export type RateLimitRecord = {
20
20
  };
21
21
  export interface CookieManagerOptions {
22
22
  request_id_max_age?: number;
23
+ request_id_cookie_name?: string;
24
+ request_id_header_name?: string;
23
25
  request_id_generator?: () => string;
26
+ device_id_max_age?: number;
27
+ device_id_cookie_name?: string;
28
+ device_id_header_name?: string;
29
+ device_id_generator?: () => string;
24
30
  }
25
31
  export interface ForceHTTPSOptions {
26
32
  enabled?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fiberx-backend-toolkit",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "A TypeScript backend toolkit providing shared domain logic, infrastructure helpers, and utilities for FiberX server-side applications and services.",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",