add CORS setting
This commit is contained in:
@@ -2,3 +2,4 @@ API_USERNAME=
|
|||||||
API_PASSWORD=
|
API_PASSWORD=
|
||||||
PORT=3000
|
PORT=3000
|
||||||
FIXED_STAFF_ACTIVITY_ID=7095
|
FIXED_STAFF_ACTIVITY_ID=7095
|
||||||
|
ALLOWED_ORIGINS=*
|
||||||
47
main.js
47
main.js
@@ -1,6 +1,7 @@
|
|||||||
// main.js
|
// main.js
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
|
import cors from 'cors'; // Import the cors middleware
|
||||||
import { fetchActivityData } from './engage-api/get-activity.mjs';
|
import { fetchActivityData } from './engage-api/get-activity.mjs';
|
||||||
import { structActivityData } from './engage-api/struct-activity.mjs';
|
import { structActivityData } from './engage-api/struct-activity.mjs';
|
||||||
import { structStaffData } from './engage-api/struct-staff.mjs';
|
import { structStaffData } from './engage-api/struct-staff.mjs';
|
||||||
@@ -11,13 +12,38 @@ dotenv.config();
|
|||||||
// --- Configuration ---
|
// --- Configuration ---
|
||||||
const USERNAME = process.env.API_USERNAME;
|
const USERNAME = process.env.API_USERNAME;
|
||||||
const PASSWORD = process.env.API_PASSWORD;
|
const PASSWORD = process.env.API_PASSWORD;
|
||||||
const PORT = process.env.PORT || 3000; // Default to port 3000 if not specified
|
const PORT = process.env.PORT || 3000;
|
||||||
const FIXED_STAFF_ACTIVITY_ID = process.env.FIXED_STAFF_ACTIVITY_ID || '3350';
|
const FIXED_STAFF_ACTIVITY_ID = process.env.FIXED_STAFF_ACTIVITY_ID || '3350';
|
||||||
|
const allowedOriginsEnv = process.env.ALLOWED_ORIGINS || '*';
|
||||||
|
|
||||||
|
let corsOptions;
|
||||||
|
|
||||||
|
if (allowedOriginsEnv === '*') {
|
||||||
|
corsOptions = { origin: '*' };
|
||||||
|
} else {
|
||||||
|
// If ALLOWED_ORIGINS is a comma-separated list, split it into an array
|
||||||
|
const originsArray = allowedOriginsEnv.split(',').map(origin => origin.trim());
|
||||||
|
corsOptions = {
|
||||||
|
origin: function (origin, callback) {
|
||||||
|
// Allow requests with no origin (like mobile apps or curl requests)
|
||||||
|
if (!origin) return callback(null, true);
|
||||||
|
if (originsArray.indexOf(origin) !== -1 || originsArray.includes('*')) {
|
||||||
|
callback(null, true);
|
||||||
|
} else {
|
||||||
|
callback(new Error('Not allowed by CORS'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// --- Initialize Express App ---
|
// --- Initialize Express App ---
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
// Middleware to parse JSON request bodies (useful if you add POST/PUT later)
|
// Apply CORS middleware globally FIRST
|
||||||
|
// This will add the 'Access-Control-Allow-Origin' header to all responses
|
||||||
|
app.use(cors(corsOptions));
|
||||||
|
|
||||||
|
// Middleware to parse JSON request bodies
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
// --- API Endpoints ---
|
// --- API Endpoints ---
|
||||||
@@ -32,9 +58,8 @@ app.get('/', (req, res) => {
|
|||||||
|
|
||||||
// GET Endpoint: Fetch structured activity data by ID
|
// GET Endpoint: Fetch structured activity data by ID
|
||||||
app.get('/v1/activity/:activityId', async (req, res) => {
|
app.get('/v1/activity/:activityId', async (req, res) => {
|
||||||
let { activityId } = req.params; // Extract activityId from URL parameter
|
let { activityId } = req.params;
|
||||||
|
|
||||||
// Validate activityId: should be 1 to 4 digits
|
|
||||||
if (!/^\d{1,4}$/.test(activityId)) {
|
if (!/^\d{1,4}$/.test(activityId)) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error: 'Invalid Activity ID format. Activity ID must be 1 to 4 digits (e.g., 1, 0001, 9999).'
|
error: 'Invalid Activity ID format. Activity ID must be 1 to 4 digits (e.g., 1, 0001, 9999).'
|
||||||
@@ -51,7 +76,7 @@ app.get('/v1/activity/:activityId', async (req, res) => {
|
|||||||
const activityJson = await fetchActivityData(activityId, USERNAME, PASSWORD);
|
const activityJson = await fetchActivityData(activityId, USERNAME, PASSWORD);
|
||||||
if (activityJson) {
|
if (activityJson) {
|
||||||
const structuredActivity = await structActivityData(activityJson);
|
const structuredActivity = await structActivityData(activityJson);
|
||||||
res.json(structuredActivity); // Assuming structActivityData returns a JSON-friendly object
|
res.json(structuredActivity);
|
||||||
} else {
|
} else {
|
||||||
res.status(404).json({ error: `Could not retrieve details for activity ${activityId}.` });
|
res.status(404).json({ error: `Could not retrieve details for activity ${activityId}.` });
|
||||||
}
|
}
|
||||||
@@ -72,9 +97,7 @@ app.get('/v1/staffs', async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
const activityJson = await fetchActivityData(FIXED_STAFF_ACTIVITY_ID, USERNAME, PASSWORD);
|
const activityJson = await fetchActivityData(FIXED_STAFF_ACTIVITY_ID, USERNAME, PASSWORD);
|
||||||
if (activityJson) {
|
if (activityJson) {
|
||||||
const staffMap = await structStaffData(activityJson); // This returns a Map
|
const staffMap = await structStaffData(activityJson);
|
||||||
|
|
||||||
// Convert Map to a plain object for JSON serialization
|
|
||||||
const staffObject = Object.fromEntries(staffMap);
|
const staffObject = Object.fromEntries(staffMap);
|
||||||
res.json(staffObject);
|
res.json(staffObject);
|
||||||
} else {
|
} else {
|
||||||
@@ -89,17 +112,17 @@ app.get('/v1/staffs', async (req, res) => {
|
|||||||
// --- Start the Server ---
|
// --- Start the Server ---
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
console.log(`Server is running on http://localhost:${PORT}`);
|
console.log(`Server is running on http://localhost:${PORT}`);
|
||||||
|
console.log(`Allowed CORS origins: ${allowedOriginsEnv === '*' ? 'All (*)' : allowedOriginsEnv}`);
|
||||||
console.log('API Endpoints:');
|
console.log('API Endpoints:');
|
||||||
console.log(` GET /v1/activity/:activityId (ID must be 1-4 digits)`);
|
console.log(` GET /v1/activity/:activityId (ID must be 1-4 digits)`);
|
||||||
console.log(` GET /v1/staffs`);
|
console.log(` GET /v1/staffs`);
|
||||||
if (!USERNAME || !PASSWORD) {
|
if (!USERNAME || !PASSWORD) {
|
||||||
console.warn('Warning: API_USERNAME or API_PASSWORD is not set. Please configure them in your .env file or environment variables.');
|
console.warn('Warning: API_USERNAME or API_PASSWORD is not set. Please configure them in your .env file or environment variables.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Graceful shutdown (optional but good practice)
|
// Graceful shutdown
|
||||||
process.on('SIGINT', () => {
|
process.on('SIGINT', () => {
|
||||||
console.log('Server shutting down...');
|
console.log('Server shutting down...');
|
||||||
// Perform any cleanup here
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"node-fetch": "^3.3.2"
|
"node-fetch": "^3.3.2"
|
||||||
|
|||||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
|||||||
axios:
|
axios:
|
||||||
specifier: ^1.9.0
|
specifier: ^1.9.0
|
||||||
version: 1.9.0
|
version: 1.9.0
|
||||||
|
cors:
|
||||||
|
specifier: ^2.8.5
|
||||||
|
version: 2.8.5
|
||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^16.5.0
|
specifier: ^16.5.0
|
||||||
version: 16.5.0
|
version: 16.5.0
|
||||||
@@ -69,6 +72,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
|
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
cors@2.8.5:
|
||||||
|
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||||
|
engines: {node: '>= 0.10'}
|
||||||
|
|
||||||
data-uri-to-buffer@4.0.1:
|
data-uri-to-buffer@4.0.1:
|
||||||
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
|
||||||
engines: {node: '>= 12'}
|
engines: {node: '>= 12'}
|
||||||
@@ -254,6 +261,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
|
object-assign@4.1.1:
|
||||||
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
object-inspect@1.13.4:
|
object-inspect@1.13.4:
|
||||||
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -413,6 +424,11 @@ snapshots:
|
|||||||
|
|
||||||
cookie@0.7.2: {}
|
cookie@0.7.2: {}
|
||||||
|
|
||||||
|
cors@2.8.5:
|
||||||
|
dependencies:
|
||||||
|
object-assign: 4.1.1
|
||||||
|
vary: 1.1.2
|
||||||
|
|
||||||
data-uri-to-buffer@4.0.1: {}
|
data-uri-to-buffer@4.0.1: {}
|
||||||
|
|
||||||
debug@4.4.0:
|
debug@4.4.0:
|
||||||
@@ -599,6 +615,8 @@ snapshots:
|
|||||||
fetch-blob: 3.2.0
|
fetch-blob: 3.2.0
|
||||||
formdata-polyfill: 4.0.10
|
formdata-polyfill: 4.0.10
|
||||||
|
|
||||||
|
object-assign@4.1.1: {}
|
||||||
|
|
||||||
object-inspect@1.13.4: {}
|
object-inspect@1.13.4: {}
|
||||||
|
|
||||||
on-finished@2.4.1:
|
on-finished@2.4.1:
|
||||||
|
|||||||
Reference in New Issue
Block a user