Sesame-Server/Sources/App/routes.swift
2022-01-29 10:26:30 +01:00

93 lines
2.9 KiB
Swift
Executable File

import Vapor
extension PublicAPI {
var path: PathComponent {
.init(stringLiteral: rawValue)
}
var pathParameter: PathComponent {
.parameter(rawValue)
}
}
private func keyTransmission(_ req: Request) -> EventLoopFuture<KeyResult> {
guard let keyId = req.parameters.get(PublicAPI.postKeyIdParameter.rawValue, as: UInt16.self) else {
return req.eventLoop.makeSucceededFuture(.invalidKeyIndex)
}
guard let body = req.body.data else {
return req.eventLoop.makeSucceededFuture(.noBodyData)
}
guard body.readableBytes == KeyManagement.keySize else {
return req.eventLoop.makeSucceededFuture(.invalidPayloadSize)
}
guard let key = body.getData(at: 0, length: KeyManagement.keySize) else {
return req.eventLoop.makeSucceededFuture(.corruptkeyData)
}
return keyManager.sendKeyToDevice(key, keyId: keyId, on: req.eventLoop)
}
func routes(_ app: Application) throws {
/**
Get the connection status of the device.
The response is a string of either "1" (connected) or "0" (disconnected)
*/
app.get(PublicAPI.getDeviceStatus.path) { req -> String in
keyManager.deviceStatus
}
/**
Get the response from the device.
The response is a string of an integer `rawValue` of a `KeyResult`
*/
app.get(PublicAPI.getDeviceResponse.path) { req -> String in
keyManager.deviceResponse
}
/**
Post a request to remove the information about the last key transmission.
- The request always succeeds and returns the string "Success"
*/
app.post(PublicAPI.clearKeyRequest.path) { req -> String in
keyManager.clearClientRequest()
return "Success"
}
/**
Post a key to the device for unlocking.
The corresponding integer key id for the key data must be contained in the url path.
The request returns a string containing a `rawValue` of a `KeyPostResponse`
A success of this method does not yet signal successful unlocking.
The client should request the status by inquiring the device response.
*/
app.post(PublicAPI.postKey.path, PublicAPI.postKeyIdParameter.pathParameter) { req in
keyTransmission(req).map { String($0.rawValue) }
}
/**
Start a new websocket connection for the client to receive table updates from the server
- Returns: Nothing
- Note: The first (and only) message from the client over the connection must be a valid session token.
*/
app.webSocket(PublicAPI.socket.path) { req, socket in
socket.onBinary { _, data in
keyManager.processDeviceResponse(data)
}
socket.onText { _, text in
keyManager.authenticateDevice(psk: text)
}
_ = socket.onClose.always { _ in
keyManager.didCloseDeviceSocket()
}
keyManager.createNewDeviceConnection(socket)
}
}