@brightchain/brightchain-api-lib 0.18.2 → 0.21.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 (160) hide show
  1. package/package.json +8 -3
  2. package/src/index.d.ts +0 -1
  3. package/src/index.d.ts.map +1 -1
  4. package/src/index.js +0 -1
  5. package/src/index.js.map +1 -1
  6. package/src/lib/application.d.ts +12 -3
  7. package/src/lib/application.d.ts.map +1 -1
  8. package/src/lib/application.js +153 -7
  9. package/src/lib/application.js.map +1 -1
  10. package/src/lib/availability/gossipService.d.ts +59 -1
  11. package/src/lib/availability/gossipService.d.ts.map +1 -1
  12. package/src/lib/availability/gossipService.js +125 -1
  13. package/src/lib/availability/gossipService.js.map +1 -1
  14. package/src/lib/availability/index.d.ts +1 -0
  15. package/src/lib/availability/index.d.ts.map +1 -1
  16. package/src/lib/availability/index.js +1 -0
  17. package/src/lib/availability/index.js.map +1 -1
  18. package/src/lib/availability/quorumGossipHandler.d.ts +126 -0
  19. package/src/lib/availability/quorumGossipHandler.d.ts.map +1 -0
  20. package/src/lib/availability/quorumGossipHandler.js +246 -0
  21. package/src/lib/availability/quorumGossipHandler.js.map +1 -0
  22. package/src/lib/constants.d.ts.map +1 -1
  23. package/src/lib/constants.js +4 -0
  24. package/src/lib/constants.js.map +1 -1
  25. package/src/lib/controllers/api/quorum.d.ts +110 -2
  26. package/src/lib/controllers/api/quorum.d.ts.map +1 -1
  27. package/src/lib/controllers/api/quorum.js +389 -0
  28. package/src/lib/controllers/api/quorum.js.map +1 -1
  29. package/src/lib/controllers/api/user.d.ts +12 -15
  30. package/src/lib/controllers/api/user.d.ts.map +1 -1
  31. package/src/lib/controllers/api/user.js +312 -94
  32. package/src/lib/controllers/api/user.js.map +1 -1
  33. package/src/lib/databaseInit.d.ts +3 -2
  34. package/src/lib/databaseInit.d.ts.map +1 -1
  35. package/src/lib/databaseInit.js +24 -12
  36. package/src/lib/databaseInit.js.map +1 -1
  37. package/src/lib/datastore/index.d.ts +0 -1
  38. package/src/lib/datastore/index.d.ts.map +1 -1
  39. package/src/lib/datastore/index.js +0 -1
  40. package/src/lib/datastore/index.js.map +1 -1
  41. package/src/lib/environment.d.ts +6 -0
  42. package/src/lib/environment.d.ts.map +1 -1
  43. package/src/lib/environment.js +14 -0
  44. package/src/lib/environment.js.map +1 -1
  45. package/src/lib/hydration/energyAccountHydration.d.ts +17 -0
  46. package/src/lib/hydration/energyAccountHydration.d.ts.map +1 -0
  47. package/src/lib/hydration/energyAccountHydration.js +24 -0
  48. package/src/lib/hydration/energyAccountHydration.js.map +1 -0
  49. package/src/lib/hydration/index.d.ts +13 -0
  50. package/src/lib/hydration/index.d.ts.map +1 -0
  51. package/src/lib/hydration/index.js +21 -0
  52. package/src/lib/hydration/index.js.map +1 -0
  53. package/src/lib/hydration/rbacHydration.d.ts +28 -0
  54. package/src/lib/hydration/rbacHydration.d.ts.map +1 -0
  55. package/src/lib/hydration/rbacHydration.js +56 -0
  56. package/src/lib/hydration/rbacHydration.js.map +1 -0
  57. package/src/lib/interfaces/environment.d.ts +7 -1
  58. package/src/lib/interfaces/environment.d.ts.map +1 -1
  59. package/src/lib/interfaces/responses/api-backup-codes-response.d.ts +1 -1
  60. package/src/lib/interfaces/responses/api-code-count-response.d.ts +1 -1
  61. package/src/lib/interfaces/responses/api-password-change-response.d.ts +9 -0
  62. package/src/lib/interfaces/responses/api-password-change-response.d.ts.map +1 -0
  63. package/src/lib/interfaces/responses/api-password-change-response.js +3 -0
  64. package/src/lib/interfaces/responses/api-password-change-response.js.map +1 -0
  65. package/src/lib/interfaces/responses/api-recovery-response.d.ts +9 -0
  66. package/src/lib/interfaces/responses/api-recovery-response.d.ts.map +1 -0
  67. package/src/lib/interfaces/responses/api-recovery-response.js +3 -0
  68. package/src/lib/interfaces/responses/api-recovery-response.js.map +1 -0
  69. package/src/lib/interfaces/responses/index.d.ts +2 -0
  70. package/src/lib/interfaces/responses/index.d.ts.map +1 -1
  71. package/src/lib/interfaces/storage/client-session.d.ts +1 -1
  72. package/src/lib/interfaces/storage/client-session.d.ts.map +1 -1
  73. package/src/lib/interfaces/storage/collection.d.ts +1 -1
  74. package/src/lib/interfaces/storage/collection.d.ts.map +1 -1
  75. package/src/lib/interfaces/storage/database-lifecycle-hooks.d.ts +1 -1
  76. package/src/lib/interfaces/storage/database-lifecycle-hooks.d.ts.map +1 -1
  77. package/src/lib/interfaces/storage/database.d.ts +1 -1
  78. package/src/lib/interfaces/storage/database.d.ts.map +1 -1
  79. package/src/lib/interfaces/storage/document-types.d.ts +1 -1
  80. package/src/lib/interfaces/storage/document-types.d.ts.map +1 -1
  81. package/src/lib/interfaces/storage/index.d.ts +1 -0
  82. package/src/lib/interfaces/storage/index.d.ts.map +1 -1
  83. package/src/lib/interfaces/storage/index.js.map +1 -1
  84. package/src/lib/interfaces/storage/storedDocumentTypes.d.ts +73 -0
  85. package/src/lib/interfaces/storage/storedDocumentTypes.d.ts.map +1 -0
  86. package/src/lib/interfaces/storage/storedDocumentTypes.js +15 -0
  87. package/src/lib/interfaces/storage/storedDocumentTypes.js.map +1 -0
  88. package/src/lib/plugins/brightchain-database-plugin.d.ts +31 -21
  89. package/src/lib/plugins/brightchain-database-plugin.d.ts.map +1 -1
  90. package/src/lib/plugins/brightchain-database-plugin.js +103 -53
  91. package/src/lib/plugins/brightchain-database-plugin.js.map +1 -1
  92. package/src/lib/plugins/configure-brightchain-app.d.ts.map +1 -1
  93. package/src/lib/plugins/configure-brightchain-app.js +5 -0
  94. package/src/lib/plugins/configure-brightchain-app.js.map +1 -1
  95. package/src/lib/services/auth.d.ts +6 -2
  96. package/src/lib/services/auth.d.ts.map +1 -1
  97. package/src/lib/services/auth.js +43 -7
  98. package/src/lib/services/auth.js.map +1 -1
  99. package/src/lib/services/backupCodeService.d.ts +35 -0
  100. package/src/lib/services/backupCodeService.d.ts.map +1 -0
  101. package/src/lib/services/backupCodeService.js +109 -0
  102. package/src/lib/services/backupCodeService.js.map +1 -0
  103. package/src/lib/services/brightchain-authentication-provider.d.ts.map +1 -1
  104. package/src/lib/services/brightchain-authentication-provider.js +28 -9
  105. package/src/lib/services/brightchain-authentication-provider.js.map +1 -1
  106. package/src/lib/services/brightchain-member-init.service.d.ts +39 -20
  107. package/src/lib/services/brightchain-member-init.service.d.ts.map +1 -1
  108. package/src/lib/services/brightchain-member-init.service.js +139 -53
  109. package/src/lib/services/brightchain-member-init.service.js.map +1 -1
  110. package/src/lib/services/cliOperatorPrompt.d.ts +81 -0
  111. package/src/lib/services/cliOperatorPrompt.d.ts.map +1 -0
  112. package/src/lib/services/cliOperatorPrompt.js +177 -0
  113. package/src/lib/services/cliOperatorPrompt.js.map +1 -0
  114. package/src/lib/services/contentAwareBlocksService.d.ts +92 -0
  115. package/src/lib/services/contentAwareBlocksService.d.ts.map +1 -0
  116. package/src/lib/services/contentAwareBlocksService.js +102 -0
  117. package/src/lib/services/contentAwareBlocksService.js.map +1 -0
  118. package/src/lib/services/contentIngestionService.d.ts +68 -0
  119. package/src/lib/services/contentIngestionService.d.ts.map +1 -0
  120. package/src/lib/services/contentIngestionService.js +139 -0
  121. package/src/lib/services/contentIngestionService.js.map +1 -0
  122. package/src/lib/services/identityExpirationScheduler.d.ts +77 -0
  123. package/src/lib/services/identityExpirationScheduler.d.ts.map +1 -0
  124. package/src/lib/services/identityExpirationScheduler.js +157 -0
  125. package/src/lib/services/identityExpirationScheduler.js.map +1 -0
  126. package/src/lib/services/index.d.ts +7 -0
  127. package/src/lib/services/index.d.ts.map +1 -1
  128. package/src/lib/services/index.js +7 -0
  129. package/src/lib/services/index.js.map +1 -1
  130. package/src/lib/services/quorumDatabaseAdapter.d.ts +60 -0
  131. package/src/lib/services/quorumDatabaseAdapter.d.ts.map +1 -0
  132. package/src/lib/services/quorumDatabaseAdapter.js +652 -0
  133. package/src/lib/services/quorumDatabaseAdapter.js.map +1 -0
  134. package/src/lib/services/secureKeyStorage.js +3 -3
  135. package/src/lib/services/secureKeyStorage.js.map +1 -1
  136. package/src/lib/services/sessionAdapter.d.ts +62 -0
  137. package/src/lib/services/sessionAdapter.d.ts.map +1 -0
  138. package/src/lib/services/sessionAdapter.js +105 -0
  139. package/src/lib/services/sessionAdapter.js.map +1 -0
  140. package/src/lib/utils/rehydration.d.ts +31 -0
  141. package/src/lib/utils/rehydration.d.ts.map +1 -0
  142. package/src/lib/utils/rehydration.js +111 -0
  143. package/src/lib/utils/rehydration.js.map +1 -0
  144. package/src/lib/utils/serialization.d.ts +21 -0
  145. package/src/lib/utils/serialization.d.ts.map +1 -0
  146. package/src/lib/utils/serialization.js +41 -0
  147. package/src/lib/utils/serialization.js.map +1 -0
  148. package/src/lib/validation/userValidation.d.ts +17 -0
  149. package/src/lib/validation/userValidation.d.ts.map +1 -1
  150. package/src/lib/validation/userValidation.js +77 -0
  151. package/src/lib/validation/userValidation.js.map +1 -1
  152. package/src/lib/adapters/brightChainDbDocumentStoreAdapter.d.ts +0 -24
  153. package/src/lib/adapters/brightChainDbDocumentStoreAdapter.d.ts.map +0 -1
  154. package/src/lib/adapters/brightChainDbDocumentStoreAdapter.js +0 -53
  155. package/src/lib/adapters/brightChainDbDocumentStoreAdapter.js.map +0 -1
  156. package/src/lib/datastore/document-model-adapter.d.ts +0 -48
  157. package/src/lib/datastore/document-model-adapter.d.ts.map +0 -1
  158. package/src/lib/datastore/document-model-adapter.js +0 -178
  159. package/src/lib/datastore/document-model-adapter.js.map +0 -1
  160. /package/{brightchain-api-lib/README.md → README.md} +0 -0
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ /**
3
+ * CLIOperatorPrompt — Node.js readline-based implementation of IOperatorPrompt.
4
+ *
5
+ * Presents quorum proposals to the node operator via the terminal and collects
6
+ * vote decisions with password authentication on approve votes.
7
+ *
8
+ * Tracks failed authentication attempts per proposal and locks voting after
9
+ * a configurable number of consecutive failures for a cooldown period.
10
+ *
11
+ * This is a Node.js-specific service that lives in brightchain-api-lib.
12
+ *
13
+ * @see Requirements 6
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.CLIOperatorPrompt = void 0;
17
+ const tslib_1 = require("tslib");
18
+ const readline = tslib_1.__importStar(require("readline"));
19
+ // ─── Default Config ─────────────────────────────────────────────────────────
20
+ const DEFAULT_CONFIG = {
21
+ maxAttempts: 3,
22
+ cooldownMs: 300000, // 5 minutes
23
+ };
24
+ // ─── Implementation ─────────────────────────────────────────────────────────
25
+ /**
26
+ * CLI-based operator prompt for quorum voting.
27
+ *
28
+ * Uses Node.js readline to interact with the operator via stdin/stdout.
29
+ * Tracks failed authentication attempts per proposal and enforces lockout
30
+ * after the configured maximum failures.
31
+ */
32
+ class CLIOperatorPrompt {
33
+ constructor(config, rlFactory, output) {
34
+ this.lockoutMap = new Map();
35
+ this.config = { ...DEFAULT_CONFIG, ...config };
36
+ this.output = output ?? process.stdout;
37
+ this.rlFactory =
38
+ rlFactory ??
39
+ (() => readline.createInterface({
40
+ input: process.stdin,
41
+ output: this.output,
42
+ }));
43
+ }
44
+ /**
45
+ * Check if the voting interface is locked for a given proposal.
46
+ * Returns true if the operator has exceeded the maximum failed attempts
47
+ * and the cooldown period has not yet elapsed.
48
+ */
49
+ isLocked(proposalId) {
50
+ const state = this.lockoutMap.get(proposalId);
51
+ if (!state || state.lockedAt === null) {
52
+ return false;
53
+ }
54
+ const elapsed = Date.now() - state.lockedAt;
55
+ if (elapsed >= this.config.cooldownMs) {
56
+ // Cooldown expired — reset lockout state
57
+ state.failedAttempts = 0;
58
+ state.lockedAt = null;
59
+ return false;
60
+ }
61
+ return true;
62
+ }
63
+ /**
64
+ * Present a proposal to the operator and collect their vote.
65
+ * Displays proposal details, collects a vote decision, and on approve
66
+ * requires password authentication.
67
+ *
68
+ * @throws Error if the proposal is currently locked due to failed attempts
69
+ */
70
+ async promptForVote(proposal) {
71
+ if (this.isLocked(proposal.proposalId)) {
72
+ throw new Error(`Voting is locked for proposal ${proposal.proposalId}. Please wait for the cooldown period to expire.`);
73
+ }
74
+ const rl = this.rlFactory();
75
+ try {
76
+ this.displayProposal(proposal);
77
+ const decision = await this.collectDecision(rl);
78
+ if (decision === 'reject') {
79
+ return { decision: 'reject' };
80
+ }
81
+ // Approve path — collect password
82
+ const password = await this.collectPassword(rl);
83
+ if (!password) {
84
+ this.recordFailedAttempt(proposal.proposalId);
85
+ throw new Error('Authentication failed: empty password provided.');
86
+ }
87
+ // Reset failed attempts on successful authentication
88
+ this.resetAttempts(proposal.proposalId);
89
+ return { decision: 'approve', password };
90
+ }
91
+ finally {
92
+ rl.close();
93
+ }
94
+ }
95
+ // ─── Private Helpers ────────────────────────────────────────────────────
96
+ /**
97
+ * Display proposal details to the operator via the readline output.
98
+ */
99
+ displayProposal(proposal) {
100
+ this.output.write('\n══════════════════════════════════════════════════\n');
101
+ this.output.write(' QUORUM PROPOSAL — VOTE REQUIRED\n');
102
+ this.output.write('══════════════════════════════════════════════════\n\n');
103
+ this.output.write(` Proposal ID: ${proposal.proposalId}\n`);
104
+ this.output.write(` Description: ${proposal.description}\n`);
105
+ this.output.write(` Action Type: ${proposal.actionType}\n`);
106
+ this.output.write(` Action Payload: ${JSON.stringify(proposal.actionPayload, null, 2)}\n`);
107
+ this.output.write(` Proposer: ${proposal.proposerMemberId}\n`);
108
+ this.output.write(` Expires At: ${proposal.expiresAt.toISOString()}\n`);
109
+ if (proposal.attachmentCblId) {
110
+ this.output.write(` Attachment: CBL ${proposal.attachmentCblId}\n`);
111
+ }
112
+ if (proposal.attachmentContent) {
113
+ this.output.write(` Attachment Size: ${proposal.attachmentContent.byteLength} bytes\n`);
114
+ }
115
+ this.output.write('\n──────────────────────────────────────────────────\n');
116
+ }
117
+ /**
118
+ * Prompt the operator for their vote decision (approve or reject).
119
+ */
120
+ collectDecision(rl) {
121
+ return new Promise((resolve) => {
122
+ const ask = () => {
123
+ rl.question(' Enter your vote (approve/reject): ', (answer) => {
124
+ const normalized = answer.trim().toLowerCase();
125
+ if (normalized === 'approve' || normalized === 'reject') {
126
+ resolve(normalized);
127
+ }
128
+ else {
129
+ this.output.write(' Invalid input. Please enter "approve" or "reject".\n');
130
+ ask();
131
+ }
132
+ });
133
+ };
134
+ ask();
135
+ });
136
+ }
137
+ /**
138
+ * Prompt the operator for their password to authenticate the approve vote.
139
+ */
140
+ collectPassword(rl) {
141
+ return new Promise((resolve) => {
142
+ rl.question(' Enter your password to authenticate: ', (answer) => {
143
+ resolve(answer);
144
+ });
145
+ });
146
+ }
147
+ /**
148
+ * Record a failed authentication attempt for a proposal.
149
+ * If the maximum attempts are reached, trigger lockout.
150
+ */
151
+ recordFailedAttempt(proposalId) {
152
+ let state = this.lockoutMap.get(proposalId);
153
+ if (!state) {
154
+ state = { failedAttempts: 0, lockedAt: null };
155
+ this.lockoutMap.set(proposalId, state);
156
+ }
157
+ state.failedAttempts += 1;
158
+ if (state.failedAttempts >= this.config.maxAttempts) {
159
+ state.lockedAt = Date.now();
160
+ }
161
+ }
162
+ /**
163
+ * Record a failed attempt externally (for use when authentication
164
+ * is validated outside this class, e.g., by the QuorumStateMachine).
165
+ */
166
+ recordAuthFailure(proposalId) {
167
+ this.recordFailedAttempt(proposalId);
168
+ }
169
+ /**
170
+ * Reset failed attempts for a proposal (on successful authentication).
171
+ */
172
+ resetAttempts(proposalId) {
173
+ this.lockoutMap.delete(proposalId);
174
+ }
175
+ }
176
+ exports.CLIOperatorPrompt = CLIOperatorPrompt;
177
+ //# sourceMappingURL=cliOperatorPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliOperatorPrompt.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/cliOperatorPrompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @fileoverview ContentAwareBlocksService — wraps BlocksService with identity
3
+ * validation and sealing via ContentIngestionService.
4
+ *
5
+ * Content is only accepted into the block store after:
6
+ * 1. Identity validation passes (signature, alias, membership proof, ban check)
7
+ * 2. Identity sealing completes (shard generation, distribution, identity replacement)
8
+ *
9
+ * @see Requirements 16
10
+ * @see Design: Content Ingestion Pipeline Integration (Task 19.2)
11
+ */
12
+ import { BlockStoreOptions, BrightenResult, ContentIngestionResult, ContentWithIdentity, IBlockMetadata, IContentIngestionService, IdentityValidationError, QuorumError } from '@brightchain/brightchain-lib';
13
+ import { Member, PlatformID } from '@digitaldefiance/ecies-lib';
14
+ import { DefaultBackendIdType } from '../shared-types';
15
+ import { BlocksService } from './blocks';
16
+ /**
17
+ * Result of storing a block with identity validation and sealing.
18
+ */
19
+ export interface ContentAwareStoreResult<TID extends PlatformID = Uint8Array> {
20
+ /** Block store result */
21
+ blockId: string;
22
+ metadata?: IBlockMetadata;
23
+ /** Identity ingestion result */
24
+ ingestion: ContentIngestionResult<TID>;
25
+ }
26
+ /**
27
+ * ContentAwareBlocksService wraps BlocksService with identity validation
28
+ * and sealing. Content is only stored after successful validation and
29
+ * shard distribution.
30
+ *
31
+ * @template TID - Platform ID type for frontend/backend DTO compatibility
32
+ */
33
+ export declare class ContentAwareBlocksService<TID extends PlatformID = DefaultBackendIdType> {
34
+ private readonly blocksService;
35
+ private readonly contentIngestionService;
36
+ constructor(blocksService: BlocksService<TID>, contentIngestionService: IContentIngestionService<TID>);
37
+ /**
38
+ * Store a block with identity validation and sealing.
39
+ *
40
+ * Flow:
41
+ * 1. Validate and seal identity via ContentIngestionService
42
+ * 2. Store the block via BlocksService (only if step 1 succeeds)
43
+ * 3. Return combined result
44
+ *
45
+ * @param dataBuffer - The raw block data
46
+ * @param member - The authenticated member
47
+ * @param content - The content identity metadata for validation/sealing
48
+ * @param canRead - Whether the block can be read
49
+ * @param canPersist - Whether the block can be persisted
50
+ * @param options - Block store options
51
+ * @returns Combined block store and ingestion result
52
+ * @throws IdentityValidationError if identity validation fails
53
+ * @throws QuorumError if identity sealing fails
54
+ */
55
+ storeBlockWithIdentity(dataBuffer: Buffer, member: Member, content: ContentWithIdentity<TID>, canRead?: boolean, canPersist?: boolean, options?: BlockStoreOptions): Promise<ContentAwareStoreResult<TID>>;
56
+ /**
57
+ * Store a block without identity validation (passthrough to BlocksService).
58
+ * Use this for system-internal blocks that don't carry user identity.
59
+ */
60
+ storeBlock(dataBuffer: Buffer, member: Member, canRead?: boolean, canPersist?: boolean, options?: BlockStoreOptions): Promise<{
61
+ blockId: string;
62
+ metadata?: IBlockMetadata;
63
+ }>;
64
+ /**
65
+ * Get a block by ID (passthrough to BlocksService).
66
+ */
67
+ getBlock(blockId: string): Promise<{
68
+ data: Buffer;
69
+ metadata?: IBlockMetadata;
70
+ }>;
71
+ /**
72
+ * Get block metadata (passthrough to BlocksService).
73
+ */
74
+ getBlockMetadata(blockId: string): Promise<IBlockMetadata | null>;
75
+ /**
76
+ * Delete a block (passthrough to BlocksService).
77
+ */
78
+ deleteBlock(blockId: string): Promise<void>;
79
+ /**
80
+ * Brighten a block (passthrough to BlocksService).
81
+ */
82
+ brightenBlock(blockId: string, randomBlockCount: number): Promise<BrightenResult>;
83
+ /**
84
+ * Create a rejection from an IdentityValidationError.
85
+ */
86
+ static createRejection(error: IdentityValidationError): import("@brightchain/brightchain-lib").ContentIngestionRejection;
87
+ /**
88
+ * Create a rejection from a QuorumError.
89
+ */
90
+ static createSealingRejection(error: QuorumError): import("@brightchain/brightchain-lib").ContentIngestionRejection;
91
+ }
92
+ //# sourceMappingURL=contentAwareBlocksService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentAwareBlocksService.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/contentAwareBlocksService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACxB,uBAAuB,EACvB,WAAW,EACZ,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU;IAC1E,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,gCAAgC;IAChC,SAAS,EAAE,sBAAsB,CAAC,GAAG,CAAC,CAAC;CACxC;AAED;;;;;;GAMG;AACH,qBAAa,yBAAyB,CACpC,GAAG,SAAS,UAAU,GAAG,oBAAoB;IAG3C,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,uBAAuB;gBADvB,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,EACjC,uBAAuB,EAAE,wBAAwB,CAAC,GAAG,CAAC;IAGzE;;;;;;;;;;;;;;;;;OAiBG;IACG,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,mBAAmB,CAAC,GAAG,CAAC,EACjC,OAAO,UAAO,EACd,UAAU,UAAO,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAqBxC;;;OAGG;IACG,UAAU,CACd,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,UAAO,EACd,UAAU,UAAO,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC;IAU1D;;OAEG;IACG,QAAQ,CACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC;IAIvD;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAIvE;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD;;OAEG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,cAAc,CAAC;IAI1B;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,uBAAuB;IAIrD;;OAEG;IACH,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,WAAW;CAGjD"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview ContentAwareBlocksService — wraps BlocksService with identity
4
+ * validation and sealing via ContentIngestionService.
5
+ *
6
+ * Content is only accepted into the block store after:
7
+ * 1. Identity validation passes (signature, alias, membership proof, ban check)
8
+ * 2. Identity sealing completes (shard generation, distribution, identity replacement)
9
+ *
10
+ * @see Requirements 16
11
+ * @see Design: Content Ingestion Pipeline Integration (Task 19.2)
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.ContentAwareBlocksService = void 0;
15
+ const contentIngestionService_1 = require("./contentIngestionService");
16
+ /**
17
+ * ContentAwareBlocksService wraps BlocksService with identity validation
18
+ * and sealing. Content is only stored after successful validation and
19
+ * shard distribution.
20
+ *
21
+ * @template TID - Platform ID type for frontend/backend DTO compatibility
22
+ */
23
+ class ContentAwareBlocksService {
24
+ constructor(blocksService, contentIngestionService) {
25
+ this.blocksService = blocksService;
26
+ this.contentIngestionService = contentIngestionService;
27
+ }
28
+ /**
29
+ * Store a block with identity validation and sealing.
30
+ *
31
+ * Flow:
32
+ * 1. Validate and seal identity via ContentIngestionService
33
+ * 2. Store the block via BlocksService (only if step 1 succeeds)
34
+ * 3. Return combined result
35
+ *
36
+ * @param dataBuffer - The raw block data
37
+ * @param member - The authenticated member
38
+ * @param content - The content identity metadata for validation/sealing
39
+ * @param canRead - Whether the block can be read
40
+ * @param canPersist - Whether the block can be persisted
41
+ * @param options - Block store options
42
+ * @returns Combined block store and ingestion result
43
+ * @throws IdentityValidationError if identity validation fails
44
+ * @throws QuorumError if identity sealing fails
45
+ */
46
+ async storeBlockWithIdentity(dataBuffer, member, content, canRead = true, canPersist = true, options) {
47
+ // Step 1: Validate and seal identity — block store write is gated on this
48
+ const ingestionResult = await this.contentIngestionService.processContent(content);
49
+ // Step 2: Store the block only after successful validation and sealing
50
+ const storeResult = await this.blocksService.storeBlock(dataBuffer, member, canRead, canPersist, options);
51
+ return {
52
+ blockId: storeResult.blockId,
53
+ metadata: storeResult.metadata,
54
+ ingestion: ingestionResult,
55
+ };
56
+ }
57
+ /**
58
+ * Store a block without identity validation (passthrough to BlocksService).
59
+ * Use this for system-internal blocks that don't carry user identity.
60
+ */
61
+ async storeBlock(dataBuffer, member, canRead = true, canPersist = true, options) {
62
+ return this.blocksService.storeBlock(dataBuffer, member, canRead, canPersist, options);
63
+ }
64
+ /**
65
+ * Get a block by ID (passthrough to BlocksService).
66
+ */
67
+ async getBlock(blockId) {
68
+ return this.blocksService.getBlock(blockId);
69
+ }
70
+ /**
71
+ * Get block metadata (passthrough to BlocksService).
72
+ */
73
+ async getBlockMetadata(blockId) {
74
+ return this.blocksService.getBlockMetadata(blockId);
75
+ }
76
+ /**
77
+ * Delete a block (passthrough to BlocksService).
78
+ */
79
+ async deleteBlock(blockId) {
80
+ return this.blocksService.deleteBlock(blockId);
81
+ }
82
+ /**
83
+ * Brighten a block (passthrough to BlocksService).
84
+ */
85
+ async brightenBlock(blockId, randomBlockCount) {
86
+ return this.blocksService.brightenBlock(blockId, randomBlockCount);
87
+ }
88
+ /**
89
+ * Create a rejection from an IdentityValidationError.
90
+ */
91
+ static createRejection(error) {
92
+ return contentIngestionService_1.ContentIngestionService.createRejection(error);
93
+ }
94
+ /**
95
+ * Create a rejection from a QuorumError.
96
+ */
97
+ static createSealingRejection(error) {
98
+ return contentIngestionService_1.ContentIngestionService.createSealingRejection(error);
99
+ }
100
+ }
101
+ exports.ContentAwareBlocksService = ContentAwareBlocksService;
102
+ //# sourceMappingURL=contentAwareBlocksService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentAwareBlocksService.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/contentAwareBlocksService.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAeH,uEAAoE;AAapE;;;;;;GAMG;AACH,MAAa,yBAAyB;IAGpC,YACmB,aAAiC,EACjC,uBAAsD;QADtD,kBAAa,GAAb,aAAa,CAAoB;QACjC,4BAAuB,GAAvB,uBAAuB,CAA+B;IACtE,CAAC;IAEJ;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,sBAAsB,CAC1B,UAAkB,EAClB,MAAc,EACd,OAAiC,EACjC,OAAO,GAAG,IAAI,EACd,UAAU,GAAG,IAAI,EACjB,OAA2B;QAE3B,0EAA0E;QAC1E,MAAM,eAAe,GACnB,MAAM,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAE7D,uEAAuE;QACvE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CACrD,UAAU,EACV,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAO,CACR,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,SAAS,EAAE,eAAe;SAC3B,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CACd,UAAkB,EAClB,MAAc,EACd,OAAO,GAAG,IAAI,EACd,UAAU,GAAG,IAAI,EACjB,OAA2B;QAE3B,OAAO,IAAI,CAAC,aAAa,CAAC,UAAU,CAClC,UAAU,EACV,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CACZ,OAAe;QAEf,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAAe;QACpC,OAAO,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,OAAe,EACf,gBAAwB;QAExB,OAAO,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAA8B;QACnD,OAAO,iDAAuB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,sBAAsB,CAAC,KAAkB;QAC9C,OAAO,iDAAuB,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;CACF;AAxHD,8DAwHC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @fileoverview ContentIngestionService — wires identity validation and sealing
3
+ * into the content ingestion path.
4
+ *
5
+ * Before content is accepted into the block store, this service:
6
+ * 1. Validates the content identity via IdentityValidator
7
+ * 2. Seals the identity via IdentitySealingPipeline (generates shards, replaces identity)
8
+ * 3. Returns the processed content ready for block store acceptance
9
+ *
10
+ * @see Requirements 16
11
+ * @see Design: Content Ingestion Pipeline Integration (Task 19)
12
+ */
13
+ import { ContentIngestionRejection, ContentIngestionResult, ContentWithIdentity, IContentIngestionService, IdentityValidationError, IIdentitySealingPipeline, IIdentityValidator, QuorumError } from '@brightchain/brightchain-lib';
14
+ import { PlatformID } from '@digitaldefiance/ecies-lib';
15
+ /**
16
+ * ContentIngestionService orchestrates identity validation and sealing
17
+ * before content is accepted into the block store.
18
+ *
19
+ * @template TID - Platform ID type for frontend/backend DTO compatibility
20
+ */
21
+ export declare class ContentIngestionService<TID extends PlatformID = Uint8Array> implements IContentIngestionService<TID> {
22
+ private readonly identityValidator;
23
+ private readonly identitySealingPipeline;
24
+ constructor(identityValidator: IIdentityValidator<TID>, identitySealingPipeline: IIdentitySealingPipeline<TID>);
25
+ /**
26
+ * Process content through identity validation and sealing.
27
+ *
28
+ * Steps:
29
+ * 1. Validate identity (signature, alias status, membership proof, ban/suspend check)
30
+ * 2. Seal identity (generate shards, replace identity field, distribute encrypted shards)
31
+ * 3. Return processed content with recovery record ID
32
+ *
33
+ * @param content - The content with identity to validate and seal
34
+ * @returns Ingestion result with processed content
35
+ * @throws IdentityValidationError with specific error type on validation failure
36
+ * @throws QuorumError with IdentitySealingFailed on sealing failure
37
+ */
38
+ processContent(content: ContentWithIdentity<TID>): Promise<ContentIngestionResult<TID>>;
39
+ /**
40
+ * Resolve the alias name from content's identity recovery record.
41
+ * The IdentityValidator already confirmed the alias exists and is active,
42
+ * so the sealing pipeline handles alias lookup internally.
43
+ */
44
+ private resolveAliasName;
45
+ /**
46
+ * Create a rejection result from an IdentityValidationError.
47
+ *
48
+ * @param error - The validation error
49
+ * @returns A structured rejection result
50
+ */
51
+ static createRejection(error: IdentityValidationError): ContentIngestionRejection;
52
+ /**
53
+ * Create a rejection result from a QuorumError (sealing failure).
54
+ *
55
+ * @param error - The quorum error
56
+ * @returns A structured rejection result
57
+ */
58
+ static createSealingRejection(error: QuorumError): ContentIngestionRejection;
59
+ /**
60
+ * Determine if an error is an IdentityValidationError.
61
+ */
62
+ static isValidationError(error: unknown): error is IdentityValidationError;
63
+ /**
64
+ * Determine if an error is a QuorumError.
65
+ */
66
+ static isQuorumError(error: unknown): error is QuorumError;
67
+ }
68
+ //# sourceMappingURL=contentIngestionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentIngestionService.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/contentIngestionService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EAEvB,wBAAwB,EACxB,kBAAkB,EAClB,WAAW,EAEZ,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAwBxD;;;;;GAKG;AACH,qBAAa,uBAAuB,CAClC,GAAG,SAAS,UAAU,GAAG,UAAU,CACnC,YAAW,wBAAwB,CAAC,GAAG,CAAC;IAEtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;gBADvB,iBAAiB,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAC1C,uBAAuB,EAAE,wBAAwB,CAAC,GAAG,CAAC;IAGzE;;;;;;;;;;;;OAYG;IACG,cAAc,CAClB,OAAO,EAAE,mBAAmB,CAAC,GAAG,CAAC,GAChC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;IA2BvC;;;;OAIG;YACW,gBAAgB;IAS9B;;;;;OAKG;IACH,MAAM,CAAC,eAAe,CACpB,KAAK,EAAE,uBAAuB,GAC7B,yBAAyB;IAW5B;;;;;OAKG;IACH,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,yBAAyB;IAwB5E;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,uBAAuB;IAI1E;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW;CAG3D"}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview ContentIngestionService — wires identity validation and sealing
4
+ * into the content ingestion path.
5
+ *
6
+ * Before content is accepted into the block store, this service:
7
+ * 1. Validates the content identity via IdentityValidator
8
+ * 2. Seals the identity via IdentitySealingPipeline (generates shards, replaces identity)
9
+ * 3. Returns the processed content ready for block store acceptance
10
+ *
11
+ * @see Requirements 16
12
+ * @see Design: Content Ingestion Pipeline Integration (Task 19)
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ContentIngestionService = void 0;
16
+ const brightchain_lib_1 = require("@brightchain/brightchain-lib");
17
+ /**
18
+ * Human-readable error messages for each IdentityValidationErrorType.
19
+ */
20
+ const VALIDATION_ERROR_MESSAGES = {
21
+ [brightchain_lib_1.IdentityValidationErrorType.InvalidSignature]: 'Content signature does not match the claimed identity public key',
22
+ [brightchain_lib_1.IdentityValidationErrorType.UnregisteredAlias]: 'The alias used for content publication is not registered',
23
+ [brightchain_lib_1.IdentityValidationErrorType.InactiveAlias]: 'The alias used for content publication has been deactivated',
24
+ [brightchain_lib_1.IdentityValidationErrorType.InvalidMembershipProof]: 'The membership proof for anonymous content is invalid',
25
+ [brightchain_lib_1.IdentityValidationErrorType.MissingMembershipProof]: 'Anonymous content must include a valid membership proof',
26
+ [brightchain_lib_1.IdentityValidationErrorType.BannedUser]: 'The content creator has been banned from the network',
27
+ [brightchain_lib_1.IdentityValidationErrorType.SuspendedUser]: 'The content creator is currently suspended',
28
+ [brightchain_lib_1.IdentityValidationErrorType.ShardVerificationFailed]: 'Identity shard verification failed during sealing',
29
+ };
30
+ /**
31
+ * ContentIngestionService orchestrates identity validation and sealing
32
+ * before content is accepted into the block store.
33
+ *
34
+ * @template TID - Platform ID type for frontend/backend DTO compatibility
35
+ */
36
+ class ContentIngestionService {
37
+ constructor(identityValidator, identitySealingPipeline) {
38
+ this.identityValidator = identityValidator;
39
+ this.identitySealingPipeline = identitySealingPipeline;
40
+ }
41
+ /**
42
+ * Process content through identity validation and sealing.
43
+ *
44
+ * Steps:
45
+ * 1. Validate identity (signature, alias status, membership proof, ban/suspend check)
46
+ * 2. Seal identity (generate shards, replace identity field, distribute encrypted shards)
47
+ * 3. Return processed content with recovery record ID
48
+ *
49
+ * @param content - The content with identity to validate and seal
50
+ * @returns Ingestion result with processed content
51
+ * @throws IdentityValidationError with specific error type on validation failure
52
+ * @throws QuorumError with IdentitySealingFailed on sealing failure
53
+ */
54
+ async processContent(content) {
55
+ // Step 1: Validate identity
56
+ const validationResult = await this.identityValidator.validateContent(content);
57
+ // Step 2: Determine alias name for alias mode
58
+ let aliasName;
59
+ if (validationResult.identityMode === brightchain_lib_1.IdentityMode.Alias) {
60
+ aliasName = await this.resolveAliasName(content);
61
+ }
62
+ // Step 3: Seal identity through the pipeline
63
+ const sealingResult = await this.identitySealingPipeline.sealIdentity(content, validationResult.identityMode, aliasName);
64
+ return {
65
+ accepted: true,
66
+ processedContent: sealingResult.modifiedContent,
67
+ recoveryRecordId: sealingResult.recoveryRecordId,
68
+ identityMode: validationResult.identityMode,
69
+ resolvedMemberId: validationResult.resolvedMemberId,
70
+ };
71
+ }
72
+ /**
73
+ * Resolve the alias name from content's identity recovery record.
74
+ * The IdentityValidator already confirmed the alias exists and is active,
75
+ * so the sealing pipeline handles alias lookup internally.
76
+ */
77
+ async resolveAliasName(_content) {
78
+ // The alias name is determined by the IdentitySealingPipeline
79
+ // based on the content's identityRecoveryRecordId.
80
+ // The sealing pipeline handles alias lookup internally.
81
+ return undefined;
82
+ }
83
+ /**
84
+ * Create a rejection result from an IdentityValidationError.
85
+ *
86
+ * @param error - The validation error
87
+ * @returns A structured rejection result
88
+ */
89
+ static createRejection(error) {
90
+ const errorType = error.type;
91
+ return {
92
+ accepted: false,
93
+ reason: VALIDATION_ERROR_MESSAGES[errorType] ??
94
+ `Identity validation failed: ${errorType}`,
95
+ errorType,
96
+ };
97
+ }
98
+ /**
99
+ * Create a rejection result from a QuorumError (sealing failure).
100
+ *
101
+ * @param error - The quorum error
102
+ * @returns A structured rejection result
103
+ */
104
+ static createSealingRejection(error) {
105
+ const errorType = error.type;
106
+ let reason;
107
+ switch (errorType) {
108
+ case brightchain_lib_1.QuorumErrorType.IdentitySealingFailed:
109
+ reason =
110
+ 'Identity sealing failed during shard generation or distribution';
111
+ break;
112
+ case brightchain_lib_1.QuorumErrorType.ShardVerificationFailed:
113
+ reason =
114
+ 'Identity shard verification failed — shards do not reconstruct correctly';
115
+ break;
116
+ default:
117
+ reason = `Identity sealing failed: ${errorType}`;
118
+ }
119
+ return {
120
+ accepted: false,
121
+ reason,
122
+ errorType: 'IDENTITY_SEALING_FAILED',
123
+ };
124
+ }
125
+ /**
126
+ * Determine if an error is an IdentityValidationError.
127
+ */
128
+ static isValidationError(error) {
129
+ return error instanceof brightchain_lib_1.IdentityValidationError;
130
+ }
131
+ /**
132
+ * Determine if an error is a QuorumError.
133
+ */
134
+ static isQuorumError(error) {
135
+ return error instanceof brightchain_lib_1.QuorumError;
136
+ }
137
+ }
138
+ exports.ContentIngestionService = ContentIngestionService;
139
+ //# sourceMappingURL=contentIngestionService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentIngestionService.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/contentIngestionService.ts"],"names":[],"mappings":"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"}