mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-10 11:33:26 +08:00
feat(websim): browser A320 cockpit to test /live-atc without MSFS (WIP)
Flight model (ground/air physics, SELECTED/NAV/APPR/AUTOLAND autopilot with STAR sequencing and ILS capture), bridge client that feeds the existing /api/bridge/* endpoints so /live-atc can't tell it apart from a real bridge, and the cockpit UI (PFD reuse, FCU, radio panel, Leaflet ND, three.js exterior, spawn presets at EDDF/EDDS). Design doc: docs/plans/2026-07-16-websim-design.md. Also adds a local-dev-only auto-login (/dev-login, server/api/dev/login.post.ts) that bypasses the invite-only login and MongoDB entirely via a fixed in-memory user, so require-auth pages are reachable for local testing even when the dev DB is unreachable. Hard-disabled outside development. Status: unit tests green (yarn test) and typecheck clean (yarn typecheck). Browser walkthrough of the actual cockpit (flying a preset, confirming telemetry reaches /live-atc) is not yet done — picking up from a fresh dev server + /dev-login?redirect=/flightlab/websim confirmed the spawn screen renders past auth, but full instrument/map/exterior verification is still outstanding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -131,6 +131,28 @@ function parseAuthorizationHeader(event: H3Event) {
|
||||
return token
|
||||
}
|
||||
|
||||
// Local-dev-only bypass session (server/api/dev/login.post.ts): a fixed,
|
||||
// entirely in-memory "user" that never touches MongoDB, so require-auth
|
||||
// pages are reachable for local testing even when the dev DB is unreachable.
|
||||
// The sub value is deliberately not a real ObjectId — resolveUserFromToken
|
||||
// below matches it BEFORE ever calling User.findById.
|
||||
export const DEV_BYPASS_USER_ID = 'dev-bypass-user'
|
||||
const DEV_BYPASS_EMAIL = 'dev-claude@localhost.test'
|
||||
|
||||
export function getDevBypassUser(): UserDocument {
|
||||
return {
|
||||
_id: DEV_BYPASS_USER_ID,
|
||||
email: DEV_BYPASS_EMAIL,
|
||||
name: 'Dev Test User',
|
||||
role: 'user',
|
||||
tokenVersion: 0,
|
||||
createdAt: new Date(0),
|
||||
invitationCodesIssued: 0,
|
||||
acceptedTermsAt: new Date(0),
|
||||
acceptedPrivacyAt: new Date(0),
|
||||
} as unknown as UserDocument
|
||||
}
|
||||
|
||||
export async function resolveUserFromToken(event: H3Event) {
|
||||
const token = parseAuthorizationHeader(event)
|
||||
if (!token) return null
|
||||
@@ -138,6 +160,9 @@ export async function resolveUserFromToken(event: H3Event) {
|
||||
const { accessSecret } = getSecrets()
|
||||
const payload = verifyJwtToken(token, accessSecret)
|
||||
if (!payload?.sub) return null
|
||||
if (payload.sub === DEV_BYPASS_USER_ID && process.env.NODE_ENV !== 'production') {
|
||||
return getDevBypassUser()
|
||||
}
|
||||
const user = await User.findById(payload.sub)
|
||||
if (!user) return null
|
||||
if (typeof payload.version === 'number' && payload.version !== user.tokenVersion) {
|
||||
|
||||
Reference in New Issue
Block a user