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 +155 -0
- package/dist/api/issuing.d.ts +1 -2
- package/dist/api/issuing.js +8 -22
- package/dist/api/types.d.ts +11 -6
- package/dist/utils/encrypt.d.ts +7 -0
- package/dist/utils/encrypt.js +22 -1
- package/package.json +1 -1
- package/src/api/issuing.ts +12 -32
- package/src/api/types.ts +12 -7
- package/src/utils/encrypt.ts +33 -0
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
|
package/dist/api/issuing.d.ts
CHANGED
|
@@ -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<
|
|
17
|
+
get: (card_id: string) => Promise<API.Cards.SensitiveData>;
|
|
19
18
|
};
|
|
20
19
|
};
|
|
21
20
|
otp: {
|
package/dist/api/issuing.js
CHANGED
|
@@ -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) =>
|
|
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
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
64
|
-
const decryptedData = (0, encrypt_1.decryptAESData)(data, iv, clientSecretKey);
|
|
65
|
-
return decryptedData;
|
|
66
|
-
}
|
|
52
|
+
return encryptedData;
|
|
67
53
|
}),
|
|
68
54
|
},
|
|
69
55
|
},
|
package/dist/api/types.d.ts
CHANGED
|
@@ -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 {
|
package/dist/utils/encrypt.d.ts
CHANGED
|
@@ -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 {};
|
package/dist/utils/encrypt.js
CHANGED
|
@@ -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
package/src/api/issuing.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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 {
|
package/src/utils/encrypt.ts
CHANGED
|
@@ -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
|
+
};
|