Point bridge download to GitHub

This commit is contained in:
Remi
2025-09-24 00:01:00 +02:00
parent 4b859f6998
commit b756bf2ea6
7 changed files with 709 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
import { createError, readBody } from 'h3'
import { requireUserSession } from '../../utils/auth'
import { normalizeBridgeToken } from '../../utils/bridge'
import { BridgeToken } from '../../models/BridgeToken'
interface ConnectBody {
token?: string
}
export default defineEventHandler(async (event) => {
const user = await requireUserSession(event)
const body = await readBody<ConnectBody>(event)
const token = normalizeBridgeToken(body.token)
if (!token) {
throw createError({ statusCode: 400, statusMessage: 'Ungültiger Token übergeben.' })
}
const now = new Date()
const document = await BridgeToken.findOneAndUpdate(
{ token },
{
$set: {
user: user._id,
connectedAt: now,
},
$setOnInsert: {
token,
},
},
{ upsert: true, new: true, runValidators: true },
).populate('user', 'name email')
if (!document) {
throw createError({ statusCode: 500, statusMessage: 'Token konnte nicht gespeichert werden.' })
}
return {
success: true,
token: document.token,
connectedAt: document.connectedAt?.toISOString() ?? now.toISOString(),
user: {
id: String(user._id),
email: user.email,
name: user.name,
},
}
})

View File

@@ -0,0 +1,44 @@
import { createError, getQuery } from 'h3'
import { BridgeToken } from '../../models/BridgeToken'
import { normalizeBridgeToken } from '../../utils/bridge'
import type { UserDocument } from '../../models/User'
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const token = normalizeBridgeToken(query.token as string | undefined)
if (!token) {
throw createError({ statusCode: 400, statusMessage: 'Token muss übergeben werden.' })
}
const document = await BridgeToken.findOne({ token }).populate('user', 'name email')
if (!document || !document.user) {
return {
token,
connected: false,
user: null,
simConnected: false,
flightActive: false,
connectedAt: document?.connectedAt ? document.connectedAt.toISOString() : null,
lastStatusAt: document?.lastStatusAt ? document.lastStatusAt.toISOString() : null,
}
}
const bridgeUser = document.user as UserDocument
return {
token: document.token,
connected: true,
user: {
id: String(bridgeUser._id),
email: bridgeUser.email,
name: bridgeUser.name,
},
simConnected: document.simConnected,
flightActive: document.flightActive,
connectedAt: document.connectedAt?.toISOString() ?? document.updatedAt.toISOString(),
lastStatusAt: document.lastStatusAt ? document.lastStatusAt.toISOString() : null,
}
})

View File

@@ -0,0 +1,63 @@
import { createError, readBody } from 'h3'
import { BridgeToken } from '../../models/BridgeToken'
import { normalizeBridgeToken } from '../../utils/bridge'
import type { UserDocument } from '../../models/User'
interface StatusBody {
token?: string
simConnected?: boolean
flightActive?: boolean
}
export default defineEventHandler(async (event) => {
const body = await readBody<StatusBody>(event)
const token = normalizeBridgeToken(body.token)
if (!token) {
throw createError({ statusCode: 400, statusMessage: 'Token muss übergeben werden.' })
}
const updatePayload: Record<string, unknown> = {
lastStatusAt: new Date(),
}
if (typeof body.simConnected === 'boolean') {
updatePayload.simConnected = body.simConnected
}
if (typeof body.flightActive === 'boolean') {
updatePayload.flightActive = body.flightActive
}
const document = await BridgeToken.findOneAndUpdate(
{ token },
{
$set: updatePayload,
$setOnInsert: { token },
},
{ new: true, upsert: true, runValidators: true },
).populate('user', 'name email')
if (!document) {
throw createError({ statusCode: 500, statusMessage: 'Status konnte nicht aktualisiert werden.' })
}
const user = document.user as UserDocument | undefined
return {
token: document.token,
connected: Boolean(user),
user: user
? {
id: String(user._id),
email: user.email,
name: user.name,
}
: null,
simConnected: document.simConnected,
flightActive: document.flightActive,
connectedAt: document.connectedAt ? document.connectedAt.toISOString() : null,
lastStatusAt: document.lastStatusAt ? document.lastStatusAt.toISOString() : null,
}
})

View File

@@ -9,6 +9,9 @@ export default defineEventHandler(async (event) => {
if (url.pathname.startsWith('/api/service/')) {
return
}
if (url.pathname.startsWith('/api/bridge/')) {
return
}
if (event.node.req.method === 'OPTIONS') {
return
}

View File

@@ -0,0 +1,32 @@
import mongoose from 'mongoose'
import type { UserDocument } from './User'
export interface BridgeTokenDocument extends mongoose.Document {
token: string
user?: mongoose.Types.ObjectId | UserDocument
connectedAt?: Date
lastStatusAt?: Date
simConnected: boolean
flightActive: boolean
createdAt: Date
updatedAt: Date
}
const bridgeTokenSchema = new mongoose.Schema<BridgeTokenDocument>(
{
token: { type: String, required: true, unique: true, index: true },
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
connectedAt: { type: Date },
lastStatusAt: { type: Date },
simConnected: { type: Boolean, default: false },
flightActive: { type: Boolean, default: false },
},
{
timestamps: true,
},
)
export const BridgeToken =
(mongoose.models.BridgeToken as mongoose.Model<BridgeTokenDocument> | undefined) ||
mongoose.model<BridgeTokenDocument>('BridgeToken', bridgeTokenSchema)

14
server/utils/bridge.ts Normal file
View File

@@ -0,0 +1,14 @@
export function normalizeBridgeToken(input: unknown) {
if (typeof input !== 'string') {
return null
}
const token = input.trim()
if (!token) {
return null
}
if (token.length < 8 || token.length > 256) {
return null
}
return token
}