squarefi-bff-api-module 1.11.2 → 1.12.0
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/README.md +7 -6
- package/dist/api/auth.d.ts +1 -1
- package/dist/api/auth.js +3 -3
- package/dist/api/issuing.d.ts +5 -0
- package/dist/api/issuing.js +64 -0
- package/dist/api/types.d.ts +6 -0
- package/dist/utils/common.d.ts +5 -0
- package/dist/utils/common.js +48 -0
- package/package.json +3 -2
- package/src/api/auth.ts +4 -4
- package/src/api/issuing.ts +43 -0
- package/src/api/types.ts +7 -0
- package/src/utils/common.ts +42 -0
package/README.md
CHANGED
|
@@ -107,12 +107,13 @@ Access different API functionalities through the client:
|
|
|
107
107
|
|
|
108
108
|
## ⚙️ Environment Variables
|
|
109
109
|
|
|
110
|
-
| Variable
|
|
111
|
-
|
|
|
112
|
-
| API_URL
|
|
113
|
-
| API_V2_URL
|
|
114
|
-
| TENANT_ID
|
|
115
|
-
| LOGOUT_URL
|
|
110
|
+
| Variable | Description | Required | Example |
|
|
111
|
+
| ------------------------ | --------------------------------------------- | -------- | -------------------- |
|
|
112
|
+
| API_URL | Base URL for the Squarefi BFF API | Yes | `https://api-v1.url` |
|
|
113
|
+
| API_V2_URL | Base URL for the Squarefi BFF API | Yes | `https://api-v2.url` |
|
|
114
|
+
| TENANT_ID | Your tenant identifier | Yes | `tenant_12345` |
|
|
115
|
+
| LOGOUT_URL | Your frontend-app logout route | No | '/auth/logout' |
|
|
116
|
+
| SERVER_PUBLIC_KEY_BASE64 | Server provides base64-encoded PEM format key | Yes | 'example' |
|
|
116
117
|
|
|
117
118
|
## 🚀 Features
|
|
118
119
|
|
package/dist/api/auth.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { API } from './types';
|
|
2
|
-
export declare const telegramSignInPath = "/auth/
|
|
2
|
+
export declare const telegramSignInPath = "/auth/sign-in/telegram";
|
|
3
3
|
export declare const telegramSignUpPath = "/auth/sign-up/telegram";
|
|
4
4
|
export declare const refreshTokenPath = "/auth/refresh/refresh-token";
|
|
5
5
|
export declare const auth: {
|
package/dist/api/auth.js
CHANGED
|
@@ -14,8 +14,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.auth = exports.refreshTokenPath = exports.telegramSignUpPath = exports.telegramSignInPath = void 0;
|
|
15
15
|
const apiClientFactory_1 = require("../utils/apiClientFactory");
|
|
16
16
|
const converters_1 = require("../utils/converters");
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
exports.telegramSignInPath = '/auth/sign-in/telegram'; // V2 path
|
|
18
|
+
// export const telegramSignInPath = '/auth/signin/telegram'; // V1 path
|
|
19
19
|
exports.telegramSignUpPath = '/auth/sign-up/telegram';
|
|
20
20
|
exports.refreshTokenPath = '/auth/refresh/refresh-token';
|
|
21
21
|
exports.auth = {
|
|
@@ -39,7 +39,7 @@ exports.auth = {
|
|
|
39
39
|
});
|
|
40
40
|
},
|
|
41
41
|
},
|
|
42
|
-
telegram: (data) => apiClientFactory_1.
|
|
42
|
+
telegram: (data) => apiClientFactory_1.apiClientV2.postRequest(exports.telegramSignInPath, { data }),
|
|
43
43
|
password: (email, password // check on backend V2
|
|
44
44
|
) => apiClientFactory_1.apiClientV2.postRequest('/auth/sign-in/password/email', {
|
|
45
45
|
data: { email, password },
|
package/dist/api/issuing.d.ts
CHANGED
|
@@ -13,6 +13,11 @@ export declare const issuing: {
|
|
|
13
13
|
getById: (card_id: string) => Promise<API.Cards.IssuingCardDetailItem>;
|
|
14
14
|
sensitiveData: {
|
|
15
15
|
get: (card_id: string) => Promise<API.Cards.SensitiveData>;
|
|
16
|
+
encrypted: {
|
|
17
|
+
secretKey: {
|
|
18
|
+
get: (card_id: string) => Promise<any>;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
16
21
|
otp: {
|
|
17
22
|
get: (card_id: string) => Promise<API.Cards.OTP>;
|
|
18
23
|
};
|
package/dist/api/issuing.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
36
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
37
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -13,6 +46,7 @@ exports.issuing = void 0;
|
|
|
13
46
|
const apiClientFactory_1 = require("../utils/apiClientFactory");
|
|
14
47
|
const constants_1 = require("../constants");
|
|
15
48
|
const fiat_accounts_1 = require("./fiat_accounts");
|
|
49
|
+
const common_1 = require("../utils/common");
|
|
16
50
|
exports.issuing = {
|
|
17
51
|
cards: {
|
|
18
52
|
create: {
|
|
@@ -34,6 +68,36 @@ exports.issuing = {
|
|
|
34
68
|
}),
|
|
35
69
|
sensitiveData: {
|
|
36
70
|
get: (card_id) => apiClientFactory_1.apiClientV1.getRequest(`/issuing/cards/${card_id}/sensitive`),
|
|
71
|
+
encrypted: {
|
|
72
|
+
secretKey: {
|
|
73
|
+
get: (card_id) => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
const serverPublicKey = process.env.SERVER_PUBLIC_KEY_BASE64;
|
|
75
|
+
if (!serverPublicKey) {
|
|
76
|
+
throw new Error('SERVER_PUBLIC_KEY_BASE64 is not set');
|
|
77
|
+
}
|
|
78
|
+
const secretKey = (0, common_1.generate256bitSecretKey)();
|
|
79
|
+
const secretKeyBase64 = (0, common_1.arrayBufferToBase64)(secretKey);
|
|
80
|
+
const JSEncrypt = (yield Promise.resolve().then(() => __importStar(require('jsencrypt')))).default;
|
|
81
|
+
const encrypt = new JSEncrypt();
|
|
82
|
+
const serverPublicKeyPEM = (0, common_1.decodePEMFromBase64)(serverPublicKey);
|
|
83
|
+
encrypt.setPublicKey(serverPublicKeyPEM);
|
|
84
|
+
const payload = {
|
|
85
|
+
key: secretKeyBase64,
|
|
86
|
+
timestamp: Date.now(),
|
|
87
|
+
};
|
|
88
|
+
const encrypted_key = encrypt.encrypt(JSON.stringify(payload));
|
|
89
|
+
const response = yield apiClientFactory_1.apiClientV1.postRequest(`/issuing/cards/${card_id}/sensitive/secretkey`, {
|
|
90
|
+
data: {
|
|
91
|
+
encrypted_key,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
if (response.success && response.encrypted && response.data && response.iv) {
|
|
95
|
+
const decryptedData = yield (0, common_1.decryptSensitiveData)(response.data, response.iv, secretKey);
|
|
96
|
+
return decryptedData;
|
|
97
|
+
}
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
},
|
|
37
101
|
otp: {
|
|
38
102
|
// have to update
|
|
39
103
|
get: (card_id) => apiClientFactory_1.apiClientV1.getRequest(`/vcards/cards/${card_id}/sensitive/otp`),
|
package/dist/api/types.d.ts
CHANGED
|
@@ -287,6 +287,12 @@ 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
|
+
}
|
|
290
296
|
interface OTP {
|
|
291
297
|
created_at: number;
|
|
292
298
|
internal_card_id: string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const generate256bitSecretKey: () => Uint8Array<ArrayBuffer>;
|
|
2
|
+
export declare const arrayBufferToBase64: (buffer: Uint8Array<ArrayBuffer>) => string;
|
|
3
|
+
export declare const decodePEMFromBase64: (base64EncodedPEM: string) => string;
|
|
4
|
+
export declare const base64ToArrayBuffer: (base64: string) => ArrayBuffer;
|
|
5
|
+
export declare const decryptSensitiveData: (encryptedData: string, iv: string, secretKey: BufferSource) => Promise<any>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.decryptSensitiveData = exports.base64ToArrayBuffer = exports.decodePEMFromBase64 = exports.arrayBufferToBase64 = exports.generate256bitSecretKey = void 0;
|
|
13
|
+
const generate256bitSecretKey = () => {
|
|
14
|
+
const array = new Uint8Array(32);
|
|
15
|
+
window.crypto.getRandomValues(array);
|
|
16
|
+
return array;
|
|
17
|
+
};
|
|
18
|
+
exports.generate256bitSecretKey = generate256bitSecretKey;
|
|
19
|
+
const arrayBufferToBase64 = (buffer) => {
|
|
20
|
+
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
|
|
21
|
+
};
|
|
22
|
+
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
23
|
+
const decodePEMFromBase64 = (base64EncodedPEM) => {
|
|
24
|
+
return atob(base64EncodedPEM);
|
|
25
|
+
};
|
|
26
|
+
exports.decodePEMFromBase64 = decodePEMFromBase64;
|
|
27
|
+
const base64ToArrayBuffer = (base64) => {
|
|
28
|
+
const binaryString = atob(base64);
|
|
29
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
30
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
31
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
32
|
+
}
|
|
33
|
+
return bytes.buffer;
|
|
34
|
+
};
|
|
35
|
+
exports.base64ToArrayBuffer = base64ToArrayBuffer;
|
|
36
|
+
const decryptSensitiveData = (encryptedData, iv, secretKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
const key = yield window.crypto.subtle.importKey('raw', secretKey, { name: 'AES-CBC' }, false, ['decrypt']);
|
|
38
|
+
const encryptedBuffer = (0, exports.base64ToArrayBuffer)(encryptedData);
|
|
39
|
+
const ivBuffer = (0, exports.base64ToArrayBuffer)(iv);
|
|
40
|
+
const decryptedBuffer = yield window.crypto.subtle.decrypt({
|
|
41
|
+
name: 'AES-CBC',
|
|
42
|
+
iv: ivBuffer,
|
|
43
|
+
}, key, encryptedBuffer);
|
|
44
|
+
const decoder = new TextDecoder();
|
|
45
|
+
const jsonText = decoder.decode(decryptedBuffer);
|
|
46
|
+
return JSON.parse(jsonText);
|
|
47
|
+
});
|
|
48
|
+
exports.decryptSensitiveData = decryptSensitiveData;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squarefi-bff-api-module",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Squarefi BFF API client module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@telegram-apps/sdk-react": "^3.1.2",
|
|
22
|
-
"axios": "^1.6.7"
|
|
22
|
+
"axios": "^1.6.7",
|
|
23
|
+
"jsencrypt": "^3.3.2"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@types/jest": "^29.x.x",
|
package/src/api/auth.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { API } from './types';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { apiClientV2 } from '../utils/apiClientFactory';
|
|
4
4
|
import { convertPhoneToSupabaseFormat } from '../utils/converters';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
export const telegramSignInPath = '/auth/signin/telegram'; // V1 path
|
|
6
|
+
export const telegramSignInPath = '/auth/sign-in/telegram'; // V2 path
|
|
7
|
+
// export const telegramSignInPath = '/auth/signin/telegram'; // V1 path
|
|
8
8
|
|
|
9
9
|
export const telegramSignUpPath = '/auth/sign-up/telegram';
|
|
10
10
|
export const refreshTokenPath = '/auth/refresh/refresh-token';
|
|
@@ -32,7 +32,7 @@ export const auth = {
|
|
|
32
32
|
}),
|
|
33
33
|
},
|
|
34
34
|
telegram: (data: API.Auth.Telegram.Signin) =>
|
|
35
|
-
|
|
35
|
+
apiClientV2.postRequest<API.Auth.Tokens>(telegramSignInPath, { data }),
|
|
36
36
|
password: (
|
|
37
37
|
email: string,
|
|
38
38
|
password: string // check on backend V2
|
package/src/api/issuing.ts
CHANGED
|
@@ -4,6 +4,12 @@ import { apiClientV1 } from '../utils/apiClientFactory';
|
|
|
4
4
|
|
|
5
5
|
import { defaultPaginationParams, SubAccountType } from '../constants';
|
|
6
6
|
import { fiat_accounts } from './fiat_accounts';
|
|
7
|
+
import {
|
|
8
|
+
arrayBufferToBase64,
|
|
9
|
+
decodePEMFromBase64,
|
|
10
|
+
decryptSensitiveData,
|
|
11
|
+
generate256bitSecretKey,
|
|
12
|
+
} from '../utils/common';
|
|
7
13
|
|
|
8
14
|
export const issuing = {
|
|
9
15
|
cards: {
|
|
@@ -31,6 +37,43 @@ export const issuing = {
|
|
|
31
37
|
},
|
|
32
38
|
sensitiveData: {
|
|
33
39
|
get: (card_id: string) => apiClientV1.getRequest<API.Cards.SensitiveData>(`/issuing/cards/${card_id}/sensitive`),
|
|
40
|
+
encrypted: {
|
|
41
|
+
secretKey: {
|
|
42
|
+
get: async (card_id: string) => {
|
|
43
|
+
const serverPublicKey = process.env.SERVER_PUBLIC_KEY_BASE64;
|
|
44
|
+
if (!serverPublicKey) {
|
|
45
|
+
throw new Error('SERVER_PUBLIC_KEY_BASE64 is not set');
|
|
46
|
+
}
|
|
47
|
+
const secretKey = generate256bitSecretKey();
|
|
48
|
+
const secretKeyBase64 = arrayBufferToBase64(secretKey);
|
|
49
|
+
const JSEncrypt = (await import('jsencrypt')).default;
|
|
50
|
+
const encrypt = new JSEncrypt();
|
|
51
|
+
const serverPublicKeyPEM = decodePEMFromBase64(serverPublicKey);
|
|
52
|
+
encrypt.setPublicKey(serverPublicKeyPEM);
|
|
53
|
+
|
|
54
|
+
const payload = {
|
|
55
|
+
key: secretKeyBase64,
|
|
56
|
+
timestamp: Date.now(),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const encrypted_key = encrypt.encrypt(JSON.stringify(payload));
|
|
60
|
+
|
|
61
|
+
const response = await apiClientV1.postRequest<API.Cards.SensitiveDataEncrypted>(
|
|
62
|
+
`/issuing/cards/${card_id}/sensitive/secretkey`,
|
|
63
|
+
{
|
|
64
|
+
data: {
|
|
65
|
+
encrypted_key,
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
if (response.success && response.encrypted && response.data && response.iv) {
|
|
70
|
+
const decryptedData = await decryptSensitiveData(response.data, response.iv, secretKey);
|
|
71
|
+
|
|
72
|
+
return decryptedData;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
34
77
|
otp: {
|
|
35
78
|
// have to update
|
|
36
79
|
get: (card_id: string) => apiClientV1.getRequest<API.Cards.OTP>(`/vcards/cards/${card_id}/sensitive/otp`),
|
package/src/api/types.ts
CHANGED
|
@@ -335,6 +335,13 @@ 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
|
+
|
|
338
345
|
export interface OTP {
|
|
339
346
|
created_at: number;
|
|
340
347
|
internal_card_id: string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const generate256bitSecretKey = () => {
|
|
2
|
+
const array = new Uint8Array(32);
|
|
3
|
+
window.crypto.getRandomValues(array);
|
|
4
|
+
return array;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const arrayBufferToBase64 = (buffer: Uint8Array<ArrayBuffer>) => {
|
|
8
|
+
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const decodePEMFromBase64 = (base64EncodedPEM: string) => {
|
|
12
|
+
return atob(base64EncodedPEM);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const base64ToArrayBuffer = (base64: string) => {
|
|
16
|
+
const binaryString = atob(base64);
|
|
17
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
18
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
19
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
20
|
+
}
|
|
21
|
+
return bytes.buffer;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const decryptSensitiveData = async (encryptedData: string, iv: string, secretKey: BufferSource) => {
|
|
25
|
+
const key = await window.crypto.subtle.importKey('raw', secretKey, { name: 'AES-CBC' }, false, ['decrypt']);
|
|
26
|
+
|
|
27
|
+
const encryptedBuffer = base64ToArrayBuffer(encryptedData);
|
|
28
|
+
const ivBuffer = base64ToArrayBuffer(iv);
|
|
29
|
+
|
|
30
|
+
const decryptedBuffer = await window.crypto.subtle.decrypt(
|
|
31
|
+
{
|
|
32
|
+
name: 'AES-CBC',
|
|
33
|
+
iv: ivBuffer,
|
|
34
|
+
},
|
|
35
|
+
key,
|
|
36
|
+
encryptedBuffer
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const decoder = new TextDecoder();
|
|
40
|
+
const jsonText = decoder.decode(decryptedBuffer);
|
|
41
|
+
return JSON.parse(jsonText);
|
|
42
|
+
};
|