Skip to content

Commit 285a18d

Browse files
feat: integrate user change password batching flow
Ticket: WP-7566 TICKET: WP-7566
1 parent ca9bdb3 commit 285a18d

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

modules/sdk-api/src/bitgoAPI.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,18 @@ export class BitGoAPI implements BitGoBase {
19321932
password: this.calculateHMAC(user.username, newPassword),
19331933
};
19341934

1935+
// Check if batching flow is enabled
1936+
const batchingFlowCheck = await this.get(this.url('/user/checkBatchingPasswordFlow', 2)).result();
1937+
1938+
if (batchingFlowCheck.isBatchingFlowEnabled) {
1939+
await this.processKeychainPasswordUpdatesInBatches(
1940+
updatePasswordParams.keychains,
1941+
updatePasswordParams.v2_keychains,
1942+
batchingFlowCheck.noOfBatches,
1943+
3
1944+
);
1945+
}
1946+
19351947
return this.post(this.url('/user/changepassword')).send(updatePasswordParams).result();
19361948
}
19371949

@@ -2173,4 +2185,63 @@ export class BitGoAPI implements BitGoBase {
21732185
const result = await req;
21742186
return result.body;
21752187
}
2188+
2189+
/**
2190+
* Process keychain password updates in batches with retry logic
2191+
* @param keychains - The v1 keychains to update
2192+
* @param v2Keychains - The v2 keychains to update
2193+
* @param noOfBatches - Number of batches to split the keychains into
2194+
* @param maxRetries - Maximum number of retries per batch
2195+
* @private
2196+
*/
2197+
private async processKeychainPasswordUpdatesInBatches(
2198+
keychains: Record<string, string>,
2199+
v2Keychains: Record<string, string>,
2200+
noOfBatches: number,
2201+
maxRetries: number
2202+
): Promise<void> {
2203+
// Split keychains into batches
2204+
const v1KeychainEntries = Object.entries(keychains);
2205+
const v2KeychainEntries = Object.entries(v2Keychains);
2206+
2207+
const v1BatchSize = Math.ceil(v1KeychainEntries.length / noOfBatches);
2208+
const v2BatchSize = Math.ceil(v2KeychainEntries.length / noOfBatches);
2209+
2210+
// Call batching API for each batch with retry logic
2211+
for (let i = 0; i < noOfBatches; i++) {
2212+
const v1Batch = Object.fromEntries(v1KeychainEntries.slice(i * v1BatchSize, (i + 1) * v1BatchSize));
2213+
const v2Batch = Object.fromEntries(v2KeychainEntries.slice(i * v2BatchSize, (i + 1) * v2BatchSize));
2214+
2215+
let retryCount = 0;
2216+
let success = false;
2217+
2218+
while (retryCount < maxRetries && !success) {
2219+
try {
2220+
const response = await this.put(this.url('/user/keychains', 2))
2221+
.send({
2222+
keychains: v1Batch,
2223+
v2_keychains: v2Batch,
2224+
})
2225+
.result();
2226+
2227+
// Check if there are any failed keychains in the response
2228+
const hasFailed =
2229+
(response.failed?.v1 && Object.keys(response.failed.v1).length > 0) ||
2230+
(response.failed?.v2 && Object.keys(response.failed.v2).length > 0);
2231+
2232+
if (hasFailed) {
2233+
throw new Error(`Batch ${i + 1} had failed keychains: ${JSON.stringify(response.failed)}`);
2234+
}
2235+
2236+
success = true;
2237+
} catch (error) {
2238+
retryCount++;
2239+
2240+
if (retryCount >= maxRetries) {
2241+
throw new Error(`Batch ${i + 1} failed after ${maxRetries} retries: ${error.message}`);
2242+
}
2243+
}
2244+
}
2245+
}
2246+
}
21762247
}

0 commit comments

Comments
 (0)