@brightchain/brightchain-api-lib 0.14.0 → 0.15.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 (242) hide show
  1. package/package.json +5 -5
  2. package/src/index.d.ts +3 -0
  3. package/src/index.d.ts.map +1 -1
  4. package/src/index.js +5 -0
  5. package/src/index.js.map +1 -1
  6. package/src/lib/application.d.ts +1 -0
  7. package/src/lib/application.d.ts.map +1 -1
  8. package/src/lib/application.js +23 -0
  9. package/src/lib/application.js.map +1 -1
  10. package/src/lib/auth/aclEnforcedAvailability.d.ts +57 -0
  11. package/src/lib/auth/aclEnforcedAvailability.d.ts.map +1 -0
  12. package/src/lib/auth/aclEnforcedAvailability.js +87 -0
  13. package/src/lib/auth/aclEnforcedAvailability.js.map +1 -0
  14. package/src/lib/auth/aclEnforcedBlockStore.d.ts +66 -0
  15. package/src/lib/auth/aclEnforcedBlockStore.d.ts.map +1 -0
  16. package/src/lib/auth/aclEnforcedBlockStore.js +83 -0
  17. package/src/lib/auth/aclEnforcedBlockStore.js.map +1 -0
  18. package/src/lib/auth/ecdsaNodeAuthenticator.d.ts +46 -0
  19. package/src/lib/auth/ecdsaNodeAuthenticator.d.ts.map +1 -0
  20. package/src/lib/auth/ecdsaNodeAuthenticator.js +110 -0
  21. package/src/lib/auth/ecdsaNodeAuthenticator.js.map +1 -0
  22. package/src/lib/auth/index.d.ts +7 -0
  23. package/src/lib/auth/index.d.ts.map +1 -0
  24. package/src/lib/auth/index.js +13 -0
  25. package/src/lib/auth/index.js.map +1 -0
  26. package/src/lib/auth/poolAclBootstrap.d.ts +36 -0
  27. package/src/lib/auth/poolAclBootstrap.d.ts.map +1 -0
  28. package/src/lib/auth/poolAclBootstrap.js +64 -0
  29. package/src/lib/auth/poolAclBootstrap.js.map +1 -0
  30. package/src/lib/auth/poolAclStore.d.ts +77 -0
  31. package/src/lib/auth/poolAclStore.d.ts.map +1 -0
  32. package/src/lib/auth/poolAclStore.js +189 -0
  33. package/src/lib/auth/poolAclStore.js.map +1 -0
  34. package/src/lib/auth/poolAclUpdater.d.ts +79 -0
  35. package/src/lib/auth/poolAclUpdater.d.ts.map +1 -0
  36. package/src/lib/auth/poolAclUpdater.js +144 -0
  37. package/src/lib/auth/poolAclUpdater.js.map +1 -0
  38. package/src/lib/availability/availabilityService.d.ts +2 -2
  39. package/src/lib/availability/availabilityService.d.ts.map +1 -1
  40. package/src/lib/availability/availabilityService.js +12 -5
  41. package/src/lib/availability/availabilityService.js.map +1 -1
  42. package/src/lib/availability/blockRegistry.d.ts +45 -3
  43. package/src/lib/availability/blockRegistry.d.ts.map +1 -1
  44. package/src/lib/availability/blockRegistry.js +123 -5
  45. package/src/lib/availability/blockRegistry.js.map +1 -1
  46. package/src/lib/availability/discoveryProtocol.d.ts +30 -1
  47. package/src/lib/availability/discoveryProtocol.d.ts.map +1 -1
  48. package/src/lib/availability/discoveryProtocol.js +76 -0
  49. package/src/lib/availability/discoveryProtocol.js.map +1 -1
  50. package/src/lib/availability/gossipService.d.ts +45 -6
  51. package/src/lib/availability/gossipService.d.ts.map +1 -1
  52. package/src/lib/availability/gossipService.js +177 -5
  53. package/src/lib/availability/gossipService.js.map +1 -1
  54. package/src/lib/availability/reconciliationService.d.ts +88 -1
  55. package/src/lib/availability/reconciliationService.d.ts.map +1 -1
  56. package/src/lib/availability/reconciliationService.js +246 -48
  57. package/src/lib/availability/reconciliationService.js.map +1 -1
  58. package/src/lib/blockFetch/blockFetcher.d.ts +100 -0
  59. package/src/lib/blockFetch/blockFetcher.d.ts.map +1 -0
  60. package/src/lib/blockFetch/blockFetcher.js +279 -0
  61. package/src/lib/blockFetch/blockFetcher.js.map +1 -0
  62. package/src/lib/blockFetch/fetchQueue.d.ts +88 -0
  63. package/src/lib/blockFetch/fetchQueue.d.ts.map +1 -0
  64. package/src/lib/blockFetch/fetchQueue.js +204 -0
  65. package/src/lib/blockFetch/fetchQueue.js.map +1 -0
  66. package/src/lib/blockFetch/httpBlockFetchTransport.d.ts +65 -0
  67. package/src/lib/blockFetch/httpBlockFetchTransport.d.ts.map +1 -0
  68. package/src/lib/blockFetch/httpBlockFetchTransport.js +104 -0
  69. package/src/lib/blockFetch/httpBlockFetchTransport.js.map +1 -0
  70. package/src/lib/blockFetch/index.d.ts +10 -0
  71. package/src/lib/blockFetch/index.d.ts.map +1 -0
  72. package/src/lib/blockFetch/index.js +13 -0
  73. package/src/lib/blockFetch/index.js.map +1 -0
  74. package/src/lib/controllers/api/brightpass.d.ts +72 -0
  75. package/src/lib/controllers/api/brightpass.d.ts.map +1 -0
  76. package/src/lib/controllers/api/brightpass.js +577 -0
  77. package/src/lib/controllers/api/brightpass.js.map +1 -0
  78. package/src/lib/controllers/api/channels.d.ts +122 -0
  79. package/src/lib/controllers/api/channels.d.ts.map +1 -0
  80. package/src/lib/controllers/api/channels.js +701 -0
  81. package/src/lib/controllers/api/channels.js.map +1 -0
  82. package/src/lib/controllers/api/conversations.d.ts +89 -0
  83. package/src/lib/controllers/api/conversations.d.ts.map +1 -0
  84. package/src/lib/controllers/api/conversations.js +259 -0
  85. package/src/lib/controllers/api/conversations.js.map +1 -0
  86. package/src/lib/controllers/api/emails.d.ts +122 -0
  87. package/src/lib/controllers/api/emails.d.ts.map +1 -0
  88. package/src/lib/controllers/api/emails.js +494 -0
  89. package/src/lib/controllers/api/emails.js.map +1 -0
  90. package/src/lib/controllers/api/explodingMessages.d.ts +79 -0
  91. package/src/lib/controllers/api/explodingMessages.d.ts.map +1 -0
  92. package/src/lib/controllers/api/explodingMessages.js +378 -0
  93. package/src/lib/controllers/api/explodingMessages.js.map +1 -0
  94. package/src/lib/controllers/api/groups.d.ts +94 -0
  95. package/src/lib/controllers/api/groups.d.ts.map +1 -0
  96. package/src/lib/controllers/api/groups.js +484 -0
  97. package/src/lib/controllers/api/groups.js.map +1 -0
  98. package/src/lib/controllers/api/index.d.ts +6 -0
  99. package/src/lib/controllers/api/index.d.ts.map +1 -1
  100. package/src/lib/controllers/api/index.js +6 -0
  101. package/src/lib/controllers/api/index.js.map +1 -1
  102. package/src/lib/controllers/api/messages.d.ts.map +1 -1
  103. package/src/lib/controllers/api/messages.js +2 -1
  104. package/src/lib/controllers/api/messages.js.map +1 -1
  105. package/src/lib/controllers/api/sync.d.ts +38 -2
  106. package/src/lib/controllers/api/sync.d.ts.map +1 -1
  107. package/src/lib/controllers/api/sync.js +89 -0
  108. package/src/lib/controllers/api/sync.js.map +1 -1
  109. package/src/lib/controllers/crypto/gitController.d.ts +70 -0
  110. package/src/lib/controllers/crypto/gitController.d.ts.map +1 -0
  111. package/src/lib/controllers/crypto/gitController.js +306 -0
  112. package/src/lib/controllers/crypto/gitController.js.map +1 -0
  113. package/src/lib/controllers/crypto/index.d.ts +3 -0
  114. package/src/lib/controllers/crypto/index.d.ts.map +1 -0
  115. package/src/lib/controllers/crypto/index.js +6 -0
  116. package/src/lib/controllers/crypto/index.js.map +1 -0
  117. package/src/lib/controllers/crypto/walletController.d.ts +64 -0
  118. package/src/lib/controllers/crypto/walletController.d.ts.map +1 -0
  119. package/src/lib/controllers/crypto/walletController.js +260 -0
  120. package/src/lib/controllers/crypto/walletController.js.map +1 -0
  121. package/src/lib/controllers/identity/deviceController.d.ts +96 -0
  122. package/src/lib/controllers/identity/deviceController.d.ts.map +1 -0
  123. package/src/lib/controllers/identity/deviceController.js +355 -0
  124. package/src/lib/controllers/identity/deviceController.js.map +1 -0
  125. package/src/lib/controllers/identity/directoryController.d.ts +75 -0
  126. package/src/lib/controllers/identity/directoryController.d.ts.map +1 -0
  127. package/src/lib/controllers/identity/directoryController.js +288 -0
  128. package/src/lib/controllers/identity/directoryController.js.map +1 -0
  129. package/src/lib/controllers/identity/identityProofController.d.ts +94 -0
  130. package/src/lib/controllers/identity/identityProofController.d.ts.map +1 -0
  131. package/src/lib/controllers/identity/identityProofController.js +454 -0
  132. package/src/lib/controllers/identity/identityProofController.js.map +1 -0
  133. package/src/lib/controllers/identity/index.d.ts +4 -0
  134. package/src/lib/controllers/identity/index.d.ts.map +1 -0
  135. package/src/lib/controllers/identity/index.js +7 -0
  136. package/src/lib/controllers/identity/index.js.map +1 -0
  137. package/src/lib/controllers/index.d.ts +2 -0
  138. package/src/lib/controllers/index.d.ts.map +1 -1
  139. package/src/lib/controllers/index.js +2 -0
  140. package/src/lib/controllers/index.js.map +1 -1
  141. package/src/lib/encryption/encryptedMetadataService.d.ts +87 -0
  142. package/src/lib/encryption/encryptedMetadataService.d.ts.map +1 -0
  143. package/src/lib/encryption/encryptedMetadataService.js +224 -0
  144. package/src/lib/encryption/encryptedMetadataService.js.map +1 -0
  145. package/src/lib/encryption/encryptionAwareReplication.d.ts +76 -0
  146. package/src/lib/encryption/encryptionAwareReplication.d.ts.map +1 -0
  147. package/src/lib/encryption/encryptionAwareReplication.js +116 -0
  148. package/src/lib/encryption/encryptionAwareReplication.js.map +1 -0
  149. package/src/lib/encryption/errors.d.ts +49 -0
  150. package/src/lib/encryption/errors.d.ts.map +1 -0
  151. package/src/lib/encryption/errors.js +80 -0
  152. package/src/lib/encryption/errors.js.map +1 -0
  153. package/src/lib/encryption/index.d.ts +6 -0
  154. package/src/lib/encryption/index.d.ts.map +1 -0
  155. package/src/lib/encryption/index.js +9 -0
  156. package/src/lib/encryption/index.js.map +1 -0
  157. package/src/lib/encryption/poolEncryptionService.d.ts +94 -0
  158. package/src/lib/encryption/poolEncryptionService.d.ts.map +1 -0
  159. package/src/lib/encryption/poolEncryptionService.js +252 -0
  160. package/src/lib/encryption/poolEncryptionService.js.map +1 -0
  161. package/src/lib/encryption/poolKeyManager.d.ts +82 -0
  162. package/src/lib/encryption/poolKeyManager.d.ts.map +1 -0
  163. package/src/lib/encryption/poolKeyManager.js +156 -0
  164. package/src/lib/encryption/poolKeyManager.js.map +1 -0
  165. package/src/lib/environment.d.ts +3 -0
  166. package/src/lib/environment.d.ts.map +1 -1
  167. package/src/lib/environment.js +5 -0
  168. package/src/lib/environment.js.map +1 -1
  169. package/src/lib/interfaces/environment.d.ts +7 -1
  170. package/src/lib/interfaces/environment.d.ts.map +1 -1
  171. package/src/lib/interfaces/index.d.ts +0 -1
  172. package/src/lib/interfaces/index.d.ts.map +1 -1
  173. package/src/lib/interfaces/requests/getBlockDataRequest.d.ts +12 -0
  174. package/src/lib/interfaces/requests/getBlockDataRequest.d.ts.map +1 -0
  175. package/src/lib/interfaces/{blockStore.js → requests/getBlockDataRequest.js} +1 -1
  176. package/src/lib/interfaces/requests/getBlockDataRequest.js.map +1 -0
  177. package/src/lib/interfaces/requests/index.d.ts +1 -0
  178. package/src/lib/interfaces/requests/index.d.ts.map +1 -1
  179. package/src/lib/routers/api.d.ts +54 -1
  180. package/src/lib/routers/api.d.ts.map +1 -1
  181. package/src/lib/routers/api.js +77 -0
  182. package/src/lib/routers/api.js.map +1 -1
  183. package/src/lib/services/blockStore.d.ts +5 -2
  184. package/src/lib/services/blockStore.d.ts.map +1 -1
  185. package/src/lib/services/blockStore.js +4 -0
  186. package/src/lib/services/blockStore.js.map +1 -1
  187. package/src/lib/services/brightpass/auditLogger.d.ts +77 -0
  188. package/src/lib/services/brightpass/auditLogger.d.ts.map +1 -0
  189. package/src/lib/services/brightpass/auditLogger.js +184 -0
  190. package/src/lib/services/brightpass/auditLogger.js.map +1 -0
  191. package/src/lib/services/brightpass/vaultEncryption.d.ts +82 -0
  192. package/src/lib/services/brightpass/vaultEncryption.d.ts.map +1 -0
  193. package/src/lib/services/brightpass/vaultEncryption.js +144 -0
  194. package/src/lib/services/brightpass/vaultEncryption.js.map +1 -0
  195. package/src/lib/services/brightpass.d.ts +294 -0
  196. package/src/lib/services/brightpass.d.ts.map +1 -0
  197. package/src/lib/services/brightpass.js +1260 -0
  198. package/src/lib/services/brightpass.js.map +1 -0
  199. package/src/lib/services/eventNotificationSystem.d.ts +69 -3
  200. package/src/lib/services/eventNotificationSystem.d.ts.map +1 -1
  201. package/src/lib/services/eventNotificationSystem.js +200 -0
  202. package/src/lib/services/eventNotificationSystem.js.map +1 -1
  203. package/src/lib/services/expirationScheduler.d.ts +90 -0
  204. package/src/lib/services/expirationScheduler.d.ts.map +1 -0
  205. package/src/lib/services/expirationScheduler.js +131 -0
  206. package/src/lib/services/expirationScheduler.js.map +1 -0
  207. package/src/lib/services/fecUsageExample.d.ts +2 -2
  208. package/src/lib/services/index.d.ts +2 -0
  209. package/src/lib/services/index.d.ts.map +1 -1
  210. package/src/lib/services/index.js +2 -0
  211. package/src/lib/services/index.js.map +1 -1
  212. package/src/lib/services/paginationService.d.ts +18 -0
  213. package/src/lib/services/paginationService.d.ts.map +1 -0
  214. package/src/lib/services/paginationService.js +32 -0
  215. package/src/lib/services/paginationService.js.map +1 -0
  216. package/src/lib/services/presenceService.d.ts +76 -0
  217. package/src/lib/services/presenceService.d.ts.map +1 -0
  218. package/src/lib/services/presenceService.js +143 -0
  219. package/src/lib/services/presenceService.js.map +1 -0
  220. package/src/lib/services/wireConversationPromotion.d.ts +23 -0
  221. package/src/lib/services/wireConversationPromotion.d.ts.map +1 -0
  222. package/src/lib/services/wireConversationPromotion.js +26 -0
  223. package/src/lib/services/wireConversationPromotion.js.map +1 -0
  224. package/src/lib/stores/availabilityAwareBlockStore.d.ts +115 -10
  225. package/src/lib/stores/availabilityAwareBlockStore.d.ts.map +1 -1
  226. package/src/lib/stores/availabilityAwareBlockStore.js +267 -23
  227. package/src/lib/stores/availabilityAwareBlockStore.js.map +1 -1
  228. package/src/lib/stores/diskBlockAsyncStore.d.ts +81 -2
  229. package/src/lib/stores/diskBlockAsyncStore.d.ts.map +1 -1
  230. package/src/lib/stores/diskBlockAsyncStore.js +297 -10
  231. package/src/lib/stores/diskBlockAsyncStore.js.map +1 -1
  232. package/src/lib/utils/communicationValidation.d.ts +44 -0
  233. package/src/lib/utils/communicationValidation.d.ts.map +1 -0
  234. package/src/lib/utils/communicationValidation.js +291 -0
  235. package/src/lib/utils/communicationValidation.js.map +1 -0
  236. package/src/lib/utils/emailValidation.d.ts +19 -0
  237. package/src/lib/utils/emailValidation.d.ts.map +1 -0
  238. package/src/lib/utils/emailValidation.js +232 -0
  239. package/src/lib/utils/emailValidation.js.map +1 -0
  240. package/src/lib/interfaces/blockStore.d.ts +0 -7
  241. package/src/lib/interfaces/blockStore.d.ts.map +0 -1
  242. package/src/lib/interfaces/blockStore.js.map +0 -1
@@ -0,0 +1,701 @@
1
+ "use strict";
2
+ /**
3
+ * ChannelController — REST API for channel management.
4
+ *
5
+ * Routes:
6
+ * POST / — Create a channel
7
+ * GET / — List discoverable channels
8
+ * GET /:channelId — Get channel metadata
9
+ * PUT /:channelId — Update channel settings
10
+ * DELETE /:channelId — Delete channel
11
+ * POST /:channelId/join — Join a channel
12
+ * POST /:channelId/leave — Leave a channel
13
+ * POST /:channelId/messages — Send message
14
+ * GET /:channelId/messages — Get message history
15
+ * GET /:channelId/messages/search — Search messages
16
+ * POST /:channelId/invites — Generate invite token
17
+ * POST /:channelId/invites/:token/redeem — Redeem invite token
18
+ * PUT /:channelId/roles/:memberId — Assign role
19
+ * POST /:channelId/messages/:messageId/reactions — Add reaction
20
+ * DELETE /:channelId/messages/:messageId/reactions/:reactionId — Remove reaction
21
+ * PUT /:channelId/messages/:messageId — Edit message
22
+ * POST /:channelId/messages/:messageId/pin — Pin message
23
+ * DELETE /:channelId/messages/:messageId/pin — Unpin message
24
+ * POST /:channelId/mute/:memberId — Mute a member
25
+ * POST /:channelId/kick/:memberId — Kick a member
26
+ *
27
+ * Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 5.1, 5.2, 5.3, 5.4, 5.5
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.ChannelController = void 0;
31
+ const channelService_1 = require("@brightchain/brightchain-lib/lib/services/communication/channelService");
32
+ const node_express_suite_1 = require("@digitaldefiance/node-express-suite");
33
+ const communicationValidation_1 = require("../../utils/communicationValidation");
34
+ const errorResponse_1 = require("../../utils/errorResponse");
35
+ const base_1 = require("../base");
36
+ /**
37
+ * Controller for channel operations.
38
+ *
39
+ * @requirements 4.1, 4.2, 4.3, 4.4, 4.5, 5.1, 5.2, 5.3, 5.4, 5.5
40
+ */
41
+ class ChannelController extends base_1.BaseController {
42
+ constructor(application) {
43
+ super(application);
44
+ this.channelService = null;
45
+ this.permissionService = null;
46
+ }
47
+ setChannelService(service) {
48
+ this.channelService = service;
49
+ }
50
+ setPermissionService(service) {
51
+ this.permissionService = service;
52
+ }
53
+ getChannelService() {
54
+ if (!this.channelService) {
55
+ throw new Error('ChannelService not initialized');
56
+ }
57
+ return this.channelService;
58
+ }
59
+ getPermissionService() {
60
+ if (!this.permissionService) {
61
+ throw new Error('PermissionService not initialized');
62
+ }
63
+ return this.permissionService;
64
+ }
65
+ /**
66
+ * Extract the authenticated member ID from the request.
67
+ * Falls back to body/query memberId for testing.
68
+ */
69
+ getMemberId(req) {
70
+ const body = req.body;
71
+ if (body && typeof body === 'object') {
72
+ const bodyRecord = body;
73
+ if (typeof bodyRecord['memberId'] === 'string')
74
+ return bodyRecord['memberId'];
75
+ if (typeof bodyRecord['requesterId'] === 'string')
76
+ return bodyRecord['requesterId'];
77
+ }
78
+ const query = req.query;
79
+ if (query && typeof query.memberId === 'string')
80
+ return query.memberId;
81
+ throw new Error('No authenticated user');
82
+ }
83
+ initRouteDefinitions() {
84
+ const noAuth = {
85
+ useAuthentication: false,
86
+ useCryptoAuthentication: false,
87
+ };
88
+ this.routeDefinitions = [
89
+ (0, node_express_suite_1.routeConfig)('post', '/', {
90
+ ...noAuth,
91
+ handlerKey: 'createChannel',
92
+ validation: () => communicationValidation_1.createChannelValidation,
93
+ }),
94
+ (0, node_express_suite_1.routeConfig)('get', '/', {
95
+ ...noAuth,
96
+ handlerKey: 'listChannels',
97
+ validation: () => communicationValidation_1.listChannelsValidation,
98
+ }),
99
+ (0, node_express_suite_1.routeConfig)('get', '/:channelId', {
100
+ ...noAuth,
101
+ handlerKey: 'getChannel',
102
+ validation: () => communicationValidation_1.channelIdParamValidation,
103
+ }),
104
+ (0, node_express_suite_1.routeConfig)('put', '/:channelId', {
105
+ ...noAuth,
106
+ handlerKey: 'updateChannel',
107
+ validation: () => communicationValidation_1.updateChannelValidation,
108
+ }),
109
+ (0, node_express_suite_1.routeConfig)('delete', '/:channelId', {
110
+ ...noAuth,
111
+ handlerKey: 'deleteChannel',
112
+ validation: () => communicationValidation_1.channelIdParamValidation,
113
+ }),
114
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/join', {
115
+ ...noAuth,
116
+ handlerKey: 'joinChannel',
117
+ validation: () => communicationValidation_1.joinChannelValidation,
118
+ }),
119
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/leave', {
120
+ ...noAuth,
121
+ handlerKey: 'leaveChannel',
122
+ validation: () => communicationValidation_1.leaveChannelValidation,
123
+ }),
124
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/messages', {
125
+ ...noAuth,
126
+ handlerKey: 'sendMessage',
127
+ validation: () => communicationValidation_1.sendChannelMessageValidation,
128
+ }),
129
+ (0, node_express_suite_1.routeConfig)('get', '/:channelId/messages', {
130
+ ...noAuth,
131
+ handlerKey: 'getMessages',
132
+ validation: () => communicationValidation_1.getChannelMessagesValidation,
133
+ }),
134
+ (0, node_express_suite_1.routeConfig)('get', '/:channelId/messages/search', {
135
+ ...noAuth,
136
+ handlerKey: 'searchMessages',
137
+ validation: () => communicationValidation_1.searchChannelMessagesValidation,
138
+ }),
139
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/invites', {
140
+ ...noAuth,
141
+ handlerKey: 'createInvite',
142
+ validation: () => communicationValidation_1.createInviteValidation,
143
+ }),
144
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/invites/:token/redeem', {
145
+ ...noAuth,
146
+ handlerKey: 'redeemInvite',
147
+ validation: () => communicationValidation_1.redeemInviteValidation,
148
+ }),
149
+ (0, node_express_suite_1.routeConfig)('put', '/:channelId/roles/:memberId', {
150
+ ...noAuth,
151
+ handlerKey: 'assignRole',
152
+ validation: () => communicationValidation_1.assignChannelRoleValidation,
153
+ }),
154
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/messages/:messageId/reactions', {
155
+ ...noAuth,
156
+ handlerKey: 'addReaction',
157
+ validation: () => communicationValidation_1.addChannelReactionValidation,
158
+ }),
159
+ (0, node_express_suite_1.routeConfig)('delete', '/:channelId/messages/:messageId/reactions/:reactionId', {
160
+ ...noAuth,
161
+ handlerKey: 'removeReaction',
162
+ validation: () => communicationValidation_1.removeChannelReactionValidation,
163
+ }),
164
+ (0, node_express_suite_1.routeConfig)('put', '/:channelId/messages/:messageId', {
165
+ ...noAuth,
166
+ handlerKey: 'editMessage',
167
+ validation: () => communicationValidation_1.editChannelMessageValidation,
168
+ }),
169
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/messages/:messageId/pin', {
170
+ ...noAuth,
171
+ handlerKey: 'pinMessage',
172
+ validation: () => communicationValidation_1.pinChannelMessageValidation,
173
+ }),
174
+ (0, node_express_suite_1.routeConfig)('delete', '/:channelId/messages/:messageId/pin', {
175
+ ...noAuth,
176
+ handlerKey: 'unpinMessage',
177
+ validation: () => communicationValidation_1.pinChannelMessageValidation,
178
+ }),
179
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/mute/:memberId', {
180
+ ...noAuth,
181
+ handlerKey: 'muteMember',
182
+ validation: () => communicationValidation_1.muteChannelMemberValidation,
183
+ }),
184
+ (0, node_express_suite_1.routeConfig)('post', '/:channelId/kick/:memberId', {
185
+ ...noAuth,
186
+ handlerKey: 'kickMember',
187
+ validation: () => communicationValidation_1.kickChannelMemberValidation,
188
+ }),
189
+ ];
190
+ this.handlers = {
191
+ createChannel: this.handleCreateChannel.bind(this),
192
+ listChannels: this.handleListChannels.bind(this),
193
+ getChannel: this.handleGetChannel.bind(this),
194
+ updateChannel: this.handleUpdateChannel.bind(this),
195
+ deleteChannel: this.handleDeleteChannel.bind(this),
196
+ joinChannel: this.handleJoinChannel.bind(this),
197
+ leaveChannel: this.handleLeaveChannel.bind(this),
198
+ sendMessage: this.handleSendMessage.bind(this),
199
+ getMessages: this.handleGetMessages.bind(this),
200
+ searchMessages: this.handleSearchMessages.bind(this),
201
+ createInvite: this.handleCreateInvite.bind(this),
202
+ redeemInvite: this.handleRedeemInvite.bind(this),
203
+ assignRole: this.handleAssignRole.bind(this),
204
+ addReaction: this.handleAddReaction.bind(this),
205
+ removeReaction: this.handleRemoveReaction.bind(this),
206
+ editMessage: this.handleEditMessage.bind(this),
207
+ pinMessage: this.handlePinMessage.bind(this),
208
+ unpinMessage: this.handleUnpinMessage.bind(this),
209
+ muteMember: this.handleMuteMember.bind(this),
210
+ kickMember: this.handleKickMember.bind(this),
211
+ };
212
+ }
213
+ // ─── Handlers ─────────────────────────────────────────────────────────
214
+ /** POST / — Create a channel. @requirements 4.1 */
215
+ async handleCreateChannel(req) {
216
+ try {
217
+ const { name, topic, visibility } = req.body;
218
+ if (!name || !visibility) {
219
+ return (0, errorResponse_1.validationError)('Missing required fields: name, visibility');
220
+ }
221
+ const memberId = this.getMemberId(req);
222
+ const channel = await this.getChannelService().createChannel(name, memberId, visibility, topic);
223
+ return {
224
+ statusCode: 201,
225
+ response: {
226
+ status: 'success',
227
+ data: channel,
228
+ message: 'Channel created',
229
+ },
230
+ };
231
+ }
232
+ catch (error) {
233
+ return this.mapServiceError(error);
234
+ }
235
+ }
236
+ /** GET / — List discoverable channels. @requirements 4.3, 5.1 */
237
+ async handleListChannels(req) {
238
+ try {
239
+ const { cursor, limit } = req.query;
240
+ const memberId = this.getMemberId(req);
241
+ const result = await this.getChannelService().listChannels(memberId, cursor, limit ? parseInt(limit, 10) : undefined);
242
+ return {
243
+ statusCode: 200,
244
+ response: {
245
+ status: 'success',
246
+ data: result,
247
+ message: 'Channels listed',
248
+ },
249
+ };
250
+ }
251
+ catch (error) {
252
+ return this.mapServiceError(error);
253
+ }
254
+ }
255
+ /** GET /:channelId — Get channel metadata. */
256
+ async handleGetChannel(req) {
257
+ try {
258
+ const { channelId } = req.params;
259
+ const memberId = this.getMemberId(req);
260
+ const channel = await this.getChannelService().getChannel(channelId, memberId);
261
+ return {
262
+ statusCode: 200,
263
+ response: {
264
+ status: 'success',
265
+ data: channel,
266
+ message: 'Channel retrieved',
267
+ },
268
+ };
269
+ }
270
+ catch (error) {
271
+ return this.mapServiceError(error);
272
+ }
273
+ }
274
+ /** PUT /:channelId — Update channel settings. @requirements 5.2 */
275
+ async handleUpdateChannel(req) {
276
+ try {
277
+ const { channelId } = req.params;
278
+ const { name, topic, visibility, historyVisibleToNewMembers } = req.body;
279
+ const memberId = this.getMemberId(req);
280
+ const channel = await this.getChannelService().updateChannel(channelId, memberId, { name, topic, visibility, historyVisibleToNewMembers });
281
+ return {
282
+ statusCode: 200,
283
+ response: {
284
+ status: 'success',
285
+ data: channel,
286
+ message: 'Channel updated',
287
+ },
288
+ };
289
+ }
290
+ catch (error) {
291
+ return this.mapServiceError(error);
292
+ }
293
+ }
294
+ /** DELETE /:channelId — Delete channel. */
295
+ async handleDeleteChannel(req) {
296
+ try {
297
+ const { channelId } = req.params;
298
+ const memberId = this.getMemberId(req);
299
+ await this.getChannelService().deleteChannel(channelId, memberId);
300
+ return {
301
+ statusCode: 200,
302
+ response: {
303
+ status: 'success',
304
+ data: { deleted: true },
305
+ message: 'Channel deleted',
306
+ },
307
+ };
308
+ }
309
+ catch (error) {
310
+ return this.mapServiceError(error);
311
+ }
312
+ }
313
+ /** POST /:channelId/join — Join a channel. @requirements 4.4, 4.5 */
314
+ async handleJoinChannel(req) {
315
+ try {
316
+ const { channelId } = req.params;
317
+ const memberId = this.getMemberId(req);
318
+ await this.getChannelService().joinChannel(channelId, memberId);
319
+ return {
320
+ statusCode: 200,
321
+ response: {
322
+ status: 'success',
323
+ data: { joined: true },
324
+ message: 'Joined channel',
325
+ },
326
+ };
327
+ }
328
+ catch (error) {
329
+ return this.mapServiceError(error);
330
+ }
331
+ }
332
+ /** POST /:channelId/leave — Leave a channel. */
333
+ async handleLeaveChannel(req) {
334
+ try {
335
+ const { channelId } = req.params;
336
+ const memberId = this.getMemberId(req);
337
+ await this.getChannelService().leaveChannel(channelId, memberId);
338
+ return {
339
+ statusCode: 200,
340
+ response: {
341
+ status: 'success',
342
+ data: { left: true },
343
+ message: 'Left channel',
344
+ },
345
+ };
346
+ }
347
+ catch (error) {
348
+ return this.mapServiceError(error);
349
+ }
350
+ }
351
+ /** POST /:channelId/messages — Send message. @requirements 4.2 */
352
+ async handleSendMessage(req) {
353
+ try {
354
+ const { channelId } = req.params;
355
+ const { content } = req.body;
356
+ if (!content) {
357
+ return (0, errorResponse_1.validationError)('Missing required field: content');
358
+ }
359
+ const memberId = this.getMemberId(req);
360
+ const message = await this.getChannelService().sendMessage(channelId, memberId, content);
361
+ return {
362
+ statusCode: 201,
363
+ response: {
364
+ status: 'success',
365
+ data: message,
366
+ message: 'Message sent',
367
+ },
368
+ };
369
+ }
370
+ catch (error) {
371
+ return this.mapServiceError(error);
372
+ }
373
+ }
374
+ /** GET /:channelId/messages — Get message history. */
375
+ async handleGetMessages(req) {
376
+ try {
377
+ const { channelId } = req.params;
378
+ const { cursor, limit } = req.query;
379
+ const memberId = this.getMemberId(req);
380
+ const result = await this.getChannelService().getMessages(channelId, memberId, cursor, limit ? parseInt(limit, 10) : undefined);
381
+ return {
382
+ statusCode: 200,
383
+ response: {
384
+ status: 'success',
385
+ data: result,
386
+ message: 'Messages retrieved',
387
+ },
388
+ };
389
+ }
390
+ catch (error) {
391
+ return this.mapServiceError(error);
392
+ }
393
+ }
394
+ /** GET /:channelId/messages/search — Search messages. */
395
+ async handleSearchMessages(req) {
396
+ try {
397
+ const { channelId } = req.params;
398
+ const { query, cursor, limit } = req.query;
399
+ if (!query) {
400
+ return (0, errorResponse_1.validationError)('Missing required query parameter: query');
401
+ }
402
+ const memberId = this.getMemberId(req);
403
+ const result = await this.getChannelService().searchMessages(channelId, memberId, query, cursor, limit ? parseInt(limit, 10) : undefined);
404
+ return {
405
+ statusCode: 200,
406
+ response: {
407
+ status: 'success',
408
+ data: result,
409
+ message: 'Search results',
410
+ },
411
+ };
412
+ }
413
+ catch (error) {
414
+ return this.mapServiceError(error);
415
+ }
416
+ }
417
+ /** POST /:channelId/invites — Generate invite token. @requirements 5.3 */
418
+ async handleCreateInvite(req) {
419
+ try {
420
+ const { channelId } = req.params;
421
+ const { maxUses, expiresInMs } = req.body;
422
+ const memberId = this.getMemberId(req);
423
+ const invite = await this.getChannelService().createInvite(channelId, memberId, maxUses, expiresInMs);
424
+ return {
425
+ statusCode: 201,
426
+ response: {
427
+ status: 'success',
428
+ data: invite,
429
+ message: 'Invite created',
430
+ },
431
+ };
432
+ }
433
+ catch (error) {
434
+ return this.mapServiceError(error);
435
+ }
436
+ }
437
+ /** POST /:channelId/invites/:token/redeem — Redeem invite. @requirements 5.4, 5.5 */
438
+ async handleRedeemInvite(req) {
439
+ try {
440
+ const { token } = req.params;
441
+ const memberId = this.getMemberId(req);
442
+ await this.getChannelService().redeemInvite(token, memberId);
443
+ return {
444
+ statusCode: 200,
445
+ response: {
446
+ status: 'success',
447
+ data: { redeemed: true },
448
+ message: 'Invite redeemed',
449
+ },
450
+ };
451
+ }
452
+ catch (error) {
453
+ return this.mapServiceError(error);
454
+ }
455
+ }
456
+ /** PUT /:channelId/roles/:memberId — Assign role. */
457
+ async handleAssignRole(req) {
458
+ try {
459
+ const { channelId, memberId: targetId } = req.params;
460
+ const { role } = req.body;
461
+ if (!role) {
462
+ return (0, errorResponse_1.validationError)('Missing required field: role');
463
+ }
464
+ const requesterId = this.getMemberId(req);
465
+ const permService = this.getPermissionService();
466
+ if (!permService.hasPermission(requesterId, channelId, 'manage_roles')) {
467
+ return (0, errorResponse_1.forbiddenError)('Missing permission: manage_roles');
468
+ }
469
+ permService.assignRole(targetId, channelId, role);
470
+ return {
471
+ statusCode: 200,
472
+ response: {
473
+ status: 'success',
474
+ data: { memberId: targetId, role },
475
+ message: 'Role assigned',
476
+ },
477
+ };
478
+ }
479
+ catch (error) {
480
+ return this.mapServiceError(error);
481
+ }
482
+ }
483
+ /** POST /:channelId/messages/:messageId/reactions — Add reaction. */
484
+ async handleAddReaction(req) {
485
+ try {
486
+ const { channelId, messageId } = req.params;
487
+ const { emoji } = req.body;
488
+ if (!emoji) {
489
+ return (0, errorResponse_1.validationError)('Missing required field: emoji');
490
+ }
491
+ const memberId = this.getMemberId(req);
492
+ const reactionId = await this.getChannelService().addReaction(channelId, messageId, memberId, emoji);
493
+ return {
494
+ statusCode: 201,
495
+ response: {
496
+ status: 'success',
497
+ data: { reactionId, emoji },
498
+ message: 'Reaction added',
499
+ },
500
+ };
501
+ }
502
+ catch (error) {
503
+ return this.mapServiceError(error);
504
+ }
505
+ }
506
+ /** DELETE /:channelId/messages/:messageId/reactions/:reactionId — Remove reaction. */
507
+ async handleRemoveReaction(req) {
508
+ try {
509
+ const { channelId, messageId, reactionId } = req
510
+ .params;
511
+ const memberId = this.getMemberId(req);
512
+ await this.getChannelService().removeReaction(channelId, messageId, memberId, reactionId);
513
+ return {
514
+ statusCode: 200,
515
+ response: {
516
+ status: 'success',
517
+ data: { removed: true },
518
+ message: 'Reaction removed',
519
+ },
520
+ };
521
+ }
522
+ catch (error) {
523
+ return this.mapServiceError(error);
524
+ }
525
+ }
526
+ /** PUT /:channelId/messages/:messageId — Edit message. */
527
+ async handleEditMessage(req) {
528
+ try {
529
+ const { channelId, messageId } = req.params;
530
+ const { content } = req.body;
531
+ if (!content) {
532
+ return (0, errorResponse_1.validationError)('Missing required field: content');
533
+ }
534
+ const memberId = this.getMemberId(req);
535
+ const message = await this.getChannelService().editMessage(channelId, messageId, memberId, content);
536
+ return {
537
+ statusCode: 200,
538
+ response: {
539
+ status: 'success',
540
+ data: message,
541
+ message: 'Message edited',
542
+ },
543
+ };
544
+ }
545
+ catch (error) {
546
+ return this.mapServiceError(error);
547
+ }
548
+ }
549
+ /** POST /:channelId/messages/:messageId/pin — Pin message. */
550
+ async handlePinMessage(req) {
551
+ try {
552
+ const { channelId, messageId } = req.params;
553
+ const memberId = this.getMemberId(req);
554
+ await this.getChannelService().pinMessage(channelId, messageId, memberId);
555
+ return {
556
+ statusCode: 200,
557
+ response: {
558
+ status: 'success',
559
+ data: { pinned: true },
560
+ message: 'Message pinned',
561
+ },
562
+ };
563
+ }
564
+ catch (error) {
565
+ return this.mapServiceError(error);
566
+ }
567
+ }
568
+ /** DELETE /:channelId/messages/:messageId/pin — Unpin message. */
569
+ async handleUnpinMessage(req) {
570
+ try {
571
+ const { channelId, messageId } = req.params;
572
+ const memberId = this.getMemberId(req);
573
+ await this.getChannelService().unpinMessage(channelId, messageId, memberId);
574
+ return {
575
+ statusCode: 200,
576
+ response: {
577
+ status: 'success',
578
+ data: { unpinned: true },
579
+ message: 'Message unpinned',
580
+ },
581
+ };
582
+ }
583
+ catch (error) {
584
+ return this.mapServiceError(error);
585
+ }
586
+ }
587
+ /** POST /:channelId/mute/:memberId — Mute a member. */
588
+ async handleMuteMember(req) {
589
+ try {
590
+ const { channelId, memberId: targetId } = req.params;
591
+ const { durationMs } = req.body;
592
+ if (!durationMs || durationMs <= 0) {
593
+ return (0, errorResponse_1.validationError)('Missing or invalid field: durationMs');
594
+ }
595
+ const requesterId = this.getMemberId(req);
596
+ await this.getChannelService().muteMember(channelId, requesterId, targetId, durationMs);
597
+ return {
598
+ statusCode: 200,
599
+ response: {
600
+ status: 'success',
601
+ data: {
602
+ muted: true,
603
+ until: new Date(Date.now() + durationMs).toISOString(),
604
+ },
605
+ message: 'Member muted',
606
+ },
607
+ };
608
+ }
609
+ catch (error) {
610
+ return this.mapServiceError(error);
611
+ }
612
+ }
613
+ /** POST /:channelId/kick/:memberId — Kick a member. */
614
+ async handleKickMember(req) {
615
+ try {
616
+ const { channelId, memberId: targetId } = req.params;
617
+ const requesterId = this.getMemberId(req);
618
+ await this.getChannelService().kickMember(channelId, requesterId, targetId);
619
+ return {
620
+ statusCode: 200,
621
+ response: {
622
+ status: 'success',
623
+ data: { kicked: true },
624
+ message: 'Member kicked',
625
+ },
626
+ };
627
+ }
628
+ catch (error) {
629
+ return this.mapServiceError(error);
630
+ }
631
+ }
632
+ // ─── Error mapping ────────────────────────────────────────────────────
633
+ mapServiceError(error) {
634
+ if (error instanceof channelService_1.ChannelNotFoundError) {
635
+ return (0, errorResponse_1.notFoundError)('Channel', 'unknown');
636
+ }
637
+ if (error instanceof channelService_1.NotChannelMemberError) {
638
+ return (0, errorResponse_1.forbiddenError)(error.message);
639
+ }
640
+ if (error instanceof channelService_1.ChannelPermissionError) {
641
+ return (0, errorResponse_1.forbiddenError)(`Missing permission: ${error.missingPermission}`);
642
+ }
643
+ if (error instanceof channelService_1.ChannelMemberMutedError) {
644
+ return (0, errorResponse_1.forbiddenError)(error.message);
645
+ }
646
+ if (error instanceof channelService_1.ChannelMessageNotFoundError) {
647
+ return (0, errorResponse_1.notFoundError)('Message', 'unknown');
648
+ }
649
+ if (error instanceof channelService_1.NotMessageAuthorError) {
650
+ return (0, errorResponse_1.forbiddenError)(error.message);
651
+ }
652
+ if (error instanceof channelService_1.ChannelReactionNotFoundError) {
653
+ return (0, errorResponse_1.notFoundError)('Reaction', 'unknown');
654
+ }
655
+ if (error instanceof channelService_1.MemberAlreadyInChannelError) {
656
+ return {
657
+ statusCode: 409,
658
+ response: {
659
+ error: {
660
+ code: 'ALREADY_EXISTS',
661
+ message: error.message,
662
+ },
663
+ },
664
+ };
665
+ }
666
+ if (error instanceof channelService_1.ChannelNameConflictError) {
667
+ return {
668
+ statusCode: 409,
669
+ response: {
670
+ error: {
671
+ code: 'ALREADY_EXISTS',
672
+ message: error.message,
673
+ },
674
+ },
675
+ };
676
+ }
677
+ if (error instanceof channelService_1.ChannelJoinDeniedError) {
678
+ return (0, errorResponse_1.forbiddenError)(error.message);
679
+ }
680
+ if (error instanceof channelService_1.InviteTokenExpiredError) {
681
+ return {
682
+ statusCode: 410,
683
+ response: {
684
+ error: {
685
+ code: 'GONE',
686
+ message: error.message,
687
+ },
688
+ },
689
+ };
690
+ }
691
+ if (error instanceof channelService_1.InviteTokenNotFoundError) {
692
+ return (0, errorResponse_1.notFoundError)('InviteToken', 'unknown');
693
+ }
694
+ if (error instanceof Error) {
695
+ return (0, errorResponse_1.internalError)(error);
696
+ }
697
+ return (0, errorResponse_1.handleError)(error);
698
+ }
699
+ }
700
+ exports.ChannelController = ChannelController;
701
+ //# sourceMappingURL=channels.js.map