49 lines
2.3 KiB
Swift
Executable File
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)
|
|
}
|
|
}
|