Skip to content

Commit 728c7e2

Browse files
authored
Merge pull request #9 from PFConnect/Fixproblem
Fixproblem
2 parents cf5d604 + 922a69a commit 728c7e2

33 files changed

+1428
-369
lines changed

.github/workflows/lint.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: lint
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths-ignore:
8+
- 'README.md'
9+
pull_request:
10+
branches:
11+
- main
12+
paths-ignore:
13+
- 'README.md'
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v4
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: 20
27+
cache: 'npm'
28+
29+
- name: Install dependencies
30+
run: npm ci
31+
32+
- name: Run lint
33+
run: npm run lint
34+
35+
- name: Run type check
36+
run: npm run type-check
37+
38+
- name: Build project
39+
run: npm run build-only

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ npm run dev
4747

4848
**Note:**
4949

50-
- Make sure Docker is installed and running on your machine.
5150
- For any issues or missing environment variables, reach out to the maintainers.
5251

53-
---
52+
---

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,11 @@
88
"prod": "cross-env NODE_ENV=production node server/server.js",
99
"build": "vite build --mode production",
1010
"build:dev": "vite build --mode development",
11-
"docker:build": "docker build -t pfcontrol-v2 .",
12-
"docker:run": "docker run -p 9900:9900 --env-file .env.production pfcontrol-v2",
13-
"docker:dev": "docker-compose -f docker-compose.dev.yml up --build",
14-
"docker:prod": "docker-compose up --build -d",
15-
"docker:stop": "docker-compose down",
16-
"docker:restart": "docker-compose down && docker-compose up --build -d",
17-
"docker:clean": "docker-compose down -v && docker system prune -f",
18-
"docker:update": "git pull && docker-compose down && docker-compose up --build -d",
19-
"docker:logs": "docker-compose logs -f",
20-
"docker:status": "docker-compose ps"
11+
"build-only": "vite build",
12+
"lint": "eslint .",
13+
"format:check": "prettier --check .",
14+
"format": "prettier --write .",
15+
"type-check": "tsc --noEmit"
2116
},
2217
"dependencies": {
2318
"@dnd-kit/core": "^6.3.1",
@@ -64,6 +59,7 @@
6459
"eslint-plugin-react-refresh": "^0.4.20",
6560
"globals": "^16.4.0",
6661
"nodemon": "^3.1.10",
62+
"prettier": "^3.6.2",
6763
"typescript": "~5.8.3",
6864
"typescript-eslint": "^8.44.0",
6965
"vite": "^7.1.7"
File renamed without changes.
31.8 KB
Binary file not shown.

server/db/flights.js

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import { generateSID, generateSquawk, getWakeTurbulence, generateRandomId } from '../utils/flightUtils.js';
1+
import {
2+
generateSID,
3+
generateSquawk,
4+
getWakeTurbulence,
5+
generateRandomId,
6+
} from '../utils/flightUtils.js';
27
import { getSessionById } from './sessions.js';
38
import flightsPool from './connections/flightsConnection.js';
9+
import crypto from 'crypto';
410

511
function sanitizeFlightForClient(flight) {
6-
const { user_id, ip_address, ...sanitizedFlight } = flight;
12+
const { user_id, ip_address, acars_token, ...sanitizedFlight } = flight;
713
return {
814
...sanitizedFlight,
915
cruisingFL: flight.cruisingfl,
@@ -17,35 +23,59 @@ export async function getFlightsBySession(sessionId) {
1723
`SELECT * FROM ${tableName} ORDER BY created_at ASC`
1824
);
1925

20-
const flights = result.rows.map(flight => sanitizeFlightForClient(flight));
26+
const flights = result.rows.map((flight) =>
27+
sanitizeFlightForClient(flight)
28+
);
2129
return flights;
2230
}
2331

32+
export async function validateAcarsAccess(sessionId, flightId, acarsToken) {
33+
const tableName = `flights_${sessionId}`;
34+
const result = await flightsPool.query(
35+
`SELECT acars_token FROM ${tableName} WHERE id = $1`,
36+
[flightId]
37+
);
38+
39+
if (result.rows.length === 0) {
40+
return false;
41+
}
42+
43+
return result.rows[0].acars_token === acarsToken;
44+
}
45+
2446
export async function getFlightsBySessionWithTime(sessionId, hoursBack = 2) {
2547
try {
2648
const tableName = `flights_${sessionId}`;
2749

28-
const tableExists = await flightsPool.query(`
50+
const tableExists = await flightsPool.query(
51+
`
2952
SELECT EXISTS (
3053
SELECT FROM information_schema.tables
3154
WHERE table_name = $1
3255
)
33-
`, [tableName]);
56+
`,
57+
[tableName]
58+
);
3459

3560
if (!tableExists.rows[0].exists) {
3661
return [];
3762
}
3863

3964
const result = await flightsPool.query(
4065
`SELECT * FROM ${tableName}
41-
WHERE created_at >= NOW() - INTERVAL '${hoursBack} hours'
42-
ORDER BY created_at ASC`
66+
WHERE created_at >= NOW() - INTERVAL '${hoursBack} hours'
67+
ORDER BY created_at ASC`
4368
);
4469

45-
const flights = result.rows.map(flight => sanitizeFlightForClient(flight));
70+
const flights = result.rows.map((flight) =>
71+
sanitizeFlightForClient(flight)
72+
);
4673
return flights;
4774
} catch (error) {
48-
console.error(`Error fetching flights for session ${sessionId}:`, error);
75+
console.error(
76+
`Error fetching flights for session ${sessionId}:`,
77+
error
78+
);
4979
return [];
5080
}
5181
}
@@ -68,21 +98,27 @@ function validateFlightFields(updates) {
6898
if (updates.cruisingFL !== undefined) {
6999
const fl = parseInt(updates.cruisingFL, 10);
70100
if (isNaN(fl) || fl < 0 || fl > 200 || fl % 5 !== 0) {
71-
throw new Error('Cruising FL must be between 0 and 200 in 50-step increments');
101+
throw new Error(
102+
'Cruising FL must be between 0 and 200 in 50-step increments'
103+
);
72104
}
73105
}
74106
if (updates.clearedFL !== undefined) {
75107
const fl = parseInt(updates.clearedFL, 10);
76108
if (isNaN(fl) || fl < 0 || fl > 200 || fl % 5 !== 0) {
77-
throw new Error('Cleared FL must be between 0 and 200 in 50-step increments');
109+
throw new Error(
110+
'Cleared FL must be between 0 and 200 in 50-step increments'
111+
);
78112
}
79113
}
80114
}
81115

82116
export async function addFlight(sessionId, flightData) {
83117
const tableName = `flights_${sessionId}`;
84118
try {
85-
await flightsPool.query(`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS gate VARCHAR(8);`);
119+
await flightsPool.query(
120+
`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS gate VARCHAR(8);`
121+
);
86122
} catch (error) {
87123
// Column might already exist, continue
88124
}
@@ -98,6 +134,7 @@ export async function addFlight(sessionId, flightData) {
98134
if (!flightData.timestamp) {
99135
flightData.timestamp = new Date().toISOString();
100136
}
137+
flightData.acars_token = crypto.randomBytes(4).toString('hex');
101138

102139
if (flightData.aircraft_type) {
103140
flightData.aircraft = flightData.aircraft_type;
@@ -113,7 +150,10 @@ export async function addFlight(sessionId, flightData) {
113150
flightData.runway = session.active_runway;
114151
}
115152
} catch (error) {
116-
console.error('Error fetching session for runway assignment:', error);
153+
console.error(
154+
'Error fetching session for runway assignment:',
155+
error
156+
);
117157
}
118158
}
119159

@@ -147,20 +187,32 @@ export async function addFlight(sessionId, flightData) {
147187
const result = await flightsPool.query(query, values);
148188

149189
const flight = result.rows[0];
150-
return sanitizeFlightForClient(flight);
190+
return {
191+
...flight,
192+
cruisingFL: flight.cruisingfl,
193+
clearedFL: flight.clearedfl,
194+
};
151195
}
152196

153197
export async function updateFlight(sessionId, flightId, updates) {
154198
const tableName = `flights_${sessionId}`;
155199

156200
// add this block to create missing text columns safely
157-
const safeCols = Object.keys(updates).filter(k => /^[a-zA-Z0-9_]+$/.test(k));
201+
const safeCols = Object.keys(updates).filter((k) =>
202+
/^[a-zA-Z0-9_]+$/.test(k)
203+
);
158204
for (const col of safeCols) {
159205
try {
160-
await flightsPool.query(`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS "${col}" text;`);
206+
await flightsPool.query(
207+
`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS "${col}" text;`
208+
);
161209
} catch (err) {
162210
// ignore - column creation failure shouldn't stop update
163-
console.error('Could not ensure column exists:', col, err?.message || err);
211+
console.error(
212+
'Could not ensure column exists:',
213+
col,
214+
err?.message || err
215+
);
164216
}
165217
}
166218

@@ -204,5 +256,7 @@ export async function updateFlight(sessionId, flightId, updates) {
204256

205257
export async function deleteFlight(sessionId, flightId) {
206258
const tableName = `flights_${sessionId}`;
207-
await flightsPool.query(`DELETE FROM ${tableName} WHERE id = $1`, [flightId]);
208-
}
259+
await flightsPool.query(`DELETE FROM ${tableName} WHERE id = $1`, [
260+
flightId,
261+
]);
262+
}

0 commit comments

Comments
 (0)