@mathrunet/masamune 0.4.4 → 0.5.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/functions/android_auth_code.d.ts +1 -0
  3. package/dist/functions/android_auth_code.js +76 -0
  4. package/dist/functions/android_auth_code.js.map +1 -0
  5. package/dist/functions/android_token.d.ts +1 -0
  6. package/dist/functions/android_token.js +117 -0
  7. package/dist/functions/android_token.js.map +1 -0
  8. package/dist/functions/consumable_verify_android.d.ts +1 -0
  9. package/dist/functions/consumable_verify_android.js +132 -0
  10. package/dist/functions/consumable_verify_android.js.map +1 -0
  11. package/dist/functions/consumable_verify_ios.d.ts +1 -0
  12. package/dist/functions/consumable_verify_ios.js +92 -0
  13. package/dist/functions/consumable_verify_ios.js.map +1 -0
  14. package/dist/functions/gmail.js +8 -3
  15. package/dist/functions/gmail.js.map +1 -1
  16. package/dist/functions/nonconsumable_verify_android.d.ts +1 -0
  17. package/dist/functions/nonconsumable_verify_android.js +126 -0
  18. package/dist/functions/nonconsumable_verify_android.js.map +1 -0
  19. package/dist/functions/nonconsumable_verify_ios.d.ts +1 -0
  20. package/dist/functions/nonconsumable_verify_ios.js +86 -0
  21. package/dist/functions/nonconsumable_verify_ios.js.map +1 -0
  22. package/dist/functions/purchase_hook_android.d.ts +1 -0
  23. package/dist/functions/purchase_hook_android.js +237 -0
  24. package/dist/functions/purchase_hook_android.js.map +1 -0
  25. package/dist/functions/purchase_hook_ios.d.ts +1 -0
  26. package/dist/functions/purchase_hook_ios.js +135 -0
  27. package/dist/functions/purchase_hook_ios.js.map +1 -0
  28. package/dist/functions/send_grid.js +6 -1
  29. package/dist/functions/send_grid.js.map +1 -1
  30. package/dist/functions/stripe.js +46 -12
  31. package/dist/functions/stripe.js.map +1 -1
  32. package/dist/functions/stripe_hook_secure.js +5 -1
  33. package/dist/functions/stripe_hook_secure.js.map +1 -1
  34. package/dist/functions/subscription_verify_android.d.ts +1 -0
  35. package/dist/functions/subscription_verify_android.js +159 -0
  36. package/dist/functions/subscription_verify_android.js.map +1 -0
  37. package/dist/functions/subscription_verify_ios.d.ts +1 -0
  38. package/dist/functions/subscription_verify_ios.js +128 -0
  39. package/dist/functions/subscription_verify_ios.js.map +1 -0
  40. package/dist/functions.d.ts +62 -0
  41. package/dist/functions.js +62 -0
  42. package/dist/functions.js.map +1 -1
  43. package/dist/lib/gmail.d.ts +6 -1
  44. package/dist/lib/gmail.js +1 -1
  45. package/dist/lib/gmail.js.map +1 -1
  46. package/dist/lib/send_grid.d.ts +6 -1
  47. package/dist/lib/send_grid.js +1 -1
  48. package/dist/lib/send_grid.js.map +1 -1
  49. package/dist/lib/update_subscription.d.ts +83 -0
  50. package/dist/lib/update_subscription.js +142 -0
  51. package/dist/lib/update_subscription.js.map +1 -0
  52. package/dist/lib/update_unlock.d.ts +13 -0
  53. package/dist/lib/update_unlock.js +64 -0
  54. package/dist/lib/update_unlock.js.map +1 -0
  55. package/dist/lib/update_wallet.d.ts +19 -0
  56. package/dist/lib/update_wallet.js +70 -0
  57. package/dist/lib/update_wallet.js.map +1 -0
  58. package/dist/lib/utils.d.ts +10 -2
  59. package/dist/lib/utils.js +2 -2
  60. package/dist/lib/utils.js.map +1 -1
  61. package/dist/lib/verify_android.d.ts +56 -0
  62. package/dist/lib/verify_android.js +128 -0
  63. package/dist/lib/verify_android.js.map +1 -0
  64. package/dist/lib/verify_ios.d.ts +26 -0
  65. package/dist/lib/verify_ios.js +115 -0
  66. package/dist/lib/verify_ios.js.map +1 -0
  67. package/package.json +2 -1
@@ -0,0 +1,128 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.verifyAndroid = void 0;
39
+ const functions = __importStar(require("firebase-functions"));
40
+ const node_fetch_1 = __importDefault(require("node-fetch"));
41
+ const form_data_1 = __importDefault(require("form-data"));
42
+ /**
43
+ * Perform Android receipt verification.
44
+ *
45
+ * Android の受信確認を実行します。
46
+ *
47
+ * @param {String} type
48
+ * Item type(products or subscriptions)
49
+ *
50
+ * アイテムの種類(製品またはサブスクリプション)
51
+ *
52
+ * @param {String} clientId
53
+ * Google OAuth client ID.
54
+ *
55
+ * Google OAuth クライアントID。
56
+ *
57
+ * @param {String} clientSecret
58
+ * Google OAuth client secret.
59
+ *
60
+ * Google OAuth クライアントシークレット。
61
+ *
62
+ * @param {String} refreshToken
63
+ * Refresh token obtained by accessing [android_auth_code].
64
+ *
65
+ * [android_auth_code]にアクセスして取得したリフレッシュトークン。
66
+ *
67
+ * @param {String} packageName
68
+ * Application package name.
69
+ *
70
+ * アプリケーションのパッケージ名。
71
+ *
72
+ * @param {String} productId
73
+ * Item ID issued by Google Play.
74
+ *
75
+ * GooglePlayで発行されたアイテムID。
76
+ *
77
+ * @param {String} purchaseToken
78
+ * The purchase token issued at the time of purchase.
79
+ *
80
+ * 購入したときに発行された購入トークン。
81
+ *
82
+ * @return {Promise<{ [key: string]: any; }}
83
+ * Receipt information for the item.
84
+ *
85
+ * アイテムの受領情報。
86
+ */
87
+ function verifyAndroid({ type, clientId, clientSecret, refreshToken, packageName, productId, purchaseToken, }) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ const formData = new form_data_1.default();
90
+ formData.append("grant_type", "refresh_token");
91
+ formData.append("client_id", clientId);
92
+ formData.append("client_secret", clientSecret);
93
+ formData.append("refresh_token", refreshToken);
94
+ let res = yield (0, node_fetch_1.default)("https://accounts.google.com/o/oauth2/token", {
95
+ method: "POST",
96
+ timeout: 30 * 1000,
97
+ headers: {
98
+ "Content-Type": "application/x-www-form-urlencoded",
99
+ },
100
+ body: formData
101
+ });
102
+ if (!res) {
103
+ throw new functions.https.HttpsError("not-found", "Cannot get access token.");
104
+ }
105
+ let json = (yield res.json());
106
+ console.log(json);
107
+ const accessToken = json["access_token"];
108
+ if (!accessToken) {
109
+ throw new functions.https.HttpsError("not-found", "Cannot get access token.");
110
+ }
111
+ console.log(accessToken);
112
+ res = yield (0, node_fetch_1.default)(`https://www.googleapis.com/androidpublisher/v3/applications/"${packageName}/purchases/${type}/${productId}/tokens/${purchaseToken}?access_token=${accessToken}`, {
113
+ method: "GET",
114
+ timeout: 30 * 1000,
115
+ headers: {
116
+ "Content-Type": "application/json",
117
+ },
118
+ });
119
+ if (!res) {
120
+ throw new functions.https.HttpsError("not-found", "The validation data is empty.");
121
+ }
122
+ json = (yield res.json());
123
+ console.log(json);
124
+ return json;
125
+ });
126
+ }
127
+ exports.verifyAndroid = verifyAndroid;
128
+ //# sourceMappingURL=verify_android.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify_android.js","sourceRoot":"","sources":["../../src/lib/verify_android.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8DAAgD;AAChD,4DAA+B;AAC/B,0DAAiC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,SAAsB,aAAa,CAAC,EAChC,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,EACT,aAAa,GAShB;;QACG,MAAM,QAAQ,GAAG,IAAI,mBAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QAC/C,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QACvC,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;QAC/C,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;QAC/C,IAAI,GAAG,GAAG,MAAM,IAAA,oBAAK,EAAC,4CAA4C,EAAE;YAChE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,GAAG,IAAI;YAClB,OAAO,EAAE;gBACL,cAAc,EAAE,mCAAmC;aACtD;YACD,IAAI,EAAE,QAAQ;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE;YACN,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;SACjF;QACD,IAAI,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2B,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE;YACd,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;SACjF;QACD,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,GAAG,GAAG,MAAM,IAAA,oBAAK,EACb,gEAAgE,WAAW,cAAc,IAAI,IAAI,SAAS,WAAW,aAAa,iBAAiB,WAAW,EAAE,EAAE;YAClK,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,GAAG,IAAI;YAClB,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;aACrC;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE;YACN,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC;SACtF;QACD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2B,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC;IAChB,CAAC;CAAA;AAtDD,sCAsDC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Perform IOS receipt verification.
3
+ *
4
+ * IOSの受信確認を実行します。
5
+ *
6
+ * @param {String} receiptData
7
+ * Receipt data for purchases.
8
+ *
9
+ * 購入の際のレシートデータ。
10
+ *
11
+ * @param {String} password
12
+ * SharedSecret for AppStore, obtained from [Apps]->[App Info]->[Shared Secret for App] in the AppStore.
13
+ *
14
+ * AppStoreのSharedSecret。AppStoreの[アプリ]->[App情報]->[App用共有シークレット]から取得します。
15
+ *
16
+ * @return {Promise<{ [key: string]: any; }}
17
+ * Receipt information for the item.
18
+ *
19
+ * アイテムの受領情報。
20
+ */
21
+ export declare function verifyIOS({ receiptData, password }: {
22
+ receiptData: string;
23
+ password: string;
24
+ }): Promise<{
25
+ [key: string]: any;
26
+ }>;
@@ -0,0 +1,115 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.verifyIOS = void 0;
39
+ const functions = __importStar(require("firebase-functions"));
40
+ const node_fetch_1 = __importDefault(require("node-fetch"));
41
+ /**
42
+ * Perform IOS receipt verification.
43
+ *
44
+ * IOSの受信確認を実行します。
45
+ *
46
+ * @param {String} receiptData
47
+ * Receipt data for purchases.
48
+ *
49
+ * 購入の際のレシートデータ。
50
+ *
51
+ * @param {String} password
52
+ * SharedSecret for AppStore, obtained from [Apps]->[App Info]->[Shared Secret for App] in the AppStore.
53
+ *
54
+ * AppStoreのSharedSecret。AppStoreの[アプリ]->[App情報]->[App用共有シークレット]から取得します。
55
+ *
56
+ * @return {Promise<{ [key: string]: any; }}
57
+ * Receipt information for the item.
58
+ *
59
+ * アイテムの受領情報。
60
+ */
61
+ function verifyIOS({ receiptData, password }) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ let res = yield (0, node_fetch_1.default)("https://buy.itunes.apple.com/verifyReceipt", {
64
+ method: "POST",
65
+ timeout: 30 * 1000,
66
+ headers: {
67
+ "Content-Type": "application/json",
68
+ "Accept": "application/json",
69
+ },
70
+ body: JSON.stringify({
71
+ "receipt-data": receiptData,
72
+ "password": password,
73
+ "exclude-old-transactions": true,
74
+ }),
75
+ });
76
+ if (!res) {
77
+ throw new functions.https.HttpsError("not-found", "The validation data is empty.");
78
+ }
79
+ let json = (yield res.json());
80
+ console.log(json);
81
+ let status = json["status"];
82
+ if (status === 21007 || status === 21008) {
83
+ res = yield (0, node_fetch_1.default)("https://sandbox.itunes.apple.com/verifyReceipt", {
84
+ method: "POST",
85
+ timeout: 30 * 1000,
86
+ headers: {
87
+ "Content-Type": "application/json",
88
+ "Accept": "application/json",
89
+ },
90
+ body: JSON.stringify({
91
+ "receipt-data": receiptData,
92
+ "password": password,
93
+ "exclude-old-transactions": true,
94
+ }),
95
+ });
96
+ if (!res) {
97
+ throw new functions.https.HttpsError("not-found", "The validation data is empty.");
98
+ }
99
+ json = (yield res.json());
100
+ console.log(json);
101
+ status = json["status"];
102
+ if (status !== 0) {
103
+ throw new functions.https.HttpsError("not-found", "Illegal receipt.");
104
+ }
105
+ }
106
+ else {
107
+ if (status !== 0) {
108
+ throw new functions.https.HttpsError("not-found", "Illegal receipt.");
109
+ }
110
+ }
111
+ return json;
112
+ });
113
+ }
114
+ exports.verifyIOS = verifyIOS;
115
+ //# sourceMappingURL=verify_ios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify_ios.js","sourceRoot":"","sources":["../../src/lib/verify_ios.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8DAAgD;AAChD,4DAA+B;AAE/B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAsB,SAAS,CAAC,EAC5B,WAAW,EACX,QAAQ,EAIX;;QACG,IAAI,GAAG,GAAG,MAAM,IAAA,oBAAK,EAAC,4CAA4C,EAAE;YAChE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,GAAG,IAAI;YAClB,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;gBAClC,QAAQ,EAAE,kBAAkB;aAC/B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACjB,cAAc,EAAE,WAAW;gBAC3B,UAAU,EAAE,QAAQ;gBACpB,0BAA0B,EAAE,IAAI;aACnC,CAAC;SACL,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE;YACN,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC;SACtF;QACD,IAAI,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2B,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE;YACtC,GAAG,GAAG,MAAM,IAAA,oBAAK,EAAC,gDAAgD,EAAE;gBAChE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,GAAG,IAAI;gBAClB,OAAO,EAAE;oBACL,cAAc,EAAE,kBAAkB;oBAClC,QAAQ,EAAE,kBAAkB;iBAC/B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACjB,cAAc,EAAE,WAAW;oBAC3B,UAAU,EAAE,QAAQ;oBACpB,0BAA0B,EAAE,IAAI;iBACnC,CAAC;aACL,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,EAAE;gBACN,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC;aACtF;YACD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2B,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxB,IAAI,MAAM,KAAK,CAAC,EAAE;gBACd,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;aACzE;SACJ;aAAM;YACH,IAAI,MAAM,KAAK,CAAC,EAAE;gBACd,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;aACzE;SACJ;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;CAAA;AAvDD,8BAuDC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mathrunet/masamune",
3
- "version": "0.4.4",
3
+ "version": "0.5.2",
4
4
  "description": "Manages packages for the server portion (NodeJS) of the Masamune framework.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -37,6 +37,7 @@
37
37
  "crypto": "^1.0.1",
38
38
  "firebase-admin": "^11.4.1",
39
39
  "firebase-functions": "^4.1.1",
40
+ "form-data": "^4.0.0",
40
41
  "node-fetch": "^2.6.9",
41
42
  "nodemailer": "^6.9.2",
42
43
  "stripe": "^12.7.0",