@brightchain/brightchain-api-lib 0.23.25 → 0.24.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.
- package/package.json +5 -5
- package/src/lib/__tests__/fixtures/mock-backend-brightchain-member.d.ts.map +1 -1
- package/src/lib/__tests__/fixtures/mock-backend-brightchain-member.js +11 -0
- package/src/lib/__tests__/fixtures/mock-backend-brightchain-member.js.map +1 -1
- package/src/lib/__tests__/fixtures/mocked-model.js +63 -60
- package/src/lib/__tests__/fixtures/mocked-model.js.map +1 -1
- package/src/lib/application.d.ts +1 -1
- package/src/lib/application.d.ts.map +1 -1
- package/src/lib/application.js +103 -34
- package/src/lib/application.js.map +1 -1
- package/src/lib/auth/aclEnforcedAvailability.js +4 -0
- package/src/lib/auth/aclEnforcedAvailability.js.map +1 -1
- package/src/lib/auth/aclEnforcedBlockStore.js +7 -0
- package/src/lib/auth/aclEnforcedBlockStore.js.map +1 -1
- package/src/lib/auth/ecdsaNodeAuthenticator.js +1 -0
- package/src/lib/auth/ecdsaNodeAuthenticator.js.map +1 -1
- package/src/lib/auth/poolAclBootstrap.js +2 -0
- package/src/lib/auth/poolAclBootstrap.js.map +1 -1
- package/src/lib/auth/poolAclStore.js +2 -1
- package/src/lib/auth/poolAclStore.js.map +1 -1
- package/src/lib/auth/poolAclUpdater.js +4 -0
- package/src/lib/auth/poolAclUpdater.js.map +1 -1
- package/src/lib/availability/availabilityMetrics.js +43 -45
- package/src/lib/availability/availabilityMetrics.js.map +1 -1
- package/src/lib/availability/availabilityService.js +26 -20
- package/src/lib/availability/availabilityService.js.map +1 -1
- package/src/lib/availability/blockRegistry.js +46 -25
- package/src/lib/availability/blockRegistry.js.map +1 -1
- package/src/lib/availability/discoveryProtocol.js +10 -8
- package/src/lib/availability/discoveryProtocol.js.map +1 -1
- package/src/lib/availability/gossipService.js +56 -45
- package/src/lib/availability/gossipService.js.map +1 -1
- package/src/lib/availability/heartbeatMonitor.js +22 -20
- package/src/lib/availability/heartbeatMonitor.js.map +1 -1
- package/src/lib/availability/poolDiscoveryService.js +7 -1
- package/src/lib/availability/poolDiscoveryService.js.map +1 -1
- package/src/lib/availability/quorumGossipHandler.js +13 -6
- package/src/lib/availability/quorumGossipHandler.js.map +1 -1
- package/src/lib/availability/reconciliationService.js +18 -12
- package/src/lib/availability/reconciliationService.js.map +1 -1
- package/src/lib/blockFetch/blockFetcher.js +14 -8
- package/src/lib/blockFetch/blockFetcher.js.map +1 -1
- package/src/lib/blockFetch/fetchQueue.js +9 -7
- package/src/lib/blockFetch/fetchQueue.js.map +1 -1
- package/src/lib/blockFetch/httpBlockFetchTransport.js +2 -0
- package/src/lib/blockFetch/httpBlockFetchTransport.js.map +1 -1
- package/src/lib/browserKeyring.js +5 -2
- package/src/lib/browserKeyring.js.map +1 -1
- package/src/lib/controllers/api/blocks.d.ts.map +1 -1
- package/src/lib/controllers/api/blocks.js +9 -3
- package/src/lib/controllers/api/blocks.js.map +1 -1
- package/src/lib/controllers/api/brighthub/connectionController.d.ts +80 -0
- package/src/lib/controllers/api/brighthub/connectionController.d.ts.map +1 -0
- package/src/lib/controllers/api/brighthub/connectionController.js +890 -0
- package/src/lib/controllers/api/brighthub/connectionController.js.map +1 -0
- package/src/lib/controllers/api/brighthub/index.d.ts +9 -0
- package/src/lib/controllers/api/brighthub/index.d.ts.map +1 -0
- package/src/lib/controllers/api/brighthub/index.js +12 -0
- package/src/lib/controllers/api/brighthub/index.js.map +1 -0
- package/src/lib/controllers/api/brighthub/messagingController.d.ts +84 -0
- package/src/lib/controllers/api/brighthub/messagingController.d.ts.map +1 -0
- package/src/lib/controllers/api/brighthub/messagingController.js +1077 -0
- package/src/lib/controllers/api/brighthub/messagingController.js.map +1 -0
- package/src/lib/controllers/api/brighthub/notificationController.d.ts +89 -0
- package/src/lib/controllers/api/brighthub/notificationController.d.ts.map +1 -0
- package/src/lib/controllers/api/brighthub/notificationController.js +444 -0
- package/src/lib/controllers/api/brighthub/notificationController.js.map +1 -0
- package/src/lib/controllers/api/brighthub/postController.d.ts +75 -0
- package/src/lib/controllers/api/brighthub/postController.d.ts.map +1 -0
- package/src/lib/controllers/api/brighthub/postController.js +388 -0
- package/src/lib/controllers/api/brighthub/postController.js.map +1 -0
- package/src/lib/controllers/api/brighthub/timelineController.d.ts +74 -0
- package/src/lib/controllers/api/brighthub/timelineController.d.ts.map +1 -0
- package/src/lib/controllers/api/brighthub/timelineController.js +418 -0
- package/src/lib/controllers/api/brighthub/timelineController.js.map +1 -0
- package/src/lib/controllers/api/brightpass.d.ts.map +1 -1
- package/src/lib/controllers/api/brightpass.js +46 -4
- package/src/lib/controllers/api/brightpass.js.map +1 -1
- package/src/lib/controllers/api/cbl.js +1 -0
- package/src/lib/controllers/api/cbl.js.map +1 -1
- package/src/lib/controllers/api/channels.js +2 -2
- package/src/lib/controllers/api/channels.js.map +1 -1
- package/src/lib/controllers/api/conversations.js +1 -1
- package/src/lib/controllers/api/conversations.js.map +1 -1
- package/src/lib/controllers/api/docs.js +2 -1
- package/src/lib/controllers/api/docs.js.map +1 -1
- package/src/lib/controllers/api/emails.d.ts.map +1 -1
- package/src/lib/controllers/api/emails.js +16 -2
- package/src/lib/controllers/api/emails.js.map +1 -1
- package/src/lib/controllers/api/explodingMessages.js +2 -4
- package/src/lib/controllers/api/explodingMessages.js.map +1 -1
- package/src/lib/controllers/api/groups.js +2 -2
- package/src/lib/controllers/api/groups.js.map +1 -1
- package/src/lib/controllers/api/health.d.ts +9 -2
- package/src/lib/controllers/api/health.d.ts.map +1 -1
- package/src/lib/controllers/api/health.js +48 -6
- package/src/lib/controllers/api/health.js.map +1 -1
- package/src/lib/controllers/api/index.d.ts +1 -0
- package/src/lib/controllers/api/index.d.ts.map +1 -1
- package/src/lib/controllers/api/index.js +1 -0
- package/src/lib/controllers/api/index.js.map +1 -1
- package/src/lib/controllers/api/introspection.js +2 -0
- package/src/lib/controllers/api/introspection.js.map +1 -1
- package/src/lib/controllers/api/messages.js +1 -1
- package/src/lib/controllers/api/messages.js.map +1 -1
- package/src/lib/controllers/api/nodes.js +6 -6
- package/src/lib/controllers/api/nodes.js.map +1 -1
- package/src/lib/controllers/api/quorum.d.ts +1 -1
- package/src/lib/controllers/api/quorum.d.ts.map +1 -1
- package/src/lib/controllers/api/quorum.js +3 -2
- package/src/lib/controllers/api/quorum.js.map +1 -1
- package/src/lib/controllers/api/scbl.js +3 -0
- package/src/lib/controllers/api/scbl.js.map +1 -1
- package/src/lib/controllers/api/sessions.d.ts +18 -2
- package/src/lib/controllers/api/sessions.d.ts.map +1 -1
- package/src/lib/controllers/api/sessions.js +60 -3
- package/src/lib/controllers/api/sessions.js.map +1 -1
- package/src/lib/controllers/api/sync.js +4 -4
- package/src/lib/controllers/api/sync.js.map +1 -1
- package/src/lib/controllers/api/user.d.ts +2 -0
- package/src/lib/controllers/api/user.d.ts.map +1 -1
- package/src/lib/controllers/api/user.js +95 -3
- package/src/lib/controllers/api/user.js.map +1 -1
- package/src/lib/controllers/identity/deviceController.js +2 -2
- package/src/lib/controllers/identity/deviceController.js.map +1 -1
- package/src/lib/controllers/identity/directoryController.js +1 -1
- package/src/lib/controllers/identity/directoryController.js.map +1 -1
- package/src/lib/controllers/identity/identityProofController.js +4 -6
- package/src/lib/controllers/identity/identityProofController.js.map +1 -1
- package/src/lib/databaseInit.d.ts +3 -3
- package/src/lib/databaseInit.js +5 -5
- package/src/lib/databaseInit.js.map +1 -1
- package/src/lib/datastore/block-document-store.d.ts.map +1 -1
- package/src/lib/datastore/block-document-store.js +18 -6
- package/src/lib/datastore/block-document-store.js.map +1 -1
- package/src/lib/datastore/document-store.d.ts.map +1 -1
- package/src/lib/datastore/memory-document-store.js +5 -2
- package/src/lib/datastore/memory-document-store.js.map +1 -1
- package/src/lib/encryption/encryptedMetadataService.js +2 -0
- package/src/lib/encryption/encryptedMetadataService.js.map +1 -1
- package/src/lib/encryption/encryptionAwareReplication.js +3 -0
- package/src/lib/encryption/encryptionAwareReplication.js.map +1 -1
- package/src/lib/encryption/errors.d.ts.map +1 -1
- package/src/lib/encryption/errors.js +8 -0
- package/src/lib/encryption/errors.js.map +1 -1
- package/src/lib/encryption/poolKeyManager.js +2 -0
- package/src/lib/encryption/poolKeyManager.js.map +1 -1
- package/src/lib/environment.js +10 -0
- package/src/lib/environment.js.map +1 -1
- package/src/lib/errors/express-validation.js +1 -0
- package/src/lib/errors/express-validation.js.map +1 -1
- package/src/lib/errors/invalid-backup-code-version.js +1 -0
- package/src/lib/errors/invalid-backup-code-version.js.map +1 -1
- package/src/lib/errors/memberIndexSchemaValidationError.js +1 -0
- package/src/lib/errors/memberIndexSchemaValidationError.js.map +1 -1
- package/src/lib/errors/missing-validated-data.js +2 -0
- package/src/lib/errors/missing-validated-data.js.map +1 -1
- package/src/lib/errors/token-not-found.js +1 -0
- package/src/lib/errors/token-not-found.js.map +1 -1
- package/src/lib/errors/typed-error-local.js +3 -0
- package/src/lib/errors/typed-error-local.js.map +1 -1
- package/src/lib/interfaces/brightpass/index.d.ts +1 -1
- package/src/lib/interfaces/brightpass/index.d.ts.map +1 -1
- package/src/lib/interfaces/environment.d.ts +1 -1
- package/src/lib/interfaces/environment.d.ts.map +1 -1
- package/src/lib/interfaces/member/memberProfileResponse.d.ts.map +1 -1
- package/src/lib/interfaces/member/operational.d.ts.map +1 -1
- package/src/lib/interfaces/member-init-config.d.ts +1 -1
- package/src/lib/interfaces/member-init-config.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-backup-codes-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-challenge-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-code-count-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-detailed-health-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-discover-block-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-express-validation-error.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-get-block-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-get-node-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-health-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-list-nodes-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-login-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-members-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-mnemonic-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-reconcile-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-register-node-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-registration-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-replicate-block-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-request-user-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-store-block-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-store-cbl-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/api-sync-request-response.d.ts.map +1 -1
- package/src/lib/interfaces/responses/brighthub/api-connection-response.d.ts +21 -0
- package/src/lib/interfaces/responses/brighthub/api-connection-response.d.ts.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-connection-response.js +3 -0
- package/src/lib/interfaces/responses/brighthub/api-connection-response.js.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-messaging-response.d.ts +39 -0
- package/src/lib/interfaces/responses/brighthub/api-messaging-response.d.ts.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-messaging-response.js +3 -0
- package/src/lib/interfaces/responses/brighthub/api-messaging-response.js.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-notification-response.d.ts +30 -0
- package/src/lib/interfaces/responses/brighthub/api-notification-response.d.ts.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-notification-response.js +3 -0
- package/src/lib/interfaces/responses/brighthub/api-notification-response.js.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-post-response.d.ts +21 -0
- package/src/lib/interfaces/responses/brighthub/api-post-response.d.ts.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-post-response.js +3 -0
- package/src/lib/interfaces/responses/brighthub/api-post-response.js.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-timeline-response.d.ts +14 -0
- package/src/lib/interfaces/responses/brighthub/api-timeline-response.d.ts.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-timeline-response.js +3 -0
- package/src/lib/interfaces/responses/brighthub/api-timeline-response.js.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-user-profile-response.d.ts +10 -0
- package/src/lib/interfaces/responses/brighthub/api-user-profile-response.d.ts.map +1 -0
- package/src/lib/interfaces/responses/brighthub/api-user-profile-response.js +3 -0
- package/src/lib/interfaces/responses/brighthub/api-user-profile-response.js.map +1 -0
- package/src/lib/interfaces/responses/brighthub/index.d.ts +13 -0
- package/src/lib/interfaces/responses/brighthub/index.d.ts.map +1 -0
- package/src/lib/interfaces/responses/brighthub/index.js +9 -0
- package/src/lib/interfaces/responses/brighthub/index.js.map +1 -0
- package/src/lib/interfaces/responses/index.d.ts +1 -0
- package/src/lib/interfaces/responses/index.d.ts.map +1 -1
- package/src/lib/interfaces/storage/storedDocumentTypes.d.ts +1 -1
- package/src/lib/interfaces/storage/storedDocumentTypes.js +1 -1
- package/src/lib/interfaces/storage/userRoleSchema.d.ts.map +1 -1
- package/src/lib/interfaces/storage/userRoleSchema.js +1 -3
- package/src/lib/interfaces/storage/userRoleSchema.js.map +1 -1
- package/src/lib/middlewares.js +31 -31
- package/src/lib/middlewares.js.map +1 -1
- package/src/lib/nodeKeyring.js +2 -0
- package/src/lib/nodeKeyring.js.map +1 -1
- package/src/lib/plugins/brightchain-database-plugin.d.ts +14 -14
- package/src/lib/plugins/brightchain-database-plugin.d.ts.map +1 -1
- package/src/lib/plugins/brightchain-database-plugin.js +36 -34
- package/src/lib/plugins/brightchain-database-plugin.js.map +1 -1
- package/src/lib/routers/api.d.ts +62 -1
- package/src/lib/routers/api.d.ts.map +1 -1
- package/src/lib/routers/api.js +123 -2
- package/src/lib/routers/api.js.map +1 -1
- package/src/lib/routers/app.d.ts.map +1 -1
- package/src/lib/routers/app.js +10 -1
- package/src/lib/routers/app.js.map +1 -1
- package/src/lib/routers/base.js +2 -0
- package/src/lib/routers/base.js.map +1 -1
- package/src/lib/secureEnclaveKeyring.js +4 -2
- package/src/lib/secureEnclaveKeyring.js.map +1 -1
- package/src/lib/services/auth.d.ts.map +1 -1
- package/src/lib/services/auth.js +11 -2
- package/src/lib/services/auth.js.map +1 -1
- package/src/lib/services/base.js +1 -0
- package/src/lib/services/base.js.map +1 -1
- package/src/lib/services/blockServiceFactory.js +2 -0
- package/src/lib/services/blockServiceFactory.js.map +1 -1
- package/src/lib/services/blockStore.js +3 -2
- package/src/lib/services/blockStore.js.map +1 -1
- package/src/lib/services/blocks.js +1 -0
- package/src/lib/services/blocks.js.map +1 -1
- package/src/lib/services/brightChainBackupCodeService.d.ts +114 -0
- package/src/lib/services/brightChainBackupCodeService.d.ts.map +1 -0
- package/src/lib/services/brightChainBackupCodeService.js +303 -0
- package/src/lib/services/brightChainBackupCodeService.js.map +1 -0
- package/src/lib/services/brightchain-authentication-provider.d.ts.map +1 -1
- package/src/lib/services/brightchain-authentication-provider.js +40 -9
- package/src/lib/services/brightchain-authentication-provider.js.map +1 -1
- package/src/lib/services/brightchain-member-init.service.d.ts +17 -17
- package/src/lib/services/brightchain-member-init.service.d.ts.map +1 -1
- package/src/lib/services/brightchain-member-init.service.js +12 -9
- package/src/lib/services/brightchain-member-init.service.js.map +1 -1
- package/src/lib/services/brighthub/connectionService.d.ts +286 -0
- package/src/lib/services/brighthub/connectionService.d.ts.map +1 -0
- package/src/lib/services/brighthub/connectionService.js +1887 -0
- package/src/lib/services/brighthub/connectionService.js.map +1 -0
- package/src/lib/services/brighthub/discoveryService.d.ts +110 -0
- package/src/lib/services/brighthub/discoveryService.d.ts.map +1 -0
- package/src/lib/services/brighthub/discoveryService.js +528 -0
- package/src/lib/services/brighthub/discoveryService.js.map +1 -0
- package/src/lib/services/brighthub/feedService.d.ts +141 -0
- package/src/lib/services/brighthub/feedService.d.ts.map +1 -0
- package/src/lib/services/brighthub/feedService.js +418 -0
- package/src/lib/services/brighthub/feedService.js.map +1 -0
- package/src/lib/services/brighthub/index.d.ts +11 -0
- package/src/lib/services/brighthub/index.d.ts.map +1 -0
- package/src/lib/services/brighthub/index.js +14 -0
- package/src/lib/services/brighthub/index.js.map +1 -0
- package/src/lib/services/brighthub/messagingService.d.ts +109 -0
- package/src/lib/services/brighthub/messagingService.d.ts.map +1 -0
- package/src/lib/services/brighthub/messagingService.js +947 -0
- package/src/lib/services/brighthub/messagingService.js.map +1 -0
- package/src/lib/services/brighthub/messagingService.test-helpers.d.ts +75 -0
- package/src/lib/services/brighthub/messagingService.test-helpers.d.ts.map +1 -0
- package/src/lib/services/brighthub/messagingService.test-helpers.js +237 -0
- package/src/lib/services/brighthub/messagingService.test-helpers.js.map +1 -0
- package/src/lib/services/brighthub/notificationService.d.ts +172 -0
- package/src/lib/services/brighthub/notificationService.d.ts.map +1 -0
- package/src/lib/services/brighthub/notificationService.js +768 -0
- package/src/lib/services/brighthub/notificationService.js.map +1 -0
- package/src/lib/services/brighthub/notificationService.test-helpers.d.ts +75 -0
- package/src/lib/services/brighthub/notificationService.test-helpers.d.ts.map +1 -0
- package/src/lib/services/brighthub/notificationService.test-helpers.js +230 -0
- package/src/lib/services/brighthub/notificationService.test-helpers.js.map +1 -0
- package/src/lib/services/brighthub/postService.d.ts +129 -0
- package/src/lib/services/brighthub/postService.d.ts.map +1 -0
- package/src/lib/services/brighthub/postService.js +470 -0
- package/src/lib/services/brighthub/postService.js.map +1 -0
- package/src/lib/services/brighthub/postService.test-helpers.d.ts +40 -0
- package/src/lib/services/brighthub/postService.test-helpers.d.ts.map +1 -0
- package/src/lib/services/brighthub/postService.test-helpers.js +84 -0
- package/src/lib/services/brighthub/postService.test-helpers.js.map +1 -0
- package/src/lib/services/brighthub/textFormatter.d.ts +64 -0
- package/src/lib/services/brighthub/textFormatter.d.ts.map +1 -0
- package/src/lib/services/brighthub/textFormatter.js +256 -0
- package/src/lib/services/brighthub/textFormatter.js.map +1 -0
- package/src/lib/services/brighthub/threadService.d.ts +79 -0
- package/src/lib/services/brighthub/threadService.d.ts.map +1 -0
- package/src/lib/services/brighthub/threadService.js +246 -0
- package/src/lib/services/brighthub/threadService.js.map +1 -0
- package/src/lib/services/brighthub/userProfileService.d.ts +203 -0
- package/src/lib/services/brighthub/userProfileService.d.ts.map +1 -0
- package/src/lib/services/brighthub/userProfileService.js +868 -0
- package/src/lib/services/brighthub/userProfileService.js.map +1 -0
- package/src/lib/services/brighthub/userProfileService.test-helpers.d.ts +86 -0
- package/src/lib/services/brighthub/userProfileService.test-helpers.d.ts.map +1 -0
- package/src/lib/services/brighthub/userProfileService.test-helpers.js +169 -0
- package/src/lib/services/brighthub/userProfileService.test-helpers.js.map +1 -0
- package/src/lib/services/brighthub/webSocketServer.d.ts +68 -0
- package/src/lib/services/brighthub/webSocketServer.d.ts.map +1 -0
- package/src/lib/services/brighthub/webSocketServer.js +194 -0
- package/src/lib/services/brighthub/webSocketServer.js.map +1 -0
- package/src/lib/services/brightpass/auditLogger.js +10 -5
- package/src/lib/services/brightpass/auditLogger.js.map +1 -1
- package/src/lib/services/brightpass/vaultEncryption.js +8 -8
- package/src/lib/services/brightpass/vaultEncryption.js.map +1 -1
- package/src/lib/services/brightpass.js +16 -8
- package/src/lib/services/brightpass.js.map +1 -1
- package/src/lib/services/cliOperatorPrompt.js +5 -2
- package/src/lib/services/cliOperatorPrompt.js.map +1 -1
- package/src/lib/services/clientWebSocketServer.d.ts +69 -4
- package/src/lib/services/clientWebSocketServer.d.ts.map +1 -1
- package/src/lib/services/clientWebSocketServer.js +188 -10
- package/src/lib/services/clientWebSocketServer.js.map +1 -1
- package/src/lib/services/contentAwareBlocksService.js +2 -0
- package/src/lib/services/contentAwareBlocksService.js.map +1 -1
- package/src/lib/services/contentIngestionService.d.ts.map +1 -1
- package/src/lib/services/contentIngestionService.js +2 -0
- package/src/lib/services/contentIngestionService.js.map +1 -1
- package/src/lib/services/diskQuorumService.js +3 -0
- package/src/lib/services/diskQuorumService.js.map +1 -1
- package/src/lib/services/email.js +5 -0
- package/src/lib/services/email.js.map +1 -1
- package/src/lib/services/eventNotificationSystem.d.ts +51 -10
- package/src/lib/services/eventNotificationSystem.d.ts.map +1 -1
- package/src/lib/services/eventNotificationSystem.js +76 -23
- package/src/lib/services/eventNotificationSystem.js.map +1 -1
- package/src/lib/services/expirationScheduler.js +6 -3
- package/src/lib/services/expirationScheduler.js.map +1 -1
- package/src/lib/services/fakeEmailService.js +3 -4
- package/src/lib/services/fakeEmailService.js.map +1 -1
- package/src/lib/services/fec.js +1 -3
- package/src/lib/services/fec.js.map +1 -1
- package/src/lib/services/fecServiceFactory.js +2 -2
- package/src/lib/services/fecServiceFactory.js.map +1 -1
- package/src/lib/services/fecUsageExample.js +1 -3
- package/src/lib/services/fecUsageExample.js.map +1 -1
- package/src/lib/services/identityExpirationScheduler.d.ts.map +1 -1
- package/src/lib/services/identityExpirationScheduler.js +7 -2
- package/src/lib/services/identityExpirationScheduler.js.map +1 -1
- package/src/lib/services/index.d.ts +3 -2
- package/src/lib/services/index.d.ts.map +1 -1
- package/src/lib/services/index.js +3 -2
- package/src/lib/services/index.js.map +1 -1
- package/src/lib/services/messageEventsWebSocketHandler.js +1 -0
- package/src/lib/services/messageEventsWebSocketHandler.js.map +1 -1
- package/src/lib/services/messagePassingService.js +5 -0
- package/src/lib/services/messagePassingService.js.map +1 -1
- package/src/lib/services/nativeRsFecService.js +3 -5
- package/src/lib/services/nativeRsFecService.js.map +1 -1
- package/src/lib/services/presenceService.js +5 -4
- package/src/lib/services/presenceService.js.map +1 -1
- package/src/lib/services/quorum.js +3 -2
- package/src/lib/services/quorum.js.map +1 -1
- package/src/lib/services/quorumDatabaseAdapter.d.ts +5 -5
- package/src/lib/services/quorumDatabaseAdapter.d.ts.map +1 -1
- package/src/lib/services/quorumDatabaseAdapter.js +5 -3
- package/src/lib/services/quorumDatabaseAdapter.js.map +1 -1
- package/src/lib/services/rbac-input-builder.js +5 -0
- package/src/lib/services/rbac-input-builder.js.map +1 -1
- package/src/lib/services/secureKeyStorage.js +3 -0
- package/src/lib/services/secureKeyStorage.js.map +1 -1
- package/src/lib/services/sessionAdapter.d.ts +4 -4
- package/src/lib/services/sessionAdapter.d.ts.map +1 -1
- package/src/lib/services/sessionAdapter.js +3 -2
- package/src/lib/services/sessionAdapter.js.map +1 -1
- package/src/lib/services/webSocketMessageServer.js +7 -4
- package/src/lib/services/webSocketMessageServer.js.map +1 -1
- package/src/lib/services/webSocketPeerProvider.js +2 -1
- package/src/lib/services/webSocketPeerProvider.js.map +1 -1
- package/src/lib/services/websocketHandler.js +9 -1
- package/src/lib/services/websocketHandler.js.map +1 -1
- package/src/lib/shared-types.d.ts +1 -2
- package/src/lib/shared-types.d.ts.map +1 -1
- package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.d.ts +63 -0
- package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.d.ts.map +1 -0
- package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.js +160 -0
- package/src/lib/stores/__tests__/helpers/mockCloudBlockStore.js.map +1 -0
- package/src/lib/stores/availabilityAwareBlockStore.js +34 -5
- package/src/lib/stores/availabilityAwareBlockStore.js.map +1 -1
- package/src/lib/stores/cloudBlockStoreBase.d.ts +121 -0
- package/src/lib/stores/cloudBlockStoreBase.d.ts.map +1 -0
- package/src/lib/stores/cloudBlockStoreBase.js +1165 -0
- package/src/lib/stores/cloudBlockStoreBase.js.map +1 -0
- package/src/lib/stores/diskBlockAsyncStore.js +9 -5
- package/src/lib/stores/diskBlockAsyncStore.js.map +1 -1
- package/src/lib/stores/diskBlockMetadataStore.js +2 -0
- package/src/lib/stores/diskBlockMetadataStore.js.map +1 -1
- package/src/lib/stores/diskBlockStore.js +10 -8
- package/src/lib/stores/diskBlockStore.js.map +1 -1
- package/src/lib/stores/diskCBLStore.d.ts.map +1 -1
- package/src/lib/stores/diskCBLStore.js +8 -0
- package/src/lib/stores/diskCBLStore.js.map +1 -1
- package/src/lib/stores/index.d.ts +1 -0
- package/src/lib/stores/index.d.ts.map +1 -1
- package/src/lib/stores/index.js +1 -0
- package/src/lib/stores/index.js.map +1 -1
- package/src/lib/systemKeyring.d.ts.map +1 -1
- package/src/lib/systemKeyring.js +5 -4
- package/src/lib/systemKeyring.js.map +1 -1
- package/src/lib/transforms/checksumTransform.js +1 -0
- package/src/lib/transforms/checksumTransform.js.map +1 -1
- package/src/lib/transforms/memoryWritableStream.js +1 -0
- package/src/lib/transforms/memoryWritableStream.js.map +1 -1
- package/src/lib/transforms/xorMultipleTransform.js +3 -0
- package/src/lib/transforms/xorMultipleTransform.js.map +1 -1
- package/src/lib/utils/rehydration.d.ts +1 -1
- package/src/lib/utils/rehydration.js +1 -1
- package/src/lib/utils/serialization.d.ts +1 -1
- package/src/lib/utils/serialization.js +1 -1
- package/src/lib/services/backupCodeService.d.ts +0 -35
- package/src/lib/services/backupCodeService.d.ts.map +0 -1
- package/src/lib/services/backupCodeService.js +0 -109
- package/src/lib/services/backupCodeService.js.map +0 -1
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserProfileService = void 0;
|
|
4
|
+
exports.createUserProfileService = createUserProfileService;
|
|
5
|
+
const brighthub_lib_1 = require("@brightchain/brighthub-lib");
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
7
|
+
/**
|
|
8
|
+
* Default pagination limit
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_PAGE_LIMIT = 20;
|
|
11
|
+
/**
|
|
12
|
+
* Maximum pagination limit
|
|
13
|
+
*/
|
|
14
|
+
const MAX_PAGE_LIMIT = 100;
|
|
15
|
+
/**
|
|
16
|
+
* User_Profile_Service implementation
|
|
17
|
+
* Handles user profiles, following, blocking, and muting
|
|
18
|
+
* @see Requirements: 4.1-4.11, 8.1-8.6, 18.1-18.6, 31.1-31.7
|
|
19
|
+
*/
|
|
20
|
+
class UserProfileService {
|
|
21
|
+
userProfilesCollection;
|
|
22
|
+
followsCollection;
|
|
23
|
+
followRequestsCollection;
|
|
24
|
+
blocksCollection;
|
|
25
|
+
mutesCollection;
|
|
26
|
+
constructor(application) {
|
|
27
|
+
this.userProfilesCollection = application.getModel('brighthub_user_profiles');
|
|
28
|
+
this.followsCollection =
|
|
29
|
+
application.getModel('brighthub_follows');
|
|
30
|
+
this.followRequestsCollection = application.getModel('brighthub_follow_requests');
|
|
31
|
+
this.blocksCollection =
|
|
32
|
+
application.getModel('brighthub_blocks');
|
|
33
|
+
this.mutesCollection = application.getModel('brighthub_mutes');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Convert a database record to the API response format
|
|
37
|
+
*/
|
|
38
|
+
recordToProfile(record) {
|
|
39
|
+
return {
|
|
40
|
+
_id: record._id,
|
|
41
|
+
username: record.username,
|
|
42
|
+
displayName: record.displayName,
|
|
43
|
+
bio: record.bio,
|
|
44
|
+
profilePictureUrl: record.profilePictureUrl,
|
|
45
|
+
headerImageUrl: record.headerImageUrl,
|
|
46
|
+
location: record.location,
|
|
47
|
+
websiteUrl: record.websiteUrl,
|
|
48
|
+
followerCount: record.followerCount,
|
|
49
|
+
followingCount: record.followingCount,
|
|
50
|
+
postCount: record.postCount,
|
|
51
|
+
isVerified: record.isVerified,
|
|
52
|
+
isProtected: record.isProtected,
|
|
53
|
+
approveFollowersMode: record.approveFollowersMode,
|
|
54
|
+
privacySettings: record.privacySettings,
|
|
55
|
+
createdAt: record.createdAt,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Convert a follow request record to the API response format
|
|
60
|
+
*/
|
|
61
|
+
recordToFollowRequest(record) {
|
|
62
|
+
return {
|
|
63
|
+
_id: record._id,
|
|
64
|
+
requesterId: record.requesterId,
|
|
65
|
+
targetId: record.targetId,
|
|
66
|
+
message: record.message,
|
|
67
|
+
status: record.status,
|
|
68
|
+
createdAt: record.createdAt,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get effective pagination limit
|
|
73
|
+
*/
|
|
74
|
+
getLimit(options) {
|
|
75
|
+
const limit = options?.limit ?? DEFAULT_PAGE_LIMIT;
|
|
76
|
+
return Math.min(Math.max(1, limit), MAX_PAGE_LIMIT);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if a user requires follow approval for a given requester
|
|
80
|
+
*/
|
|
81
|
+
async requiresApproval(targetProfile, requesterId) {
|
|
82
|
+
if (!targetProfile.isProtected) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
switch (targetProfile.approveFollowersMode) {
|
|
86
|
+
case brighthub_lib_1.ApproveFollowersMode.ApproveNone:
|
|
87
|
+
return false;
|
|
88
|
+
case brighthub_lib_1.ApproveFollowersMode.ApproveAll:
|
|
89
|
+
return true;
|
|
90
|
+
case brighthub_lib_1.ApproveFollowersMode.ApproveNonMutuals: {
|
|
91
|
+
// Check if target follows requester (mutual)
|
|
92
|
+
const isMutual = await this.isFollowing(targetProfile._id, requesterId);
|
|
93
|
+
return !isMutual;
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ═══════════════════════════════════════════════════════
|
|
100
|
+
// Follow Operations (Requirements 4.1-4.6)
|
|
101
|
+
// ═══════════════════════════════════════════════════════
|
|
102
|
+
/**
|
|
103
|
+
* Follow a user
|
|
104
|
+
* @see Requirements: 4.1, 4.3
|
|
105
|
+
*/
|
|
106
|
+
async follow(followerId, followedId, options) {
|
|
107
|
+
// Prevent self-follow
|
|
108
|
+
if (followerId === followedId) {
|
|
109
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.SelfFollowNotAllowed, 'You cannot follow yourself');
|
|
110
|
+
}
|
|
111
|
+
// Check if already following
|
|
112
|
+
const existingFollow = await this.followsCollection
|
|
113
|
+
.findOne({ followerId, followedId })
|
|
114
|
+
.exec();
|
|
115
|
+
if (existingFollow) {
|
|
116
|
+
return { success: true }; // Idempotent
|
|
117
|
+
}
|
|
118
|
+
// Check if blocked
|
|
119
|
+
const isBlocked = await this.isBlocked(followedId, followerId);
|
|
120
|
+
if (isBlocked) {
|
|
121
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserBlocked, 'You cannot follow this user');
|
|
122
|
+
}
|
|
123
|
+
// Get target user profile
|
|
124
|
+
const targetProfile = await this.userProfilesCollection
|
|
125
|
+
.findOne({ _id: followedId })
|
|
126
|
+
.exec();
|
|
127
|
+
if (!targetProfile) {
|
|
128
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
129
|
+
}
|
|
130
|
+
// Check if approval is required
|
|
131
|
+
const needsApproval = await this.requiresApproval(targetProfile, followerId);
|
|
132
|
+
if (needsApproval) {
|
|
133
|
+
// Check for existing pending request
|
|
134
|
+
const existingRequest = await this.followRequestsCollection
|
|
135
|
+
.findOne({
|
|
136
|
+
requesterId: followerId,
|
|
137
|
+
targetId: followedId,
|
|
138
|
+
status: brighthub_lib_1.FollowRequestStatus.Pending,
|
|
139
|
+
})
|
|
140
|
+
.exec();
|
|
141
|
+
if (existingRequest) {
|
|
142
|
+
return {
|
|
143
|
+
success: true,
|
|
144
|
+
requestCreated: false,
|
|
145
|
+
followRequest: this.recordToFollowRequest(existingRequest),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Create follow request
|
|
149
|
+
const now = new Date().toISOString();
|
|
150
|
+
const requestRecord = {
|
|
151
|
+
_id: (0, crypto_1.randomUUID)(),
|
|
152
|
+
requesterId: followerId,
|
|
153
|
+
targetId: followedId,
|
|
154
|
+
message: options?.message,
|
|
155
|
+
status: brighthub_lib_1.FollowRequestStatus.Pending,
|
|
156
|
+
createdAt: now,
|
|
157
|
+
};
|
|
158
|
+
const created = await this.followRequestsCollection.create(requestRecord);
|
|
159
|
+
return {
|
|
160
|
+
success: true,
|
|
161
|
+
requestCreated: true,
|
|
162
|
+
followRequest: this.recordToFollowRequest(created),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// Create follow relationship directly
|
|
166
|
+
await this.createFollowRelationship(followerId, followedId);
|
|
167
|
+
return { success: true };
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Create a follow relationship and update counts
|
|
171
|
+
*/
|
|
172
|
+
async createFollowRelationship(followerId, followedId) {
|
|
173
|
+
const now = new Date().toISOString();
|
|
174
|
+
// Create follow record
|
|
175
|
+
await this.followsCollection.create({
|
|
176
|
+
_id: (0, crypto_1.randomUUID)(),
|
|
177
|
+
followerId,
|
|
178
|
+
followedId,
|
|
179
|
+
createdAt: now,
|
|
180
|
+
});
|
|
181
|
+
// Update follower's following count
|
|
182
|
+
const followerProfile = await this.userProfilesCollection
|
|
183
|
+
.findOne({ _id: followerId })
|
|
184
|
+
.exec();
|
|
185
|
+
if (followerProfile) {
|
|
186
|
+
await this.userProfilesCollection
|
|
187
|
+
.updateOne({ _id: followerId }, {
|
|
188
|
+
followingCount: followerProfile.followingCount + 1,
|
|
189
|
+
updatedAt: now,
|
|
190
|
+
})
|
|
191
|
+
.exec();
|
|
192
|
+
}
|
|
193
|
+
// Update followed user's follower count
|
|
194
|
+
const followedProfile = await this.userProfilesCollection
|
|
195
|
+
.findOne({ _id: followedId })
|
|
196
|
+
.exec();
|
|
197
|
+
if (followedProfile) {
|
|
198
|
+
await this.userProfilesCollection
|
|
199
|
+
.updateOne({ _id: followedId }, {
|
|
200
|
+
followerCount: followedProfile.followerCount + 1,
|
|
201
|
+
updatedAt: now,
|
|
202
|
+
})
|
|
203
|
+
.exec();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Unfollow a user
|
|
208
|
+
* @see Requirements: 4.2
|
|
209
|
+
*/
|
|
210
|
+
async unfollow(followerId, followedId) {
|
|
211
|
+
// Check if following
|
|
212
|
+
const existingFollow = await this.followsCollection
|
|
213
|
+
.findOne({ followerId, followedId })
|
|
214
|
+
.exec();
|
|
215
|
+
if (!existingFollow) {
|
|
216
|
+
// Idempotent: not following, just return
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const now = new Date().toISOString();
|
|
220
|
+
// Delete follow record
|
|
221
|
+
await this.followsCollection.deleteOne({ _id: existingFollow._id }).exec();
|
|
222
|
+
// Update follower's following count
|
|
223
|
+
const followerProfile = await this.userProfilesCollection
|
|
224
|
+
.findOne({ _id: followerId })
|
|
225
|
+
.exec();
|
|
226
|
+
if (followerProfile && followerProfile.followingCount > 0) {
|
|
227
|
+
await this.userProfilesCollection
|
|
228
|
+
.updateOne({ _id: followerId }, {
|
|
229
|
+
followingCount: followerProfile.followingCount - 1,
|
|
230
|
+
updatedAt: now,
|
|
231
|
+
})
|
|
232
|
+
.exec();
|
|
233
|
+
}
|
|
234
|
+
// Update followed user's follower count
|
|
235
|
+
const followedProfile = await this.userProfilesCollection
|
|
236
|
+
.findOne({ _id: followedId })
|
|
237
|
+
.exec();
|
|
238
|
+
if (followedProfile && followedProfile.followerCount > 0) {
|
|
239
|
+
await this.userProfilesCollection
|
|
240
|
+
.updateOne({ _id: followedId }, {
|
|
241
|
+
followerCount: followedProfile.followerCount - 1,
|
|
242
|
+
updatedAt: now,
|
|
243
|
+
})
|
|
244
|
+
.exec();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Check if a user is following another user
|
|
249
|
+
*/
|
|
250
|
+
async isFollowing(followerId, followedId) {
|
|
251
|
+
const follow = await this.followsCollection
|
|
252
|
+
.findOne({ followerId, followedId })
|
|
253
|
+
.exec();
|
|
254
|
+
return !!follow;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get a user's followers
|
|
258
|
+
* @see Requirements: 4.4, 4.6
|
|
259
|
+
*/
|
|
260
|
+
async getFollowers(userId, options) {
|
|
261
|
+
const limit = this.getLimit(options);
|
|
262
|
+
const cursor = options?.cursor;
|
|
263
|
+
// Build query
|
|
264
|
+
const query = { followedId: userId };
|
|
265
|
+
// Get follows with pagination
|
|
266
|
+
let followsQuery = this.followsCollection.find(query);
|
|
267
|
+
if (followsQuery.sort) {
|
|
268
|
+
followsQuery = followsQuery.sort({ createdAt: -1 });
|
|
269
|
+
}
|
|
270
|
+
if (cursor && followsQuery.skip) {
|
|
271
|
+
followsQuery = followsQuery.skip(parseInt(cursor, 10));
|
|
272
|
+
}
|
|
273
|
+
if (followsQuery.limit) {
|
|
274
|
+
followsQuery = followsQuery.limit(limit + 1);
|
|
275
|
+
}
|
|
276
|
+
const follows = await followsQuery.exec();
|
|
277
|
+
const hasMore = follows.length > limit;
|
|
278
|
+
const items = follows.slice(0, limit);
|
|
279
|
+
// Get user profiles for followers
|
|
280
|
+
const profiles = [];
|
|
281
|
+
for (const follow of items) {
|
|
282
|
+
const profile = await this.userProfilesCollection
|
|
283
|
+
.findOne({ _id: follow.followerId })
|
|
284
|
+
.exec();
|
|
285
|
+
if (profile) {
|
|
286
|
+
profiles.push(this.recordToProfile(profile));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const nextCursor = hasMore
|
|
290
|
+
? String((cursor ? parseInt(cursor, 10) : 0) + limit)
|
|
291
|
+
: undefined;
|
|
292
|
+
return {
|
|
293
|
+
items: profiles,
|
|
294
|
+
cursor: nextCursor,
|
|
295
|
+
hasMore,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get users that a user is following
|
|
300
|
+
* @see Requirements: 4.5, 4.6
|
|
301
|
+
*/
|
|
302
|
+
async getFollowing(userId, options) {
|
|
303
|
+
const limit = this.getLimit(options);
|
|
304
|
+
const cursor = options?.cursor;
|
|
305
|
+
// Build query
|
|
306
|
+
const query = { followerId: userId };
|
|
307
|
+
// Get follows with pagination
|
|
308
|
+
let followsQuery = this.followsCollection.find(query);
|
|
309
|
+
if (followsQuery.sort) {
|
|
310
|
+
followsQuery = followsQuery.sort({ createdAt: -1 });
|
|
311
|
+
}
|
|
312
|
+
if (cursor && followsQuery.skip) {
|
|
313
|
+
followsQuery = followsQuery.skip(parseInt(cursor, 10));
|
|
314
|
+
}
|
|
315
|
+
if (followsQuery.limit) {
|
|
316
|
+
followsQuery = followsQuery.limit(limit + 1);
|
|
317
|
+
}
|
|
318
|
+
const follows = await followsQuery.exec();
|
|
319
|
+
const hasMore = follows.length > limit;
|
|
320
|
+
const items = follows.slice(0, limit);
|
|
321
|
+
// Get user profiles for followed users
|
|
322
|
+
const profiles = [];
|
|
323
|
+
for (const follow of items) {
|
|
324
|
+
const profile = await this.userProfilesCollection
|
|
325
|
+
.findOne({ _id: follow.followedId })
|
|
326
|
+
.exec();
|
|
327
|
+
if (profile) {
|
|
328
|
+
profiles.push(this.recordToProfile(profile));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const nextCursor = hasMore
|
|
332
|
+
? String((cursor ? parseInt(cursor, 10) : 0) + limit)
|
|
333
|
+
: undefined;
|
|
334
|
+
return {
|
|
335
|
+
items: profiles,
|
|
336
|
+
cursor: nextCursor,
|
|
337
|
+
hasMore,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
// ═══════════════════════════════════════════════════════
|
|
341
|
+
// Protected Account Features (Requirements 4.7-4.11)
|
|
342
|
+
// ═══════════════════════════════════════════════════════
|
|
343
|
+
/**
|
|
344
|
+
* Get pending follow requests for a user
|
|
345
|
+
* @see Requirements: 4.7, 4.8
|
|
346
|
+
*/
|
|
347
|
+
async getFollowRequests(userId, options) {
|
|
348
|
+
const limit = this.getLimit(options);
|
|
349
|
+
const cursor = options?.cursor;
|
|
350
|
+
// Build query for pending requests
|
|
351
|
+
const query = {
|
|
352
|
+
targetId: userId,
|
|
353
|
+
status: brighthub_lib_1.FollowRequestStatus.Pending,
|
|
354
|
+
};
|
|
355
|
+
// Get requests with pagination
|
|
356
|
+
let requestsQuery = this.followRequestsCollection.find(query);
|
|
357
|
+
if (requestsQuery.sort) {
|
|
358
|
+
requestsQuery = requestsQuery.sort({ createdAt: -1 });
|
|
359
|
+
}
|
|
360
|
+
if (cursor && requestsQuery.skip) {
|
|
361
|
+
requestsQuery = requestsQuery.skip(parseInt(cursor, 10));
|
|
362
|
+
}
|
|
363
|
+
if (requestsQuery.limit) {
|
|
364
|
+
requestsQuery = requestsQuery.limit(limit + 1);
|
|
365
|
+
}
|
|
366
|
+
const requests = await requestsQuery.exec();
|
|
367
|
+
const hasMore = requests.length > limit;
|
|
368
|
+
const items = requests.slice(0, limit);
|
|
369
|
+
const nextCursor = hasMore
|
|
370
|
+
? String((cursor ? parseInt(cursor, 10) : 0) + limit)
|
|
371
|
+
: undefined;
|
|
372
|
+
return {
|
|
373
|
+
items: items.map((r) => this.recordToFollowRequest(r)),
|
|
374
|
+
cursor: nextCursor,
|
|
375
|
+
hasMore,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Approve a follow request
|
|
380
|
+
* @see Requirements: 4.9
|
|
381
|
+
*/
|
|
382
|
+
async approveFollowRequest(userId, requestId) {
|
|
383
|
+
// Find the request
|
|
384
|
+
const request = await this.followRequestsCollection
|
|
385
|
+
.findOne({ _id: requestId })
|
|
386
|
+
.exec();
|
|
387
|
+
if (!request) {
|
|
388
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.FollowRequestNotFound, 'Follow request not found');
|
|
389
|
+
}
|
|
390
|
+
// Verify the request is for this user
|
|
391
|
+
if (request.targetId !== userId) {
|
|
392
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.Unauthorized, 'You can only approve requests sent to you');
|
|
393
|
+
}
|
|
394
|
+
// Verify the request is pending
|
|
395
|
+
if (request.status !== brighthub_lib_1.FollowRequestStatus.Pending) {
|
|
396
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.FollowRequestNotFound, 'Follow request is no longer pending');
|
|
397
|
+
}
|
|
398
|
+
// Update request status
|
|
399
|
+
await this.followRequestsCollection
|
|
400
|
+
.updateOne({ _id: requestId }, { status: brighthub_lib_1.FollowRequestStatus.Approved })
|
|
401
|
+
.exec();
|
|
402
|
+
// Create the follow relationship
|
|
403
|
+
await this.createFollowRelationship(request.requesterId, request.targetId);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Reject a follow request
|
|
407
|
+
* @see Requirements: 4.10
|
|
408
|
+
*/
|
|
409
|
+
async rejectFollowRequest(userId, requestId) {
|
|
410
|
+
// Find the request
|
|
411
|
+
const request = await this.followRequestsCollection
|
|
412
|
+
.findOne({ _id: requestId })
|
|
413
|
+
.exec();
|
|
414
|
+
if (!request) {
|
|
415
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.FollowRequestNotFound, 'Follow request not found');
|
|
416
|
+
}
|
|
417
|
+
// Verify the request is for this user
|
|
418
|
+
if (request.targetId !== userId) {
|
|
419
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.Unauthorized, 'You can only reject requests sent to you');
|
|
420
|
+
}
|
|
421
|
+
// Update request status
|
|
422
|
+
await this.followRequestsCollection
|
|
423
|
+
.updateOne({ _id: requestId }, { status: brighthub_lib_1.FollowRequestStatus.Rejected })
|
|
424
|
+
.exec();
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Set the approve followers mode for a user
|
|
428
|
+
* @see Requirements: 4.11
|
|
429
|
+
*/
|
|
430
|
+
async setApproveFollowersMode(userId, mode) {
|
|
431
|
+
const profile = await this.userProfilesCollection
|
|
432
|
+
.findOne({ _id: userId })
|
|
433
|
+
.exec();
|
|
434
|
+
if (!profile) {
|
|
435
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
436
|
+
}
|
|
437
|
+
const now = new Date().toISOString();
|
|
438
|
+
const isProtected = mode !== brighthub_lib_1.ApproveFollowersMode.ApproveNone;
|
|
439
|
+
await this.userProfilesCollection
|
|
440
|
+
.updateOne({ _id: userId }, {
|
|
441
|
+
approveFollowersMode: mode,
|
|
442
|
+
isProtected,
|
|
443
|
+
updatedAt: now,
|
|
444
|
+
})
|
|
445
|
+
.exec();
|
|
446
|
+
}
|
|
447
|
+
// ═══════════════════════════════════════════════════════
|
|
448
|
+
// Profile Management (Requirements 8.1-8.6)
|
|
449
|
+
// ═══════════════════════════════════════════════════════
|
|
450
|
+
/**
|
|
451
|
+
* Get a user's profile
|
|
452
|
+
* @see Requirements: 8.6
|
|
453
|
+
*/
|
|
454
|
+
async getProfile(userId, requesterId) {
|
|
455
|
+
const profile = await this.userProfilesCollection
|
|
456
|
+
.findOne({ _id: userId })
|
|
457
|
+
.exec();
|
|
458
|
+
if (!profile) {
|
|
459
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
460
|
+
}
|
|
461
|
+
const result = this.recordToProfile(profile);
|
|
462
|
+
// Apply privacy settings if requester is different from profile owner
|
|
463
|
+
if (requesterId && requesterId !== userId) {
|
|
464
|
+
const isFollower = await this.isFollowing(requesterId, userId);
|
|
465
|
+
// Hide counts if privacy settings require it
|
|
466
|
+
if (profile.privacySettings.hideFollowerCount) {
|
|
467
|
+
result.followerCount = -1; // Indicate hidden
|
|
468
|
+
}
|
|
469
|
+
if (profile.privacySettings.hideFollowingCount) {
|
|
470
|
+
result.followingCount = -1; // Indicate hidden
|
|
471
|
+
}
|
|
472
|
+
// Hide follower/following lists from non-followers
|
|
473
|
+
if (!isFollower &&
|
|
474
|
+
profile.privacySettings.hideFollowersFromNonFollowers) {
|
|
475
|
+
// The caller should check this flag when fetching followers list
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return result;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Update a user's display name
|
|
482
|
+
* @see Requirements: 8.1
|
|
483
|
+
*/
|
|
484
|
+
async updateDisplayName(userId, displayName) {
|
|
485
|
+
if (!displayName || displayName.trim().length === 0) {
|
|
486
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.InvalidDisplayName, 'Display name cannot be empty');
|
|
487
|
+
}
|
|
488
|
+
const profile = await this.userProfilesCollection
|
|
489
|
+
.findOne({ _id: userId })
|
|
490
|
+
.exec();
|
|
491
|
+
if (!profile) {
|
|
492
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
493
|
+
}
|
|
494
|
+
const now = new Date().toISOString();
|
|
495
|
+
await this.userProfilesCollection
|
|
496
|
+
.updateOne({ _id: userId }, { displayName: displayName.trim(), updatedAt: now })
|
|
497
|
+
.exec();
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Update a user's bio
|
|
501
|
+
* @see Requirements: 8.2
|
|
502
|
+
*/
|
|
503
|
+
async updateBio(userId, bio) {
|
|
504
|
+
if (bio.length > brighthub_lib_1.MAX_BIO_LENGTH) {
|
|
505
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.BioTooLong, `Bio cannot exceed ${brighthub_lib_1.MAX_BIO_LENGTH} characters`);
|
|
506
|
+
}
|
|
507
|
+
const profile = await this.userProfilesCollection
|
|
508
|
+
.findOne({ _id: userId })
|
|
509
|
+
.exec();
|
|
510
|
+
if (!profile) {
|
|
511
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
512
|
+
}
|
|
513
|
+
const now = new Date().toISOString();
|
|
514
|
+
await this.userProfilesCollection
|
|
515
|
+
.updateOne({ _id: userId }, { bio, updatedAt: now })
|
|
516
|
+
.exec();
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Validate image MIME type
|
|
520
|
+
*/
|
|
521
|
+
validateImageFormat(mimeType) {
|
|
522
|
+
if (!brighthub_lib_1.ALLOWED_PROFILE_IMAGE_TYPES.includes(mimeType)) {
|
|
523
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.InvalidImageFormat, `Invalid image format: ${mimeType}. Allowed: ${brighthub_lib_1.ALLOWED_PROFILE_IMAGE_TYPES.join(', ')}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Update a user's profile picture
|
|
528
|
+
* @see Requirements: 8.3
|
|
529
|
+
*/
|
|
530
|
+
async updateProfilePicture(userId, url, mimeType) {
|
|
531
|
+
this.validateImageFormat(mimeType);
|
|
532
|
+
const profile = await this.userProfilesCollection
|
|
533
|
+
.findOne({ _id: userId })
|
|
534
|
+
.exec();
|
|
535
|
+
if (!profile) {
|
|
536
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
537
|
+
}
|
|
538
|
+
const now = new Date().toISOString();
|
|
539
|
+
await this.userProfilesCollection
|
|
540
|
+
.updateOne({ _id: userId }, { profilePictureUrl: url, updatedAt: now })
|
|
541
|
+
.exec();
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Update a user's header image
|
|
545
|
+
* @see Requirements: 8.4
|
|
546
|
+
*/
|
|
547
|
+
async updateHeaderImage(userId, url, mimeType) {
|
|
548
|
+
this.validateImageFormat(mimeType);
|
|
549
|
+
const profile = await this.userProfilesCollection
|
|
550
|
+
.findOne({ _id: userId })
|
|
551
|
+
.exec();
|
|
552
|
+
if (!profile) {
|
|
553
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
554
|
+
}
|
|
555
|
+
const now = new Date().toISOString();
|
|
556
|
+
await this.userProfilesCollection
|
|
557
|
+
.updateOne({ _id: userId }, { headerImageUrl: url, updatedAt: now })
|
|
558
|
+
.exec();
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Update multiple profile fields at once
|
|
562
|
+
* @see Requirements: 8.1-8.5
|
|
563
|
+
*/
|
|
564
|
+
async updateProfile(userId, updates) {
|
|
565
|
+
const profile = await this.userProfilesCollection
|
|
566
|
+
.findOne({ _id: userId })
|
|
567
|
+
.exec();
|
|
568
|
+
if (!profile) {
|
|
569
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
570
|
+
}
|
|
571
|
+
// Validate updates
|
|
572
|
+
if (updates.displayName !== undefined) {
|
|
573
|
+
if (!updates.displayName || updates.displayName.trim().length === 0) {
|
|
574
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.InvalidDisplayName, 'Display name cannot be empty');
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (updates.bio !== undefined && updates.bio.length > brighthub_lib_1.MAX_BIO_LENGTH) {
|
|
578
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.BioTooLong, `Bio cannot exceed ${brighthub_lib_1.MAX_BIO_LENGTH} characters`);
|
|
579
|
+
}
|
|
580
|
+
const now = new Date().toISOString();
|
|
581
|
+
const updateFields = { updatedAt: now };
|
|
582
|
+
if (updates.displayName !== undefined) {
|
|
583
|
+
updateFields.displayName = updates.displayName.trim();
|
|
584
|
+
}
|
|
585
|
+
if (updates.bio !== undefined) {
|
|
586
|
+
updateFields.bio = updates.bio;
|
|
587
|
+
}
|
|
588
|
+
if (updates.profilePictureUrl !== undefined) {
|
|
589
|
+
updateFields.profilePictureUrl = updates.profilePictureUrl;
|
|
590
|
+
}
|
|
591
|
+
if (updates.headerImageUrl !== undefined) {
|
|
592
|
+
updateFields.headerImageUrl = updates.headerImageUrl;
|
|
593
|
+
}
|
|
594
|
+
if (updates.location !== undefined) {
|
|
595
|
+
updateFields.location = updates.location;
|
|
596
|
+
}
|
|
597
|
+
if (updates.websiteUrl !== undefined) {
|
|
598
|
+
updateFields.websiteUrl = updates.websiteUrl;
|
|
599
|
+
}
|
|
600
|
+
await this.userProfilesCollection
|
|
601
|
+
.updateOne({ _id: userId }, updateFields)
|
|
602
|
+
.exec();
|
|
603
|
+
const updated = await this.userProfilesCollection
|
|
604
|
+
.findOne({ _id: userId })
|
|
605
|
+
.exec();
|
|
606
|
+
if (!updated) {
|
|
607
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
608
|
+
}
|
|
609
|
+
return this.recordToProfile(updated);
|
|
610
|
+
}
|
|
611
|
+
// ═══════════════════════════════════════════════════════
|
|
612
|
+
// Block and Mute (Requirements 18.1-18.6)
|
|
613
|
+
// ═══════════════════════════════════════════════════════
|
|
614
|
+
/**
|
|
615
|
+
* Block a user
|
|
616
|
+
* @see Requirements: 18.1, 18.2
|
|
617
|
+
*/
|
|
618
|
+
async blockUser(blockerId, blockedId) {
|
|
619
|
+
// Prevent self-block
|
|
620
|
+
if (blockerId === blockedId) {
|
|
621
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.SelfBlockNotAllowed, 'You cannot block yourself');
|
|
622
|
+
}
|
|
623
|
+
// Check if already blocked (idempotent)
|
|
624
|
+
const existingBlock = await this.blocksCollection
|
|
625
|
+
.findOne({ blockerId, blockedId })
|
|
626
|
+
.exec();
|
|
627
|
+
if (existingBlock) {
|
|
628
|
+
return; // Already blocked
|
|
629
|
+
}
|
|
630
|
+
const now = new Date().toISOString();
|
|
631
|
+
// Create block record
|
|
632
|
+
await this.blocksCollection.create({
|
|
633
|
+
_id: (0, crypto_1.randomUUID)(),
|
|
634
|
+
blockerId,
|
|
635
|
+
blockedId,
|
|
636
|
+
createdAt: now,
|
|
637
|
+
});
|
|
638
|
+
// Remove any existing follow relationships (both directions)
|
|
639
|
+
// Blocker unfollows blocked
|
|
640
|
+
const blockerFollowsBlocked = await this.followsCollection
|
|
641
|
+
.findOne({ followerId: blockerId, followedId: blockedId })
|
|
642
|
+
.exec();
|
|
643
|
+
if (blockerFollowsBlocked) {
|
|
644
|
+
await this.unfollow(blockerId, blockedId);
|
|
645
|
+
}
|
|
646
|
+
// Blocked unfollows blocker
|
|
647
|
+
const blockedFollowsBlocker = await this.followsCollection
|
|
648
|
+
.findOne({ followerId: blockedId, followedId: blockerId })
|
|
649
|
+
.exec();
|
|
650
|
+
if (blockedFollowsBlocker) {
|
|
651
|
+
await this.unfollow(blockedId, blockerId);
|
|
652
|
+
}
|
|
653
|
+
// Cancel any pending follow requests (both directions)
|
|
654
|
+
await this.followRequestsCollection
|
|
655
|
+
.deleteOne({
|
|
656
|
+
requesterId: blockerId,
|
|
657
|
+
targetId: blockedId,
|
|
658
|
+
status: brighthub_lib_1.FollowRequestStatus.Pending,
|
|
659
|
+
})
|
|
660
|
+
.exec();
|
|
661
|
+
await this.followRequestsCollection
|
|
662
|
+
.deleteOne({
|
|
663
|
+
requesterId: blockedId,
|
|
664
|
+
targetId: blockerId,
|
|
665
|
+
status: brighthub_lib_1.FollowRequestStatus.Pending,
|
|
666
|
+
})
|
|
667
|
+
.exec();
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Unblock a user
|
|
671
|
+
* @see Requirements: 18.6
|
|
672
|
+
*/
|
|
673
|
+
async unblockUser(blockerId, blockedId) {
|
|
674
|
+
const existingBlock = await this.blocksCollection
|
|
675
|
+
.findOne({ blockerId, blockedId })
|
|
676
|
+
.exec();
|
|
677
|
+
if (!existingBlock) {
|
|
678
|
+
// Idempotent: not blocked, just return
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
await this.blocksCollection.deleteOne({ _id: existingBlock._id }).exec();
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Check if a user has blocked another user
|
|
685
|
+
*/
|
|
686
|
+
async isBlocked(blockerId, blockedId) {
|
|
687
|
+
const block = await this.blocksCollection
|
|
688
|
+
.findOne({ blockerId, blockedId })
|
|
689
|
+
.exec();
|
|
690
|
+
return !!block;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Get list of blocked users
|
|
694
|
+
* @see Requirements: 18.5
|
|
695
|
+
*/
|
|
696
|
+
async getBlockedUsers(userId, options) {
|
|
697
|
+
const limit = this.getLimit(options);
|
|
698
|
+
const cursor = options?.cursor;
|
|
699
|
+
// Build query
|
|
700
|
+
const query = { blockerId: userId };
|
|
701
|
+
// Get blocks with pagination
|
|
702
|
+
let blocksQuery = this.blocksCollection.find(query);
|
|
703
|
+
if (blocksQuery.sort) {
|
|
704
|
+
blocksQuery = blocksQuery.sort({ createdAt: -1 });
|
|
705
|
+
}
|
|
706
|
+
if (cursor && blocksQuery.skip) {
|
|
707
|
+
blocksQuery = blocksQuery.skip(parseInt(cursor, 10));
|
|
708
|
+
}
|
|
709
|
+
if (blocksQuery.limit) {
|
|
710
|
+
blocksQuery = blocksQuery.limit(limit + 1);
|
|
711
|
+
}
|
|
712
|
+
const blocks = await blocksQuery.exec();
|
|
713
|
+
const hasMore = blocks.length > limit;
|
|
714
|
+
const items = blocks.slice(0, limit);
|
|
715
|
+
// Get user profiles for blocked users
|
|
716
|
+
const profiles = [];
|
|
717
|
+
for (const block of items) {
|
|
718
|
+
const profile = await this.userProfilesCollection
|
|
719
|
+
.findOne({ _id: block.blockedId })
|
|
720
|
+
.exec();
|
|
721
|
+
if (profile) {
|
|
722
|
+
profiles.push(this.recordToProfile(profile));
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
const nextCursor = hasMore
|
|
726
|
+
? String((cursor ? parseInt(cursor, 10) : 0) + limit)
|
|
727
|
+
: undefined;
|
|
728
|
+
return {
|
|
729
|
+
items: profiles,
|
|
730
|
+
cursor: nextCursor,
|
|
731
|
+
hasMore,
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Mute a user
|
|
736
|
+
* @see Requirements: 18.3
|
|
737
|
+
*/
|
|
738
|
+
async muteUser(muterId, mutedId) {
|
|
739
|
+
// Prevent self-mute
|
|
740
|
+
if (muterId === mutedId) {
|
|
741
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.SelfMuteNotAllowed, 'You cannot mute yourself');
|
|
742
|
+
}
|
|
743
|
+
// Check if already muted (idempotent)
|
|
744
|
+
const existingMute = await this.mutesCollection
|
|
745
|
+
.findOne({ muterId, mutedId })
|
|
746
|
+
.exec();
|
|
747
|
+
if (existingMute) {
|
|
748
|
+
return; // Already muted
|
|
749
|
+
}
|
|
750
|
+
const now = new Date().toISOString();
|
|
751
|
+
// Create mute record
|
|
752
|
+
await this.mutesCollection.create({
|
|
753
|
+
_id: (0, crypto_1.randomUUID)(),
|
|
754
|
+
muterId,
|
|
755
|
+
mutedId,
|
|
756
|
+
createdAt: now,
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Unmute a user
|
|
761
|
+
* @see Requirements: 18.4
|
|
762
|
+
*/
|
|
763
|
+
async unmuteUser(muterId, mutedId) {
|
|
764
|
+
const existingMute = await this.mutesCollection
|
|
765
|
+
.findOne({ muterId, mutedId })
|
|
766
|
+
.exec();
|
|
767
|
+
if (!existingMute) {
|
|
768
|
+
// Idempotent: not muted, just return
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
await this.mutesCollection.deleteOne({ _id: existingMute._id }).exec();
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Check if a user has muted another user
|
|
775
|
+
*/
|
|
776
|
+
async isMuted(muterId, mutedId) {
|
|
777
|
+
const mute = await this.mutesCollection
|
|
778
|
+
.findOne({ muterId, mutedId })
|
|
779
|
+
.exec();
|
|
780
|
+
return !!mute;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Get list of muted users
|
|
784
|
+
* @see Requirements: 18.5
|
|
785
|
+
*/
|
|
786
|
+
async getMutedUsers(userId, options) {
|
|
787
|
+
const limit = this.getLimit(options);
|
|
788
|
+
const cursor = options?.cursor;
|
|
789
|
+
// Build query
|
|
790
|
+
const query = { muterId: userId };
|
|
791
|
+
// Get mutes with pagination
|
|
792
|
+
let mutesQuery = this.mutesCollection.find(query);
|
|
793
|
+
if (mutesQuery.sort) {
|
|
794
|
+
mutesQuery = mutesQuery.sort({ createdAt: -1 });
|
|
795
|
+
}
|
|
796
|
+
if (cursor && mutesQuery.skip) {
|
|
797
|
+
mutesQuery = mutesQuery.skip(parseInt(cursor, 10));
|
|
798
|
+
}
|
|
799
|
+
if (mutesQuery.limit) {
|
|
800
|
+
mutesQuery = mutesQuery.limit(limit + 1);
|
|
801
|
+
}
|
|
802
|
+
const mutes = await mutesQuery.exec();
|
|
803
|
+
const hasMore = mutes.length > limit;
|
|
804
|
+
const items = mutes.slice(0, limit);
|
|
805
|
+
// Get user profiles for muted users
|
|
806
|
+
const profiles = [];
|
|
807
|
+
for (const mute of items) {
|
|
808
|
+
const profile = await this.userProfilesCollection
|
|
809
|
+
.findOne({ _id: mute.mutedId })
|
|
810
|
+
.exec();
|
|
811
|
+
if (profile) {
|
|
812
|
+
profiles.push(this.recordToProfile(profile));
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
const nextCursor = hasMore
|
|
816
|
+
? String((cursor ? parseInt(cursor, 10) : 0) + limit)
|
|
817
|
+
: undefined;
|
|
818
|
+
return {
|
|
819
|
+
items: profiles,
|
|
820
|
+
cursor: nextCursor,
|
|
821
|
+
hasMore,
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
// ═══════════════════════════════════════════════════════
|
|
825
|
+
// Privacy Settings (Requirements 31.1-31.7)
|
|
826
|
+
// ═══════════════════════════════════════════════════════
|
|
827
|
+
/**
|
|
828
|
+
* Get a user's privacy settings
|
|
829
|
+
*/
|
|
830
|
+
async getPrivacySettings(userId) {
|
|
831
|
+
const profile = await this.userProfilesCollection
|
|
832
|
+
.findOne({ _id: userId })
|
|
833
|
+
.exec();
|
|
834
|
+
if (!profile) {
|
|
835
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
836
|
+
}
|
|
837
|
+
return profile.privacySettings;
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Update a user's privacy settings
|
|
841
|
+
* @see Requirements: 31.1-31.7
|
|
842
|
+
*/
|
|
843
|
+
async updatePrivacySettings(userId, settings) {
|
|
844
|
+
const profile = await this.userProfilesCollection
|
|
845
|
+
.findOne({ _id: userId })
|
|
846
|
+
.exec();
|
|
847
|
+
if (!profile) {
|
|
848
|
+
throw new brighthub_lib_1.UserProfileServiceError(brighthub_lib_1.UserProfileErrorCode.UserNotFound, 'User not found');
|
|
849
|
+
}
|
|
850
|
+
const updatedSettings = {
|
|
851
|
+
...profile.privacySettings,
|
|
852
|
+
...settings,
|
|
853
|
+
};
|
|
854
|
+
const now = new Date().toISOString();
|
|
855
|
+
await this.userProfilesCollection
|
|
856
|
+
.updateOne({ _id: userId }, { privacySettings: updatedSettings, updatedAt: now })
|
|
857
|
+
.exec();
|
|
858
|
+
return updatedSettings;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
exports.UserProfileService = UserProfileService;
|
|
862
|
+
/**
|
|
863
|
+
* Create a new UserProfileService instance
|
|
864
|
+
*/
|
|
865
|
+
function createUserProfileService(application) {
|
|
866
|
+
return new UserProfileService(application);
|
|
867
|
+
}
|
|
868
|
+
//# sourceMappingURL=userProfileService.js.map
|