90dc-core 1.10.4 → 1.10.5

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.
@@ -6,6 +6,7 @@ export interface UserTypes {
6
6
  lastName: string;
7
7
  avatar: string;
8
8
  role: string;
9
+ isSubscriptionActive: boolean;
9
10
  }
10
11
  export interface VerificationStatus {
11
12
  status: string;
@@ -1 +1 @@
1
- {"version":3,"file":"UserInterfaces.d.ts","sourceRoot":"","sources":["../../../src/lib/models/UserInterfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserInterfaces.d.ts","sourceRoot":"","sources":["../../../src/lib/models/UserInterfaces.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/models/UserInterfaces.ts"],"sourcesContent":["import type jwt from \"jsonwebtoken\";\n\nexport interface UserTypes {\n userUuid: string;\n email: string;\n firstName: string;\n lastName: string;\n avatar: string;\n role: string;\n}\n\nexport interface VerificationStatus {\n status: string;\n}\n\nexport interface TransactionsResponse {\n revision: string;\n bundleId: string;\n environment: string;\n hasMore: boolean;\n signedTransactions: string[];\n errorCode?: number;\n}\n\nexport interface UserInfoModel {\n userUuid: string;\n height: string;\n weight: string;\n}\n\nexport interface SingleTransactionResponse {\n revision: string;\n bundleId: string;\n environment: string;\n hasMore: boolean;\n signedTransactionInfo: string;\n errorCode?: number;\n}\n\nexport interface SubscriptionStatus {\n originalTransactionId: string;\n status: number;\n signedTransactionInfo: string;\n signedRenewalInfo: string;\n}\n\nexport interface SubscriptionStatusResponse {\n environment: string;\n bundleId: string;\n data: [\n {\n subscriptionGroupIdentifier: string;\n lastTransactions: SubscriptionStatus[];\n }\n ];\n errorCode?: number;\n}\n\nexport interface SubscriptionStatusResponseError {\n errorCode: number;\n errorMessage: string;\n}\n\nexport interface SubscriptionStatusResult {\n originalTransactionId: string;\n status: number;\n signedTransactionInfo: string | jwt.JwtPayload | null;\n signedRenewalInfo: string | jwt.JwtPayload | null;\n}\n\nexport interface SignedTransactions {\n transactionId: string;\n originalTransactionId: string;\n webOrderLineItemId: string;\n bundleId: string;\n productId: string;\n subscriptionGroupIdentifier: string;\n purchaseDate: number;\n originalPurchaseDate: number;\n expiresDate: number;\n quantity: number;\n type: string;\n inAppOwnershipType: string;\n signedDate: number;\n environment: string;\n transactionReason: string;\n storefront: string;\n storefrontId: string;\n}\n\nexport interface Credentials {\n refresh_token?: string | null,\n expiry_date?: number | null,\n access_token?: string | null,\n token_type?: string | null ,\n id_token?: string | null,\n scope?: string\n}\n\n\nexport interface LoginRequest {\n email: string;\n password: string;\n}\n\nexport interface UserPhotoRequest {\n base64: string;\n}\n\nexport interface ProgressPhoto {\n date: Date;\n progressPhoto: string;\n userUuid: string;\n}\n\nexport interface ForgotPassword {\n uuid: string;\n userUuid: string;\n token: string;\n date: Date;\n}\n\nexport interface RefreshPayload {\n userUuid: string;\n}\n\nexport interface TokenRequest {\n token: string;\n}\n\nexport interface RefreshRequest {\n refreshToken: string;\n}\n\nexport interface UuidRequest {\n userUuid: string;\n}\n\nexport interface EmailRequest {\n email: string;\n}\n\nexport interface TitleRequest {\n title: string;\n}\n\nexport interface UserPhoto {\n base64: string;\n title: string;\n}\n\nexport default interface AuthenticationToken {\n type: string;\n contents: string;\n}\n\nexport interface RestorePasswordRequest {\n email: string;\n}\n\nexport interface BeforeSubscriptionOptions {\n firstName: string;\n lastName: string;\n sex: string;\n goal: string;\n weightGoal: string;\n level: string;\n type: string;\n days: number;\n}\n\nexport interface AfterSubscriptionOptions {\n dateOfBirth: string;\n metricSystem: string;\n height: string;\n weight: string;\n}\n"],"names":[],"mappings":"AAAA,WAgLC"}
1
+ {"version":3,"sources":["../../../src/lib/models/UserInterfaces.ts"],"sourcesContent":["import type jwt from \"jsonwebtoken\";\n\nexport interface UserTypes {\n userUuid: string;\n email: string;\n firstName: string;\n lastName: string;\n avatar: string;\n role: string;\n isSubscriptionActive: boolean;\n}\n\nexport interface VerificationStatus {\n status: string;\n}\n\nexport interface TransactionsResponse {\n revision: string;\n bundleId: string;\n environment: string;\n hasMore: boolean;\n signedTransactions: string[];\n errorCode?: number;\n}\n\nexport interface UserInfoModel {\n userUuid: string;\n height: string;\n weight: string;\n}\n\nexport interface SingleTransactionResponse {\n revision: string;\n bundleId: string;\n environment: string;\n hasMore: boolean;\n signedTransactionInfo: string;\n errorCode?: number;\n}\n\nexport interface SubscriptionStatus {\n originalTransactionId: string;\n status: number;\n signedTransactionInfo: string;\n signedRenewalInfo: string;\n}\n\nexport interface SubscriptionStatusResponse {\n environment: string;\n bundleId: string;\n data: [\n {\n subscriptionGroupIdentifier: string;\n lastTransactions: SubscriptionStatus[];\n }\n ];\n errorCode?: number;\n}\n\nexport interface SubscriptionStatusResponseError {\n errorCode: number;\n errorMessage: string;\n}\n\nexport interface SubscriptionStatusResult {\n originalTransactionId: string;\n status: number;\n signedTransactionInfo: string | jwt.JwtPayload | null;\n signedRenewalInfo: string | jwt.JwtPayload | null;\n}\n\nexport interface SignedTransactions {\n transactionId: string;\n originalTransactionId: string;\n webOrderLineItemId: string;\n bundleId: string;\n productId: string;\n subscriptionGroupIdentifier: string;\n purchaseDate: number;\n originalPurchaseDate: number;\n expiresDate: number;\n quantity: number;\n type: string;\n inAppOwnershipType: string;\n signedDate: number;\n environment: string;\n transactionReason: string;\n storefront: string;\n storefrontId: string;\n}\n\nexport interface Credentials {\n refresh_token?: string | null,\n expiry_date?: number | null,\n access_token?: string | null,\n token_type?: string | null ,\n id_token?: string | null,\n scope?: string\n}\n\n\nexport interface LoginRequest {\n email: string;\n password: string;\n}\n\nexport interface UserPhotoRequest {\n base64: string;\n}\n\nexport interface ProgressPhoto {\n date: Date;\n progressPhoto: string;\n userUuid: string;\n}\n\nexport interface ForgotPassword {\n uuid: string;\n userUuid: string;\n token: string;\n date: Date;\n}\n\nexport interface RefreshPayload {\n userUuid: string;\n}\n\nexport interface TokenRequest {\n token: string;\n}\n\nexport interface RefreshRequest {\n refreshToken: string;\n}\n\nexport interface UuidRequest {\n userUuid: string;\n}\n\nexport interface EmailRequest {\n email: string;\n}\n\nexport interface TitleRequest {\n title: string;\n}\n\nexport interface UserPhoto {\n base64: string;\n title: string;\n}\n\nexport default interface AuthenticationToken {\n type: string;\n contents: string;\n}\n\nexport interface RestorePasswordRequest {\n email: string;\n}\n\nexport interface BeforeSubscriptionOptions {\n firstName: string;\n lastName: string;\n sex: string;\n goal: string;\n weightGoal: string;\n level: string;\n type: string;\n days: number;\n}\n\nexport interface AfterSubscriptionOptions {\n dateOfBirth: string;\n metricSystem: string;\n height: string;\n weight: string;\n}\n"],"names":[],"mappings":"AAAA,WAiLC"}
@@ -2,23 +2,10 @@ import jwt from "jsonwebtoken";
2
2
  import type { LoginTicket } from "google-auth-library";
3
3
  import { PersistedUser } from "../dbmodels/PersistedUser";
4
4
  import type { Credentials as CredentialsType, SignedTransactions, SubscriptionStatusResult, UserTypes, VerificationStatus } from "../models/UserInterfaces";
5
- /**
6
- * Comprehensive Authentication Utility
7
- * Handles JWT tokens, OAuth (Google, Apple, Facebook), and subscription verification (Apple, Google, Mollie)
8
- *
9
- * @class AuthenticationUtil
10
- * @version 2.0.0 - Consolidated from auth-service and core
11
- */
12
5
  export declare class AuthenticationUtil {
13
6
  static readonly ACCESS_SECRET: string;
14
7
  static readonly REFRESH_SECRET: string;
15
- /**
16
- * Fetch user from database using JWT token
17
- */
18
8
  static fetchUserWithTokenInfo(token: string): Promise<PersistedUser | null>;
19
- /**
20
- * Verify JWT token and fetch user from database
21
- */
22
9
  static verifyTokenAndFetchUser(token: string): Promise<PersistedUser | null | false>;
23
10
  /**
24
11
  * Sign access token
@@ -1 +1 @@
1
- {"version":3,"file":"AuthenticationUtil.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/AuthenticationUtil.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AuthenticationUtil.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/AuthenticationUtil.ts"],"names":[],"mappings":"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"}
@@ -17,28 +17,17 @@ var TokenExpiration;
17
17
  const appleJwksClient = jwksClient({
18
18
  jwksUri: "https://appleid.apple.com/auth/keys"
19
19
  });
20
- /**
21
- * Comprehensive Authentication Utility
22
- * Handles JWT tokens, OAuth (Google, Apple, Facebook), and subscription verification (Apple, Google, Mollie)
23
- *
24
- * @class AuthenticationUtil
25
- * @version 2.0.0 - Consolidated from auth-service and core
26
- */ export class AuthenticationUtil {
27
- // JWT Secrets
20
+ export class AuthenticationUtil {
28
21
  static ACCESS_SECRET = process.env.ACCESS_TOKEN_SECRET;
29
22
  static REFRESH_SECRET = process.env.REFRESH_TOKEN_SECRET;
30
- /**
31
- * Fetch user from database using JWT token
32
- */ static async fetchUserWithTokenInfo(token) {
23
+ static async fetchUserWithTokenInfo(token) {
33
24
  const userInToken = await AuthenticationUtil.verifyTokenAndFetchUser(token);
34
25
  if (!userInToken || !userInToken.userUuid) {
35
26
  return null;
36
27
  }
37
28
  return userInToken;
38
29
  }
39
- /**
40
- * Verify JWT token and fetch user from database
41
- */ static verifyTokenAndFetchUser(token) {
30
+ static verifyTokenAndFetchUser(token) {
42
31
  return new Promise((resolve, reject)=>{
43
32
  jwt.verify(token, this.ACCESS_SECRET, (err, decoded)=>{
44
33
  if (err) {
@@ -1 +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, androidpublisher_v3 } from \"googleapis\";\nimport * as bcrypt from \"bcryptjs\";\nimport type {\n Credentials,\n LoginTicket,\n OAuth2Client,\n TokenPayload,\n} from \"google-auth-library\";\nimport { OAuth2Client as OAuth2ClientImpl } from \"google-auth-library\";\nimport jwksClient, { SigningKey } from \"jwks-rsa\";\nimport Schema$SubscriptionPurchaseV2 = androidpublisher_v3.Schema$SubscriptionPurchaseV2;\nimport { PersistedUser } from \"../dbmodels/PersistedUser\";\nimport type {\n Credentials as CredentialsType,\n SignedTransactions,\n SingleTransactionResponse,\n SubscriptionStatusResponse,\n SubscriptionStatusResponseError,\n SubscriptionStatusResult,\n TransactionsResponse,\n UserTypes,\n VerificationStatus,\n LoginRequest,\n} from \"../models/UserInterfaces\";\nimport { AppleTransactionError } from \"../Errors/Errors\";\n\ndotenv.config();\n\nenum TokenExpiration {\n ACCESS = 60 * 60,\n REFRESH = 356 * 24 * 60 * 60,\n}\n\nconst appleJwksClient = jwksClient({\n jwksUri: \"https://appleid.apple.com/auth/keys\",\n});\n\n/**\n * Comprehensive Authentication Utility\n * Handles JWT tokens, OAuth (Google, Apple, Facebook), and subscription verification (Apple, Google, Mollie)\n *\n * @class AuthenticationUtil\n * @version 2.0.0 - Consolidated from auth-service and core\n */\nexport class AuthenticationUtil {\n // JWT Secrets\n public static readonly ACCESS_SECRET = process.env.ACCESS_TOKEN_SECRET as string;\n public static readonly REFRESH_SECRET = process.env.REFRESH_TOKEN_SECRET as string;\n\n\n /**\n * Fetch user from database using JWT token\n */\n public static async fetchUserWithTokenInfo(token: string): Promise<PersistedUser | null> {\n const userInToken = await AuthenticationUtil.verifyTokenAndFetchUser(token);\n if (!userInToken || !userInToken.userUuid) {\n return null;\n }\n return userInToken;\n }\n\n /**\n * Verify JWT token and fetch user from database\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 return;\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 /**\n * Sign access token\n */\n public static signAccessToken(user: UserTypes): string {\n return jwt.sign(user, this.ACCESS_SECRET, {\n expiresIn: TokenExpiration.ACCESS,\n });\n }\n\n /**\n * Sign refresh token\n */\n public static signRefreshToken(user: UserTypes): string {\n return jwt.sign(user, this.REFRESH_SECRET);\n }\n\n /**\n * Verify refresh token and return new access token\n */\n public static verifyRefreshToken(refreshToken: string): Promise<string | null | false> {\n return new Promise<string | null | false>((resolve, reject) => {\n jwt.verify(\n refreshToken,\n this.REFRESH_SECRET,\n async (err: VerifyErrors | null, user: JwtPayload | string | undefined) => {\n if (err) {\n reject(err);\n return;\n }\n\n if (user === undefined) {\n resolve(null);\n return;\n }\n\n const userTypes = <UserTypes>user;\n const newAccessToken = this.signAccessToken(userTypes);\n resolve(newAccessToken);\n }\n );\n });\n }\n\n // ==================== Password Management ====================\n\n /**\n * Hash password using bcrypt\n */\n public static async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, 10);\n }\n\n /**\n * Compare password with hash\n */\n public static async comparePassword(plainPassword: string, hash: string): Promise<boolean> {\n return bcrypt.compare(plainPassword, hash);\n }\n\n // ==================== User Registration & Login ====================\n\n /**\n * Check if user is already registered\n */\n public static async checkIfUserAlreadyRegistered(email: string | undefined): Promise<boolean> {\n if (!email) return false;\n const user = await PersistedUser.findOne({ where: { email } });\n return user !== null;\n }\n\n /**\n * Login user with email and password\n */\n public static async login(email: string, password: string): Promise<PersistedUser | null> {\n const users = await PersistedUser.findAll({ where: { email } });\n\n if (!users || users.length === 0) {\n return null;\n }\n\n for (const user of users) {\n const passwordsMatch = await this.comparePassword(password, user.password);\n if (passwordsMatch) {\n return user;\n }\n }\n\n return null;\n }\n\n // ==================== Google OAuth ====================\n\n /**\n * Verify Google OAuth token\n */\n public static async verifyGoogleToken(\n idToken: string,\n audience: string\n ): Promise<LoginTicket | null> {\n const client = new OAuth2ClientImpl(audience);\n try {\n return await client.verifyIdToken({ idToken, audience });\n } catch (error) {\n console.error(\"Google Token Verification Error:\", error);\n return null;\n }\n }\n\n /**\n * Get Google OAuth client ID based on platform\n */\n public static getGoogleClientId(platform: string): string | undefined {\n switch (platform) {\n case \"android\":\n return process.env.ANDROID_GOOGLE_CLIENT_ID;\n case \"ios\":\n return process.env.IOS_GOOGLE_CLIENT_ID;\n case \"web\":\n return process.env.WEB_GOOGLE_CLIENT_ID;\n default:\n return undefined;\n }\n }\n\n // ==================== Apple OAuth & Subscriptions ====================\n\n /**\n * Generate Apple JWT for App Store Connect API\n */\n public static generateAppleJWT(): string {\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 * Verify Apple JWT for Sign in with Apple\n */\n public static verifyAppleJwt(userData: string, key: string) {\n try {\n return jwt.verify(userData, key);\n } catch (e) {\n console.error(e);\n return null;\n }\n }\n\n /**\n * Get Apple Sign In public key\n */\n public static async getAppleSignInKey(kid: string): Promise<string | undefined> {\n try {\n const key: SigningKey = await appleJwksClient.getSigningKey(kid);\n return key.getPublicKey();\n } catch (e) {\n console.error(e);\n return undefined;\n }\n }\n\n /**\n * Verify Apple receipt (legacy)\n */\n public static async verifyAppleReceipt(data: string): Promise<VerificationStatus> {\n const response: AxiosResponse = await axios.post(\n \"https://buy.itunes.apple.com/verifyReceipt\",\n {\n \"receipt-data\": data,\n password: process.env.APPLE_SHARED_SECRET as string,\n \"exclude-old-transactions\": true,\n }\n );\n\n return response.data as VerificationStatus;\n }\n\n /**\n * Get Apple transaction history\n */\n public static async getAppleTransactions(\n originalTransactionId: string\n ): Promise<SignedTransactions[]> {\n const result: SignedTransactions[] = [];\n\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 // Try sandbox environment\n if (\n isAxiosError(error) &&\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 * Get Apple subscription status\n */\n public static async getAppleSubscriptionsStatuses(\n transactionId: string\n ): Promise<SubscriptionStatusResult[]> {\n const result: SubscriptionStatusResult[] = [];\n\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 // Try sandbox\n if (\n isAxiosError(error) &&\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 /**\n * Check if Apple subscription is active\n */\n public static async isAppleSubscriptionActive(transactionId: string): Promise<boolean> {\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 /**\n * Get single Apple transaction info\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 // Try sandbox\n if (\n isAxiosError(error) &&\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 /**\n * Check if user bought a program (non-consumable)\n */\n public static async checkIfUserBoughtProgram(transactionId: string): Promise<string[]> {\n try {\n const productIds: string[] = [];\n const url = process.env.PURCHASE_HISTORY_URL || \"https://api.storekit.itunes.apple.com\";\n const response: AxiosResponse = await axios.get(\n `${url}/inApps/v2/history/${transactionId}?productType=NON_CONSUMABLE`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n for (const transaction of response.data.signedTransactions) {\n productIds.push((jwt.decode(transaction) as { productId: string }).productId);\n }\n\n return productIds;\n } catch (e) {\n console.error((e as Error).message);\n return [];\n }\n }\n\n /**\n * Extend Apple subscription\n */\n public static async extendAppleSubscription(\n transactionId: string,\n extendByDays: number\n ): Promise<any> {\n const response: AxiosResponse = await axios.put(\n `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/extend/${transactionId}`,\n {\n extendByDays,\n extendReasonCode: 1,\n requestIdentifier: require(\"crypto\").randomUUID(),\n },\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n },\n }\n );\n\n return response.data;\n }\n\n // ==================== Android (Google Play) Subscriptions ====================\n\n /**\n * Get Android access token for Google Play API\n */\n public static async getAndroidAccessToken(): Promise<CredentialsType> {\n const keyPath = process.env.GOOGLE_SERVICE_ACCOUNT_KEY_PATH as string;\n\n const jwtClient = new google.auth.JWT({\n keyFile: keyPath,\n scopes: [\"https://www.googleapis.com/auth/androidpublisher\"],\n });\n\n const authResponse: CredentialsType = await jwtClient.authorize();\n return authResponse;\n }\n\n /**\n * Get Android subscription status\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/${process.env.ANDROID_PACKAGE_NAME || \"nl.browney.nintydayschallenge\"}/purchases/subscriptionsv2/tokens/${token}`,\n {\n headers: {\n Authorization: `Bearer ${credentials.access_token as string}`,\n },\n }\n );\n\n return response.data;\n } catch (error) {\n if (isAxiosError(error) && error.response && error.response.status === 410) {\n // Subscription expired\n return {\n lineItems: [\n {\n expiryTime: new Date(Date.now() - 86400000).toISOString(), // Yesterday\n },\n ],\n };\n } else {\n if (isAxiosError(error)) {\n console.error(\"Android subscription error:\", error.message);\n return false;\n }\n }\n }\n }\n\n /**\n * Check if Android subscription is active\n */\n public static async isAndroidSubscriptionsActive(token: string): Promise<boolean> {\n try {\n const credentials = await this.getAndroidAccessToken();\n\n const response: AxiosResponse = await axios.get(\n `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${process.env.ANDROID_PACKAGE_NAME || \"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"],"names":["dotenv","jwt","axios","isAxiosError","fs","google","bcrypt","OAuth2Client","OAuth2ClientImpl","jwksClient","PersistedUser","AppleTransactionError","config","TokenExpiration","ACCESS","REFRESH","appleJwksClient","jwksUri","AuthenticationUtil","ACCESS_SECRET","process","env","ACCESS_TOKEN_SECRET","REFRESH_SECRET","REFRESH_TOKEN_SECRET","fetchUserWithTokenInfo","token","userInToken","verifyTokenAndFetchUser","userUuid","Promise","resolve","reject","verify","err","decoded","undefined","user","findByPk","then","persistedUser","catch","e","signAccessToken","sign","expiresIn","signRefreshToken","verifyRefreshToken","refreshToken","userTypes","newAccessToken","hashPassword","password","hash","comparePassword","plainPassword","compare","checkIfUserAlreadyRegistered","email","findOne","where","login","users","findAll","length","passwordsMatch","verifyGoogleToken","idToken","audience","client","verifyIdToken","error","console","getGoogleClientId","platform","ANDROID_GOOGLE_CLIENT_ID","IOS_GOOGLE_CLIENT_ID","WEB_GOOGLE_CLIENT_ID","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","verifyAppleJwt","userData","key","getAppleSignInKey","getSigningKey","getPublicKey","verifyAppleReceipt","data","response","post","APPLE_SHARED_SECRET","getAppleTransactions","originalTransactionId","result","get","headers","Authorization","signedTransactions","push","decode","status","errorCode","getAppleSubscriptionsStatuses","transactionId","transaction","lastTransactions","signedTransactionInfo","signedRenewalInfo","isAppleSubscriptionActive","getSingleAppleTransactionsInfo","checkIfUserBoughtProgram","productIds","url","PURCHASE_HISTORY_URL","productId","message","extendAppleSubscription","extendByDays","put","extendReasonCode","requestIdentifier","require","randomUUID","getAndroidAccessToken","keyPath","GOOGLE_SERVICE_ACCOUNT_KEY_PATH","jwtClient","auth","JWT","keyFile","scopes","authResponse","authorize","getAndroidSubscriptionsStatuses","credentials","ANDROID_PACKAGE_NAME","access_token","lineItems","expiryTime","toISOString","isAndroidSubscriptionsActive","subscriptionState"],"mappings":"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"}
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, androidpublisher_v3 } from \"googleapis\";\nimport * as bcrypt from \"bcryptjs\";\nimport type {\n Credentials,\n LoginTicket,\n OAuth2Client,\n TokenPayload,\n} from \"google-auth-library\";\nimport { OAuth2Client as OAuth2ClientImpl } from \"google-auth-library\";\nimport jwksClient, { SigningKey } from \"jwks-rsa\";\nimport Schema$SubscriptionPurchaseV2 = androidpublisher_v3.Schema$SubscriptionPurchaseV2;\nimport { PersistedUser } from \"../dbmodels/PersistedUser\";\nimport type {\n Credentials as CredentialsType,\n SignedTransactions,\n SingleTransactionResponse,\n SubscriptionStatusResponse,\n SubscriptionStatusResponseError,\n SubscriptionStatusResult,\n TransactionsResponse,\n UserTypes,\n VerificationStatus,\n LoginRequest,\n} from \"../models/UserInterfaces\";\nimport { AppleTransactionError } from \"../Errors/Errors\";\n\ndotenv.config();\n\nenum TokenExpiration {\n ACCESS = 60 * 60,\n REFRESH = 356 * 24 * 60 * 60,\n}\n\nconst appleJwksClient = jwksClient({\n jwksUri: \"https://appleid.apple.com/auth/keys\",\n});\n\nexport class AuthenticationUtil {\n public static readonly ACCESS_SECRET = process.env.ACCESS_TOKEN_SECRET as string;\n public static readonly REFRESH_SECRET = process.env.REFRESH_TOKEN_SECRET as string;\n\n\n\n public static async fetchUserWithTokenInfo(token: string): Promise<PersistedUser | null> {\n const userInToken = await AuthenticationUtil.verifyTokenAndFetchUser(token);\n if (!userInToken || !userInToken.userUuid) {\n return null;\n }\n return userInToken;\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 return;\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 /**\n * Sign access token\n */\n public static signAccessToken(user: UserTypes): string {\n return jwt.sign(user, this.ACCESS_SECRET, {\n expiresIn: TokenExpiration.ACCESS,\n });\n }\n\n /**\n * Sign refresh token\n */\n public static signRefreshToken(user: UserTypes): string {\n return jwt.sign(user, this.REFRESH_SECRET);\n }\n\n /**\n * Verify refresh token and return new access token\n */\n public static verifyRefreshToken(refreshToken: string): Promise<string | null | false> {\n return new Promise<string | null | false>((resolve, reject) => {\n jwt.verify(\n refreshToken,\n this.REFRESH_SECRET,\n async (err: VerifyErrors | null, user: JwtPayload | string | undefined) => {\n if (err) {\n reject(err);\n return;\n }\n\n if (user === undefined) {\n resolve(null);\n return;\n }\n\n const userTypes = <UserTypes>user;\n const newAccessToken = this.signAccessToken(userTypes);\n resolve(newAccessToken);\n }\n );\n });\n }\n\n // ==================== Password Management ====================\n\n /**\n * Hash password using bcrypt\n */\n public static async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, 10);\n }\n\n /**\n * Compare password with hash\n */\n public static async comparePassword(plainPassword: string, hash: string): Promise<boolean> {\n return bcrypt.compare(plainPassword, hash);\n }\n\n // ==================== User Registration & Login ====================\n\n /**\n * Check if user is already registered\n */\n public static async checkIfUserAlreadyRegistered(email: string | undefined): Promise<boolean> {\n if (!email) return false;\n const user = await PersistedUser.findOne({ where: { email } });\n return user !== null;\n }\n\n /**\n * Login user with email and password\n */\n public static async login(email: string, password: string): Promise<PersistedUser | null> {\n const users = await PersistedUser.findAll({ where: { email } });\n\n if (!users || users.length === 0) {\n return null;\n }\n\n for (const user of users) {\n const passwordsMatch = await this.comparePassword(password, user.password);\n if (passwordsMatch) {\n return user;\n }\n }\n\n return null;\n }\n\n // ==================== Google OAuth ====================\n\n /**\n * Verify Google OAuth token\n */\n public static async verifyGoogleToken(\n idToken: string,\n audience: string\n ): Promise<LoginTicket | null> {\n const client = new OAuth2ClientImpl(audience);\n try {\n return await client.verifyIdToken({ idToken, audience });\n } catch (error) {\n console.error(\"Google Token Verification Error:\", error);\n return null;\n }\n }\n\n /**\n * Get Google OAuth client ID based on platform\n */\n public static getGoogleClientId(platform: string): string | undefined {\n switch (platform) {\n case \"android\":\n return process.env.ANDROID_GOOGLE_CLIENT_ID;\n case \"ios\":\n return process.env.IOS_GOOGLE_CLIENT_ID;\n case \"web\":\n return process.env.WEB_GOOGLE_CLIENT_ID;\n default:\n return undefined;\n }\n }\n\n // ==================== Apple OAuth & Subscriptions ====================\n\n /**\n * Generate Apple JWT for App Store Connect API\n */\n public static generateAppleJWT(): string {\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 * Verify Apple JWT for Sign in with Apple\n */\n public static verifyAppleJwt(userData: string, key: string) {\n try {\n return jwt.verify(userData, key);\n } catch (e) {\n console.error(e);\n return null;\n }\n }\n\n /**\n * Get Apple Sign In public key\n */\n public static async getAppleSignInKey(kid: string): Promise<string | undefined> {\n try {\n const key: SigningKey = await appleJwksClient.getSigningKey(kid);\n return key.getPublicKey();\n } catch (e) {\n console.error(e);\n return undefined;\n }\n }\n\n /**\n * Verify Apple receipt (legacy)\n */\n public static async verifyAppleReceipt(data: string): Promise<VerificationStatus> {\n const response: AxiosResponse = await axios.post(\n \"https://buy.itunes.apple.com/verifyReceipt\",\n {\n \"receipt-data\": data,\n password: process.env.APPLE_SHARED_SECRET as string,\n \"exclude-old-transactions\": true,\n }\n );\n\n return response.data as VerificationStatus;\n }\n\n /**\n * Get Apple transaction history\n */\n public static async getAppleTransactions(\n originalTransactionId: string\n ): Promise<SignedTransactions[]> {\n const result: SignedTransactions[] = [];\n\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 // Try sandbox environment\n if (\n isAxiosError(error) &&\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 * Get Apple subscription status\n */\n public static async getAppleSubscriptionsStatuses(\n transactionId: string\n ): Promise<SubscriptionStatusResult[]> {\n const result: SubscriptionStatusResult[] = [];\n\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 // Try sandbox\n if (\n isAxiosError(error) &&\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 /**\n * Check if Apple subscription is active\n */\n public static async isAppleSubscriptionActive(transactionId: string): Promise<boolean> {\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 /**\n * Get single Apple transaction info\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 // Try sandbox\n if (\n isAxiosError(error) &&\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 /**\n * Check if user bought a program (non-consumable)\n */\n public static async checkIfUserBoughtProgram(transactionId: string): Promise<string[]> {\n try {\n const productIds: string[] = [];\n const url = process.env.PURCHASE_HISTORY_URL || \"https://api.storekit.itunes.apple.com\";\n const response: AxiosResponse = await axios.get(\n `${url}/inApps/v2/history/${transactionId}?productType=NON_CONSUMABLE`,\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n for (const transaction of response.data.signedTransactions) {\n productIds.push((jwt.decode(transaction) as { productId: string }).productId);\n }\n\n return productIds;\n } catch (e) {\n console.error((e as Error).message);\n return [];\n }\n }\n\n /**\n * Extend Apple subscription\n */\n public static async extendAppleSubscription(\n transactionId: string,\n extendByDays: number\n ): Promise<any> {\n const response: AxiosResponse = await axios.put(\n `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/extend/${transactionId}`,\n {\n extendByDays,\n extendReasonCode: 1,\n requestIdentifier: require(\"crypto\").randomUUID(),\n },\n {\n headers: {\n Authorization: `Bearer ${this.generateAppleJWT()}`,\n },\n }\n );\n\n return response.data;\n }\n\n // ==================== Android (Google Play) Subscriptions ====================\n\n /**\n * Get Android access token for Google Play API\n */\n public static async getAndroidAccessToken(): Promise<CredentialsType> {\n const keyPath = process.env.GOOGLE_SERVICE_ACCOUNT_KEY_PATH as string;\n\n const jwtClient = new google.auth.JWT({\n keyFile: keyPath,\n scopes: [\"https://www.googleapis.com/auth/androidpublisher\"],\n });\n\n const authResponse: CredentialsType = await jwtClient.authorize();\n return authResponse;\n }\n\n /**\n * Get Android subscription status\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/${process.env.ANDROID_PACKAGE_NAME || \"nl.browney.nintydayschallenge\"}/purchases/subscriptionsv2/tokens/${token}`,\n {\n headers: {\n Authorization: `Bearer ${credentials.access_token as string}`,\n },\n }\n );\n\n return response.data;\n } catch (error) {\n if (isAxiosError(error) && error.response && error.response.status === 410) {\n // Subscription expired\n return {\n lineItems: [\n {\n expiryTime: new Date(Date.now() - 86400000).toISOString(), // Yesterday\n },\n ],\n };\n } else {\n if (isAxiosError(error)) {\n console.error(\"Android subscription error:\", error.message);\n return false;\n }\n }\n }\n }\n\n /**\n * Check if Android subscription is active\n */\n public static async isAndroidSubscriptionsActive(token: string): Promise<boolean> {\n try {\n const credentials = await this.getAndroidAccessToken();\n\n const response: AxiosResponse = await axios.get(\n `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${process.env.ANDROID_PACKAGE_NAME || \"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"],"names":["dotenv","jwt","axios","isAxiosError","fs","google","bcrypt","OAuth2Client","OAuth2ClientImpl","jwksClient","PersistedUser","AppleTransactionError","config","TokenExpiration","ACCESS","REFRESH","appleJwksClient","jwksUri","AuthenticationUtil","ACCESS_SECRET","process","env","ACCESS_TOKEN_SECRET","REFRESH_SECRET","REFRESH_TOKEN_SECRET","fetchUserWithTokenInfo","token","userInToken","verifyTokenAndFetchUser","userUuid","Promise","resolve","reject","verify","err","decoded","undefined","user","findByPk","then","persistedUser","catch","e","signAccessToken","sign","expiresIn","signRefreshToken","verifyRefreshToken","refreshToken","userTypes","newAccessToken","hashPassword","password","hash","comparePassword","plainPassword","compare","checkIfUserAlreadyRegistered","email","findOne","where","login","users","findAll","length","passwordsMatch","verifyGoogleToken","idToken","audience","client","verifyIdToken","error","console","getGoogleClientId","platform","ANDROID_GOOGLE_CLIENT_ID","IOS_GOOGLE_CLIENT_ID","WEB_GOOGLE_CLIENT_ID","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","verifyAppleJwt","userData","key","getAppleSignInKey","getSigningKey","getPublicKey","verifyAppleReceipt","data","response","post","APPLE_SHARED_SECRET","getAppleTransactions","originalTransactionId","result","get","headers","Authorization","signedTransactions","push","decode","status","errorCode","getAppleSubscriptionsStatuses","transactionId","transaction","lastTransactions","signedTransactionInfo","signedRenewalInfo","isAppleSubscriptionActive","getSingleAppleTransactionsInfo","checkIfUserBoughtProgram","productIds","url","PURCHASE_HISTORY_URL","productId","message","extendAppleSubscription","extendByDays","put","extendReasonCode","requestIdentifier","require","randomUUID","getAndroidAccessToken","keyPath","GOOGLE_SERVICE_ACCOUNT_KEY_PATH","jwtClient","auth","JWT","keyFile","scopes","authResponse","authorize","getAndroidSubscriptionsStatuses","credentials","ANDROID_PACKAGE_NAME","access_token","lineItems","expiryTime","toISOString","isAndroidSubscriptionsActive","subscriptionState"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "90dc-core",
3
- "version": "1.10.4",
3
+ "version": "1.10.5",
4
4
  "description": "A package that contains utils and interfaces used to create 90dc",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -7,6 +7,7 @@ export interface UserTypes {
7
7
  lastName: string;
8
8
  avatar: string;
9
9
  role: string;
10
+ isSubscriptionActive: boolean;
10
11
  }
11
12
 
12
13
  export interface VerificationStatus {
@@ -39,22 +39,12 @@ const appleJwksClient = jwksClient({
39
39
  jwksUri: "https://appleid.apple.com/auth/keys",
40
40
  });
41
41
 
42
- /**
43
- * Comprehensive Authentication Utility
44
- * Handles JWT tokens, OAuth (Google, Apple, Facebook), and subscription verification (Apple, Google, Mollie)
45
- *
46
- * @class AuthenticationUtil
47
- * @version 2.0.0 - Consolidated from auth-service and core
48
- */
49
42
  export class AuthenticationUtil {
50
- // JWT Secrets
51
43
  public static readonly ACCESS_SECRET = process.env.ACCESS_TOKEN_SECRET as string;
52
44
  public static readonly REFRESH_SECRET = process.env.REFRESH_TOKEN_SECRET as string;
53
45
 
54
46
 
55
- /**
56
- * Fetch user from database using JWT token
57
- */
47
+
58
48
  public static async fetchUserWithTokenInfo(token: string): Promise<PersistedUser | null> {
59
49
  const userInToken = await AuthenticationUtil.verifyTokenAndFetchUser(token);
60
50
  if (!userInToken || !userInToken.userUuid) {
@@ -63,40 +53,37 @@ export class AuthenticationUtil {
63
53
  return userInToken;
64
54
  }
65
55
 
66
- /**
67
- * Verify JWT token and fetch user from database
68
- */
69
56
  public static verifyTokenAndFetchUser(token: string): Promise<PersistedUser | null | false> {
70
57
  return new Promise<PersistedUser | null | false>((resolve, reject) => {
71
58
  jwt.verify(
72
- token,
73
- this.ACCESS_SECRET,
74
- (err: VerifyErrors | null, decoded: JwtPayload | string | undefined) => {
75
- if (err) {
76
- reject(err);
77
- return;
78
- }
59
+ token,
60
+ this.ACCESS_SECRET,
61
+ (err: VerifyErrors | null, decoded: JwtPayload | string | undefined) => {
62
+ if (err) {
63
+ reject(err);
64
+ return;
65
+ }
79
66
 
80
- if (decoded === undefined) {
81
- resolve(null);
82
- return;
83
- }
67
+ if (decoded === undefined) {
68
+ resolve(null);
69
+ return;
70
+ }
84
71
 
85
- const user: UserTypes = <UserTypes>decoded;
72
+ const user: UserTypes = <UserTypes>decoded;
86
73
 
87
- if (!user.userUuid) {
88
- resolve(false);
89
- return;
90
- }
74
+ if (!user.userUuid) {
75
+ resolve(false);
76
+ return;
77
+ }
91
78
 
92
- PersistedUser.findByPk(user.userUuid)
93
- .then((persistedUser: PersistedUser | null) => {
94
- resolve(persistedUser);
95
- })
96
- .catch((e: Error) => {
97
- reject(e);
98
- });
99
- }
79
+ PersistedUser.findByPk(user.userUuid)
80
+ .then((persistedUser: PersistedUser | null) => {
81
+ resolve(persistedUser);
82
+ })
83
+ .catch((e: Error) => {
84
+ reject(e);
85
+ });
86
+ }
100
87
  );
101
88
  });
102
89
  }
@@ -123,23 +110,23 @@ export class AuthenticationUtil {
123
110
  public static verifyRefreshToken(refreshToken: string): Promise<string | null | false> {
124
111
  return new Promise<string | null | false>((resolve, reject) => {
125
112
  jwt.verify(
126
- refreshToken,
127
- this.REFRESH_SECRET,
128
- async (err: VerifyErrors | null, user: JwtPayload | string | undefined) => {
129
- if (err) {
130
- reject(err);
131
- return;
132
- }
113
+ refreshToken,
114
+ this.REFRESH_SECRET,
115
+ async (err: VerifyErrors | null, user: JwtPayload | string | undefined) => {
116
+ if (err) {
117
+ reject(err);
118
+ return;
119
+ }
133
120
 
134
- if (user === undefined) {
135
- resolve(null);
136
- return;
137
- }
121
+ if (user === undefined) {
122
+ resolve(null);
123
+ return;
124
+ }
138
125
 
139
- const userTypes = <UserTypes>user;
140
- const newAccessToken = this.signAccessToken(userTypes);
141
- resolve(newAccessToken);
142
- }
126
+ const userTypes = <UserTypes>user;
127
+ const newAccessToken = this.signAccessToken(userTypes);
128
+ resolve(newAccessToken);
129
+ }
143
130
  );
144
131
  });
145
132
  }
@@ -197,8 +184,8 @@ export class AuthenticationUtil {
197
184
  * Verify Google OAuth token
198
185
  */
199
186
  public static async verifyGoogleToken(
200
- idToken: string,
201
- audience: string
187
+ idToken: string,
188
+ audience: string
202
189
  ): Promise<LoginTicket | null> {
203
190
  const client = new OAuth2ClientImpl(audience);
204
191
  try {
@@ -232,8 +219,8 @@ export class AuthenticationUtil {
232
219
  */
233
220
  public static generateAppleJWT(): string {
234
221
  const privateKey: string = fs.readFileSync(
235
- process.env.APPLE_SUBSCRIPTION_KEY_PATH as string,
236
- "utf-8"
222
+ process.env.APPLE_SUBSCRIPTION_KEY_PATH as string,
223
+ "utf-8"
237
224
  );
238
225
 
239
226
  const header = {
@@ -283,12 +270,12 @@ export class AuthenticationUtil {
283
270
  */
284
271
  public static async verifyAppleReceipt(data: string): Promise<VerificationStatus> {
285
272
  const response: AxiosResponse = await axios.post(
286
- "https://buy.itunes.apple.com/verifyReceipt",
287
- {
288
- "receipt-data": data,
289
- password: process.env.APPLE_SHARED_SECRET as string,
290
- "exclude-old-transactions": true,
291
- }
273
+ "https://buy.itunes.apple.com/verifyReceipt",
274
+ {
275
+ "receipt-data": data,
276
+ password: process.env.APPLE_SHARED_SECRET as string,
277
+ "exclude-old-transactions": true,
278
+ }
292
279
  );
293
280
 
294
281
  return response.data as VerificationStatus;
@@ -298,19 +285,19 @@ export class AuthenticationUtil {
298
285
  * Get Apple transaction history
299
286
  */
300
287
  public static async getAppleTransactions(
301
- originalTransactionId: string
288
+ originalTransactionId: string
302
289
  ): Promise<SignedTransactions[]> {
303
290
  const result: SignedTransactions[] = [];
304
291
 
305
292
  try {
306
293
  const response: AxiosResponse<TransactionsResponse> = await axios.get(
307
- `https://api.storekit.itunes.apple.com/inApps/v1/history/${originalTransactionId}`,
308
- {
309
- headers: {
310
- Authorization: `Bearer ${this.generateAppleJWT()}`,
311
- "Content-Type": "application/json",
312
- },
313
- }
294
+ `https://api.storekit.itunes.apple.com/inApps/v1/history/${originalTransactionId}`,
295
+ {
296
+ headers: {
297
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
298
+ "Content-Type": "application/json",
299
+ },
300
+ }
314
301
  );
315
302
 
316
303
  for (const token of response.data.signedTransactions) {
@@ -325,18 +312,18 @@ export class AuthenticationUtil {
325
312
 
326
313
  // Try sandbox environment
327
314
  if (
328
- isAxiosError(error) &&
329
- (error.response?.data.errorCode === 4040010 || error.response?.status === 401)
315
+ isAxiosError(error) &&
316
+ (error.response?.data.errorCode === 4040010 || error.response?.status === 401)
330
317
  ) {
331
318
  try {
332
319
  const response: AxiosResponse<TransactionsResponse> = await axios.get(
333
- `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/history/${originalTransactionId}`,
334
- {
335
- headers: {
336
- Authorization: `Bearer ${this.generateAppleJWT()}`,
337
- "Content-Type": "application/json",
338
- },
339
- }
320
+ `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/history/${originalTransactionId}`,
321
+ {
322
+ headers: {
323
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
324
+ "Content-Type": "application/json",
325
+ },
326
+ }
340
327
  );
341
328
 
342
329
  for (const token of response.data.signedTransactions) {
@@ -359,19 +346,19 @@ export class AuthenticationUtil {
359
346
  * Get Apple subscription status
360
347
  */
361
348
  public static async getAppleSubscriptionsStatuses(
362
- transactionId: string
349
+ transactionId: string
363
350
  ): Promise<SubscriptionStatusResult[]> {
364
351
  const result: SubscriptionStatusResult[] = [];
365
352
 
366
353
  try {
367
354
  const response: AxiosResponse<SubscriptionStatusResponse> = await axios.get(
368
- `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,
369
- {
370
- headers: {
371
- Authorization: `Bearer ${this.generateAppleJWT()}`,
372
- "Content-Type": "application/json",
373
- },
374
- }
355
+ `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,
356
+ {
357
+ headers: {
358
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
359
+ "Content-Type": "application/json",
360
+ },
361
+ }
375
362
  );
376
363
 
377
364
  for (const transaction of response.data.data[0].lastTransactions) {
@@ -391,18 +378,18 @@ export class AuthenticationUtil {
391
378
 
392
379
  // Try sandbox
393
380
  if (
394
- isAxiosError(error) &&
395
- (error.response?.data.errorCode === 4040010 || error.response?.status === 401)
381
+ isAxiosError(error) &&
382
+ (error.response?.data.errorCode === 4040010 || error.response?.status === 401)
396
383
  ) {
397
384
  try {
398
385
  const response: AxiosResponse<SubscriptionStatusResponse> = await axios.get(
399
- `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,
400
- {
401
- headers: {
402
- Authorization: `Bearer ${this.generateAppleJWT()}`,
403
- "Content-Type": "application/json",
404
- },
405
- }
386
+ `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,
387
+ {
388
+ headers: {
389
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
390
+ "Content-Type": "application/json",
391
+ },
392
+ }
406
393
  );
407
394
 
408
395
  for (const transaction of response.data.data[0].lastTransactions) {
@@ -432,24 +419,24 @@ export class AuthenticationUtil {
432
419
  public static async isAppleSubscriptionActive(transactionId: string): Promise<boolean> {
433
420
  try {
434
421
  const response: AxiosResponse<SubscriptionStatusResponse> = await axios.get(
435
- `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,
436
- {
437
- headers: {
438
- Authorization: `Bearer ${this.generateAppleJWT()}`,
439
- "Content-Type": "application/json",
440
- },
441
- }
422
+ `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/${transactionId}`,
423
+ {
424
+ headers: {
425
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
426
+ "Content-Type": "application/json",
427
+ },
428
+ }
442
429
  );
443
430
 
444
431
  return (
445
- response.data.data[0].lastTransactions[0].status === 0 ||
446
- response.data.data[0].lastTransactions[0].status === 2
432
+ response.data.data[0].lastTransactions[0].status === 0 ||
433
+ response.data.data[0].lastTransactions[0].status === 2
447
434
  );
448
435
  } catch (e) {
449
436
  if (
450
- axios.isAxiosError(e) &&
451
- e.response &&
452
- (e.response.data as SubscriptionStatusResponseError)["errorMessage"] ===
437
+ axios.isAxiosError(e) &&
438
+ e.response &&
439
+ (e.response.data as SubscriptionStatusResponseError)["errorMessage"] ===
453
440
  "Invalid transaction id."
454
441
  ) {
455
442
  return false;
@@ -464,13 +451,13 @@ export class AuthenticationUtil {
464
451
  public static async getSingleAppleTransactionsInfo(transactionId: string) {
465
452
  try {
466
453
  const response: AxiosResponse<SingleTransactionResponse> = await axios.get(
467
- `https://api.storekit.itunes.apple.com/inApps/v1/transactions/${transactionId}`,
468
- {
469
- headers: {
470
- Authorization: `Bearer ${this.generateAppleJWT()}`,
471
- "Content-Type": "application/json",
472
- },
473
- }
454
+ `https://api.storekit.itunes.apple.com/inApps/v1/transactions/${transactionId}`,
455
+ {
456
+ headers: {
457
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
458
+ "Content-Type": "application/json",
459
+ },
460
+ }
474
461
  );
475
462
 
476
463
  return { signedTransactionInfo: jwt.decode(response.data.signedTransactionInfo) };
@@ -481,18 +468,18 @@ export class AuthenticationUtil {
481
468
 
482
469
  // Try sandbox
483
470
  if (
484
- isAxiosError(error) &&
485
- (error.response?.data.errorCode === 4040010 || error.response?.status === 401)
471
+ isAxiosError(error) &&
472
+ (error.response?.data.errorCode === 4040010 || error.response?.status === 401)
486
473
  ) {
487
474
  try {
488
475
  const response: AxiosResponse<SingleTransactionResponse> = await axios.get(
489
- `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/${transactionId}`,
490
- {
491
- headers: {
492
- Authorization: `Bearer ${this.generateAppleJWT()}`,
493
- "Content-Type": "application/json",
494
- },
495
- }
476
+ `https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/${transactionId}`,
477
+ {
478
+ headers: {
479
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
480
+ "Content-Type": "application/json",
481
+ },
482
+ }
496
483
  );
497
484
 
498
485
  return { signedTransactionInfo: jwt.decode(response.data.signedTransactionInfo) };
@@ -515,13 +502,13 @@ export class AuthenticationUtil {
515
502
  const productIds: string[] = [];
516
503
  const url = process.env.PURCHASE_HISTORY_URL || "https://api.storekit.itunes.apple.com";
517
504
  const response: AxiosResponse = await axios.get(
518
- `${url}/inApps/v2/history/${transactionId}?productType=NON_CONSUMABLE`,
519
- {
520
- headers: {
521
- Authorization: `Bearer ${this.generateAppleJWT()}`,
522
- "Content-Type": "application/json",
523
- },
524
- }
505
+ `${url}/inApps/v2/history/${transactionId}?productType=NON_CONSUMABLE`,
506
+ {
507
+ headers: {
508
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
509
+ "Content-Type": "application/json",
510
+ },
511
+ }
525
512
  );
526
513
 
527
514
  for (const transaction of response.data.signedTransactions) {
@@ -539,21 +526,21 @@ export class AuthenticationUtil {
539
526
  * Extend Apple subscription
540
527
  */
541
528
  public static async extendAppleSubscription(
542
- transactionId: string,
543
- extendByDays: number
529
+ transactionId: string,
530
+ extendByDays: number
544
531
  ): Promise<any> {
545
532
  const response: AxiosResponse = await axios.put(
546
- `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/extend/${transactionId}`,
547
- {
548
- extendByDays,
549
- extendReasonCode: 1,
550
- requestIdentifier: require("crypto").randomUUID(),
551
- },
552
- {
553
- headers: {
554
- Authorization: `Bearer ${this.generateAppleJWT()}`,
533
+ `https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/extend/${transactionId}`,
534
+ {
535
+ extendByDays,
536
+ extendReasonCode: 1,
537
+ requestIdentifier: require("crypto").randomUUID(),
555
538
  },
556
- }
539
+ {
540
+ headers: {
541
+ Authorization: `Bearer ${this.generateAppleJWT()}`,
542
+ },
543
+ }
557
544
  );
558
545
 
559
546
  return response.data;
@@ -584,12 +571,12 @@ export class AuthenticationUtil {
584
571
  const credentials = await this.getAndroidAccessToken();
585
572
 
586
573
  const response: AxiosResponse = await axios.get(
587
- `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${process.env.ANDROID_PACKAGE_NAME || "nl.browney.nintydayschallenge"}/purchases/subscriptionsv2/tokens/${token}`,
588
- {
589
- headers: {
590
- Authorization: `Bearer ${credentials.access_token as string}`,
591
- },
592
- }
574
+ `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${process.env.ANDROID_PACKAGE_NAME || "nl.browney.nintydayschallenge"}/purchases/subscriptionsv2/tokens/${token}`,
575
+ {
576
+ headers: {
577
+ Authorization: `Bearer ${credentials.access_token as string}`,
578
+ },
579
+ }
593
580
  );
594
581
 
595
582
  return response.data;
@@ -620,17 +607,17 @@ export class AuthenticationUtil {
620
607
  const credentials = await this.getAndroidAccessToken();
621
608
 
622
609
  const response: AxiosResponse = await axios.get(
623
- `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${process.env.ANDROID_PACKAGE_NAME || "nl.browney.nintydayschallenge"}/purchases/subscriptionsv2/tokens/${token}`,
624
- {
625
- headers: {
626
- Authorization: `Bearer ${credentials.access_token as string}`,
627
- },
628
- }
610
+ `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${process.env.ANDROID_PACKAGE_NAME || "nl.browney.nintydayschallenge"}/purchases/subscriptionsv2/tokens/${token}`,
611
+ {
612
+ headers: {
613
+ Authorization: `Bearer ${credentials.access_token as string}`,
614
+ },
615
+ }
629
616
  );
630
617
 
631
618
  return (
632
- (response.data as { subscriptionState: string }).subscriptionState ===
633
- "SUBSCRIPTION_STATE_ACTIVE"
619
+ (response.data as { subscriptionState: string }).subscriptionState ===
620
+ "SUBSCRIPTION_STATE_ACTIVE"
634
621
  );
635
622
  } catch (error) {
636
623
  if (isAxiosError(error)) {