mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-05 17:05:53 +08:00
Point bridge download to GitHub
This commit is contained in:
50
server/api/bridge/connect.post.ts
Normal file
50
server/api/bridge/connect.post.ts
Normal 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,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
44
server/api/bridge/me.get.ts
Normal file
44
server/api/bridge/me.get.ts
Normal 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,
|
||||
}
|
||||
})
|
||||
|
||||
63
server/api/bridge/status.post.ts
Normal file
63
server/api/bridge/status.post.ts
Normal 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,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
32
server/models/BridgeToken.ts
Normal file
32
server/models/BridgeToken.ts
Normal 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
14
server/utils/bridge.ts
Normal 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user