This is a Node.js Express API that provides authentication, subscription management, and device-based session management. The backend uses Firebase for authentication and SQLite for session storage.
- Firebase authentication integration
- Device-based session management system
- Subscription management with OTP verification
- Secure API endpoints with middleware protection
- Single active device per user (prevents multiple logins)
- Request/response logging with daily log files
- Centralized error handling with standardized responses
- Automatic log cleanup (logs older than 3 months are removed)
- Rate limiting protection against API abuse
- Node.js and Express
- Firebase Authentication and Admin SDK
- SQLite (via better-sqlite3)
- Express Async Handler for error management
- UUID for session ID generation
- Node.js (v18 or higher)
- npm
- Firebase project with authentication enabled
-
Clone the repository:
git clone https://github.com/sxchintha/ideamart-mspace-subscription-service.git -
Install dependencies:
npm install -
Create a
.envfile based on.env.sample -
Add
firebase.jsonto config folder. -
Start the development server:
npm run dev
All API endpoints require authentication using Firebase ID tokens. To access protected endpoints:
- Authenticate the user on the client side using Firebase Authentication
- Obtain the user's ID token using
getIdToken()from the Firebase Auth SDK - Include the token in the
Authorizationheader asBearer <firebase-id-token>
Example:
// Get the ID token from Firebase Auth
const idToken = await firebase.auth().currentUser.getIdToken();
// Include it in your API request
fetch("/auth/subscriber-id", {
headers: {
Authorization: `Bearer ${idToken}`,
},
});GET /auth/subscriber-id
Retrieves the subscriber ID associated with the authenticated user.
Headers:
Authorization: Bearer <firebase-id-token>
Response:
{
"apiStatus": "success",
"subscriberId": "subscriber-id-value"
}POST /auth/update-device
Registers or updates a device for the authenticated user. This endpoint is used for device-based session management.
Headers:
Authorization: Bearer <firebase-id-token>
Request Body:
{
"deviceId": "unique-device-identifier"
}Response:
{
"apiStatus": "success",
"message": "Device registered successfully",
"updatedAt": 1234567890
}GET /auth/check-device
Checks if the current device is valid for the authenticated user.
Headers:
Authorization: Bearer <firebase-id-token>x-device-id: unique-device-identifier
Response (Valid Device):
{
"apiStatus": "success",
"message": "Device is valid",
"isCurrentDevice": true,
"updatedAt": 1234567890
}Response (Invalid Device):
{
"apiStatus": "success",
"message": "Device is not the current registered device",
"isCurrentDevice": false,
"updatedAt": 1234567890,
"statusCode": "DEVICE_MISMATCH"
}All subscription endpoints require authentication and valid device verification.
POST /subscription/otp/request
Requests an OTP for subscription verification.
Headers:
Authorization: Bearer <firebase-id-token>x-device-id: unique-device-identifier
Request Body:
{
"subscriberId": "phone-number-or-subscriber-id",
"device": "device-name",
"os": "operating-system"
}Response:
{
"apiStatus": "success",
"data": {
"referenceNo": "reference-number-for-verification"
}
}POST /subscription/otp/verify
Verifies the OTP and completes the subscription process.
Headers:
Authorization: Bearer <firebase-id-token>x-device-id: unique-device-identifier
Request Body:
{
"subscriberId": "phone-number-or-subscriber-id",
"referenceNo": "reference-number-from-otp-request",
"otp": "one-time-password"
}Response:
{
"apiStatus": "success",
"data": {
"statusCode": "success-code",
"subscriberId": "masked-subscriber-id"
}
}POST /subscription/unsubscribe
Unsubscribes a user from the service.
Headers:
Authorization: Bearer <firebase-id-token>x-device-id: unique-device-identifier
Request Body:
{
"subscriberId": "phone-number-or-subscriber-id"
}Response:
{
"apiStatus": "success",
"data": {
"statusCode": "success-code"
}
}POST /subscription/get-status
Gets the current subscription status for a user.
Headers:
Authorization: Bearer <firebase-id-token>x-device-id: unique-device-identifier
Request Body:
{
"subscriberId": "phone-number-or-subscriber-id"
}Response:
{
"apiStatus": "success",
"data": {
"statusCode": "status-code",
"subscriptionStatus": "active/inactive"
}
}POST /subscription/get-charging-info
Gets charging information for a subscriber.
Headers:
Authorization: Bearer <firebase-id-token>x-device-id: unique-device-identifier
Request Body:
{
"subscriberId": "phone-number-or-subscriber-id"
}Response:
{
"apiStatus": "success",
"data": {
"chargingInfo": {
// Charging details
}
}
}The backend implements a device-based session management system to prevent multiple logins from the same account. Here's how it works:
- Single active device per user
- Automatic device registration and updating
- Tracks last update time for each device
- Device validation middleware
- API endpoints for device registration and checking
- Device information is stored in a SQLite database
- Each user can have only one active device at a time
- When a user registers a new device, it becomes their active device
- The system tracks when each device was last updated
For all authenticated requests, include the device ID in the x-device-id header:
x-device-id: unique-device-identifier
If a device ID is missing:
{
"apiStatus": "error",
"message": "Device ID is required"
}If a user tries to access a protected route with an invalid device:
{
"apiStatus": "error",
"message": "This account is logged in on another device",
"statusCode": "DEVICE_MISMATCH"
}npm start- Start the production servernpm run dev- Start the development server with nodemonnpm run build- No build step required (placeholder)
/controllers- Request handlers for each route/middleware- Express middleware for authentication and session verification/services- Business logic and external service integrations/routes- API route definitions/config- Configuration files (Firebase, etc.)/database- SQLite database files/constants- Application constants and status codes/utils- Utility functions/logs- Application log files
This project is licensed under the MIT License. See the LICENSE file for details.
This project is not officially affiliated with Dialog Ideamart or mSpace.