diff --git a/modules/express/encryptedPrivKeys.json b/modules/express/encryptedPrivKeys.json index fa9742e4d4..9e26dfeeb6 100644 --- a/modules/express/encryptedPrivKeys.json +++ b/modules/express/encryptedPrivKeys.json @@ -1,3 +1 @@ -{ - "61f039aad587c2000745c687373e0fa9": "{\"iv\":\"/Gnh+Ip1G+IOhy+Cms+umQ==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"FYnd1xwReTw=\",\"ct\":\"vgnCvdJ1Z9sqeV6urYxNsscwnkB/6eSPsZhzaW4Cuc7RKEY1uWNlleR0Tjtd8nlQuhsA5UXFpOID3lHHHjPDvB+jWtRm08I2F+HNGYuklWG12vIiSrY2KnkYRJkyCghn5Pq3iEimQb9M2kkwj5wf4EtfAiz9jsY=\"}" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index 9b876303b5..377e77c312 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -1700,6 +1700,7 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { // auth router.post('express.login', [prepareBitGo(config), typedPromiseWrapper(handleLogin)]); + router.post('express.v1.decrypt', [prepareBitGo(config), typedPromiseWrapper(handleDecrypt)]); router.post('express.decrypt', [prepareBitGo(config), typedPromiseWrapper(handleDecrypt)]); router.post('express.encrypt', [prepareBitGo(config), typedPromiseWrapper(handleEncrypt)]); router.post('express.verifyaddress', [prepareBitGo(config), typedPromiseWrapper(handleVerifyAddress)]); diff --git a/modules/express/src/typedRoutes/api/index.ts b/modules/express/src/typedRoutes/api/index.ts index 6b08dff1ce..7a8ad98173 100644 --- a/modules/express/src/typedRoutes/api/index.ts +++ b/modules/express/src/typedRoutes/api/index.ts @@ -5,7 +5,8 @@ import * as express from 'express'; import { GetPing } from './common/ping'; import { GetPingExpress } from './common/pingExpress'; import { PostLogin } from './common/login'; -import { PostDecrypt } from './common/decrypt'; +import { PostV1Decrypt } from './v1/decrypt'; +import { PostV2Decrypt } from './v2/decrypt'; import { PostEncrypt } from './common/encrypt'; import { PostVerifyAddress } from './common/verifyAddress'; import { PostV1CalculateMinerFeeInfo } from './v1/calculateMinerFeeInfo'; @@ -81,8 +82,11 @@ export const ExpressLoginApiSpec = apiSpec({ }); export const ExpressDecryptApiSpec = apiSpec({ + 'express.v1.decrypt': { + post: PostV1Decrypt, + }, 'express.decrypt': { - post: PostDecrypt, + post: PostV2Decrypt, }, }); diff --git a/modules/express/src/typedRoutes/api/common/decrypt.ts b/modules/express/src/typedRoutes/api/v1/decrypt.ts similarity index 64% rename from modules/express/src/typedRoutes/api/common/decrypt.ts rename to modules/express/src/typedRoutes/api/v1/decrypt.ts index d7ad264169..f347b6945d 100644 --- a/modules/express/src/typedRoutes/api/common/decrypt.ts +++ b/modules/express/src/typedRoutes/api/v1/decrypt.ts @@ -3,18 +3,22 @@ import { httpRoute, httpRequest, optional } from '@api-ts/io-ts-http'; import { BitgoExpressError } from '../../schemas/error'; export const DecryptRequestBody = { + /** Ciphertext to decrypt */ input: t.string, + /** Key which is used for decryption */ password: optional(t.string), }; /** - * Decrypt + * Decrypt (v1) * - * @operationId express.decrypt + * Decrypts an encrypted string using the provided password. + * + * @operationId express.v1.decrypt * @tag express */ -export const PostDecrypt = httpRoute({ - path: '/api/v[12]/decrypt', +export const PostV1Decrypt = httpRoute({ + path: '/api/v1/decrypt', method: 'POST', request: httpRequest({ body: DecryptRequestBody, diff --git a/modules/express/src/typedRoutes/api/v2/decrypt.ts b/modules/express/src/typedRoutes/api/v2/decrypt.ts new file mode 100644 index 0000000000..df92a92bf8 --- /dev/null +++ b/modules/express/src/typedRoutes/api/v2/decrypt.ts @@ -0,0 +1,26 @@ +import * as t from 'io-ts'; +import { httpRoute, httpRequest } from '@api-ts/io-ts-http'; +import { BitgoExpressError } from '../../schemas/error'; +import { DecryptRequestBody } from '../v1/decrypt'; + +/** + * Decrypt + * + * Decrypt a ciphertext generated by encrypt route with provided password + * + * @operationId express.decrypt + * @tag Express + */ +export const PostV2Decrypt = httpRoute({ + path: '/api/v2/decrypt', + method: 'POST', + request: httpRequest({ + body: DecryptRequestBody, + }), + response: { + 200: t.type({ + decrypted: t.string, + }), + 404: BitgoExpressError, + }, +}); diff --git a/modules/express/test/unit/typedRoutes/decode.ts b/modules/express/test/unit/typedRoutes/decode.ts index 17d1d0cc73..e2577032ef 100644 --- a/modules/express/test/unit/typedRoutes/decode.ts +++ b/modules/express/test/unit/typedRoutes/decode.ts @@ -1,6 +1,6 @@ import * as assert from 'assert'; import * as t from 'io-ts'; -import { DecryptRequestBody } from '../../../src/typedRoutes/api/common/decrypt'; +import { DecryptRequestBody } from '../../../src/typedRoutes/api/v1/decrypt'; import { EncryptRequestBody } from '../../../src/typedRoutes/api/common/encrypt'; import { LoginRequest } from '../../../src/typedRoutes/api/common/login'; import { VerifyAddressBody } from '../../../src/typedRoutes/api/common/verifyAddress'; diff --git a/modules/express/test/unit/typedRoutes/decrypt.ts b/modules/express/test/unit/typedRoutes/decrypt.ts index 32ad1dd40a..dca0c0fa1b 100644 --- a/modules/express/test/unit/typedRoutes/decrypt.ts +++ b/modules/express/test/unit/typedRoutes/decrypt.ts @@ -1,6 +1,7 @@ import * as assert from 'assert'; import * as t from 'io-ts'; -import { DecryptRequestBody, PostDecrypt } from '../../../src/typedRoutes/api/common/decrypt'; +import { DecryptRequestBody, PostV1Decrypt } from '../../../src/typedRoutes/api/v1/decrypt'; +import { PostV2Decrypt } from '../../../src/typedRoutes/api/v2/decrypt'; import { assertDecode } from './common'; import 'should'; import 'should-http'; @@ -65,7 +66,7 @@ describe('Decrypt codec tests', function () { }); describe('DecryptResponse', function () { - const DecryptResponse = PostDecrypt.response[200]; + const DecryptResponse = PostV1Decrypt.response[200]; it('should validate response with required field', function () { const validResponse = { @@ -112,24 +113,41 @@ describe('Decrypt codec tests', function () { }); }); - describe('PostDecrypt route definition', function () { + describe('PostV1Decrypt route definition', function () { it('should have the correct path', function () { - assert.strictEqual(PostDecrypt.path, '/api/v[12]/decrypt'); + assert.strictEqual(PostV1Decrypt.path, '/api/v1/decrypt'); }); it('should have the correct HTTP method', function () { - assert.strictEqual(PostDecrypt.method, 'POST'); + assert.strictEqual(PostV1Decrypt.method, 'POST'); }); it('should have the correct request configuration', function () { - // Verify the route is configured with a request property - assert.ok(PostDecrypt.request); + assert.ok(PostV1Decrypt.request); }); it('should have the correct response types', function () { - // Check that the response object has the expected status codes - assert.ok(PostDecrypt.response[200]); - assert.ok(PostDecrypt.response[404]); + assert.ok(PostV1Decrypt.response[200]); + assert.ok(PostV1Decrypt.response[404]); + }); + }); + + describe('PostV2Decrypt route definition', function () { + it('should have the correct path', function () { + assert.strictEqual(PostV2Decrypt.path, '/api/v2/decrypt'); + }); + + it('should have the correct HTTP method', function () { + assert.strictEqual(PostV2Decrypt.method, 'POST'); + }); + + it('should have the correct request configuration', function () { + assert.ok(PostV2Decrypt.request); + }); + + it('should have the correct response types', function () { + assert.ok(PostV2Decrypt.response[200]); + assert.ok(PostV2Decrypt.response[404]); }); }); @@ -164,7 +182,7 @@ describe('Decrypt codec tests', function () { result.body.should.have.property('decrypted'); assert.strictEqual(result.body.decrypted, mockDecryptResponse); - const decodedResponse = assertDecode(PostDecrypt.response[200], result.body); + const decodedResponse = assertDecode(PostV1Decrypt.response[200], result.body); assert.strictEqual(decodedResponse.decrypted, mockDecryptResponse); }); @@ -186,7 +204,7 @@ describe('Decrypt codec tests', function () { result.body.should.have.property('decrypted'); assert.strictEqual(result.body.decrypted, mockDecryptResponse); - const decodedResponse = assertDecode(PostDecrypt.response[200], result.body); + const decodedResponse = assertDecode(PostV2Decrypt.response[200], result.body); assert.strictEqual(decodedResponse.decrypted, mockDecryptResponse); }); @@ -208,7 +226,7 @@ describe('Decrypt codec tests', function () { assert.strictEqual(result.status, 200); assert.strictEqual(result.body.decrypted, mockLongDecrypted); - const decodedResponse = assertDecode(PostDecrypt.response[200], result.body); + const decodedResponse = assertDecode(PostV1Decrypt.response[200], result.body); assert.strictEqual(decodedResponse.decrypted, mockLongDecrypted); }); @@ -229,7 +247,7 @@ describe('Decrypt codec tests', function () { assert.strictEqual(result.status, 200); assert.strictEqual(result.body.decrypted, mockDecryptResponse); - const decodedResponse = assertDecode(PostDecrypt.response[200], result.body); + const decodedResponse = assertDecode(PostV2Decrypt.response[200], result.body); assert.ok(decodedResponse); }); });