@wabot-dev/framework 0.1.0-beta.9 → 0.2.0-beta.1

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 (212) hide show
  1. package/dist/src/addon/async/pg/PgJobRepository.js +26 -0
  2. package/dist/src/addon/auth/api-key/@apiKeyConnectionGuard.js +16 -0
  3. package/dist/src/addon/auth/api-key/@apiKeyGuard.js +17 -0
  4. package/dist/src/addon/auth/api-key/ApiKey.js +45 -0
  5. package/dist/src/addon/auth/api-key/ApiKeyConnectionGuardMiddleware.js +57 -0
  6. package/dist/src/addon/auth/api-key/ApiKeyGuardMiddleware.js +45 -0
  7. package/dist/src/addon/auth/api-key/ApiKeyRepository.js +22 -0
  8. package/dist/src/addon/auth/api-key/PgApiKeyRepository.js +53 -0
  9. package/dist/src/addon/auth/api-key/RemoteApiKeyRepository.js +62 -0
  10. package/dist/src/addon/auth/jwt/@jwtConnectionGuard.js +16 -0
  11. package/dist/src/addon/auth/jwt/@jwtGuard.js +17 -0
  12. package/dist/src/addon/auth/jwt/Jwt.js +53 -0
  13. package/dist/src/addon/auth/jwt/JwtAccessAndRefreshTokenDto.js +20 -0
  14. package/dist/src/addon/auth/jwt/JwtConfig.js +28 -0
  15. package/dist/src/addon/auth/jwt/JwtConnectionGuardMiddleware.js +57 -0
  16. package/dist/src/addon/auth/jwt/JwtGuardMiddleware.js +45 -0
  17. package/dist/src/addon/auth/jwt/JwtRefreshToken.js +56 -0
  18. package/dist/src/addon/auth/jwt/JwtRefreshTokenRepository.js +25 -0
  19. package/dist/src/addon/auth/jwt/JwtSigner.js +36 -0
  20. package/dist/src/addon/auth/jwt/JwtTokenDto.js +22 -0
  21. package/dist/src/addon/auth/jwt/PgJwtRefreshTokenRepository.js +21 -0
  22. package/dist/src/addon/chat-bot/anthropic/AnthropicChatAdapter.js +135 -0
  23. package/dist/src/addon/chat-bot/deepseek/DeepSeekChatAdapter.js +137 -0
  24. package/dist/src/addon/chat-bot/google/GoogleChatAdapter.js +128 -0
  25. package/dist/src/addon/chat-bot/openia/OpenaiChatAdapter.js +117 -0
  26. package/dist/src/{pre-made/repository/chat → addon/chat-bot}/pg/PgChatMemory.js +6 -4
  27. package/dist/src/{pre-made/repository/chat → addon/chat-bot}/pg/PgChatRepository.js +6 -5
  28. package/dist/src/{pre-made/repository/chat → addon/chat-bot}/ram/RamChatRepository.js +2 -2
  29. package/dist/src/addon/chat-bot/wabot/WabotChatAdapter.js +41 -0
  30. package/dist/src/addon/chat-controller/cmd/@cmd.js +24 -0
  31. package/dist/src/addon/chat-controller/cmd/CmdChannel.js +91 -0
  32. package/dist/src/{channels → addon/chat-controller}/socket/@socket.js +10 -4
  33. package/dist/src/{channels → addon/chat-controller}/socket/SocketChannel.js +9 -23
  34. package/dist/src/{channels → addon/chat-controller}/socket/SocketChannelConfig.js +1 -1
  35. package/dist/src/{channels → addon/chat-controller}/telegram/@telegram.js +10 -4
  36. package/dist/src/{channels → addon/chat-controller}/telegram/TelegramChannel.js +4 -22
  37. package/dist/src/addon/chat-controller/whatsapp/@whatsApp.js +26 -0
  38. package/dist/src/{channels → addon/chat-controller}/whatsapp/EnvWhatsAppRepository.js +3 -3
  39. package/dist/src/{channels → addon/chat-controller}/whatsapp/PgWhatsAppRepository.js +2 -2
  40. package/dist/src/{channels → addon/chat-controller}/whatsapp/WhatsApp.js +2 -4
  41. package/dist/src/{channels → addon/chat-controller}/whatsapp/WhatsAppChannel.js +6 -18
  42. package/dist/src/addon/chat-controller/whatsapp/WhatsAppReceiver.js +10 -0
  43. package/dist/src/{channels → addon/chat-controller}/whatsapp/WhatsAppSender.js +15 -39
  44. package/dist/src/addon/chat-controller/whatsapp/cloud-api/WhatsAppReceiverByCloudApi.js +97 -0
  45. package/dist/src/{channels/whatsapp → addon/chat-controller/whatsapp/cloud-api}/WhatsAppSenderByCloudApi.js +27 -20
  46. package/dist/src/addon/chat-controller/whatsapp/proxy/WhatsAppProxyContracts.js +5 -0
  47. package/dist/src/addon/chat-controller/whatsapp/proxy/WhatsAppReceiverByWabotProxy.js +65 -0
  48. package/dist/src/addon/chat-controller/whatsapp/proxy/WhatsAppSenderByWabotProxy.js +61 -0
  49. package/dist/src/addon/chat-controller/whatsapp/proxy/WhatsAppWabotProxyConnection.js +45 -0
  50. package/dist/src/{pre-made/module → addon/mindset}/html/HtmlModule.js +7 -7
  51. package/dist/src/core/auth/Auth.js +33 -0
  52. package/dist/src/core/{Persistent.js → entity/Entity.js} +24 -12
  53. package/dist/src/core/env/Env.js +39 -0
  54. package/dist/src/core/error/CustomError.js +15 -0
  55. package/dist/src/core/injection/index.js +4 -0
  56. package/dist/src/core/mapper/Mapper.js +42 -0
  57. package/dist/src/core/password/Password.js +30 -0
  58. package/dist/src/core/random/Random.js +65 -0
  59. package/dist/src/core/storable/Storable.js +8 -0
  60. package/dist/src/core/validation/core/validateArray.js +51 -0
  61. package/dist/src/core/validation/core/validateModel.js +36 -0
  62. package/dist/src/{validation/metadata/@isNumber.js → core/validation/metadata/@isArray.js} +5 -4
  63. package/dist/src/{validation/metadata/@isDate.js → core/validation/metadata/@isModel.js} +5 -4
  64. package/dist/src/{validation → core/validation}/metadata/@isOptional.js +1 -1
  65. package/dist/src/core/validation/metadata/ValidationMetadataStore.js +98 -0
  66. package/dist/src/core/validation/modelInfo.js +9 -0
  67. package/dist/src/{validation/validateModel2.js → core/validation/validate.js} +3 -3
  68. package/dist/src/{validation/metadata → core/validation/validators/is-boolean}/@isBoolean.js +3 -3
  69. package/dist/src/core/validation/validators/is-date/@isDate.js +17 -0
  70. package/dist/src/core/validation/validators/is-in/@isIn.js +18 -0
  71. package/dist/src/core/validation/validators/is-in/validateIsIn.js +12 -0
  72. package/dist/src/{validation/metadata → core/validation/validators/is-not-empty}/@isNotEmpty.js +3 -3
  73. package/dist/src/core/validation/validators/is-number/@isNumber.js +17 -0
  74. package/dist/src/{validation/metadata → core/validation/validators/is-present}/@isPresent.js +3 -3
  75. package/dist/src/{validation/metadata → core/validation/validators/is-string}/@isString.js +3 -3
  76. package/dist/src/{validation/metadata → core/validation/validators/max}/@max.js +3 -3
  77. package/dist/src/{validation/metadata → core/validation/validators/min}/@min.js +3 -3
  78. package/dist/src/feature/async/@command.js +11 -0
  79. package/dist/src/feature/async/@commandHandler.js +12 -0
  80. package/dist/src/feature/async/Async.js +38 -0
  81. package/dist/src/feature/async/Command.js +9 -0
  82. package/dist/src/feature/async/CommandMetadataStore.js +38 -0
  83. package/dist/src/feature/async/Job.js +27 -0
  84. package/dist/src/feature/async/JobRepository.js +31 -0
  85. package/dist/src/feature/async/JobRunner.js +48 -0
  86. package/dist/src/feature/async/JobsEventsHub.js +36 -0
  87. package/dist/src/feature/async/runCommandHandlers.js +29 -0
  88. package/dist/src/{core/chat → feature/chat-bot}/Chat.js +2 -2
  89. package/dist/src/feature/chat-bot/ChatAdapter.js +7 -0
  90. package/dist/src/feature/chat-bot/ChatBot.js +73 -0
  91. package/dist/src/feature/chat-bot/ChatItem.js +24 -0
  92. package/dist/src/feature/chat-bot/ChatMemory.js +10 -0
  93. package/dist/src/{core/chat/repository/IChatRepository.js → feature/chat-bot/ChatRepository.js} +2 -8
  94. package/dist/src/feature/chat-bot/IChatItem.js +3 -0
  95. package/dist/src/{chatbot → feature/chat-bot}/metadata/@chatBot.js +1 -1
  96. package/dist/src/{chatbot → feature/chat-bot}/metadata/ChatBotMetadataStore.js +1 -1
  97. package/dist/src/{controller/channel → feature/chat-controller}/ChatResolver.js +6 -4
  98. package/dist/src/{controller → feature/chat-controller}/metadata/ControllerMetadataStore.js +1 -1
  99. package/dist/src/{controller → feature/chat-controller}/metadata/controller/@chatController.js +1 -1
  100. package/dist/src/feature/chat-controller/runChatControllers.js +83 -0
  101. package/dist/src/{channels → feature}/express/ExpressProvider.js +2 -4
  102. package/dist/src/{channels → feature}/http/HttpServerProvider.js +2 -2
  103. package/dist/src/{mindset → feature/mindset}/IMindset.js +6 -0
  104. package/dist/src/feature/mindset/MindsetOperator.js +180 -0
  105. package/dist/src/{mindset → feature/mindset}/metadata/MindsetMetadataStore.js +1 -1
  106. package/dist/src/{mindset → feature/mindset}/metadata/functions/@mindsetFunction.js +1 -1
  107. package/dist/src/{mindset → feature/mindset}/metadata/mindsets/@mindset.js +1 -1
  108. package/dist/src/{mindset → feature/mindset}/metadata/modules/@mindsetModule.js +1 -2
  109. package/dist/src/{mindset → feature/mindset}/metadata/params/@param.js +1 -1
  110. package/dist/src/feature/money/Money.js +61 -0
  111. package/dist/src/feature/money/MoneyDto.js +22 -0
  112. package/dist/src/{repository → feature}/pg/PgCrudRepository.js +24 -10
  113. package/dist/src/{repository → feature}/pg/PgRepositoryBase.js +2 -2
  114. package/dist/src/feature/rest-controller/injection-tokens.js +4 -0
  115. package/dist/src/{rest-controller/metadata/@post.js → feature/rest-controller/metadata/@middleware.js} +5 -8
  116. package/dist/src/feature/rest-controller/metadata/@onDelete.js +7 -0
  117. package/dist/src/feature/rest-controller/metadata/@onGet.js +7 -0
  118. package/dist/src/feature/rest-controller/metadata/@onPost.js +7 -0
  119. package/dist/src/feature/rest-controller/metadata/@onPut.js +7 -0
  120. package/dist/src/{rest-controller → feature/rest-controller}/metadata/@restController.js +2 -2
  121. package/dist/src/{rest-controller → feature/rest-controller}/metadata/RestControllerMetadataStore.js +14 -1
  122. package/dist/src/{rest-controller/metadata/@get.js → feature/rest-controller/metadata/methodDecorator.js} +5 -5
  123. package/dist/src/feature/rest-controller/runRestControllers.js +103 -0
  124. package/dist/src/{channels → feature}/socket/SocketServerProvider.js +2 -2
  125. package/dist/src/feature/socket-controller/metadata/@connectionMiddleware.js +16 -0
  126. package/dist/src/feature/socket-controller/metadata/@socketConnection.js +18 -0
  127. package/dist/src/feature/socket-controller/metadata/@socketController.js +15 -0
  128. package/dist/src/feature/socket-controller/metadata/@socketEvent.js +18 -0
  129. package/dist/src/feature/socket-controller/metadata/SocketControllerMetadataStore.js +65 -0
  130. package/dist/src/feature/socket-controller/runSocketControllers.js +99 -0
  131. package/dist/src/index.d.ts +1219 -718
  132. package/dist/src/index.js +147 -102
  133. package/package.json +8 -2
  134. package/dist/src/_virtual/_commonjsHelpers.js +0 -5
  135. package/dist/src/_virtual/cjs.js +0 -7
  136. package/dist/src/ai/deepseek/DeepSeekChatBotAdapter.js +0 -107
  137. package/dist/src/ai/openia/OpenaiChatBotAdapter.js +0 -88
  138. package/dist/src/channels/cmd/@cmd.js +0 -18
  139. package/dist/src/channels/cmd/CmdChannel.js +0 -73
  140. package/dist/src/channels/wabot/WabotDevConnection.js +0 -57
  141. package/dist/src/channels/wabot/WabotDevSocketContracts.js +0 -10
  142. package/dist/src/channels/whatsapp/@whatsapp.js +0 -20
  143. package/dist/src/channels/whatsapp/WhatsAppReceiver.js +0 -59
  144. package/dist/src/channels/whatsapp/WhatsAppReceiverByDevConnection.js +0 -32
  145. package/dist/src/channels/whatsapp/WhatsAppReceiverByWebHook.js +0 -63
  146. package/dist/src/channels/whatsapp/WhatsAppSenderByDevConnection.js +0 -61
  147. package/dist/src/chatbot/ChatBot.js +0 -51
  148. package/dist/src/chatbot/ChatBotAdapter.js +0 -72
  149. package/dist/src/controller/channel/UserResolver.js +0 -21
  150. package/dist/src/core/IMessageContext.js +0 -12
  151. package/dist/src/core/chat/ChatItem.js +0 -15
  152. package/dist/src/core/chat/repository/IChatMemory.js +0 -10
  153. package/dist/src/core/user/IUserRepository.js +0 -19
  154. package/dist/src/core/user/User.js +0 -26
  155. package/dist/src/env/WabotEnv.js +0 -27
  156. package/dist/src/injection/index.js +0 -4
  157. package/dist/src/mindset/MindsetOperator.js +0 -101
  158. package/dist/src/node_modules/@selderee/plugin-htmlparser2/lib/hp2-builder.js +0 -90
  159. package/dist/src/node_modules/deepmerge/dist/cjs.js +0 -142
  160. package/dist/src/node_modules/dom-serializer/lib/esm/foreignNames.js +0 -102
  161. package/dist/src/node_modules/dom-serializer/lib/esm/index.js +0 -186
  162. package/dist/src/node_modules/domelementtype/lib/esm/index.js +0 -53
  163. package/dist/src/node_modules/domhandler/lib/esm/index.js +0 -148
  164. package/dist/src/node_modules/domhandler/lib/esm/node.js +0 -334
  165. package/dist/src/node_modules/entities/lib/esm/decode.js +0 -458
  166. package/dist/src/node_modules/entities/lib/esm/decode_codepoint.js +0 -62
  167. package/dist/src/node_modules/entities/lib/esm/escape.js +0 -99
  168. package/dist/src/node_modules/entities/lib/esm/generated/decode-data-html.js +0 -8
  169. package/dist/src/node_modules/entities/lib/esm/generated/decode-data-xml.js +0 -8
  170. package/dist/src/node_modules/html-to-text/lib/html-to-text.js +0 -2147
  171. package/dist/src/node_modules/htmlparser2/lib/esm/Parser.js +0 -491
  172. package/dist/src/node_modules/htmlparser2/lib/esm/Tokenizer.js +0 -928
  173. package/dist/src/node_modules/htmlparser2/lib/esm/index.js +0 -18
  174. package/dist/src/node_modules/leac/lib/leac.js +0 -3
  175. package/dist/src/node_modules/parseley/lib/parseley.js +0 -270
  176. package/dist/src/node_modules/peberminta/lib/core.js +0 -171
  177. package/dist/src/node_modules/selderee/lib/selderee.js +0 -380
  178. package/dist/src/pre-made/module/authentication/AuthenticationModule.js +0 -97
  179. package/dist/src/pre-made/module/authentication/requests/SendOneTimePasswordRequest.js +0 -25
  180. package/dist/src/pre-made/module/authentication/requests/ValidateOneTimePasswordRequest.js +0 -25
  181. package/dist/src/pre-made/module/register-user/RegisterUserModule.js +0 -56
  182. package/dist/src/pre-made/module/register-user/requests/RegisterUserWithEmailRequest.js +0 -25
  183. package/dist/src/pre-made/repository/user/pg/PgUserRepository.js +0 -33
  184. package/dist/src/pre-made/repository/user/ram/RamUserRepository.js +0 -27
  185. package/dist/src/pre-made/service/EmailService.js +0 -13
  186. package/dist/src/pre-made/service/OtpService.js +0 -14
  187. package/dist/src/rest-controller/runRestControllers.js +0 -74
  188. package/dist/src/server/prepareChatContainer.js +0 -43
  189. package/dist/src/server/runChannel.js +0 -27
  190. package/dist/src/server/runServer.js +0 -40
  191. package/dist/src/validation/metadata/@validable.js +0 -14
  192. package/dist/src/validation/metadata/ValidationMetadataStore.js +0 -55
  193. package/dist/src/validation/validators/validateModel.js +0 -47
  194. /package/dist/src/{pre-made/repository/chat → addon/chat-bot}/ram/RamChatMemory.js +0 -0
  195. /package/dist/src/{channels → addon/chat-controller}/telegram/TelegramChannelConfig.js +0 -0
  196. /package/dist/src/{channels → addon/chat-controller}/whatsapp/WhatsAppChannelConfig.js +0 -0
  197. /package/dist/src/{channels → addon/chat-controller}/whatsapp/WhatsAppRepository.js +0 -0
  198. /package/dist/src/{injection → core/injection}/Container.js +0 -0
  199. /package/dist/src/{logger → core/logger}/Logger.js +0 -0
  200. /package/dist/src/{validation/validators → core/validation/core}/validateIsOptional.js +0 -0
  201. /package/dist/src/{validation/validators → core/validation/validators/is-boolean}/validateIsBoolean.js +0 -0
  202. /package/dist/src/{validation/validators → core/validation/validators/is-date}/validateIsDate.js +0 -0
  203. /package/dist/src/{validation/validators → core/validation/validators/is-not-empty}/validateIsNotEmpty.js +0 -0
  204. /package/dist/src/{validation/validators → core/validation/validators/is-number}/validateIsNumber.js +0 -0
  205. /package/dist/src/{validation/validators → core/validation/validators/is-present}/validateIsPresent.js +0 -0
  206. /package/dist/src/{validation/validators → core/validation/validators/is-string}/validateIsString.js +0 -0
  207. /package/dist/src/{validation/validators → core/validation/validators/max}/validateMax.js +0 -0
  208. /package/dist/src/{validation/validators → core/validation/validators/min}/validateMin.js +0 -0
  209. /package/dist/src/{mindset → feature/mindset}/metadata/functions/decoratorNames.js +0 -0
  210. /package/dist/src/{mindset → feature/mindset}/metadata/mindsets/decoratorNames.js +0 -0
  211. /package/dist/src/{mindset → feature/mindset}/metadata/modules/decoratorNames.js +0 -0
  212. /package/dist/src/{mindset → feature/mindset}/metadata/params/decoratorNames.js +0 -0
@@ -0,0 +1,26 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { Pool } from 'pg';
3
+ import { singleton } from '../../../core/injection/index.js';
4
+ import { PgCrudRepository } from '../../../feature/pg/PgCrudRepository.js';
5
+ import '../../../feature/async/CommandMetadataStore.js';
6
+ import '../../../feature/async/Async.js';
7
+ import { Job } from '../../../feature/async/Job.js';
8
+ import '../../../feature/async/JobRepository.js';
9
+ import '../../../feature/async/JobRunner.js';
10
+ import '../../../feature/async/JobsEventsHub.js';
11
+
12
+ let PgJobRepository = class PgJobRepository extends PgCrudRepository {
13
+ constructor(pool) {
14
+ super(pool, {
15
+ schema: 'wabot',
16
+ table: 'job',
17
+ constructor: Job,
18
+ });
19
+ }
20
+ };
21
+ PgJobRepository = __decorate([
22
+ singleton(),
23
+ __metadata("design:paramtypes", [Pool])
24
+ ], PgJobRepository);
25
+
26
+ export { PgJobRepository };
@@ -0,0 +1,16 @@
1
+ import { connectionMiddleware } from '../../../feature/socket-controller/metadata/@connectionMiddleware.js';
2
+ import '../../../core/injection/index.js';
3
+ import '../../../feature/socket-controller/metadata/SocketControllerMetadataStore.js';
4
+ import 'path';
5
+ import 'debug';
6
+ import '../../../feature/socket/SocketServerProvider.js';
7
+ import '../../../core/validation/metadata/ValidationMetadataStore.js';
8
+ import { ApiKeyConnectionGuardMiddleware } from './ApiKeyConnectionGuardMiddleware.js';
9
+
10
+ function apiKeyConnectionGuard() {
11
+ return function (target, propertyKey) {
12
+ connectionMiddleware(ApiKeyConnectionGuardMiddleware)(target, propertyKey);
13
+ };
14
+ }
15
+
16
+ export { apiKeyConnectionGuard };
@@ -0,0 +1,17 @@
1
+ import '../../../core/injection/index.js';
2
+ import '../../../feature/rest-controller/metadata/RestControllerMetadataStore.js';
3
+ import { middleware } from '../../../feature/rest-controller/metadata/@middleware.js';
4
+ import 'debug';
5
+ import '../../../core/validation/metadata/ValidationMetadataStore.js';
6
+ import '../../../feature/express/ExpressProvider.js';
7
+ import 'express';
8
+ import 'path';
9
+ import { ApiKeyGuardMiddleware } from './ApiKeyGuardMiddleware.js';
10
+
11
+ function apiKeyGuard() {
12
+ return function (target, propertyKey) {
13
+ middleware(ApiKeyGuardMiddleware)(target, propertyKey);
14
+ };
15
+ }
16
+
17
+ export { apiKeyGuard };
@@ -0,0 +1,45 @@
1
+ import { Entity } from '../../../core/entity/Entity.js';
2
+ import { CustomError } from '../../../core/error/CustomError.js';
3
+ import crypto from 'node:crypto';
4
+
5
+ class ApiKey extends Entity {
6
+ static PREFIX = 'sk_';
7
+ static hashSecret(secret) {
8
+ return crypto.createHash('sha256').update(secret).digest('hex');
9
+ }
10
+ get authInfo() {
11
+ return this.data.authInfo;
12
+ }
13
+ get metadata() {
14
+ return this.data.metadata ?? {};
15
+ }
16
+ setAuthInfo(authInfo) {
17
+ this.data.authInfo = authInfo;
18
+ }
19
+ generateSecret() {
20
+ if (this.data.secretHash) {
21
+ throw new Error('This API key already has a secret');
22
+ }
23
+ const secret = `${ApiKey.PREFIX}${crypto.randomBytes(32).toString('hex')}`;
24
+ this.data.secretHash = ApiKey.hashSecret(secret);
25
+ return secret;
26
+ }
27
+ isValidSecret(secret) {
28
+ if (!secret.startsWith(ApiKey.PREFIX))
29
+ return false;
30
+ if (!this.data.secretHash)
31
+ return false;
32
+ const hashed = ApiKey.hashSecret(secret);
33
+ const stored = this.data.secretHash;
34
+ const hashedBuf = Buffer.from(hashed, 'hex');
35
+ const storedBuf = Buffer.from(stored, 'hex');
36
+ return hashedBuf.length === storedBuf.length && crypto.timingSafeEqual(hashedBuf, storedBuf);
37
+ }
38
+ validateSecret(secret) {
39
+ if (!this.isValidSecret(secret)) {
40
+ throw new CustomError({ message: 'Invalid API key', httpCode: 401 });
41
+ }
42
+ }
43
+ }
44
+
45
+ export { ApiKey };
@@ -0,0 +1,57 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { Auth } from '../../../core/auth/Auth.js';
3
+ import { CustomError } from '../../../core/error/CustomError.js';
4
+ import { injectable } from '../../../core/injection/index.js';
5
+ import { ApiKeyRepository } from './ApiKeyRepository.js';
6
+
7
+ let ApiKeyConnectionGuardMiddleware = class ApiKeyConnectionGuardMiddleware {
8
+ apiKeyRepository;
9
+ auth;
10
+ constructor(apiKeyRepository, auth) {
11
+ this.apiKeyRepository = apiKeyRepository;
12
+ this.auth = auth;
13
+ }
14
+ async handle(socket, container) {
15
+ if (!socket.handshake.auth.token) {
16
+ let authorization = socket.handshake.headers['Authorization'] ?? socket.handshake.headers['authorization'];
17
+ if (Array.isArray(authorization)) {
18
+ authorization = authorization[0];
19
+ }
20
+ if (authorization) {
21
+ const [prefix, token] = authorization.split(' ');
22
+ if (prefix.toLowerCase() !== 'api-key' || !token) {
23
+ throw new CustomError({
24
+ httpCode: 401,
25
+ message: 'Authorization should be an Api-Key',
26
+ });
27
+ }
28
+ socket.handshake.auth.token = token;
29
+ }
30
+ }
31
+ let keySecret = socket.handshake.auth.token;
32
+ if (!keySecret) {
33
+ throw new CustomError({ httpCode: 401, message: 'Token not available' });
34
+ }
35
+ try {
36
+ const authInfo = await this.apiKeyRepository.findAuthInfoBySecret(keySecret);
37
+ if (!authInfo) {
38
+ throw new CustomError({ httpCode: 401, message: 'Invalid token' });
39
+ }
40
+ this.auth.assign(authInfo);
41
+ }
42
+ catch (err) {
43
+ throw new CustomError({
44
+ httpCode: 401,
45
+ message: err instanceof Error ? `Invalid token: ${err.message}` : 'Invalid token',
46
+ cause: err instanceof Error ? err : undefined,
47
+ });
48
+ }
49
+ }
50
+ };
51
+ ApiKeyConnectionGuardMiddleware = __decorate([
52
+ injectable(),
53
+ __metadata("design:paramtypes", [ApiKeyRepository,
54
+ Auth])
55
+ ], ApiKeyConnectionGuardMiddleware);
56
+
57
+ export { ApiKeyConnectionGuardMiddleware };
@@ -0,0 +1,45 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { injectable } from '../../../core/injection/index.js';
3
+ import { Auth } from '../../../core/auth/Auth.js';
4
+ import { CustomError } from '../../../core/error/CustomError.js';
5
+ import { ApiKeyRepository } from './ApiKeyRepository.js';
6
+
7
+ let ApiKeyGuardMiddleware = class ApiKeyGuardMiddleware {
8
+ apiKeyRepository;
9
+ auth;
10
+ constructor(apiKeyRepository, auth) {
11
+ this.apiKeyRepository = apiKeyRepository;
12
+ this.auth = auth;
13
+ }
14
+ async handle(req, res, container) {
15
+ const authorization = req.header('Authorization');
16
+ if (!authorization) {
17
+ throw new CustomError({ httpCode: 401, message: 'Authorization header not available' });
18
+ }
19
+ const [keyPrefix, keySecret] = authorization.split(' ');
20
+ if (keyPrefix.toLowerCase() !== 'api-key' || !keySecret) {
21
+ throw new CustomError({ httpCode: 401, message: 'Authorization should be an Api-Key' });
22
+ }
23
+ try {
24
+ const authInfo = await this.apiKeyRepository.findAuthInfoBySecret(keySecret);
25
+ if (!authInfo) {
26
+ throw new CustomError({ httpCode: 401, message: 'Invalid key' });
27
+ }
28
+ this.auth.assign(authInfo);
29
+ }
30
+ catch (err) {
31
+ throw new CustomError({
32
+ httpCode: 401,
33
+ message: err instanceof Error ? `Invalid key: ${err.message}` : 'Invalid key',
34
+ cause: err instanceof Error ? err : undefined,
35
+ });
36
+ }
37
+ }
38
+ };
39
+ ApiKeyGuardMiddleware = __decorate([
40
+ injectable(),
41
+ __metadata("design:paramtypes", [ApiKeyRepository,
42
+ Auth])
43
+ ], ApiKeyGuardMiddleware);
44
+
45
+ export { ApiKeyGuardMiddleware };
@@ -0,0 +1,22 @@
1
+ class ApiKeyRepository {
2
+ findAuthInfoBySecret(secret) {
3
+ throw new Error('Method not implemented.');
4
+ }
5
+ findByMetadata(metadata) {
6
+ throw new Error('Method not implemented.');
7
+ }
8
+ find(id) {
9
+ throw new Error('Method not implemented.');
10
+ }
11
+ findOrThrow(id) {
12
+ throw new Error('Method not implemented.');
13
+ }
14
+ create(item) {
15
+ throw new Error('Method not implemented.');
16
+ }
17
+ generate(req) {
18
+ throw new Error('Method not implemented.');
19
+ }
20
+ }
21
+
22
+ export { ApiKeyRepository };
@@ -0,0 +1,53 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { PgCrudRepository } from '../../../feature/pg/PgCrudRepository.js';
3
+ import { Pool } from 'pg';
4
+ import { singleton } from 'tsyringe';
5
+ import { ApiKey } from './ApiKey.js';
6
+
7
+ let PgApiKeyRepository = class PgApiKeyRepository extends PgCrudRepository {
8
+ constructor(pool) {
9
+ super(pool, {
10
+ schema: 'wabot',
11
+ table: 'api_key',
12
+ constructor: ApiKey,
13
+ });
14
+ }
15
+ async findAuthInfoBySecret(secret) {
16
+ const secretHash = ApiKey.hashSecret(secret);
17
+ const query = `
18
+ SELECT ${this.columns}
19
+ FROM ${this.table}
20
+ WHERE data @> $1::jsonb
21
+ LIMIT 1
22
+ `;
23
+ const items = await this.query(query, [JSON.stringify({ secretHash })]);
24
+ return items[0]?.authInfo ?? null;
25
+ }
26
+ async findByMetadata(metadata) {
27
+ const query = `
28
+ SELECT ${this.columns}
29
+ FROM ${this.table}
30
+ WHERE data @> $1::jsonb
31
+ `;
32
+ return await this.query(query, [JSON.stringify({ metadata })]);
33
+ }
34
+ async generate(req) {
35
+ const apiKey = new ApiKey({
36
+ name: req.name,
37
+ metadata: req.metadata,
38
+ authInfo: req.authInfo,
39
+ });
40
+ const secret = apiKey.generateSecret();
41
+ await this.create(apiKey);
42
+ return {
43
+ apiKey,
44
+ secret,
45
+ };
46
+ }
47
+ };
48
+ PgApiKeyRepository = __decorate([
49
+ singleton(),
50
+ __metadata("design:paramtypes", [Pool])
51
+ ], PgApiKeyRepository);
52
+
53
+ export { PgApiKeyRepository };
@@ -0,0 +1,62 @@
1
+ import { CustomError } from '../../../core/error/CustomError.js';
2
+
3
+ class RemoteApiKeyRepository {
4
+ fetcher;
5
+ cacheSeconds;
6
+ cacheById = new Map();
7
+ cacheBySecret = new Map();
8
+ constructor(fetcher, cacheSeconds) {
9
+ this.fetcher = fetcher;
10
+ this.cacheSeconds = cacheSeconds;
11
+ }
12
+ async find(id) {
13
+ const now = Date.now();
14
+ const cached = this.cacheById.get(id);
15
+ if (cached && cached.expiresAt > now) {
16
+ return cached.value;
17
+ }
18
+ const result = await this.fetcher.fetchById(id);
19
+ this.cacheById.set(id, {
20
+ value: result,
21
+ expiresAt: now + this.cacheSeconds * 1000,
22
+ });
23
+ return result;
24
+ }
25
+ async findOrThrow(id) {
26
+ const result = await this.find(id);
27
+ if (!result) {
28
+ throw new Error(`API key with ID '${id}' not found.`);
29
+ }
30
+ return result;
31
+ }
32
+ async findAuthInfoBySecret(secret) {
33
+ const now = Date.now();
34
+ const cached = this.cacheBySecret.get(secret);
35
+ if (cached && cached.expiresAt > now) {
36
+ if (!cached.value) {
37
+ throw new CustomError({ message: 'Invalid Api Key', httpCode: 401 });
38
+ }
39
+ return cached.value.authInfo;
40
+ }
41
+ const result = await this.fetcher.fetchBySecret(secret);
42
+ this.cacheBySecret.set(secret, {
43
+ value: result,
44
+ expiresAt: now + this.cacheSeconds * 1000,
45
+ });
46
+ if (!result) {
47
+ throw new CustomError({ message: 'Invalid Api Key', httpCode: 401 });
48
+ }
49
+ return result.authInfo;
50
+ }
51
+ findByMetadata(metadata) {
52
+ throw new Error('Method not implemented.');
53
+ }
54
+ create(item) {
55
+ throw new Error('Method not implemented.');
56
+ }
57
+ generate(req) {
58
+ throw new Error('Method not implemented.');
59
+ }
60
+ }
61
+
62
+ export { RemoteApiKeyRepository };
@@ -0,0 +1,16 @@
1
+ import { connectionMiddleware } from '../../../feature/socket-controller/metadata/@connectionMiddleware.js';
2
+ import '../../../core/injection/index.js';
3
+ import '../../../feature/socket-controller/metadata/SocketControllerMetadataStore.js';
4
+ import 'path';
5
+ import 'debug';
6
+ import '../../../feature/socket/SocketServerProvider.js';
7
+ import '../../../core/validation/metadata/ValidationMetadataStore.js';
8
+ import { JwtConnectionGuardMiddleware } from './JwtConnectionGuardMiddleware.js';
9
+
10
+ function jwtConnectionGuard() {
11
+ return function (target, propertyKey) {
12
+ connectionMiddleware(JwtConnectionGuardMiddleware)(target, propertyKey);
13
+ };
14
+ }
15
+
16
+ export { jwtConnectionGuard };
@@ -0,0 +1,17 @@
1
+ import '../../../core/injection/index.js';
2
+ import '../../../feature/rest-controller/metadata/RestControllerMetadataStore.js';
3
+ import { middleware } from '../../../feature/rest-controller/metadata/@middleware.js';
4
+ import 'debug';
5
+ import '../../../core/validation/metadata/ValidationMetadataStore.js';
6
+ import '../../../feature/express/ExpressProvider.js';
7
+ import 'express';
8
+ import 'path';
9
+ import { JwtGuardMiddleware } from './JwtGuardMiddleware.js';
10
+
11
+ function jwtGuard() {
12
+ return function (target, propertyKey) {
13
+ middleware(JwtGuardMiddleware)(target, propertyKey);
14
+ };
15
+ }
16
+
17
+ export { jwtGuard };
@@ -0,0 +1,53 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { JwtSigner } from './JwtSigner.js';
3
+ import { JwtRefreshTokenRepository } from './JwtRefreshTokenRepository.js';
4
+ import { JwtRefreshToken } from './JwtRefreshToken.js';
5
+ import { injectable } from '../../../core/injection/index.js';
6
+ import { Auth } from '../../../core/auth/Auth.js';
7
+ import { JwtConfig } from './JwtConfig.js';
8
+
9
+ let Jwt = class Jwt {
10
+ auth;
11
+ jwtSigner;
12
+ jwtRefreshTokenRepository;
13
+ config;
14
+ constructor(auth, jwtSigner, jwtRefreshTokenRepository, config) {
15
+ this.auth = auth;
16
+ this.jwtSigner = jwtSigner;
17
+ this.jwtRefreshTokenRepository = jwtRefreshTokenRepository;
18
+ this.config = config;
19
+ }
20
+ async createToken() {
21
+ const authInfo = this.auth.require();
22
+ const refreshToken = new JwtRefreshToken({
23
+ authInfo,
24
+ expirationTime: new Date().getTime() + this.config.refreshExpirationSeconds * 1000,
25
+ });
26
+ const refreshPassword = refreshToken.generatePassword();
27
+ await this.jwtRefreshTokenRepository.create(refreshToken);
28
+ const access = await this.jwtSigner.signAccessToken(refreshToken);
29
+ const refresh = {
30
+ token: JwtRefreshToken.deflate({ id: refreshToken.id, pass: refreshPassword }),
31
+ expiration: new Date(refreshToken.expirationTime),
32
+ };
33
+ return {
34
+ access,
35
+ refresh,
36
+ };
37
+ }
38
+ async refreshToken(refreshSecret) {
39
+ const { id, pass } = JwtRefreshToken.inflate(refreshSecret);
40
+ const refreshToken = await this.jwtRefreshTokenRepository.findOrThrow(id);
41
+ refreshToken.validatePassword(pass);
42
+ return this.jwtSigner.signAccessToken(refreshToken);
43
+ }
44
+ };
45
+ Jwt = __decorate([
46
+ injectable(),
47
+ __metadata("design:paramtypes", [Auth,
48
+ JwtSigner,
49
+ JwtRefreshTokenRepository,
50
+ JwtConfig])
51
+ ], Jwt);
52
+
53
+ export { Jwt };
@@ -0,0 +1,20 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { isModel } from '../../../core/validation/metadata/@isModel.js';
3
+ import '../../../core/injection/index.js';
4
+ import '../../../core/validation/metadata/ValidationMetadataStore.js';
5
+ import { JwtTokenDto } from './JwtTokenDto.js';
6
+
7
+ class JwtAccessAndRefreshTokenDto {
8
+ access;
9
+ refresh;
10
+ }
11
+ __decorate([
12
+ isModel(JwtTokenDto),
13
+ __metadata("design:type", JwtTokenDto)
14
+ ], JwtAccessAndRefreshTokenDto.prototype, "access", void 0);
15
+ __decorate([
16
+ isModel(JwtTokenDto),
17
+ __metadata("design:type", JwtTokenDto)
18
+ ], JwtAccessAndRefreshTokenDto.prototype, "refresh", void 0);
19
+
20
+ export { JwtAccessAndRefreshTokenDto };
@@ -0,0 +1,28 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { Env } from '../../../core/env/Env.js';
3
+ import { singleton } from '../../../core/injection/index.js';
4
+
5
+ let JwtConfig = class JwtConfig {
6
+ secretOrPublicKey;
7
+ secretOrPrivateKey;
8
+ algorithm;
9
+ accessExpirationSeconds;
10
+ refreshExpirationSeconds;
11
+ constructor(env) {
12
+ this.algorithm = env.requireString('JWT_ALGORITHM', { default: 'HS256' });
13
+ this.secretOrPublicKey = env.requireString('JWT_SECRET');
14
+ this.secretOrPrivateKey = env.requireString('JWT_SECRET');
15
+ this.accessExpirationSeconds = env.requireNumber('JWT_ACCESS_EXPIRATION_SECONDS', {
16
+ default: 10 * 60,
17
+ });
18
+ this.refreshExpirationSeconds = env.requireNumber('JWT_REFRESH_EXPIRATION_SECONDS', {
19
+ default: 365 * 24 * 3600,
20
+ });
21
+ }
22
+ };
23
+ JwtConfig = __decorate([
24
+ singleton(),
25
+ __metadata("design:paramtypes", [Env])
26
+ ], JwtConfig);
27
+
28
+ export { JwtConfig };
@@ -0,0 +1,57 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import jwt from 'jsonwebtoken';
3
+ import { injectable } from '../../../core/injection/index.js';
4
+ import { Auth } from '../../../core/auth/Auth.js';
5
+ import { CustomError } from '../../../core/error/CustomError.js';
6
+ import { JwtConfig } from './JwtConfig.js';
7
+
8
+ let JwtConnectionGuardMiddleware = class JwtConnectionGuardMiddleware {
9
+ config;
10
+ auth;
11
+ constructor(config, auth) {
12
+ this.config = config;
13
+ this.auth = auth;
14
+ }
15
+ async handle(socket, container) {
16
+ if (!socket.handshake.auth.token) {
17
+ let authorization = socket.handshake.headers['Authorization'] ?? socket.handshake.headers['authorization'];
18
+ if (Array.isArray(authorization)) {
19
+ authorization = authorization[0];
20
+ }
21
+ if (authorization) {
22
+ const [prefix, token] = authorization.split(' ');
23
+ if (prefix.toLowerCase() !== 'bearer' || !token) {
24
+ throw new CustomError({
25
+ httpCode: 401,
26
+ message: 'Authorization should be a bearer token',
27
+ });
28
+ }
29
+ socket.handshake.auth.token = token;
30
+ }
31
+ }
32
+ let token = socket.handshake.auth.token;
33
+ if (!token) {
34
+ throw new CustomError({ httpCode: 401, message: 'Token not available' });
35
+ }
36
+ try {
37
+ const jwtPayload = jwt.verify(token, this.config.secretOrPublicKey, {
38
+ algorithms: [this.config.algorithm],
39
+ });
40
+ this.auth.assign(jwtPayload);
41
+ }
42
+ catch (err) {
43
+ throw new CustomError({
44
+ httpCode: 401,
45
+ message: err instanceof Error ? `Invalid token: ${err.message}` : 'Invalid token',
46
+ cause: err instanceof Error ? err : undefined,
47
+ });
48
+ }
49
+ }
50
+ };
51
+ JwtConnectionGuardMiddleware = __decorate([
52
+ injectable(),
53
+ __metadata("design:paramtypes", [JwtConfig,
54
+ Auth])
55
+ ], JwtConnectionGuardMiddleware);
56
+
57
+ export { JwtConnectionGuardMiddleware };
@@ -0,0 +1,45 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { CustomError } from '../../../core/error/CustomError.js';
3
+ import { injectable } from '../../../core/injection/index.js';
4
+ import jwt from 'jsonwebtoken';
5
+ import { Auth } from '../../../core/auth/Auth.js';
6
+ import { JwtConfig } from './JwtConfig.js';
7
+
8
+ let JwtGuardMiddleware = class JwtGuardMiddleware {
9
+ config;
10
+ auth;
11
+ constructor(config, auth) {
12
+ this.config = config;
13
+ this.auth = auth;
14
+ }
15
+ async handle(req, res, container) {
16
+ const authorization = req.header('Authorization');
17
+ if (!authorization) {
18
+ throw new CustomError({ httpCode: 401, message: 'Authorization header not available' });
19
+ }
20
+ const [bearer, token] = authorization.split(' ');
21
+ if (bearer.toLowerCase() !== 'bearer' || !token) {
22
+ throw new CustomError({ httpCode: 401, message: 'Authorization should be a bearer token' });
23
+ }
24
+ try {
25
+ const jwtPayload = jwt.verify(token, this.config.secretOrPublicKey, {
26
+ algorithms: [this.config.algorithm],
27
+ });
28
+ this.auth.assign(jwtPayload);
29
+ }
30
+ catch (err) {
31
+ throw new CustomError({
32
+ httpCode: 401,
33
+ message: err instanceof Error ? `Invalid token: ${err.message}` : 'Invalid token',
34
+ cause: err instanceof Error ? err : undefined,
35
+ });
36
+ }
37
+ }
38
+ };
39
+ JwtGuardMiddleware = __decorate([
40
+ injectable(),
41
+ __metadata("design:paramtypes", [JwtConfig,
42
+ Auth])
43
+ ], JwtGuardMiddleware);
44
+
45
+ export { JwtGuardMiddleware };
@@ -0,0 +1,56 @@
1
+ import { Entity } from '../../../core/entity/Entity.js';
2
+ import { CustomError } from '../../../core/error/CustomError.js';
3
+ import { Password } from '../../../core/password/Password.js';
4
+
5
+ class JwtRefreshToken extends Entity {
6
+ get authInfo() {
7
+ return this.data.authInfo;
8
+ }
9
+ get expirationTime() {
10
+ return new Date(this.data.expirationTime);
11
+ }
12
+ generatePassword() {
13
+ if (this.data.passwordHash) {
14
+ throw new Error('This api key, already has a secret');
15
+ }
16
+ const password = Password.generate(64);
17
+ this.data.passwordHash = Password.hash({ password: password });
18
+ return password;
19
+ }
20
+ isValidPassword(password) {
21
+ if (new Date().getTime() > this.data.expirationTime) {
22
+ return false;
23
+ }
24
+ if (!this.data.passwordHash)
25
+ return false;
26
+ return Password.isValid({ password: password, hash: this.data.passwordHash });
27
+ }
28
+ validatePassword(password) {
29
+ if (!this.isValidPassword(password)) {
30
+ throw new CustomError({ message: 'Invalid Api key', httpCode: 401 });
31
+ }
32
+ }
33
+ static inflate(secret) {
34
+ try {
35
+ const json = Buffer.from(secret, 'base64').toString('utf-8');
36
+ const data = JSON.parse(json);
37
+ if (!data.id || !data.pass) {
38
+ throw new Error('invalid secret structure');
39
+ }
40
+ return data;
41
+ }
42
+ catch (err) {
43
+ throw new Error('fail to inflate secret: ' + err.message);
44
+ }
45
+ }
46
+ static deflate(data) {
47
+ const { id, pass } = data;
48
+ if (!id || !pass) {
49
+ throw new Error('id and pass required');
50
+ }
51
+ const json = JSON.stringify({ id, pass });
52
+ return Buffer.from(json, 'utf-8').toString('base64');
53
+ }
54
+ }
55
+
56
+ export { JwtRefreshToken };