squarefi-bff-api-module 1.13.0 → 1.13.2

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/CHANGELOG.md CHANGED
@@ -5,6 +5,161 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.13.2] - 2025-04-08
9
+
10
+ ### Changed
11
+
12
+ - Refactored encryption logic for improved security and maintainability
13
+
14
+ ## [1.13.1] - 2025-04-08
15
+
16
+ ### Fixed
17
+
18
+ - Deprecated card sensitive data retrieval method
19
+ - Improved error handling in API responses
20
+ - Fixed decryption handling in issuing API
21
+
22
+ ## [1.13.0] - 2025-04-08
23
+
24
+ ### Changed
25
+
26
+ - Replaced JSEncrypt with NodeRSA for encryption implementation
27
+
28
+ ## [1.12.1] - 2025-04-08
29
+
30
+ ### Fixed
31
+
32
+ - Improved encryption implementation for card data
33
+
34
+ ## [1.12.0] - 2025-04-08
35
+
36
+ ### Added
37
+
38
+ - Implemented encryption for sensitive card data
39
+
40
+ ## [1.11.3] - 2025-04-07
41
+
42
+ ### Changed
43
+
44
+ - Updated Telegram sign-in method to use apiClientV2
45
+
46
+ ## [1.11.2] - 2025-04-07
47
+
48
+ ### Changed
49
+
50
+ - Updated Telegram sign-in path for versioning clarity
51
+
52
+ ## [1.11.1] - 2025-04-07
53
+
54
+ ### Changed
55
+
56
+ - Switched to apiClientV1 for Telegram sign-in
57
+
58
+ ## [1.11.0] - 2025-04-07
59
+
60
+ ### Changed
61
+
62
+ - Updated external_crypto_data type in Counterparty destination
63
+ - Simplified Response type for Counterparty destination
64
+
65
+ ## [1.10.13] - 2025-04-07
66
+
67
+ ### Changed
68
+
69
+ - Updated external_crypto_data type in Counterparty destination
70
+
71
+ ## [1.10.12] - 2025-04-07
72
+
73
+ ### Changed
74
+
75
+ - Simplified Response type for Counterparty destination
76
+
77
+ ## [1.10.11] - 2025-04-05
78
+
79
+ ### Fixed
80
+
81
+ - Formatted phone numbers for Supabase compatibility
82
+
83
+ ## [1.10.10] - 2025-04-04
84
+
85
+ ### Fixed
86
+
87
+ - Added search parameter to Counterparty request type
88
+
89
+ ## [1.10.9] - 2025-04-04
90
+
91
+ ### Fixed
92
+
93
+ - Updated Counterparty fields to allow null values
94
+
95
+ ## [1.10.8] - 2025-04-04
96
+
97
+ ### Fixed
98
+
99
+ - Added counterparty_account_id to Update request type for Counterparty
100
+
101
+ ## [1.10.7] - 2025-04-04
102
+
103
+ ### Fixed
104
+
105
+ - Added wallet_id to Create and Update request types for Counterparty
106
+
107
+ ## [1.10.6] - 2025-04-04
108
+
109
+ ### Fixed
110
+
111
+ - Made Counterparty fields optional in API types
112
+
113
+ ## [1.10.5] - 2025-04-03
114
+
115
+ ### Fixed
116
+
117
+ - Included additional parameters in wallet transaction request
118
+
119
+ ## [1.10.4] - 2025-04-03
120
+
121
+ ### Fixed
122
+
123
+ - Made wallet transaction filter fields optional
124
+
125
+ ## [1.10.3] - 2025-04-03
126
+
127
+ ### Added
128
+
129
+ - Added WalletTransactionStatus enum
130
+ - Updated API types with new status enum
131
+
132
+ ## [1.10.2] - 2025-04-02
133
+
134
+ ### Added
135
+
136
+ - Added IssuingProgramStatus enum
137
+ - Updated API types with new status enum
138
+
139
+ ## [1.10.1] - 2025-04-02
140
+
141
+ ### Fixed
142
+
143
+ - Made filter object optional in wallet transaction request
144
+
145
+ ## [1.10.0] - 2025-04-02
146
+
147
+ ### Fixed
148
+
149
+ - Simplified token refresh logic by removing TMA check
150
+
151
+ ## [1.9.0] - 2025-03-31
152
+
153
+ ### Added
154
+
155
+ - Added filter options to wallet transaction request
156
+
157
+ ## [1.8.2] - 2025-03-26
158
+
159
+ ### Changed
160
+
161
+ - Clarified LOGOUT_URL description in documentation
162
+
8
163
  ## [1.8.1] - 2025-03-26
9
164
 
10
165
  ### Added
@@ -12,10 +12,9 @@ export declare const issuing: {
12
12
  };
13
13
  getById: (card_id: string) => Promise<API.Cards.IssuingCardDetailItem>;
14
14
  sensitiveData: {
15
- get: (card_id: string) => Promise<API.Cards.SensitiveData>;
16
15
  encrypted: {
17
16
  secretKey: {
18
- get: (card_id: string) => Promise<any>;
17
+ get: (card_id: string) => Promise<API.Cards.SensitiveData>;
19
18
  };
20
19
  };
21
20
  otp: {
@@ -8,12 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.issuing = void 0;
16
- const node_rsa_1 = __importDefault(require("node-rsa"));
17
13
  const apiClientFactory_1 = require("../utils/apiClientFactory");
18
14
  const constants_1 = require("../constants");
19
15
  const fiat_accounts_1 = require("./fiat_accounts");
@@ -38,32 +34,22 @@ exports.issuing = {
38
34
  return Object.assign(Object.assign({}, card), { fiat_account: Object.assign(Object.assign({}, fiatAccountData), { type: card.fiat_account.type }) });
39
35
  }),
40
36
  sensitiveData: {
41
- get: (card_id) => apiClientFactory_1.apiClientV1.getRequest(`/issuing/cards/${card_id}/sensitive`),
37
+ // get: (card_id: string) => apiClientV1.getRequest<API.Cards.SensitiveData>(`/issuing/cards/${card_id}/sensitive`), deprecated from v1.13.1
42
38
  encrypted: {
43
39
  secretKey: {
44
40
  get: (card_id) => __awaiter(void 0, void 0, void 0, function* () {
45
41
  const serverPublicKeyEnv = process.env.SERVER_PUBLIC_KEY_BASE64;
46
- const clientRsa = new node_rsa_1.default();
42
+ const callback = (props) => apiClientFactory_1.apiClientV1.postRequest(`/issuing/cards/${card_id}/sensitive/secretkey`, {
43
+ data: props,
44
+ });
47
45
  if (!serverPublicKeyEnv) {
48
46
  throw new Error('SERVER_PUBLIC_KEY_BASE64 is not set');
49
47
  }
50
- const serverPublicKey = Buffer.from(serverPublicKeyEnv, 'base64').toString('utf8');
51
- clientRsa.importKey(serverPublicKey, 'pkcs8-public-pem');
52
- const clientSecretKey = (0, encrypt_1.generateSecretKey)();
53
- const clientPayload = {
54
- key: clientSecretKey.toString('base64'),
55
- timestamp: Date.now(),
56
- };
57
- const encrypted_key = clientRsa.encrypt(JSON.stringify(clientPayload), 'base64');
58
- const { success, encrypted, data, iv } = yield apiClientFactory_1.apiClientV1.postRequest(`/issuing/cards/${card_id}/sensitive/secretkey`, {
59
- data: {
60
- encrypted_key,
61
- },
48
+ const encryptedData = yield (0, encrypt_1.makeSecureRequest)({
49
+ callback,
50
+ publicKey: serverPublicKeyEnv,
62
51
  });
63
- if (success && encrypted && data && iv) {
64
- const decryptedData = (0, encrypt_1.decryptAESData)(data, iv, clientSecretKey);
65
- return decryptedData;
66
- }
52
+ return encryptedData;
67
53
  }),
68
54
  },
69
55
  },
@@ -287,12 +287,6 @@ export declare namespace API {
287
287
  expiry_year: number;
288
288
  security_code?: string;
289
289
  }
290
- interface SensitiveDataEncrypted {
291
- data?: string;
292
- success?: boolean;
293
- encrypted?: boolean;
294
- iv?: string;
295
- }
296
290
  interface OTP {
297
291
  created_at: number;
298
292
  internal_card_id: string;
@@ -354,6 +348,17 @@ export declare namespace API {
354
348
  filter?: Partial<Record<keyof T, any>>;
355
349
  }
356
350
  }
351
+ namespace Encrypted {
352
+ interface Request {
353
+ encrypted_key: string;
354
+ }
355
+ interface Response {
356
+ data: string;
357
+ success: boolean;
358
+ encrypted: boolean;
359
+ iv: string;
360
+ }
361
+ }
357
362
  }
358
363
  namespace Counterparties {
359
364
  interface Counterparty {
@@ -1,3 +1,10 @@
1
1
  import { CipherKey } from 'crypto';
2
+ import { API } from '../api/types';
3
+ type MakeSecureRequestParams = {
4
+ callback: (props: API.Common.Encrypted.Request) => Promise<API.Common.Encrypted.Response>;
5
+ publicKey: string;
6
+ };
2
7
  export declare const generateSecretKey: () => Buffer<ArrayBufferLike>;
3
8
  export declare const decryptAESData: (encryptedData: string, iv: string, secretKey: CipherKey) => Promise<any>;
9
+ export declare const makeSecureRequest: <T>({ callback, publicKey }: MakeSecureRequestParams) => Promise<T>;
10
+ export {};
@@ -12,8 +12,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.decryptAESData = exports.generateSecretKey = void 0;
15
+ exports.makeSecureRequest = exports.decryptAESData = exports.generateSecretKey = void 0;
16
16
  const crypto_1 = __importDefault(require("crypto"));
17
+ const node_rsa_1 = __importDefault(require("node-rsa"));
17
18
  const generateSecretKey = () => {
18
19
  const secretKey = crypto_1.default.randomBytes(32);
19
20
  return secretKey;
@@ -26,3 +27,23 @@ const decryptAESData = (encryptedData, iv, secretKey) => __awaiter(void 0, void
26
27
  return JSON.parse(decrypted);
27
28
  });
28
29
  exports.decryptAESData = decryptAESData;
30
+ const makeSecureRequest = (_a) => __awaiter(void 0, [_a], void 0, function* ({ callback, publicKey }) {
31
+ const clientRsa = new node_rsa_1.default();
32
+ const publicKeyBase64 = Buffer.from(publicKey, 'base64').toString('utf8');
33
+ clientRsa.importKey(publicKeyBase64, 'pkcs8-public-pem');
34
+ const clientSecretKey = (0, exports.generateSecretKey)();
35
+ const clientPayload = {
36
+ key: clientSecretKey.toString('base64'),
37
+ timestamp: Date.now(),
38
+ };
39
+ const encrypted_key = clientRsa.encrypt(JSON.stringify(clientPayload), 'base64');
40
+ const { success, encrypted, data, iv } = yield callback({ encrypted_key });
41
+ if (success && encrypted && data && iv) {
42
+ const decryptedData = yield (0, exports.decryptAESData)(data, iv, clientSecretKey);
43
+ return decryptedData.data;
44
+ }
45
+ else {
46
+ throw new Error('Failed to get encrypted secret key');
47
+ }
48
+ });
49
+ exports.makeSecureRequest = makeSecureRequest;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squarefi-bff-api-module",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "description": "Squarefi BFF API client module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,12 +1,8 @@
1
1
  import { API } from './types';
2
- import NodeRSA from 'node-rsa';
3
-
4
2
  import { apiClientV1 } from '../utils/apiClientFactory';
5
-
6
3
  import { defaultPaginationParams } from '../constants';
7
4
  import { fiat_accounts } from './fiat_accounts';
8
- import { decryptAESData, generateSecretKey } from '../utils/encrypt';
9
-
5
+ import { makeSecureRequest } from '../utils/encrypt';
10
6
  export const issuing = {
11
7
  cards: {
12
8
  create: {
@@ -32,42 +28,26 @@ export const issuing = {
32
28
  return { ...card, fiat_account: { ...fiatAccountData, type: card.fiat_account.type } };
33
29
  },
34
30
  sensitiveData: {
35
- get: (card_id: string) => apiClientV1.getRequest<API.Cards.SensitiveData>(`/issuing/cards/${card_id}/sensitive`),
31
+ // get: (card_id: string) => apiClientV1.getRequest<API.Cards.SensitiveData>(`/issuing/cards/${card_id}/sensitive`), deprecated from v1.13.1
36
32
  encrypted: {
37
33
  secretKey: {
38
- get: async (card_id: string) => {
34
+ get: async (card_id: string): Promise<API.Cards.SensitiveData> => {
39
35
  const serverPublicKeyEnv = process.env.SERVER_PUBLIC_KEY_BASE64;
40
- const clientRsa = new NodeRSA();
36
+ const callback = (props: API.Common.Encrypted.Request) =>
37
+ apiClientV1.postRequest<API.Common.Encrypted.Response>(`/issuing/cards/${card_id}/sensitive/secretkey`, {
38
+ data: props,
39
+ });
41
40
 
42
41
  if (!serverPublicKeyEnv) {
43
42
  throw new Error('SERVER_PUBLIC_KEY_BASE64 is not set');
44
43
  }
45
44
 
46
- const serverPublicKey = Buffer.from(serverPublicKeyEnv, 'base64').toString('utf8');
47
- clientRsa.importKey(serverPublicKey, 'pkcs8-public-pem');
48
-
49
- const clientSecretKey = generateSecretKey();
50
- const clientPayload = {
51
- key: clientSecretKey.toString('base64'),
52
- timestamp: Date.now(),
53
- };
45
+ const encryptedData = await makeSecureRequest<API.Cards.SensitiveData>({
46
+ callback,
47
+ publicKey: serverPublicKeyEnv,
48
+ });
54
49
 
55
- const encrypted_key = clientRsa.encrypt(JSON.stringify(clientPayload), 'base64');
56
-
57
- const { success, encrypted, data, iv } = await apiClientV1.postRequest<API.Cards.SensitiveDataEncrypted>(
58
- `/issuing/cards/${card_id}/sensitive/secretkey`,
59
- {
60
- data: {
61
- encrypted_key,
62
- },
63
- }
64
- );
65
-
66
- if (success && encrypted && data && iv) {
67
- const decryptedData = decryptAESData(data, iv, clientSecretKey);
68
-
69
- return decryptedData;
70
- }
50
+ return encryptedData;
71
51
  },
72
52
  },
73
53
  },
package/src/api/types.ts CHANGED
@@ -335,13 +335,6 @@ export namespace API {
335
335
  security_code?: string;
336
336
  }
337
337
 
338
- export interface SensitiveDataEncrypted {
339
- data?: string;
340
- success?: boolean;
341
- encrypted?: boolean;
342
- iv?: string;
343
- }
344
-
345
338
  export interface OTP {
346
339
  created_at: number;
347
340
  internal_card_id: string;
@@ -413,6 +406,18 @@ export namespace API {
413
406
  filter?: Partial<Record<keyof T, any>>;
414
407
  }
415
408
  }
409
+
410
+ export namespace Encrypted {
411
+ export interface Request {
412
+ encrypted_key: string;
413
+ }
414
+ export interface Response {
415
+ data: string;
416
+ success: boolean;
417
+ encrypted: boolean;
418
+ iv: string;
419
+ }
420
+ }
416
421
  }
417
422
 
418
423
  export namespace Counterparties {
@@ -1,4 +1,12 @@
1
1
  import crypto, { CipherKey } from 'crypto';
2
+ import NodeRSA from 'node-rsa';
3
+
4
+ import { API } from '../api/types';
5
+
6
+ type MakeSecureRequestParams = {
7
+ callback: (props: API.Common.Encrypted.Request) => Promise<API.Common.Encrypted.Response>;
8
+ publicKey: string;
9
+ };
2
10
 
3
11
  export const generateSecretKey = () => {
4
12
  const secretKey = crypto.randomBytes(32);
@@ -11,3 +19,28 @@ export const decryptAESData = async (encryptedData: string, iv: string, secretKe
11
19
  decrypted += decipher.final('utf8');
12
20
  return JSON.parse(decrypted);
13
21
  };
22
+
23
+ export const makeSecureRequest = async <T>({ callback, publicKey }: MakeSecureRequestParams): Promise<T> => {
24
+ const clientRsa = new NodeRSA();
25
+
26
+ const publicKeyBase64 = Buffer.from(publicKey, 'base64').toString('utf8');
27
+ clientRsa.importKey(publicKeyBase64, 'pkcs8-public-pem');
28
+
29
+ const clientSecretKey = generateSecretKey();
30
+ const clientPayload = {
31
+ key: clientSecretKey.toString('base64'),
32
+ timestamp: Date.now(),
33
+ };
34
+
35
+ const encrypted_key = clientRsa.encrypt(JSON.stringify(clientPayload), 'base64');
36
+
37
+ const { success, encrypted, data, iv } = await callback({ encrypted_key });
38
+
39
+ if (success && encrypted && data && iv) {
40
+ const decryptedData = await decryptAESData(data, iv, clientSecretKey);
41
+
42
+ return decryptedData.data;
43
+ } else {
44
+ throw new Error('Failed to get encrypted secret key');
45
+ }
46
+ };