Skip to content

Commit effaa5f

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

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

modules/sdk-api/src/bitgoAPI.ts

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

1935+
// Check if batching flow is enabled
1936+
try {
1937+
const batchingFlowCheck = await this.get(this.url('/user/checkBatchingPasswordFlow', 2)).result();
1938+
1939+
if (batchingFlowCheck.isBatchingFlowEnabled) {
1940+
await this.processKeychainPasswordUpdatesInBatches(
1941+
updatePasswordParams.keychains,
1942+
updatePasswordParams.v2_keychains,
1943+
batchingFlowCheck.noOfBatches,
1944+
3
1945+
);
1946+
// Call changepassword API without keychains for batching flow
1947+
return this.post(this.url('/user/changepassword'))
1948+
.send({
1949+
version: updatePasswordParams.version,
1950+
oldPassword: updatePasswordParams.oldPassword,
1951+
password: updatePasswordParams.password,
1952+
})
1953+
.result();
1954+
}
1955+
} catch (error) {
1956+
// batching flow check failed
1957+
}
1958+
19351959
return this.post(this.url('/user/changepassword')).send(updatePasswordParams).result();
19361960
}
19371961

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

0 commit comments

Comments
 (0)