@heavybit/pendoadmin-shared-lib 1.0.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.
Files changed (132) hide show
  1. package/dist/common/index.d.ts +6 -0
  2. package/dist/common/index.d.ts.map +1 -0
  3. package/dist/common/index.js +6 -0
  4. package/dist/common/index.js.map +1 -0
  5. package/dist/common/jwt.utils.d.ts +7 -0
  6. package/dist/common/jwt.utils.d.ts.map +1 -0
  7. package/dist/common/jwt.utils.js +31 -0
  8. package/dist/common/jwt.utils.js.map +1 -0
  9. package/dist/common/password.utils.d.ts +4 -0
  10. package/dist/common/password.utils.d.ts.map +1 -0
  11. package/dist/common/password.utils.js +17 -0
  12. package/dist/common/password.utils.js.map +1 -0
  13. package/dist/common/phone.utils.d.ts +4 -0
  14. package/dist/common/phone.utils.d.ts.map +1 -0
  15. package/dist/common/phone.utils.js +36 -0
  16. package/dist/common/phone.utils.js.map +1 -0
  17. package/dist/common/response.utils.d.ts +6 -0
  18. package/dist/common/response.utils.d.ts.map +1 -0
  19. package/dist/common/response.utils.js +33 -0
  20. package/dist/common/response.utils.js.map +1 -0
  21. package/dist/common/uuid.utils.d.ts +5 -0
  22. package/dist/common/uuid.utils.d.ts.map +1 -0
  23. package/dist/common/uuid.utils.js +10 -0
  24. package/dist/common/uuid.utils.js.map +1 -0
  25. package/dist/config/index.d.ts +95 -0
  26. package/dist/config/index.d.ts.map +1 -0
  27. package/dist/config/index.js +71 -0
  28. package/dist/config/index.js.map +1 -0
  29. package/dist/database/index.d.ts +25 -0
  30. package/dist/database/index.d.ts.map +1 -0
  31. package/dist/database/index.js +62 -0
  32. package/dist/database/index.js.map +1 -0
  33. package/dist/express/auth.middleware.d.ts +20 -0
  34. package/dist/express/auth.middleware.d.ts.map +1 -0
  35. package/dist/express/auth.middleware.js +83 -0
  36. package/dist/express/auth.middleware.js.map +1 -0
  37. package/dist/express/correlation.middleware.d.ts +6 -0
  38. package/dist/express/correlation.middleware.d.ts.map +1 -0
  39. package/dist/express/correlation.middleware.js +15 -0
  40. package/dist/express/correlation.middleware.js.map +1 -0
  41. package/dist/express/error-handler.d.ts +8 -0
  42. package/dist/express/error-handler.d.ts.map +1 -0
  43. package/dist/express/error-handler.js +18 -0
  44. package/dist/express/error-handler.js.map +1 -0
  45. package/dist/express/index.d.ts +6 -0
  46. package/dist/express/index.d.ts.map +1 -0
  47. package/dist/express/index.js +6 -0
  48. package/dist/express/index.js.map +1 -0
  49. package/dist/express/permission.guard.d.ts +14 -0
  50. package/dist/express/permission.guard.d.ts.map +1 -0
  51. package/dist/express/permission.guard.js +66 -0
  52. package/dist/express/permission.guard.js.map +1 -0
  53. package/dist/express/validation.middleware.d.ts +14 -0
  54. package/dist/express/validation.middleware.d.ts.map +1 -0
  55. package/dist/express/validation.middleware.js +80 -0
  56. package/dist/express/validation.middleware.js.map +1 -0
  57. package/dist/index.d.ts +9 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +17 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/logging/index.d.ts +4 -0
  62. package/dist/logging/index.d.ts.map +1 -0
  63. package/dist/logging/index.js +24 -0
  64. package/dist/logging/index.js.map +1 -0
  65. package/dist/messaging/index.d.ts +58 -0
  66. package/dist/messaging/index.d.ts.map +1 -0
  67. package/dist/messaging/index.js +132 -0
  68. package/dist/messaging/index.js.map +1 -0
  69. package/dist/nestjs/auth.guard.d.ts +12 -0
  70. package/dist/nestjs/auth.guard.d.ts.map +1 -0
  71. package/dist/nestjs/auth.guard.js +75 -0
  72. package/dist/nestjs/auth.guard.js.map +1 -0
  73. package/dist/nestjs/correlation.interceptor.d.ts +9 -0
  74. package/dist/nestjs/correlation.interceptor.d.ts.map +1 -0
  75. package/dist/nestjs/correlation.interceptor.js +29 -0
  76. package/dist/nestjs/correlation.interceptor.js.map +1 -0
  77. package/dist/nestjs/exception.filter.d.ts +8 -0
  78. package/dist/nestjs/exception.filter.d.ts.map +1 -0
  79. package/dist/nestjs/exception.filter.js +54 -0
  80. package/dist/nestjs/exception.filter.js.map +1 -0
  81. package/dist/nestjs/index.d.ts +7 -0
  82. package/dist/nestjs/index.d.ts.map +1 -0
  83. package/dist/nestjs/index.js +7 -0
  84. package/dist/nestjs/index.js.map +1 -0
  85. package/dist/nestjs/permission.decorator.d.ts +22 -0
  86. package/dist/nestjs/permission.decorator.d.ts.map +1 -0
  87. package/dist/nestjs/permission.decorator.js +30 -0
  88. package/dist/nestjs/permission.decorator.js.map +1 -0
  89. package/dist/nestjs/permission.guard.d.ts +12 -0
  90. package/dist/nestjs/permission.guard.d.ts.map +1 -0
  91. package/dist/nestjs/permission.guard.js +66 -0
  92. package/dist/nestjs/permission.guard.js.map +1 -0
  93. package/dist/nestjs/user.decorator.d.ts +12 -0
  94. package/dist/nestjs/user.decorator.d.ts.map +1 -0
  95. package/dist/nestjs/user.decorator.js +16 -0
  96. package/dist/nestjs/user.decorator.js.map +1 -0
  97. package/dist/types/index.d.ts +193 -0
  98. package/dist/types/index.d.ts.map +1 -0
  99. package/dist/types/index.js +17 -0
  100. package/dist/types/index.js.map +1 -0
  101. package/dist/validation/index.d.ts +32 -0
  102. package/dist/validation/index.d.ts.map +1 -0
  103. package/dist/validation/index.js +21 -0
  104. package/dist/validation/index.js.map +1 -0
  105. package/package.json +100 -0
  106. package/src/common/index.ts +5 -0
  107. package/src/common/jwt.utils.ts +43 -0
  108. package/src/common/password.utils.ts +20 -0
  109. package/src/common/phone.utils.ts +36 -0
  110. package/src/common/response.utils.ts +48 -0
  111. package/src/common/uuid.utils.ts +11 -0
  112. package/src/config/index.ts +73 -0
  113. package/src/database/index.ts +77 -0
  114. package/src/express/auth.middleware.ts +93 -0
  115. package/src/express/correlation.middleware.ts +16 -0
  116. package/src/express/error-handler.ts +28 -0
  117. package/src/express/index.ts +5 -0
  118. package/src/express/permission.guard.ts +72 -0
  119. package/src/express/validation.middleware.ts +76 -0
  120. package/src/index.ts +23 -0
  121. package/src/logging/index.ts +31 -0
  122. package/src/messaging/index.ts +161 -0
  123. package/src/nestjs/auth.guard.ts +69 -0
  124. package/src/nestjs/correlation.interceptor.ts +30 -0
  125. package/src/nestjs/exception.filter.ts +53 -0
  126. package/src/nestjs/index.ts +11 -0
  127. package/src/nestjs/permission.decorator.ts +36 -0
  128. package/src/nestjs/permission.guard.ts +76 -0
  129. package/src/nestjs/user.decorator.ts +19 -0
  130. package/src/types/index.ts +239 -0
  131. package/src/validation/index.ts +26 -0
  132. package/tsconfig.json +22 -0
@@ -0,0 +1,6 @@
1
+ export * from './jwt.utils.js';
2
+ export * from './phone.utils.js';
3
+ export * from './password.utils.js';
4
+ export * from './uuid.utils.js';
5
+ export * from './response.utils.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './jwt.utils.js';
2
+ export * from './phone.utils.js';
3
+ export * from './password.utils.js';
4
+ export * from './uuid.utils.js';
5
+ export * from './response.utils.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { IJwtPayload } from '../types/index.js';
2
+ export declare function signAccessToken(payload: Omit<IJwtPayload, 'iat' | 'exp' | 'iss'>, secret: string, expiresIn?: string): string;
3
+ export declare function signRefreshToken(userId: string, secret: string, expiresIn?: string): string;
4
+ export declare function verifyToken(token: string, secret: string): IJwtPayload;
5
+ export declare function decodeToken(token: string): IJwtPayload | null;
6
+ export declare function extractBearerToken(authHeader?: string): string | null;
7
+ //# sourceMappingURL=jwt.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.utils.d.ts","sourceRoot":"","sources":["../../src/common/jwt.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,EACjD,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAAa,GACvB,MAAM,CAKR;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAAa,GACvB,MAAM,CAKR;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAEtE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAM7D;AAED,wBAAgB,kBAAkB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrE"}
@@ -0,0 +1,31 @@
1
+ import jwt from 'jsonwebtoken';
2
+ const JWT_ISSUER = 'pendoadmin-auth';
3
+ export function signAccessToken(payload, secret, expiresIn = '1h') {
4
+ return jwt.sign(payload, secret, {
5
+ expiresIn: expiresIn,
6
+ issuer: JWT_ISSUER,
7
+ });
8
+ }
9
+ export function signRefreshToken(userId, secret, expiresIn = '7d') {
10
+ return jwt.sign({ sub: userId, type: 'refresh' }, secret, {
11
+ expiresIn: expiresIn,
12
+ issuer: JWT_ISSUER,
13
+ });
14
+ }
15
+ export function verifyToken(token, secret) {
16
+ return jwt.verify(token, secret, { issuer: JWT_ISSUER });
17
+ }
18
+ export function decodeToken(token) {
19
+ try {
20
+ return jwt.decode(token);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ export function extractBearerToken(authHeader) {
27
+ if (!authHeader?.startsWith('Bearer '))
28
+ return null;
29
+ return authHeader.slice(7);
30
+ }
31
+ //# sourceMappingURL=jwt.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.utils.js","sourceRoot":"","sources":["../../src/common/jwt.utils.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAG/B,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAErC,MAAM,UAAU,eAAe,CAC7B,OAAiD,EACjD,MAAc,EACd,YAAoB,IAAI;IAExB,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;QAC/B,SAAS,EAAE,SAAoD;QAC/D,MAAM,EAAE,UAAU;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,MAAc,EACd,YAAoB,IAAI;IAExB,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE;QACxD,SAAS,EAAE,SAAoD;QAC/D,MAAM,EAAE,UAAU;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,MAAc;IACvD,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAgB,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAgB,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,UAAmB;IACpD,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function hashPassword(password: string): Promise<string>;
2
+ export declare function verifyPassword(password: string, hash: string): Promise<boolean>;
3
+ export declare function generateRandomPassword(length?: number): string;
4
+ //# sourceMappingURL=password.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.utils.d.ts","sourceRoot":"","sources":["../../src/common/password.utils.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM,CAOlE"}
@@ -0,0 +1,17 @@
1
+ import bcrypt from 'bcrypt';
2
+ const SALT_ROUNDS = 12;
3
+ export async function hashPassword(password) {
4
+ return bcrypt.hash(password, SALT_ROUNDS);
5
+ }
6
+ export async function verifyPassword(password, hash) {
7
+ return bcrypt.compare(password, hash);
8
+ }
9
+ export function generateRandomPassword(length = 16) {
10
+ const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*';
11
+ let password = '';
12
+ for (let i = 0; i < length; i++) {
13
+ password += chars.charAt(Math.floor(Math.random() * chars.length));
14
+ }
15
+ return password;
16
+ }
17
+ //# sourceMappingURL=password.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.utils.js","sourceRoot":"","sources":["../../src/common/password.utils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAY;IACjE,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE;IACxD,MAAM,KAAK,GAAG,wEAAwE,CAAC;IACvF,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function normalizePhoneNumber(phone: string, defaultCountry?: string): string;
2
+ export declare function isValidPhoneNumber(phone: string, defaultCountry?: string): boolean;
3
+ export declare function formatPhoneNumber(phone: string, format?: 'e164' | 'international' | 'national', defaultCountry?: string): string;
4
+ //# sourceMappingURL=phone.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone.utils.d.ts","sourceRoot":"","sources":["../../src/common/phone.utils.ts"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,GAAE,MAAa,GAAG,MAAM,CAOzF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,GAAE,MAAa,GAAG,OAAO,CAOxF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,eAAe,GAAG,UAAmB,EAAE,cAAc,GAAE,MAAa,GAAG,MAAM,CAY9I"}
@@ -0,0 +1,36 @@
1
+ import pkg from 'google-libphonenumber';
2
+ const { PhoneNumberUtil, PhoneNumberFormat } = pkg;
3
+ const phoneUtil = PhoneNumberUtil.getInstance();
4
+ export function normalizePhoneNumber(phone, defaultCountry = 'KE') {
5
+ try {
6
+ const parsed = phoneUtil.parse(phone, defaultCountry);
7
+ return phoneUtil.format(parsed, PhoneNumberFormat.E164);
8
+ }
9
+ catch {
10
+ return phone;
11
+ }
12
+ }
13
+ export function isValidPhoneNumber(phone, defaultCountry = 'KE') {
14
+ try {
15
+ const parsed = phoneUtil.parse(phone, defaultCountry);
16
+ return phoneUtil.isValidNumber(parsed);
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ export function formatPhoneNumber(phone, format = 'e164', defaultCountry = 'KE') {
23
+ try {
24
+ const parsed = phoneUtil.parse(phone, defaultCountry);
25
+ const formatMap = {
26
+ e164: PhoneNumberFormat.E164,
27
+ international: PhoneNumberFormat.INTERNATIONAL,
28
+ national: PhoneNumberFormat.NATIONAL,
29
+ };
30
+ return phoneUtil.format(parsed, formatMap[format]);
31
+ }
32
+ catch {
33
+ return phone;
34
+ }
35
+ }
36
+ //# sourceMappingURL=phone.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone.utils.js","sourceRoot":"","sources":["../../src/common/phone.utils.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,uBAAuB,CAAC;AACxC,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,GAAG,GAAG,CAAC;AAEnD,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,EAAE,CAAC;AAEhD,MAAM,UAAU,oBAAoB,CAAC,KAAa,EAAE,iBAAyB,IAAI;IAC/E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACtD,OAAO,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,iBAAyB,IAAI;IAC7E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACtD,OAAO,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,SAAgD,MAAM,EAAE,iBAAyB,IAAI;IACpI,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG;YAChB,IAAI,EAAE,iBAAiB,CAAC,IAAI;YAC5B,aAAa,EAAE,iBAAiB,CAAC,aAAa;YAC9C,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;SACrC,CAAC;QACF,OAAO,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { IApiResponse, IPaginatedResult } from '../types/index.js';
2
+ export declare function successResponse<T>(data: T, message?: string): IApiResponse<T>;
3
+ export declare function errorResponse(message: string, errors?: Record<string, string[]>): IApiResponse;
4
+ export declare function paginatedResponse<T>(data: T[], total: number, page: number, limit: number, message?: string): IApiResponse<T[]>;
5
+ export declare function buildPaginatedResult<T>(data: T[], total: number, page: number, limit: number): IPaginatedResult<T>;
6
+ //# sourceMappingURL=response.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.utils.d.ts","sourceRoot":"","sources":["../../src/common/response.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAmB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEzF,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,GAAE,MAAkB,GAAG,YAAY,CAAC,CAAC,CAAC,CAExF;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,YAAY,CAE9F;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAAkB,GAC1B,YAAY,CAAC,CAAC,EAAE,CAAC,CAWnB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,gBAAgB,CAAC,CAAC,CAAC,CAarB"}
@@ -0,0 +1,33 @@
1
+ export function successResponse(data, message = 'Success') {
2
+ return { success: true, message, data };
3
+ }
4
+ export function errorResponse(message, errors) {
5
+ return { success: false, message, errors };
6
+ }
7
+ export function paginatedResponse(data, total, page, limit, message = 'Success') {
8
+ const totalPages = Math.ceil(total / limit);
9
+ const meta = {
10
+ page,
11
+ limit,
12
+ total,
13
+ totalPages,
14
+ hasNext: page < totalPages,
15
+ hasPrev: page > 1,
16
+ };
17
+ return { success: true, message, data, meta };
18
+ }
19
+ export function buildPaginatedResult(data, total, page, limit) {
20
+ const totalPages = Math.ceil(total / limit);
21
+ return {
22
+ data,
23
+ meta: {
24
+ page,
25
+ limit,
26
+ total,
27
+ totalPages,
28
+ hasNext: page < totalPages,
29
+ hasPrev: page > 1,
30
+ },
31
+ };
32
+ }
33
+ //# sourceMappingURL=response.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.utils.js","sourceRoot":"","sources":["../../src/common/response.utils.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAI,IAAO,EAAE,UAAkB,SAAS;IACrE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,MAAiC;IAC9E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,IAAS,EACT,KAAa,EACb,IAAY,EACZ,KAAa,EACb,UAAkB,SAAS;IAE3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAoB;QAC5B,IAAI;QACJ,KAAK;QACL,KAAK;QACL,UAAU;QACV,OAAO,EAAE,IAAI,GAAG,UAAU;QAC1B,OAAO,EAAE,IAAI,GAAG,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAS,EACT,KAAa,EACb,IAAY,EACZ,KAAa;IAEb,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IAC5C,OAAO;QACL,IAAI;QACJ,IAAI,EAAE;YACJ,IAAI;YACJ,KAAK;YACL,KAAK;YACL,UAAU;YACV,OAAO,EAAE,IAAI,GAAG,UAAU;YAC1B,OAAO,EAAE,IAAI,GAAG,CAAC;SAClB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ /** Generate a UUID v7 (time-ordered, recommended for primary keys) */
2
+ export declare function generateId(): string;
3
+ /** Generate a UUID v4 (random, for tokens/secrets) */
4
+ export declare function generateRandomId(): string;
5
+ //# sourceMappingURL=uuid.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.utils.d.ts","sourceRoot":"","sources":["../../src/common/uuid.utils.ts"],"names":[],"mappings":"AAEA,sEAAsE;AACtE,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
@@ -0,0 +1,10 @@
1
+ import { v7 as uuidv7, v4 as uuidv4 } from 'uuid';
2
+ /** Generate a UUID v7 (time-ordered, recommended for primary keys) */
3
+ export function generateId() {
4
+ return uuidv7();
5
+ }
6
+ /** Generate a UUID v4 (random, for tokens/secrets) */
7
+ export function generateRandomId() {
8
+ return uuidv4();
9
+ }
10
+ //# sourceMappingURL=uuid.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.utils.js","sourceRoot":"","sources":["../../src/common/uuid.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAElD,sEAAsE;AACtE,MAAM,UAAU,UAAU;IACxB,OAAO,MAAM,EAAE,CAAC;AAClB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,EAAE,CAAC;AAClB,CAAC"}
@@ -0,0 +1,95 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Base environment schema shared across all services.
4
+ */
5
+ export declare const baseEnvSchema: z.ZodObject<{
6
+ NODE_ENV: z.ZodDefault<z.ZodEnum<["development", "staging", "production"]>>;
7
+ PORT: z.ZodDefault<z.ZodNumber>;
8
+ DB_HOST: z.ZodDefault<z.ZodString>;
9
+ DB_PORT: z.ZodDefault<z.ZodNumber>;
10
+ DB_USER: z.ZodDefault<z.ZodString>;
11
+ DB_PASSWORD: z.ZodDefault<z.ZodString>;
12
+ DB_NAME: z.ZodString;
13
+ JWT_SECRET: z.ZodString;
14
+ JWT_ACCESS_EXPIRY: z.ZodDefault<z.ZodString>;
15
+ JWT_REFRESH_EXPIRY: z.ZodDefault<z.ZodString>;
16
+ RABBITMQ_URL: z.ZodDefault<z.ZodString>;
17
+ REDIS_URL: z.ZodDefault<z.ZodString>;
18
+ LOG_LEVEL: z.ZodDefault<z.ZodEnum<["error", "warn", "info", "debug"]>>;
19
+ CORS_ORIGINS: z.ZodDefault<z.ZodString>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ NODE_ENV: "production" | "development" | "staging";
22
+ LOG_LEVEL: "info" | "debug" | "error" | "warn";
23
+ PORT: number;
24
+ DB_HOST: string;
25
+ DB_PORT: number;
26
+ DB_USER: string;
27
+ DB_PASSWORD: string;
28
+ DB_NAME: string;
29
+ JWT_SECRET: string;
30
+ JWT_ACCESS_EXPIRY: string;
31
+ JWT_REFRESH_EXPIRY: string;
32
+ RABBITMQ_URL: string;
33
+ REDIS_URL: string;
34
+ CORS_ORIGINS: string;
35
+ }, {
36
+ DB_NAME: string;
37
+ JWT_SECRET: string;
38
+ NODE_ENV?: "production" | "development" | "staging" | undefined;
39
+ LOG_LEVEL?: "info" | "debug" | "error" | "warn" | undefined;
40
+ PORT?: number | undefined;
41
+ DB_HOST?: string | undefined;
42
+ DB_PORT?: number | undefined;
43
+ DB_USER?: string | undefined;
44
+ DB_PASSWORD?: string | undefined;
45
+ JWT_ACCESS_EXPIRY?: string | undefined;
46
+ JWT_REFRESH_EXPIRY?: string | undefined;
47
+ RABBITMQ_URL?: string | undefined;
48
+ REDIS_URL?: string | undefined;
49
+ CORS_ORIGINS?: string | undefined;
50
+ }>;
51
+ export type BaseEnv = z.infer<typeof baseEnvSchema>;
52
+ /**
53
+ * Load and validate environment variables using a Zod schema.
54
+ * Reads .env file from cwd if present (manual parse, no dotenv dependency needed).
55
+ */
56
+ export declare function loadEnv<T extends z.ZodObject<any>>(schema: T): z.infer<T>;
57
+ /**
58
+ * Service registry: central list of service names and default ports.
59
+ */
60
+ export declare const SERVICE_REGISTRY: {
61
+ readonly 'auth-admin': {
62
+ readonly port: 3000;
63
+ readonly prefix: "/api/v1/auth";
64
+ };
65
+ readonly sms: {
66
+ readonly port: 3001;
67
+ readonly prefix: "/api/v1/sms";
68
+ };
69
+ readonly mpesa: {
70
+ readonly port: 3002;
71
+ readonly prefix: "/api/v1/mpesa";
72
+ };
73
+ readonly ussd: {
74
+ readonly port: 3003;
75
+ readonly prefix: "/api/v1/ussd";
76
+ };
77
+ readonly whatsapp: {
78
+ readonly port: 3004;
79
+ readonly prefix: "/api/v1/whatsapp";
80
+ };
81
+ readonly notification: {
82
+ readonly port: 3005;
83
+ readonly prefix: "/api/v1/notifications";
84
+ };
85
+ readonly analytics: {
86
+ readonly port: 3006;
87
+ readonly prefix: "/api/v1/analytics";
88
+ };
89
+ readonly ai: {
90
+ readonly port: 3007;
91
+ readonly prefix: "/api/v1/ai";
92
+ };
93
+ };
94
+ export type ServiceName = keyof typeof SERVICE_REGISTRY;
95
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAexB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CA0BzE;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASnB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,gBAAgB,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { z } from 'zod';
2
+ import { readFileSync, existsSync } from 'fs';
3
+ import { resolve } from 'path';
4
+ /**
5
+ * Base environment schema shared across all services.
6
+ */
7
+ export const baseEnvSchema = z.object({
8
+ NODE_ENV: z.enum(['development', 'staging', 'production']).default('development'),
9
+ PORT: z.coerce.number().int().positive().default(3000),
10
+ DB_HOST: z.string().default('localhost'),
11
+ DB_PORT: z.coerce.number().int().positive().default(3306),
12
+ DB_USER: z.string().default('root'),
13
+ DB_PASSWORD: z.string().default(''),
14
+ DB_NAME: z.string(),
15
+ JWT_SECRET: z.string().min(16),
16
+ JWT_ACCESS_EXPIRY: z.string().default('15m'),
17
+ JWT_REFRESH_EXPIRY: z.string().default('7d'),
18
+ RABBITMQ_URL: z.string().url().default('amqp://localhost:5672'),
19
+ REDIS_URL: z.string().default('redis://localhost:6379'),
20
+ LOG_LEVEL: z.enum(['error', 'warn', 'info', 'debug']).default('info'),
21
+ CORS_ORIGINS: z.string().default('*'),
22
+ });
23
+ /**
24
+ * Load and validate environment variables using a Zod schema.
25
+ * Reads .env file from cwd if present (manual parse, no dotenv dependency needed).
26
+ */
27
+ export function loadEnv(schema) {
28
+ // Parse .env file from cwd if it exists
29
+ try {
30
+ const envPath = resolve(process.cwd(), '.env');
31
+ if (existsSync(envPath)) {
32
+ const content = readFileSync(envPath, 'utf-8');
33
+ for (const line of content.split('\n')) {
34
+ const trimmed = line.trim();
35
+ if (!trimmed || trimmed.startsWith('#'))
36
+ continue;
37
+ const eqIdx = trimmed.indexOf('=');
38
+ if (eqIdx === -1)
39
+ continue;
40
+ const key = trimmed.slice(0, eqIdx).trim();
41
+ const val = trimmed.slice(eqIdx + 1).trim();
42
+ if (!process.env[key])
43
+ process.env[key] = val;
44
+ }
45
+ }
46
+ }
47
+ catch { /* ignore */ }
48
+ const result = schema.safeParse(process.env);
49
+ if (!result.success) {
50
+ const formatted = result.error.issues
51
+ .map((i) => ` ${i.path.join('.')}: ${i.message}`)
52
+ .join('\n');
53
+ console.error(`❌ Environment validation failed:\n${formatted}`);
54
+ process.exit(1);
55
+ }
56
+ return result.data;
57
+ }
58
+ /**
59
+ * Service registry: central list of service names and default ports.
60
+ */
61
+ export const SERVICE_REGISTRY = {
62
+ 'auth-admin': { port: 3000, prefix: '/api/v1/auth' },
63
+ sms: { port: 3001, prefix: '/api/v1/sms' },
64
+ mpesa: { port: 3002, prefix: '/api/v1/mpesa' },
65
+ ussd: { port: 3003, prefix: '/api/v1/ussd' },
66
+ whatsapp: { port: 3004, prefix: '/api/v1/whatsapp' },
67
+ notification: { port: 3005, prefix: '/api/v1/notifications' },
68
+ analytics: { port: 3006, prefix: '/api/v1/analytics' },
69
+ ai: { port: 3007, prefix: '/api/v1/ai' },
70
+ };
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { Knex } from 'knex';
2
+ export interface DatabaseConfig {
3
+ host: string;
4
+ port: number;
5
+ user: string;
6
+ password: string;
7
+ database: string;
8
+ }
9
+ /**
10
+ * Create a Knex instance for MySQL 8.0.
11
+ * Used for migrations, seeds, and as a fallback query builder.
12
+ */
13
+ export declare function createKnexInstance(config: DatabaseConfig): Knex;
14
+ /**
15
+ * Standard Knex config for migrations/seeds.
16
+ */
17
+ export declare function createKnexConfig(config: DatabaseConfig): Knex.Config;
18
+ /**
19
+ * Helper: build paginated query with Knex.
20
+ */
21
+ export declare function paginateQuery<T>(query: Knex.QueryBuilder, countQuery: Knex.QueryBuilder, page: number, limit: number): Promise<{
22
+ data: T[];
23
+ total: number;
24
+ }>;
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,OAAa,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAqB/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC,MAAM,CAoBpE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,KAAK,EAAE,IAAI,CAAC,YAAY,EACxB,UAAU,EAAE,IAAI,CAAC,YAAY,EAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAMvC"}
@@ -0,0 +1,62 @@
1
+ import knex from 'knex';
2
+ /**
3
+ * Create a Knex instance for MySQL 8.0.
4
+ * Used for migrations, seeds, and as a fallback query builder.
5
+ */
6
+ export function createKnexInstance(config) {
7
+ return knex({
8
+ client: 'mysql2',
9
+ connection: {
10
+ host: config.host,
11
+ port: config.port,
12
+ user: config.user,
13
+ password: config.password,
14
+ database: config.database,
15
+ charset: 'utf8mb4',
16
+ timezone: '+00:00',
17
+ },
18
+ pool: {
19
+ min: 2,
20
+ max: 10,
21
+ acquireTimeoutMillis: 30000,
22
+ },
23
+ migrations: {
24
+ tableName: 'knex_migrations',
25
+ },
26
+ });
27
+ }
28
+ /**
29
+ * Standard Knex config for migrations/seeds.
30
+ */
31
+ export function createKnexConfig(config) {
32
+ return {
33
+ client: 'mysql2',
34
+ connection: {
35
+ host: config.host,
36
+ port: config.port,
37
+ user: config.user,
38
+ password: config.password,
39
+ database: config.database,
40
+ charset: 'utf8mb4',
41
+ },
42
+ migrations: {
43
+ directory: './migrations',
44
+ extension: 'cjs',
45
+ },
46
+ seeds: {
47
+ directory: './seeds',
48
+ extension: 'cjs',
49
+ },
50
+ };
51
+ }
52
+ /**
53
+ * Helper: build paginated query with Knex.
54
+ */
55
+ export async function paginateQuery(query, countQuery, page, limit) {
56
+ const offset = (page - 1) * limit;
57
+ const [countResult] = await countQuery.count('* as total');
58
+ const total = countResult.total;
59
+ const data = await query.limit(limit).offset(offset);
60
+ return { data, total };
61
+ }
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAc,MAAM,MAAM,CAAC;AAUlC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,OAAO,IAAI,CAAC;QACV,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE;YACV,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,QAAQ;SACnB;QACD,IAAI,EAAE;YACJ,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,EAAE;YACP,oBAAoB,EAAE,KAAK;SAC5B;QACD,UAAU,EAAE;YACV,SAAS,EAAE,iBAAiB;SAC7B;KACF,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE;YACV,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,SAAS;SACnB;QACD,UAAU,EAAE;YACV,SAAS,EAAE,cAAc;YACzB,SAAS,EAAE,KAAK;SACjB;QACD,KAAK,EAAE;YACL,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,KAAK;SACjB;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAwB,EACxB,UAA6B,EAC7B,IAAY,EACZ,KAAa;IAEb,MAAM,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;IAClC,MAAM,CAAC,WAAW,CAAC,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAI,WAAmB,CAAC,KAAe,CAAC;IACnD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAQ,CAAC;IAC5D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ import { type IAuthUser } from '../types/index.js';
3
+ declare global {
4
+ namespace Express {
5
+ interface Request {
6
+ user?: IAuthUser;
7
+ }
8
+ }
9
+ }
10
+ /**
11
+ * Auth middleware for downstream services (behind API gateway).
12
+ * Reads user context from gateway-injected headers.
13
+ * Falls back to JWT validation if headers are missing (direct access).
14
+ */
15
+ export declare function authenticateFromGateway(jwtSecret?: string): (req: Request, _res: Response, next: NextFunction) => void;
16
+ /**
17
+ * Optional auth — attaches user if present, continues if not.
18
+ */
19
+ export declare function optionalAuthFromGateway(jwtSecret?: string): (req: Request, _res: Response, next: NextFunction) => void;
20
+ //# sourceMappingURL=auth.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.middleware.d.ts","sourceRoot":"","sources":["../../src/express/auth.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE/D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGpE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE,SAAS,CAAC;SAClB;KACF;CACF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,CAAC,EAAE,MAAM,IAChD,KAAK,OAAO,EAAE,MAAM,QAAQ,EAAE,MAAM,YAAY,KAAG,IAAI,CAsChE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,CAAC,EAAE,MAAM,IAChD,KAAK,OAAO,EAAE,MAAM,QAAQ,EAAE,MAAM,YAAY,KAAG,IAAI,CA6BhE"}
@@ -0,0 +1,83 @@
1
+ import { verifyToken, extractBearerToken } from '../common/jwt.utils.js';
2
+ import { GATEWAY_HEADERS } from '../types/index.js';
3
+ /**
4
+ * Auth middleware for downstream services (behind API gateway).
5
+ * Reads user context from gateway-injected headers.
6
+ * Falls back to JWT validation if headers are missing (direct access).
7
+ */
8
+ export function authenticateFromGateway(jwtSecret) {
9
+ return (req, _res, next) => {
10
+ // Method 1: Read gateway-injected headers
11
+ const userId = req.headers[GATEWAY_HEADERS.USER_ID];
12
+ if (userId) {
13
+ req.user = {
14
+ id: userId,
15
+ email: req.headers[GATEWAY_HEADERS.USER_EMAIL] || '',
16
+ companyId: req.headers[GATEWAY_HEADERS.COMPANY_ID] || '',
17
+ roles: (req.headers[GATEWAY_HEADERS.USER_ROLES] || '').split(',').filter(Boolean),
18
+ permissions: (req.headers[GATEWAY_HEADERS.USER_PERMISSIONS] || '').split(',').filter(Boolean),
19
+ isSuperAdmin: req.headers[GATEWAY_HEADERS.IS_SUPERADMIN] === 'true',
20
+ };
21
+ return next();
22
+ }
23
+ // Method 2: Direct JWT validation (for development / direct access)
24
+ if (jwtSecret) {
25
+ const token = extractBearerToken(req.headers.authorization);
26
+ if (token) {
27
+ try {
28
+ const payload = verifyToken(token, jwtSecret);
29
+ req.user = {
30
+ id: payload.sub,
31
+ email: payload.email,
32
+ companyId: payload.companyId,
33
+ roles: payload.roles || [],
34
+ permissions: payload.permissions || [],
35
+ isSuperAdmin: payload.isSuperAdmin || false,
36
+ };
37
+ return next();
38
+ }
39
+ catch {
40
+ // Fall through to 401
41
+ }
42
+ }
43
+ }
44
+ _res.status(401).json({ success: false, message: 'Authentication required' });
45
+ };
46
+ }
47
+ /**
48
+ * Optional auth — attaches user if present, continues if not.
49
+ */
50
+ export function optionalAuthFromGateway(jwtSecret) {
51
+ return (req, _res, next) => {
52
+ const userId = req.headers[GATEWAY_HEADERS.USER_ID];
53
+ if (userId) {
54
+ req.user = {
55
+ id: userId,
56
+ email: req.headers[GATEWAY_HEADERS.USER_EMAIL] || '',
57
+ companyId: req.headers[GATEWAY_HEADERS.COMPANY_ID] || '',
58
+ roles: (req.headers[GATEWAY_HEADERS.USER_ROLES] || '').split(',').filter(Boolean),
59
+ permissions: (req.headers[GATEWAY_HEADERS.USER_PERMISSIONS] || '').split(',').filter(Boolean),
60
+ isSuperAdmin: req.headers[GATEWAY_HEADERS.IS_SUPERADMIN] === 'true',
61
+ };
62
+ }
63
+ else if (jwtSecret) {
64
+ const token = extractBearerToken(req.headers.authorization);
65
+ if (token) {
66
+ try {
67
+ const payload = verifyToken(token, jwtSecret);
68
+ req.user = {
69
+ id: payload.sub,
70
+ email: payload.email,
71
+ companyId: payload.companyId,
72
+ roles: payload.roles || [],
73
+ permissions: payload.permissions || [],
74
+ isSuperAdmin: payload.isSuperAdmin || false,
75
+ };
76
+ }
77
+ catch { /* ignore */ }
78
+ }
79
+ }
80
+ next();
81
+ };
82
+ }
83
+ //# sourceMappingURL=auth.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.middleware.js","sourceRoot":"","sources":["../../src/express/auth.middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ /**
3
+ * Ensures every request has a correlation ID for distributed tracing.
4
+ */
5
+ export declare function correlationMiddleware(serviceName: string): (req: Request, res: Response, next: NextFunction) => void;
6
+ //# sourceMappingURL=correlation.middleware.d.ts.map