90dc-core 1.3.1 → 1.4.1

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.
@@ -0,0 +1,265 @@
1
+ import * as dotenv from "dotenv";
2
+ import jwt from "jsonwebtoken";
3
+ import axios, { isAxiosError } from "axios";
4
+ import fs from "fs";
5
+ import { google } from "googleapis";
6
+ import { PersistedUser } from "../dbmodels/PersistedUser";
7
+ import { AppleTransactionError } from "../Errors/Errors";
8
+ dotenv.config();
9
+ export default class AuthenticationUtil {
10
+ static ACCESS_SECRET = process.env.ACCESS_TOKEN_SECRET;
11
+ static async fetchUserWithTokenInfo(token) {
12
+ const userInToken = await AuthenticationUtil.verifyTokenAndFetchUser(token);
13
+ if (userInToken === null || !userInToken || !userInToken.userUuid || !userInToken.userUuid) {
14
+ return null;
15
+ }
16
+ return userInToken;
17
+ }
18
+ static async verifyAppleReceipt(data) {
19
+ const response = await axios.post("https://buy.itunes.apple.com/verifyReceipt", {
20
+ "receipt-data": data,
21
+ password: "55a50fe585494a11b6f848f4d2a7dff3",
22
+ "exclude-old-transactions": true
23
+ });
24
+ return response.data;
25
+ }
26
+ static verifyTokenAndFetchUser(token) {
27
+ return new Promise((resolve, reject)=>{
28
+ jwt.verify(token, this.ACCESS_SECRET, (err, decoded)=>{
29
+ if (err) {
30
+ reject(err);
31
+ }
32
+ if (decoded === undefined) {
33
+ resolve(null);
34
+ return;
35
+ }
36
+ const user = decoded;
37
+ if (!user.userUuid) {
38
+ resolve(false);
39
+ return;
40
+ }
41
+ PersistedUser.findByPk(user.userUuid).then((persistedUser)=>{
42
+ resolve(persistedUser);
43
+ }).catch((e)=>{
44
+ reject(e);
45
+ });
46
+ });
47
+ });
48
+ }
49
+ static generateAppleJWT() {
50
+ const privateKey = fs.readFileSync(process.env.APPLE_SUBSCRIPTION_KEY_PATH, "utf-8");
51
+ const header = {
52
+ alg: "ES256",
53
+ kid: process.env.APPLE_KID,
54
+ typ: "JWT"
55
+ };
56
+ const payload = {
57
+ iss: process.env.APPLE_ISSUER,
58
+ iat: Math.floor(Date.now() / 1000),
59
+ exp: Math.floor(Date.now() / 1000) + 3600,
60
+ aud: "appstoreconnect-v1",
61
+ bid: process.env.APPLE_BUNDLE_ID
62
+ };
63
+ return jwt.sign(payload, privateKey, {
64
+ header
65
+ });
66
+ }
67
+ static async getAppleTransactions(originalTransactionId) {
68
+ const result = [];
69
+ try {
70
+ const response = await axios.get(`https://api.storekit.itunes.apple.com/inApps/v1/history/${originalTransactionId}`, {
71
+ headers: {
72
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
73
+ "Content-Type": "application/json"
74
+ }
75
+ });
76
+ for (const token of response.data.signedTransactions){
77
+ result.push(jwt.decode(token));
78
+ }
79
+ return result;
80
+ } catch (error) {
81
+ if (isAxiosError(error) && error.response?.status === 400) {
82
+ throw new AppleTransactionError("Invalid transaction id.");
83
+ }
84
+ if (isAxiosError(error) && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
85
+ (error.response?.data.errorCode === 4040010 || error.response?.status === 401)) {
86
+ try {
87
+ const response = await axios.get(`https://api.storekit-sandbox.itunes.apple.com/inApps/v1/history/${originalTransactionId}`, {
88
+ headers: {
89
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
90
+ "Content-Type": "application/json"
91
+ }
92
+ });
93
+ for (const token of response.data.signedTransactions){
94
+ result.push(jwt.decode(token));
95
+ }
96
+ return result;
97
+ } catch (e) {
98
+ if (isAxiosError(error) && error.response?.status === 400) {
99
+ throw new AppleTransactionError("Invalid transaction id.");
100
+ }
101
+ }
102
+ throw new AppleTransactionError("Transaction was not found in both environments.");
103
+ }
104
+ throw error;
105
+ }
106
+ }
107
+ static async getAndroidAccessToken() {
108
+ const keyPath = "src/lib/utils/dayschallenge-373510-dbde66bc0d05.json";
109
+ const jwtClient = new google.auth.JWT({
110
+ keyFile: keyPath,
111
+ scopes: [
112
+ "https://www.googleapis.com/auth/androidpublisher"
113
+ ]
114
+ });
115
+ const authResponse = await jwtClient.authorize();
116
+ return authResponse;
117
+ }
118
+ static async getAndroidSubscriptionsStatuses(token) {
119
+ try {
120
+ const credentials = await this.getAndroidAccessToken();
121
+ const response = await axios.get(`https://androidpublisher.googleapis.com/androidpublisher/v3/applications/nl.browney.nintydayschallenge/purchases/subscriptionsv2/tokens/${token}`, {
122
+ headers: {
123
+ Authorization: `Bearer ${credentials.access_token}`
124
+ }
125
+ });
126
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
127
+ return response.data;
128
+ } catch (error) {
129
+ if (isAxiosError(error) && error.response && error.response.status === 410) {
130
+ return {
131
+ lineItems: [
132
+ {
133
+ expiryTime: "2024-01-04T13:05:16.831Z"
134
+ }
135
+ ]
136
+ };
137
+ } else {
138
+ if (isAxiosError(error)) {
139
+ return false;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ static async isAndroidSubscriptionsActive(token) {
145
+ try {
146
+ const credentials = await this.getAndroidAccessToken();
147
+ const response = await axios.get(`https://androidpublisher.googleapis.com/androidpublisher/v3/applications/nl.browney.nintydayschallenge/purchases/subscriptionsv2/tokens/${token}`, {
148
+ headers: {
149
+ Authorization: `Bearer ${credentials.access_token}`
150
+ }
151
+ });
152
+ return response.data.subscriptionState === "SUBSCRIPTION_STATE_ACTIVE";
153
+ } catch (error) {
154
+ if (isAxiosError(error)) {
155
+ console.error("An error occurred:", error.message);
156
+ }
157
+ return false;
158
+ }
159
+ }
160
+ static async isAppleSubscriptionActive(transactionId) {
161
+ try {
162
+ const response = await axios.get(`https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`, {
163
+ headers: {
164
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
165
+ "Content-Type": "application/json"
166
+ }
167
+ });
168
+ return response.data.data[0].lastTransactions[0].status === 0 || response.data.data[0].lastTransactions[0].status === 2;
169
+ } catch (e) {
170
+ if (axios.isAxiosError(e) && e.response && e.response.data["errorMessage"] === "Invalid transaction id.") {
171
+ return false;
172
+ }
173
+ return false;
174
+ }
175
+ }
176
+ static async getAppleSubscriptionsStatuses(transactionId) {
177
+ const result = [];
178
+ try {
179
+ const response = await axios.get(`https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`, {
180
+ headers: {
181
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
182
+ "Content-Type": "application/json"
183
+ }
184
+ });
185
+ for (const transaction of response.data.data[0].lastTransactions){
186
+ result.push({
187
+ originalTransactionId: transaction.originalTransactionId,
188
+ status: transaction.status,
189
+ signedTransactionInfo: jwt.decode(transaction.signedTransactionInfo),
190
+ signedRenewalInfo: jwt.decode(transaction.signedRenewalInfo)
191
+ });
192
+ }
193
+ return result;
194
+ } catch (error) {
195
+ if (isAxiosError(error) && error.response?.status === 400) {
196
+ throw new AppleTransactionError("Invalid transaction id.");
197
+ }
198
+ if (isAxiosError(error) && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
199
+ (error.response?.data.errorCode === 4040010 || error.response?.status === 401)) {
200
+ try {
201
+ const response = await axios.get(`https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`, {
202
+ headers: {
203
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
204
+ "Content-Type": "application/json"
205
+ }
206
+ });
207
+ for (const transaction of response.data.data[0].lastTransactions){
208
+ result.push({
209
+ originalTransactionId: transaction.originalTransactionId,
210
+ status: transaction.status,
211
+ signedTransactionInfo: jwt.decode(transaction.signedTransactionInfo),
212
+ signedRenewalInfo: jwt.decode(transaction.signedRenewalInfo)
213
+ });
214
+ }
215
+ return result;
216
+ } catch (e) {
217
+ if (isAxiosError(error) && error.response?.status === 400) {
218
+ throw new AppleTransactionError("Invalid transaction id.");
219
+ }
220
+ }
221
+ throw new AppleTransactionError("Transaction was not found in both environments.");
222
+ }
223
+ throw error;
224
+ }
225
+ }
226
+ static async getSingleAppleTransactionsInfo(transactionId) {
227
+ try {
228
+ const response = await axios.get(`https://api.storekit.itunes.apple.com/inApps/v1/transactions/${transactionId}`, {
229
+ headers: {
230
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
231
+ "Content-Type": "application/json"
232
+ }
233
+ });
234
+ return {
235
+ signedTransactionInfo: jwt.decode(response.data.signedTransactionInfo)
236
+ };
237
+ } catch (error) {
238
+ if (isAxiosError(error) && error.response?.status === 400) {
239
+ throw new AppleTransactionError("Invalid transaction id.");
240
+ }
241
+ if (isAxiosError(error) && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
242
+ (error.response?.data.errorCode === 4040010 || error.response?.status === 401)) {
243
+ try {
244
+ const response = await axios.get(`https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/${transactionId}`, {
245
+ headers: {
246
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
247
+ "Content-Type": "application/json"
248
+ }
249
+ });
250
+ return {
251
+ signedTransactionInfo: jwt.decode(response.data.signedTransactionInfo)
252
+ };
253
+ } catch (e) {
254
+ if (isAxiosError(error) && error.response?.status === 400) {
255
+ throw new AppleTransactionError("Invalid transaction id.");
256
+ }
257
+ }
258
+ throw new AppleTransactionError("Transaction was not found in both environments.");
259
+ }
260
+ throw error;
261
+ }
262
+ }
263
+ }
264
+
265
+ //# sourceMappingURL=AuthenticationUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils/AuthenticationUtil.ts"],"sourcesContent":["import * as dotenv from \"dotenv\";\nimport jwt, { JwtPayload, VerifyErrors } from \"jsonwebtoken\";\nimport axios, { AxiosResponse, isAxiosError } from \"axios\";\nimport fs from \"fs\";\nimport { google } from \"googleapis\";\nimport { PersistedUser } from \"../dbmodels/PersistedUser\";\nimport type {\n Credentials,\n SignedTransactions, SingleTransactionResponse,\n SubscriptionStatusResponse, SubscriptionStatusResponseError, SubscriptionStatusResult,\n TransactionsResponse,\n UserTypes,\n VerificationStatus\n} from \"../models/UserInterfaces\";\nimport { AppleTransactionError } from \"../Errors/Errors\";\n\ndotenv.config();\n\n\nexport default class AuthenticationUtil {\n private static readonly ACCESS_SECRET = <string>process.env.ACCESS_TOKEN_SECRET;\n\n public static async fetchUserWithTokenInfo(token: string): Promise<PersistedUser | null> {\n const userInToken: PersistedUser | null | false = await AuthenticationUtil.verifyTokenAndFetchUser(\n token\n );\n if (userInToken === null || !userInToken || !userInToken.userUuid || !userInToken.userUuid) {\n return null;\n }\n\n return userInToken;\n }\n\n public static async verifyAppleReceipt(data: string): Promise<VerificationStatus> {\n const response: AxiosResponse = await axios.post(\"https://buy.itunes.apple.com/verifyReceipt\", {\n \"receipt-data\": data,\n password: \"55a50fe585494a11b6f848f4d2a7dff3\",\n \"exclude-old-transactions\": true,\n });\n\n return response.data as VerificationStatus;\n }\n\n public static verifyTokenAndFetchUser(token: string): Promise<PersistedUser | null | false> {\n return new Promise<PersistedUser | null | false>((resolve, reject) => {\n jwt.verify(\n token,\n this.ACCESS_SECRET,\n (err: VerifyErrors | null, decoded: JwtPayload | string | undefined) => {\n if (err) {\n reject(err);\n }\n\n if (decoded === undefined) {\n resolve(null);\n return;\n }\n\n const user: UserTypes = <UserTypes>decoded;\n\n if (!user.userUuid) {\n resolve(false);\n return;\n }\n\n PersistedUser.findByPk(user.userUuid)\n .then((persistedUser: PersistedUser | null) => {\n resolve(persistedUser);\n })\n .catch((e: Error) => {\n reject(e);\n });\n }\n );\n });\n }\n\n public static generateAppleJWT() {\n const privateKey: string = fs.readFileSync(\n process.env.APPLE_SUBSCRIPTION_KEY_PATH as string,\n \"utf-8\"\n );\n\n const header = {\n alg: \"ES256\",\n kid: process.env.APPLE_KID as string,\n typ: \"JWT\",\n };\n\n const payload = {\n iss: process.env.APPLE_ISSUER as string,\n iat: Math.floor(Date.now() / 1000),\n exp: Math.floor(Date.now() / 1000) + 3600,\n aud: \"appstoreconnect-v1\",\n bid: process.env.APPLE_BUNDLE_ID as string,\n };\n\n return jwt.sign(payload, privateKey, { header });\n\n }\n\n public static async getAppleTransactions(originalTransactionId: string) {\n const result: SignedTransactions[] = [];\n try {\n const response: AxiosResponse<TransactionsResponse> = await axios.get(\n `https://api.storekit.itunes.apple.com/inApps/v1/history/${originalTransactionId}`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n for (const token of response.data.signedTransactions) {\n result.push(jwt.decode(token) as SignedTransactions);\n }\n\n return result;\n } catch (error) {\n if (isAxiosError(error) && error.response?.status === 400) {\n throw new AppleTransactionError(\"Invalid transaction id.\");\n }\n\n if (\n isAxiosError(error) &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (error.response?.data.errorCode === 4040010 || error.response?.status === 401)\n ) {\n try {\n const response: AxiosResponse<TransactionsResponse> = await axios.get(\n `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/history/${originalTransactionId}`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n for (const token of response.data.signedTransactions) {\n result.push(jwt.decode(token) as SignedTransactions);\n }\n\n return result;\n } catch (e) {\n if (isAxiosError(error) && error.response?.status === 400) {\n throw new AppleTransactionError(\"Invalid transaction id.\");\n }\n }\n throw new AppleTransactionError(\"Transaction was not found in both environments.\");\n }\n throw error\n\n }\n }\n\n public static async getAndroidAccessToken() {\n const keyPath = \"src/lib/utils/dayschallenge-373510-dbde66bc0d05.json\";\n\n const jwtClient = new google.auth.JWT({\n keyFile: keyPath,\n scopes: [\"https://www.googleapis.com/auth/androidpublisher\"],\n });\n\n const authResponse: Credentials = await jwtClient.authorize();\n return authResponse;\n }\n\n public static async getAndroidSubscriptionsStatuses(token: string) {\n try {\n const credentials = await this.getAndroidAccessToken();\n\n const response: AxiosResponse = await axios.get(\n `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/nl.browney.nintydayschallenge/purchases/subscriptionsv2/tokens/${token}`,\n {\n headers: {\n Authorization: `Bearer ${credentials.access_token as string}`,\n },\n }\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return response.data;\n } catch (error) {\n if (isAxiosError(error) && error.response && error.response.status === 410) {\n return {\n lineItems: [\n {\n expiryTime: \"2024-01-04T13:05:16.831Z\",\n },\n ],\n };\n } else {\n if (isAxiosError(error)) {\n return false;\n }\n }\n }\n }\n\n public static async isAndroidSubscriptionsActive(token: string) {\n try {\n const credentials = await this.getAndroidAccessToken();\n\n const response: AxiosResponse = await axios.get(\n `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/nl.browney.nintydayschallenge/purchases/subscriptionsv2/tokens/${token}`,\n {\n headers: {\n Authorization: `Bearer ${credentials.access_token as string}`,\n },\n }\n );\n\n return (\n (response.data as { subscriptionState: string }).subscriptionState ===\n \"SUBSCRIPTION_STATE_ACTIVE\"\n );\n } catch (error) {\n if (isAxiosError(error)) {\n console.error(\"An error occurred:\", error.message);\n }\n return false\n }\n }\n\n public static async isAppleSubscriptionActive(transactionId: string) {\n try {\n const response: AxiosResponse<SubscriptionStatusResponse> = await axios.get(\n `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n return (\n response.data.data[0].lastTransactions[0].status === 0 ||\n response.data.data[0].lastTransactions[0].status === 2\n );\n } catch (e) {\n if (\n axios.isAxiosError(e) &&\n e.response &&\n (e.response.data as SubscriptionStatusResponseError)[\"errorMessage\"] ===\n \"Invalid transaction id.\"\n ) {\n return false;\n }\n return false;\n }\n }\n\n public static async getAppleSubscriptionsStatuses(transactionId: string) {\n const result: SubscriptionStatusResult[] = [];\n try {\n const response: AxiosResponse<SubscriptionStatusResponse> = await axios.get(\n `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n for (const transaction of response.data.data[0].lastTransactions) {\n result.push({\n originalTransactionId: transaction.originalTransactionId,\n status: transaction.status,\n signedTransactionInfo: jwt.decode(transaction.signedTransactionInfo),\n signedRenewalInfo: jwt.decode(transaction.signedRenewalInfo),\n });\n }\n\n return result;\n } catch (error: unknown) {\n if (isAxiosError(error) && error.response?.status === 400) {\n throw new AppleTransactionError(\"Invalid transaction id.\");\n }\n\n if (\n isAxiosError(error) &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (error.response?.data.errorCode === 4040010 || error.response?.status === 401)\n ) {\n try {\n const response: AxiosResponse<SubscriptionStatusResponse> = await axios.get(\n `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n for (const transaction of response.data.data[0].lastTransactions) {\n result.push({\n originalTransactionId: transaction.originalTransactionId,\n status: transaction.status,\n signedTransactionInfo: jwt.decode(transaction.signedTransactionInfo),\n signedRenewalInfo: jwt.decode(transaction.signedRenewalInfo),\n });\n }\n\n return result;\n } catch (e) {\n if (isAxiosError(error) && error.response?.status === 400) {\n throw new AppleTransactionError(\"Invalid transaction id.\");\n }\n }\n throw new AppleTransactionError(\"Transaction was not found in both environments.\");\n }\n throw error\n }\n }\n\n public static async getSingleAppleTransactionsInfo(transactionId: string) {\n try {\n const response: AxiosResponse<SingleTransactionResponse> = await axios.get(\n `https://api.storekit.itunes.apple.com/inApps/v1/transactions/${transactionId}`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n return { signedTransactionInfo: jwt.decode(response.data.signedTransactionInfo) };\n } catch (error) {\n if (isAxiosError(error) && error.response?.status === 400) {\n throw new AppleTransactionError(\"Invalid transaction id.\");\n }\n\n if (\n isAxiosError(error) &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (error.response?.data.errorCode === 4040010 || error.response?.status === 401)\n ) {\n try {\n const response: AxiosResponse<SingleTransactionResponse> = await axios.get(\n `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/${transactionId}`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n return { signedTransactionInfo: jwt.decode(response.data.signedTransactionInfo) };\n } catch (e) {\n if (isAxiosError(error) && error.response?.status === 400) {\n throw new AppleTransactionError(\"Invalid transaction id.\");\n }\n }\n throw new AppleTransactionError(\"Transaction was not found in both environments.\");\n }\n throw error\n }\n }\n}\n"],"names":["dotenv","jwt","axios","isAxiosError","fs","google","PersistedUser","AppleTransactionError","config","AuthenticationUtil","ACCESS_SECRET","process","env","ACCESS_TOKEN_SECRET","fetchUserWithTokenInfo","token","userInToken","verifyTokenAndFetchUser","userUuid","verifyAppleReceipt","data","response","post","password","Promise","resolve","reject","verify","err","decoded","undefined","user","findByPk","then","persistedUser","catch","e","generateAppleJWT","privateKey","readFileSync","APPLE_SUBSCRIPTION_KEY_PATH","header","alg","kid","APPLE_KID","typ","payload","iss","APPLE_ISSUER","iat","Math","floor","Date","now","exp","aud","bid","APPLE_BUNDLE_ID","sign","getAppleTransactions","originalTransactionId","result","get","headers","Authorization","signedTransactions","push","decode","error","status","errorCode","getAndroidAccessToken","keyPath","jwtClient","auth","JWT","keyFile","scopes","authResponse","authorize","getAndroidSubscriptionsStatuses","credentials","access_token","lineItems","expiryTime","isAndroidSubscriptionsActive","subscriptionState","console","message","isAppleSubscriptionActive","transactionId","lastTransactions","getAppleSubscriptionsStatuses","transaction","signedTransactionInfo","signedRenewalInfo","getSingleAppleTransactionsInfo"],"mappings":"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"}
@@ -1,11 +1,9 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access */
2
- import axios from "axios";
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access */ import axios from "axios";
3
2
  import Debug from "debug";
4
3
  import * as crypto from "crypto";
5
4
  export class Log {
6
5
  static instance = null;
7
- debugLib;
8
- constructor(debug) {
6
+ constructor(debug){
9
7
  this.debugLib = debug;
10
8
  }
11
9
  static getInstance() {
@@ -45,8 +43,7 @@ export class Log {
45
43
  if (typeof error === "string") {
46
44
  error.toUpperCase(); // works, `e` narrowed to string
47
45
  this.error(error);
48
- }
49
- else if (error instanceof Error) {
46
+ } else if (error instanceof Error) {
50
47
  error.message; // works, `e` narrowed to Error
51
48
  this.error(error.message);
52
49
  }
@@ -62,3 +59,5 @@ export class Log {
62
59
  return new Log(debugExtension);
63
60
  }
64
61
  }
62
+
63
+ //# sourceMappingURL=Logger.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "90dc-core",
3
- "version": "1.3.1",
3
+ "version": "1.4.1",
4
4
  "description": "A package that contains utils and interfaces used to create 90dc",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -9,6 +9,7 @@
9
9
  "@swc/core": "^1.3.36",
10
10
  "@types/debug": "^4.1.12",
11
11
  "@types/jest": "^29.4.0",
12
+ "@types/jsonwebtoken": "^9.0.6",
12
13
  "@types/node": "^18.14.1",
13
14
  "@types/validator": "^13.7.12",
14
15
  "@typescript-eslint/eslint-plugin": "^5.53.0",
@@ -23,7 +24,10 @@
23
24
  "@typescript-eslint/parser": "^5.53.0",
24
25
  "axios": "^1.6.2",
25
26
  "debug": "^4.3.4",
27
+ "dotenv": "^16.4.5",
26
28
  "eslint": "^8.34.0",
29
+ "googleapis": "^140.0.0",
30
+ "jsonwebtoken": "^9.0.2",
27
31
  "sequelize-typescript": "^2.1.5",
28
32
  "winston": "^3.8.2"
29
33
  },
@@ -39,7 +43,7 @@
39
43
  "homepage": "https://github.com/RomaPchel/90DC-core#readme",
40
44
  "scripts": {
41
45
  "dev": "tsnd --respawn src/index.ts",
42
- "build": "npx swc --config-file .swcrc ./src -d dist && tsc",
46
+ "build": "npx swc --config-file .swcrc ./src -d dist ",
43
47
  "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
44
48
  "lint": "eslint './src/**/*.ts' --ext .ts",
45
49
  "preversion": "npm run lint",
@@ -0,0 +1,49 @@
1
+ export class ExerciseNotFound extends Error {
2
+ error = {};
3
+
4
+ constructor(message: object) {
5
+ super();
6
+ this.error = message;
7
+ Object.setPrototypeOf(this, ExerciseNotFound.prototype);
8
+ }
9
+ }
10
+
11
+ export class ExerciseAlreadyUsed extends Error {
12
+ error = {};
13
+
14
+ constructor(message: object) {
15
+ super();
16
+ this.error = message;
17
+ Object.setPrototypeOf(this, ExerciseNotFound.prototype);
18
+ }
19
+ }
20
+
21
+ export class AppleTransactionError extends Error {
22
+ error = {};
23
+
24
+ constructor(message: string) {
25
+ super();
26
+ this.error = message;
27
+ Object.setPrototypeOf(this, AppleTransactionError.prototype);
28
+ }
29
+ }
30
+
31
+ export class ProgramNotFound extends Error {
32
+ error = {};
33
+
34
+ constructor(message: object) {
35
+ super();
36
+ this.error = message;
37
+ Object.setPrototypeOf(this, ProgramNotFound.prototype);
38
+ }
39
+ }
40
+
41
+ export class NotificationNotSent extends Error {
42
+ error = {};
43
+
44
+ constructor(message: object) {
45
+ super();
46
+ this.error = message;
47
+ Object.setPrototypeOf(this, NotificationNotSent.prototype);
48
+ }
49
+ }
@@ -1,4 +1,5 @@
1
1
  import { Column, DataType, Default, Index, Model, Table } from "sequelize-typescript";
2
+ import type { Subscription } from "../models/UserInterfaces";
2
3
 
3
4
  @Table
4
5
  export class PersistedUser extends Model {
@@ -95,6 +96,6 @@ export class PersistedUser extends Model {
95
96
  declare changeUtilityEmail: boolean;
96
97
 
97
98
  @Column({ type: DataType.JSONB, allowNull: true })
98
- declare subscription: object;
99
+ declare subscription: Subscription;
99
100
 
100
101
  }
@@ -1,3 +1,5 @@
1
+ import type jwt from "jsonwebtoken";
2
+
1
3
  export interface UserTypes {
2
4
  userUuid: string;
3
5
  email: string;
@@ -7,12 +9,100 @@ export interface UserTypes {
7
9
  role: string;
8
10
  }
9
11
 
12
+ export interface VerificationStatus {
13
+ status: string;
14
+ }
15
+
16
+ export interface TransactionsResponse {
17
+ revision: string;
18
+ bundleId: string;
19
+ environment: string;
20
+ hasMore: boolean;
21
+ signedTransactions: string[];
22
+ errorCode?: number;
23
+ }
24
+
10
25
  export interface UserInfoModel {
11
26
  userUuid: string;
12
27
  height: string;
13
28
  weight: string;
14
29
  }
15
30
 
31
+ export interface Subscription {
32
+ type: "android" | "ios",
33
+ [key: string]: string;
34
+ }
35
+
36
+ export interface SingleTransactionResponse {
37
+ revision: string;
38
+ bundleId: string;
39
+ environment: string;
40
+ hasMore: boolean;
41
+ signedTransactionInfo: string;
42
+ errorCode?: number;
43
+ }
44
+
45
+ export interface SubscriptionStatus {
46
+ originalTransactionId: string;
47
+ status: number;
48
+ signedTransactionInfo: string;
49
+ signedRenewalInfo: string;
50
+ }
51
+
52
+ export interface SubscriptionStatusResponse {
53
+ environment: string;
54
+ bundleId: string;
55
+ data: [
56
+ {
57
+ subscriptionGroupIdentifier: string;
58
+ lastTransactions: SubscriptionStatus[];
59
+ }
60
+ ];
61
+ errorCode?: number;
62
+ }
63
+
64
+ export interface SubscriptionStatusResponseError {
65
+ errorCode: number;
66
+ errorMessage: string;
67
+ }
68
+
69
+ export interface SubscriptionStatusResult {
70
+ originalTransactionId: string;
71
+ status: number;
72
+ signedTransactionInfo: string | jwt.JwtPayload | null;
73
+ signedRenewalInfo: string | jwt.JwtPayload | null;
74
+ }
75
+
76
+ export interface SignedTransactions {
77
+ transactionId: string;
78
+ originalTransactionId: string;
79
+ webOrderLineItemId: string;
80
+ bundleId: string;
81
+ productId: string;
82
+ subscriptionGroupIdentifier: string;
83
+ purchaseDate: number;
84
+ originalPurchaseDate: number;
85
+ expiresDate: number;
86
+ quantity: number;
87
+ type: string;
88
+ inAppOwnershipType: string;
89
+ signedDate: number;
90
+ environment: string;
91
+ transactionReason: string;
92
+ storefront: string;
93
+ storefrontId: string;
94
+ }
95
+
96
+ export interface Credentials {
97
+ refresh_token?: string | null,
98
+ expiry_date?: number | null,
99
+ access_token?: string | null,
100
+ token_type?: string | null ,
101
+ id_token?: string | null,
102
+ scope?: string
103
+ }
104
+
105
+
16
106
  export interface LoginRequest {
17
107
  email: string;
18
108
  password: string;