@yosle/tropipayjs 0.1.18 → 0.1.20

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/.nvmrc CHANGED
@@ -1 +1 @@
1
- v18.16.1
1
+ v20.10.0
package/README.md CHANGED
@@ -47,8 +47,8 @@ or
47
47
 
48
48
  ## Setting up your app credentials
49
49
 
50
- ![alt](https://github.com/yosle/tropipayjs/blob/master/docs/images/app-credentials-menu.png?raw=true)
51
- ![alt](https://github.com/yosle/tropipayjs/blob/master/docs/images/confirmation-code-screen.png?raw=true)
50
+ ![alt](https://yosle.github.io/tropipayjs-docs/images/cred1.png)
51
+ ![alt](https://yosle.github.io/tropipayjs-docs/images/cred3.png)
52
52
 
53
53
  In order to use the Tropipay API you'll need a client ID and a client secret. Sign up with your [Tropipay](www.tropipay.com) account, go to the App Menu->Applications and credentials. You'll be asked to enter a confirmation code (use 123456 in the test enviroment). _Make sure you test everything in the [test environment](https://tropipay-dev.herokuapp.com) first before using your real account._ Create an app and configure the client id an client secret for the app.
54
54
 
@@ -5,7 +5,7 @@
5
5
  *
6
6
  */
7
7
  import { Axios } from "axios";
8
- import { TropipayConfig, AccountBalance, Country, PaymentLink, mediationPaymentCardConfig, LoginResponse, AccountDeposits } from "../interfaces";
8
+ import { TropipayConfig, AccountBalance, Country, PaymentLink, mediationPaymentCardConfig, LoginResponse } from "../interfaces";
9
9
  type ServerMode = "Development" | "Production";
10
10
  import { TropipayHooks } from "../hooks/TropipayHooks";
11
11
  import { PaymentCard } from "../paymentcard/PaymentCard";
@@ -22,12 +22,6 @@ export declare class Tropipay {
22
22
  depositAccounts: DepositAccounts;
23
23
  constructor(config: TropipayConfig);
24
24
  login(): Promise<LoginResponse>;
25
- /**
26
- * Get all deposits in this account.
27
- * @returns A Promise of an Array of AccountDeposits or throws an Exception
28
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/b3A6OTgyOTQ1Mg-get-deposit-accounts-list
29
- */
30
- getDepositAccounts(): Promise<AccountDeposits[] | Error>;
31
25
  /**
32
26
  * Get the list of all supported countries by Tropipay.
33
27
  * @returns Array of Countries Data
@@ -1 +1,2 @@
1
1
  export type ServerMode = "Development" | "Production";
2
+ export declare const MAX_IMAGE_SIZE_MB = 1;
package/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Axios } from 'axios';
2
2
 
3
3
  type ServerMode$1 = "Development" | "Production";
4
+ declare const MAX_IMAGE_SIZE_MB = 1;
4
5
 
5
6
  type AccountBalance = {
6
7
  balance: number;
@@ -62,6 +63,7 @@ interface PaymentLinkPayload {
62
63
  };
63
64
  directPayment: boolean;
64
65
  paymentMethods?: string[];
66
+ imageBase?: string;
65
67
  }
66
68
  interface PaymentLink extends PaymentLinkPayload {
67
69
  expirationDate: string;
@@ -301,12 +303,6 @@ declare class Tropipay {
301
303
  depositAccounts: DepositAccounts;
302
304
  constructor(config: TropipayConfig);
303
305
  login(): Promise<LoginResponse>;
304
- /**
305
- * Get all deposits in this account.
306
- * @returns A Promise of an Array of AccountDeposits or throws an Exception
307
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/b3A6OTgyOTQ1Mg-get-deposit-accounts-list
308
- */
309
- getDepositAccounts(): Promise<AccountDeposits[] | Error>;
310
306
  /**
311
307
  * Get the list of all supported countries by Tropipay.
312
308
  * @returns Array of Countries Data
@@ -382,8 +378,36 @@ declare class ServerSideUtils {
382
378
  clientId: string;
383
379
  clientSecret: string;
384
380
  } | Tropipay, originalCurrencyAmount: string, bankOrderCode: string, signature: string): boolean;
381
+ /**
382
+ * Checks if the provided base64 string represents a square image.
383
+ *
384
+ * @param {string} base64String - The base64 string of the image
385
+ * @return {Promise<boolean>} A Promise that resolves to a boolean indicating whether the image is square
386
+ */
387
+ static isBase64ImageSquare(base64String: string): Promise<boolean>;
388
+ /**
389
+ * Takes a local file path and returns a base64 representation of the file content.
390
+ *
391
+ * @param {string} filepath - the path of the file to be converted to base64
392
+ * @return {Promise<string>} a Promise that resolves to the base64 representation of the file content
393
+ */
394
+ static fileToBase64(filepath: string): Promise<string>;
395
+ /**
396
+ * Get the base64 representation of a remote file from the given URL.
397
+ *
398
+ * @param {string} url - the URL of the file
399
+ * @return {Promise<string>} the base64 representation of the file
400
+ */
401
+ static getBase64FromFileUrl(url: string): Promise<string>;
402
+ /**
403
+ * Check if the base64 string represents a valid image and has a valid size
404
+ *
405
+ * @param {string} base64Image - the base64 image to be validated
406
+ * @return {Promise<string>} the valid base64 image
407
+ */
408
+ static isValidImage(base64Image: string): boolean;
385
409
  }
386
410
 
387
411
  declare const SERVER_MODE: ServerMode$1;
388
412
 
389
- export { AccountBalance, AccountDeposits, ClientSideUtils, Country, Deposit, DepositAccounts, HookEventType, HookTargetType, LoginError, LoginResponse, PaymentCard, PaymentLink, PaymentLinkPayload, SERVER_MODE, ServerMode$1 as ServerMode, ServerSideUtils, Tropipay, TropipayConfig, TropipayCredentials, TropipayHooks, UserHook, UserHookSubscribed, mediationPaymentCardConfig };
413
+ export { AccountBalance, AccountDeposits, ClientSideUtils, Country, Deposit, DepositAccounts, HookEventType, HookTargetType, LoginError, LoginResponse, MAX_IMAGE_SIZE_MB, PaymentCard, PaymentLink, PaymentLinkPayload, SERVER_MODE, ServerMode$1 as ServerMode, ServerSideUtils, Tropipay, TropipayConfig, TropipayCredentials, TropipayHooks, UserHook, UserHookSubscribed, mediationPaymentCardConfig };
package/index.js CHANGED
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var axios = require('axios');
6
6
  var crypto = require('crypto');
7
+ var fs = require('fs/promises');
7
8
 
8
9
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
10
 
@@ -27,6 +28,7 @@ function _interopNamespace(e) {
27
28
 
28
29
  var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
29
30
  var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
31
+ var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
30
32
 
31
33
  function handleExceptions(error) {
32
34
  if (error instanceof axios.AxiosError) {
@@ -452,29 +454,6 @@ class Tropipay {
452
454
  throw handleExceptions(error);
453
455
  }
454
456
  }
455
- /**
456
- * Get all deposits in this account.
457
- * @returns A Promise of an Array of AccountDeposits or throws an Exception
458
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/b3A6OTgyOTQ1Mg-get-deposit-accounts-list
459
- */
460
- async getDepositAccounts() {
461
- if (!Tropipay.accessToken) {
462
- await this.login();
463
- }
464
- try {
465
- const deposits = await this.request.get("/api/v2/deposit_accounts", {
466
- headers: {
467
- "Content-Type": "application/json",
468
- Authorization: `Bearer ${Tropipay.accessToken}`,
469
- Accept: "application/json",
470
- },
471
- });
472
- return deposits.data;
473
- }
474
- catch (error) {
475
- throw handleExceptions(error);
476
- }
477
- }
478
457
  /**
479
458
  * Get the list of all supported countries by Tropipay.
480
459
  * @returns Array of Countries Data
@@ -650,6 +629,8 @@ class ClientSideUtils {
650
629
  }
651
630
  }
652
631
 
632
+ const MAX_IMAGE_SIZE_MB = 1;
633
+
653
634
  class ServerSideUtils {
654
635
  tropipay;
655
636
  constructor(tropipayInstance) {
@@ -673,6 +654,79 @@ class ServerSideUtils {
673
654
  .digest("hex");
674
655
  return localSignature === signature;
675
656
  }
657
+ /**
658
+ * Checks if the provided base64 string represents a square image.
659
+ *
660
+ * @param {string} base64String - The base64 string of the image
661
+ * @return {Promise<boolean>} A Promise that resolves to a boolean indicating whether the image is square
662
+ */
663
+ static async isBase64ImageSquare(base64String) {
664
+ return new Promise((resolve, reject) => {
665
+ const img = new Image();
666
+ img.onload = () => {
667
+ // Check if the image has a 1:1 aspect ratio
668
+ const isSquare = img.width === img.height;
669
+ resolve(isSquare);
670
+ };
671
+ img.onerror = (error) => {
672
+ reject(error);
673
+ };
674
+ img.src = base64String;
675
+ });
676
+ }
677
+ /**
678
+ * Takes a local file path and returns a base64 representation of the file content.
679
+ *
680
+ * @param {string} filepath - the path of the file to be converted to base64
681
+ * @return {Promise<string>} a Promise that resolves to the base64 representation of the file content
682
+ */
683
+ static async fileToBase64(filepath) {
684
+ const contents = await fs__default["default"].readFile(filepath);
685
+ let base64content = contents.toString("base64");
686
+ const ext = filepath.split(".").pop();
687
+ return `data:image/${ext};base64,` + base64content;
688
+ }
689
+ /**
690
+ * Get the base64 representation of a remote file from the given URL.
691
+ *
692
+ * @param {string} url - the URL of the file
693
+ * @return {Promise<string>} the base64 representation of the file
694
+ */
695
+ static async getBase64FromFileUrl(url) {
696
+ const response = await axios__default["default"].get(url, {
697
+ responseType: "arraybuffer",
698
+ maxRedirects: 5,
699
+ });
700
+ return Buffer.from(response.data, "binary").toString("base64");
701
+ }
702
+ /**
703
+ * Check if the base64 string represents a valid image and has a valid size
704
+ *
705
+ * @param {string} base64Image - the base64 image to be validated
706
+ * @return {Promise<string>} the valid base64 image
707
+ */
708
+ static isValidImage(base64Image) {
709
+ // Check if the base64 string represents a valid image and has a valid size
710
+ try {
711
+ const isBase64Image = base64Image.startsWith("data:image/");
712
+ if (!isBase64Image) {
713
+ console.error("Not a valid base64 image");
714
+ throw new Error("Not a valid base64 image");
715
+ }
716
+ // TODO: use constants intead of magic numbers here
717
+ const isSizeLessThan2MB = base64Image.length * 0.75 <= MAX_IMAGE_SIZE_MB * 1024 * 1024;
718
+ if (!isSizeLessThan2MB) {
719
+ console.error(`The image should be less than 2mb`);
720
+ throw new Error(`The image should be less than 2mb`);
721
+ }
722
+ // all is fine
723
+ return true;
724
+ }
725
+ catch (error) {
726
+ console.error("Error checking base64 image:", error);
727
+ throw new Error(`Error checking base64 image`);
728
+ }
729
+ }
676
730
  }
677
731
 
678
732
  const SERVER_MODE = "Development"; // Move the constant here
@@ -689,11 +743,14 @@ const SERVER_MODE = "Development"; // Move the constant here
689
743
  * @license MIT
690
744
  */
691
745
  if (typeof window !== "undefined") {
692
- console.warn("DANGER This library should not be used client side, your credentials could be exposed");
746
+ const err_msg = `⚠️ **Warning:** The Tropipay SDK should only be instantiated server-side for security reasons. Using it client-side may lead to unexpected behavior and security vulnerabilities. YOUR CREDENTIALS COULD BE EXPOSED. Check https://yosle.github.io/tropipayjs-docs/guides/installation/ for more details.`;
747
+ console.error(err_msg);
748
+ throw new Error(err_msg);
693
749
  }
694
750
 
695
751
  exports.ClientSideUtils = ClientSideUtils;
696
752
  exports.DepositAccounts = DepositAccounts;
753
+ exports.MAX_IMAGE_SIZE_MB = MAX_IMAGE_SIZE_MB;
697
754
  exports.PaymentCard = PaymentCard;
698
755
  exports.SERVER_MODE = SERVER_MODE;
699
756
  exports.ServerSideUtils = ServerSideUtils;
@@ -59,6 +59,7 @@ export interface PaymentLinkPayload {
59
59
  };
60
60
  directPayment: boolean;
61
61
  paymentMethods?: string[];
62
+ imageBase?: string;
62
63
  }
63
64
  export interface PaymentLink extends PaymentLinkPayload {
64
65
  expirationDate: string;
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@yosle/tropipayjs",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "Javascript / Typescript SDK for the Tropipay API",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1",
7
+ "test": "vitest run",
8
8
  "_clear": "rimraf src/dist/*",
9
9
  "_tsc": "tsc",
10
10
  "_make-bundle": "rollup --config",
@@ -30,11 +30,13 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@rollup/plugin-typescript": "^8.5.0",
33
+ "@types/tough-cookie": "^4.0.5",
33
34
  "rimraf": "^3.0.2",
34
35
  "rollup": "^2.79.1",
35
36
  "rollup-plugin-dts": "^4.2.2",
36
37
  "run-s": "^0.0.0",
37
- "typescript": "^5.0.4"
38
+ "typescript": "^5.0.4",
39
+ "vitest": "^1.2.2"
38
40
  },
39
41
  "funding": {
40
42
  "type": "individual",
@@ -0,0 +1 @@
1
+ export {};
package/rollup.config.js CHANGED
@@ -9,7 +9,7 @@ const config = [
9
9
  format: "cjs",
10
10
  sourcemap: true,
11
11
  },
12
- external: ["axios", "crypto"],
12
+ external: ["axios", "crypto", "fs/promises"],
13
13
  plugins: [typescript()],
14
14
  },
15
15
  {
@@ -79,29 +79,6 @@ export class Tropipay {
79
79
  }
80
80
  }
81
81
 
82
- /**
83
- * Get all deposits in this account.
84
- * @returns A Promise of an Array of AccountDeposits or throws an Exception
85
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/b3A6OTgyOTQ1Mg-get-deposit-accounts-list
86
- */
87
- async getDepositAccounts(): Promise<AccountDeposits[] | Error> {
88
- if (!Tropipay.accessToken) {
89
- await this.login();
90
- }
91
- try {
92
- const deposits = await this.request.get("/api/v2/deposit_accounts", {
93
- headers: {
94
- "Content-Type": "application/json",
95
- Authorization: `Bearer ${Tropipay.accessToken}`,
96
- Accept: "application/json",
97
- },
98
- });
99
- return deposits.data;
100
- } catch (error) {
101
- throw handleExceptions(error as any);
102
- }
103
- }
104
-
105
82
  /**
106
83
  * Get the list of all supported countries by Tropipay.
107
84
  * @returns Array of Countries Data
@@ -1 +1,2 @@
1
1
  export type ServerMode = "Development" | "Production";
2
+ export const MAX_IMAGE_SIZE_MB = 1;
package/src/index.ts CHANGED
@@ -10,14 +10,10 @@
10
10
  * @license MIT
11
11
  */
12
12
 
13
- import { DepositAccounts } from "./depositAccount/depositAccounts";
14
-
15
13
  if (typeof window !== "undefined") {
16
- console.warn(
17
- `⚠️ **Warning:** The Tropipay SDK should only be instantiated server-side for security reasons.
18
- Using it client-side may lead to unexpected behavior and security vulnerabilities. YOUR CREDENTIALS COULD BE EXPOSED. Check
19
- https://yosle.github.io/tropipayjs-docs/guides/installation/ for more details.`
20
- );
14
+ const err_msg = `⚠️ **Warning:** The Tropipay SDK should only be instantiated server-side for security reasons. Using it client-side may lead to unexpected behavior and security vulnerabilities. YOUR CREDENTIALS COULD BE EXPOSED. Check https://yosle.github.io/tropipayjs-docs/guides/installation/ for more details.`;
15
+ console.error(err_msg);
16
+ throw new Error(err_msg);
21
17
  }
22
18
 
23
19
  export { Tropipay } from "./api/TropipayAPI";
@@ -86,6 +86,7 @@ export interface PaymentLinkPayload {
86
86
  };
87
87
  directPayment: boolean;
88
88
  paymentMethods?: string[];
89
+ imageBase?: string;
89
90
  }
90
91
 
91
92
  export interface PaymentLink extends PaymentLinkPayload {
@@ -0,0 +1,10 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ function sum(a: number, b: number) {
4
+ return a + b;
5
+ }
6
+ describe("dummy test", () => {
7
+ it("dummy test", () => {
8
+ expect(sum(1, 2)).toBe(3);
9
+ });
10
+ });
@@ -1,7 +1,9 @@
1
1
  import * as crypto from "crypto";
2
2
  import { Tropipay } from "../api/TropipayAPI";
3
- import { AxiosError, AxiosResponse } from "axios";
4
3
 
4
+ import axios from "axios";
5
+ import fs from "fs/promises";
6
+ import { MAX_IMAGE_SIZE_MB } from "../constants/TropipayConstants";
5
7
  export class ServerSideUtils {
6
8
  private tropipay: Tropipay;
7
9
  constructor(tropipayInstance: Tropipay) {
@@ -38,4 +40,87 @@ export class ServerSideUtils {
38
40
  .digest("hex");
39
41
  return localSignature === signature;
40
42
  }
43
+ /**
44
+ * Checks if the provided base64 string represents a square image.
45
+ *
46
+ * @param {string} base64String - The base64 string of the image
47
+ * @return {Promise<boolean>} A Promise that resolves to a boolean indicating whether the image is square
48
+ */
49
+ public static async isBase64ImageSquare(
50
+ base64String: string
51
+ ): Promise<boolean> {
52
+ return new Promise<boolean>((resolve, reject) => {
53
+ const img = new Image();
54
+
55
+ img.onload = () => {
56
+ // Check if the image has a 1:1 aspect ratio
57
+ const isSquare = img.width === img.height;
58
+ resolve(isSquare);
59
+ };
60
+
61
+ img.onerror = (error) => {
62
+ reject(error);
63
+ };
64
+
65
+ img.src = base64String;
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Takes a local file path and returns a base64 representation of the file content.
71
+ *
72
+ * @param {string} filepath - the path of the file to be converted to base64
73
+ * @return {Promise<string>} a Promise that resolves to the base64 representation of the file content
74
+ */
75
+ public static async fileToBase64(filepath: string): Promise<string> {
76
+ const contents = await fs.readFile(filepath);
77
+ let base64content = contents.toString("base64");
78
+ const ext = filepath.split(".").pop();
79
+ return `data:image/${ext};base64,` + base64content;
80
+ }
81
+
82
+ /**
83
+ * Get the base64 representation of a remote file from the given URL.
84
+ *
85
+ * @param {string} url - the URL of the file
86
+ * @return {Promise<string>} the base64 representation of the file
87
+ */
88
+ public static async getBase64FromFileUrl(url: string): Promise<string> {
89
+ const response = await axios.get(url, {
90
+ responseType: "arraybuffer",
91
+ maxRedirects: 5,
92
+ });
93
+ return Buffer.from(response.data, "binary").toString("base64");
94
+ }
95
+
96
+ /**
97
+ * Check if the base64 string represents a valid image and has a valid size
98
+ *
99
+ * @param {string} base64Image - the base64 image to be validated
100
+ * @return {Promise<string>} the valid base64 image
101
+ */
102
+ public static isValidImage(base64Image: string): boolean {
103
+ // Check if the base64 string represents a valid image and has a valid size
104
+ try {
105
+ const isBase64Image = base64Image.startsWith("data:image/");
106
+ if (!isBase64Image) {
107
+ console.error("Not a valid base64 image");
108
+ throw new Error("Not a valid base64 image");
109
+ }
110
+
111
+ // TODO: use constants intead of magic numbers here
112
+ const isSizeLessThan2MB =
113
+ base64Image.length * 0.75 <= MAX_IMAGE_SIZE_MB * 1024 * 1024;
114
+
115
+ if (!isSizeLessThan2MB) {
116
+ console.error(`The image should be less than 2mb`);
117
+ throw new Error(`The image should be less than 2mb`);
118
+ }
119
+ // all is fine
120
+ return true;
121
+ } catch (error) {
122
+ console.error("Error checking base64 image:", error);
123
+ throw new Error(`Error checking base64 image`);
124
+ }
125
+ }
41
126
  }
@@ -82,7 +82,7 @@ export function handleExceptions(
82
82
  }
83
83
  }
84
84
 
85
- class TropipayJSException extends Error {
85
+ export class TropipayJSException extends Error {
86
86
  code: number; // Status code
87
87
  error: unknown;
88
88
  message: string;
@@ -14,4 +14,32 @@ export declare class ServerSideUtils {
14
14
  clientId: string;
15
15
  clientSecret: string;
16
16
  } | Tropipay, originalCurrencyAmount: string, bankOrderCode: string, signature: string): boolean;
17
+ /**
18
+ * Checks if the provided base64 string represents a square image.
19
+ *
20
+ * @param {string} base64String - The base64 string of the image
21
+ * @return {Promise<boolean>} A Promise that resolves to a boolean indicating whether the image is square
22
+ */
23
+ static isBase64ImageSquare(base64String: string): Promise<boolean>;
24
+ /**
25
+ * Takes a local file path and returns a base64 representation of the file content.
26
+ *
27
+ * @param {string} filepath - the path of the file to be converted to base64
28
+ * @return {Promise<string>} a Promise that resolves to the base64 representation of the file content
29
+ */
30
+ static fileToBase64(filepath: string): Promise<string>;
31
+ /**
32
+ * Get the base64 representation of a remote file from the given URL.
33
+ *
34
+ * @param {string} url - the URL of the file
35
+ * @return {Promise<string>} the base64 representation of the file
36
+ */
37
+ static getBase64FromFileUrl(url: string): Promise<string>;
38
+ /**
39
+ * Check if the base64 string represents a valid image and has a valid size
40
+ *
41
+ * @param {string} base64Image - the base64 image to be validated
42
+ * @return {Promise<string>} the valid base64 image
43
+ */
44
+ static isValidImage(base64Image: string): boolean;
17
45
  }
package/utils/errors.d.ts CHANGED
@@ -8,10 +8,9 @@ export interface ErrorDetail {
8
8
  meta: unknown;
9
9
  }
10
10
  export declare function handleExceptions(error: AxiosError | Error): TropipayJSException;
11
- declare class TropipayJSException extends Error {
11
+ export declare class TropipayJSException extends Error {
12
12
  code: number;
13
13
  error: unknown;
14
14
  message: string;
15
15
  constructor(message: string, code: number, data: unknown);
16
16
  }
17
- export {};