Sesame-Server/Sources/App/routes.swift

88 lines
3.2 KiB
Swift
Raw Normal View History

2022-01-23 20:49:06 +01:00
import Vapor
2022-04-13 14:56:47 +02:00
extension RouteAPI {
2022-01-24 17:17:06 +01:00
var path: PathComponent {
.init(stringLiteral: rawValue)
}
var pathParameter: PathComponent {
.parameter(rawValue)
}
}
2023-11-10 13:45:42 +01:00
private func messageTransmission(_ req: Request) async throws -> Data {
2022-01-24 17:17:06 +01:00
guard let body = req.body.data else {
2023-11-10 13:45:42 +01:00
throw MessageResult.noBodyData
2022-01-24 17:17:06 +01:00
}
2022-05-01 13:12:16 +02:00
guard let message = ServerMessage(decodeFrom: body) else {
2023-11-10 13:45:42 +01:00
throw MessageResult.invalidMessageSize
2022-01-24 17:17:06 +01:00
}
2022-05-01 13:12:16 +02:00
guard deviceManager.authenticateRemote(message.authToken) else {
2023-11-10 13:45:42 +01:00
throw MessageResult.messageAuthenticationFailed
2022-05-01 13:12:16 +02:00
}
2023-11-10 13:45:42 +01:00
return try await deviceManager.sendMessageToDevice(message.message, on: req.eventLoop)
2022-05-01 13:12:16 +02:00
}
2023-11-10 13:45:42 +01:00
private func deviceStatus(_ req: Request) -> MessageResult {
2022-05-01 13:12:16 +02:00
guard let body = req.body.data else {
2023-11-10 13:45:42 +01:00
return .noBodyData
2022-05-01 13:12:16 +02:00
}
guard let authToken = ServerMessage.token(from: body) else {
2023-11-10 13:45:42 +01:00
return .invalidMessageSize
2022-05-01 13:12:16 +02:00
}
guard deviceManager.authenticateRemote(authToken) else {
2023-11-10 13:45:42 +01:00
return .messageAuthenticationFailed
2022-05-01 13:12:16 +02:00
}
guard deviceManager.deviceIsConnected else {
2023-11-10 13:45:42 +01:00
return .deviceNotConnected
2022-05-01 13:12:16 +02:00
}
2023-11-10 13:45:42 +01:00
return .deviceConnected
2022-01-24 17:17:06 +01:00
}
2022-01-23 20:49:06 +01:00
func routes(_ app: Application) throws {
2022-01-24 17:17:06 +01:00
/**
Get the connection status of the device.
2022-05-01 13:12:16 +02:00
The request expects the authentication token of the remote in the body data of the POST request.
2022-01-24 17:17:06 +01:00
2022-05-01 13:12:16 +02:00
The request returns one byte of data, which is the raw value of a `MessageResult`.
2023-08-09 16:26:07 +02:00
Possible results are `noBodyData`, `invalidMessageSize`, `deviceNotConnected`, `deviceConnected`.
2022-01-24 17:17:06 +01:00
*/
2023-11-10 13:45:42 +01:00
app.post(RouteAPI.getDeviceStatus.path) { request in
let result = deviceStatus(request)
return Response(status: .ok, body: .init(data: result.encoded))
2022-01-24 17:17:06 +01:00
}
/**
Post a message to the device for unlocking.
2022-05-01 13:12:16 +02:00
The expects a `ServerMessage` in the body data of the POST request, containing the valid remote authentication token and the message to send to the device.
2022-01-24 17:17:06 +01:00
2022-04-07 23:53:25 +02:00
The request returns one or `Message.length+1` bytes of data, where the first byte is the raw value of a `MessageResult`,
and the optional following bytes contain the response message of the device. This request does not complete until either the device responds or the request times out. The timeout is specified by `KeyManagement.deviceTimeout`.
2022-01-24 17:17:06 +01:00
*/
2023-11-10 13:45:42 +01:00
app.post(RouteAPI.postMessage.path) { request async throws in
do {
let result = try await messageTransmission(request)
return Response(status: .ok, body: .init(data: result))
} catch let error as MessageResult {
return Response(status: .ok, body: .init(data: error.encoded))
2022-04-07 23:53:25 +02:00
}
2022-01-23 20:49:06 +01:00
}
/**
Start a new websocket connection for the device to receive messages from the server
2022-01-23 20:49:06 +01:00
- Returns: Nothing
- Note: The first message from the device over the connection must be a valid auth token.
2022-01-23 20:49:06 +01:00
*/
2023-12-06 09:05:41 +01:00
app.webSocket(RouteAPI.socket.path) { request, socket async in
guard let authToken = request.headers.first(name: "Authorization") else {
try? await socket.close()
return
}
await deviceManager.createNewDeviceConnection(socket: socket, auth: authToken)
2022-01-23 20:49:06 +01:00
}
}