Sesame-Server/Sources/App/routes.swift
2023-12-08 15:43:29 +01:00

49 lines
2.3 KiB
Swift
Executable File

import Vapor
func routes(_ app: Application) {
/**
Post a message to the device for unlocking.
The expects a `Message` in the body data of the POST request, containing the message to send to the device.
Expects a header ``RouteAPI.authenticationHeader`` with the hexencoded authentication token with binary length ``ServerMessage.authTokenSize``.
The request returns the ``ServerMessage.messageSize`` bytes of data constituting the device response,
or a status code corresponding to a ``MessageResult``.
This request does not complete until either the device responds or the request times out.
The timeout is specified by the configuration parameter `deviceTimeout`.
*/
app.post(SesameRoute.postMessage.path) { request async throws in
do {
guard let authString = request.headers.first(name: SesameHeader.authenticationHeader),
let authToken = Data(fromHexEncodedString: authString),
authToken.count == SesameHeader.serverAuthenticationTokenSize else {
throw MessageResult.missingOrInvalidAuthenticationHeaderFromRemote
}
guard let body = request.body.data,
let message = body.getData(at: 0, length: body.readableBytes) else {
throw MessageResult.noOrInvalidBodyDataFromRemote
}
let responseMessage = try await deviceManager.sendMessageToDevice(message, authToken: authToken, on: request.eventLoop)
return Response(status: .ok, body: .init(data: responseMessage))
} catch let error as MessageResult {
return Response(status: .init(statusCode: error.statusCode))
}
}
/**
Start a new websocket connection for the device to receive messages from the server.
The request must contain a header ``RouteAPI.socketAuthenticationHeader`` with a valid authentication token.
*/
app.webSocket(SesameRoute.socket.path) { request, socket async in
guard let authToken = request.headers.first(name: SesameHeader.authenticationHeader) else {
try? await socket.close()
return
}
await deviceManager.createNewDeviceConnection(socket: socket, auth: authToken)
}
}